mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
Merge branch 'drm/next/platform' of git://linuxtv.org/pinchartl/media into drm-misc-next
Merge Laurent's drm_platform removal code. Only conflict is with the drm_pci.h extraction, which allows me to fix up the misplayed drm_platform_init fumble that 0day and Stephen Rothwell reported. Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
This commit is contained in:
commit
a45216547e
@ -240,9 +240,6 @@ drivers.
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_pci.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_platform.c
|
||||
:export:
|
||||
|
||||
Open/Close, File Operations and IOCTLs
|
||||
======================================
|
||||
|
||||
|
@ -7,7 +7,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \
|
||||
drm_file.o drm_gem.o drm_ioctl.o drm_irq.o \
|
||||
drm_lock.o drm_memory.o drm_drv.o \
|
||||
drm_scatter.o drm_pci.o \
|
||||
drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \
|
||||
drm_sysfs.o drm_hashtab.o drm_mm.o \
|
||||
drm_crtc.o drm_fourcc.o drm_modes.o drm_edid.o \
|
||||
drm_info.o drm_encoder_slave.o \
|
||||
drm_trace_points.o drm_global.o drm_prime.o \
|
||||
|
@ -137,10 +137,9 @@ static int armada_drm_bind(struct device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
priv->drm.platformdev = to_platform_device(dev);
|
||||
priv->drm.dev_private = priv;
|
||||
|
||||
platform_set_drvdata(priv->drm.platformdev, &priv->drm);
|
||||
dev_set_drvdata(dev, &priv->drm);
|
||||
|
||||
INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work);
|
||||
INIT_KFIFO(priv->fb_unref);
|
||||
|
@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Derived from drm_pci.c
|
||||
*
|
||||
* Copyright 2003 José Fonseca.
|
||||
* Copyright 2003 Leif Delgass.
|
||||
* Copyright (c) 2009, Code Aurora Forum.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <drm/drmP.h>
|
||||
|
||||
/*
|
||||
* Register.
|
||||
*
|
||||
* \param platdev - Platform device struture
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
* Attempt to gets inter module "drm" information. If we are first
|
||||
* then register the character device and inter module information.
|
||||
* Try and register, if we fail to register, backout previous work.
|
||||
*/
|
||||
|
||||
static int drm_get_platform_dev(struct platform_device *platdev,
|
||||
struct drm_driver *driver)
|
||||
{
|
||||
struct drm_device *dev;
|
||||
int ret;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
dev = drm_dev_alloc(driver, &platdev->dev);
|
||||
if (IS_ERR(dev))
|
||||
return PTR_ERR(dev);
|
||||
|
||||
dev->platformdev = platdev;
|
||||
|
||||
ret = drm_dev_register(dev, 0);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free:
|
||||
drm_dev_unref(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_platform_init - Register a platform device with the DRM subsystem
|
||||
* @driver: DRM device driver
|
||||
* @platform_device: platform device to register
|
||||
*
|
||||
* Registers the specified DRM device driver and platform device with the DRM
|
||||
* subsystem, initializing a drm_device structure and calling the driver's
|
||||
* .load() function.
|
||||
*
|
||||
* NOTE: This function is deprecated, please use drm_dev_alloc() and
|
||||
* drm_dev_register() instead and remove your &drm_driver.load callback.
|
||||
*
|
||||
* Return: 0 on success or a negative error code on failure.
|
||||
*/
|
||||
int drm_platform_init(struct drm_driver *driver, struct platform_device *platform_device)
|
||||
{
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
return drm_get_platform_dev(platform_device, driver);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_platform_init);
|
@ -101,7 +101,6 @@ static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data,
|
||||
struct exynos_dp_device *dp = to_dp(plat_data);
|
||||
int ret;
|
||||
|
||||
drm_connector_register(connector);
|
||||
dp->connector = connector;
|
||||
|
||||
/* Pre-empt DP connector creation if there's a bridge */
|
||||
|
@ -114,7 +114,6 @@ static int exynos_dpi_create_connector(struct drm_encoder *encoder)
|
||||
}
|
||||
|
||||
drm_connector_helper_add(connector, &exynos_dpi_connector_helper_funcs);
|
||||
drm_connector_register(connector);
|
||||
drm_mode_connector_attach_encoder(connector, encoder);
|
||||
|
||||
return 0;
|
||||
|
@ -39,118 +39,6 @@
|
||||
|
||||
static struct device *exynos_drm_get_dma_device(void);
|
||||
|
||||
static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
|
||||
{
|
||||
struct exynos_drm_private *private;
|
||||
struct drm_encoder *encoder;
|
||||
unsigned int clone_mask;
|
||||
int cnt, ret;
|
||||
|
||||
private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL);
|
||||
if (!private)
|
||||
return -ENOMEM;
|
||||
|
||||
init_waitqueue_head(&private->wait);
|
||||
spin_lock_init(&private->lock);
|
||||
|
||||
dev_set_drvdata(dev->dev, dev);
|
||||
dev->dev_private = (void *)private;
|
||||
|
||||
/* the first real CRTC device is used for all dma mapping operations */
|
||||
private->dma_dev = exynos_drm_get_dma_device();
|
||||
if (!private->dma_dev) {
|
||||
DRM_ERROR("no device found for DMA mapping operations.\n");
|
||||
ret = -ENODEV;
|
||||
goto err_free_private;
|
||||
}
|
||||
DRM_INFO("Exynos DRM: using %s device for DMA mapping operations\n",
|
||||
dev_name(private->dma_dev));
|
||||
|
||||
/* create common IOMMU mapping for all devices attached to Exynos DRM */
|
||||
ret = drm_create_iommu_mapping(dev);
|
||||
if (ret < 0) {
|
||||
DRM_ERROR("failed to create iommu mapping.\n");
|
||||
goto err_free_private;
|
||||
}
|
||||
|
||||
drm_mode_config_init(dev);
|
||||
|
||||
exynos_drm_mode_config_init(dev);
|
||||
|
||||
/* setup possible_clones. */
|
||||
cnt = 0;
|
||||
clone_mask = 0;
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
|
||||
clone_mask |= (1 << (cnt++));
|
||||
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
|
||||
encoder->possible_clones = clone_mask;
|
||||
|
||||
platform_set_drvdata(dev->platformdev, dev);
|
||||
|
||||
/* Try to bind all sub drivers. */
|
||||
ret = component_bind_all(dev->dev, dev);
|
||||
if (ret)
|
||||
goto err_mode_config_cleanup;
|
||||
|
||||
ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
|
||||
if (ret)
|
||||
goto err_unbind_all;
|
||||
|
||||
/* Probe non kms sub drivers and virtual display driver. */
|
||||
ret = exynos_drm_device_subdrv_probe(dev);
|
||||
if (ret)
|
||||
goto err_cleanup_vblank;
|
||||
|
||||
drm_mode_config_reset(dev);
|
||||
|
||||
/*
|
||||
* enable drm irq mode.
|
||||
* - with irq_enabled = true, we can use the vblank feature.
|
||||
*
|
||||
* P.S. note that we wouldn't use drm irq handler but
|
||||
* just specific driver own one instead because
|
||||
* drm framework supports only one irq handler.
|
||||
*/
|
||||
dev->irq_enabled = true;
|
||||
|
||||
/* init kms poll for handling hpd */
|
||||
drm_kms_helper_poll_init(dev);
|
||||
|
||||
/* force connectors detection */
|
||||
drm_helper_hpd_irq_event(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_cleanup_vblank:
|
||||
drm_vblank_cleanup(dev);
|
||||
err_unbind_all:
|
||||
component_unbind_all(dev->dev, dev);
|
||||
err_mode_config_cleanup:
|
||||
drm_mode_config_cleanup(dev);
|
||||
drm_release_iommu_mapping(dev);
|
||||
err_free_private:
|
||||
kfree(private);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void exynos_drm_unload(struct drm_device *dev)
|
||||
{
|
||||
exynos_drm_device_subdrv_remove(dev);
|
||||
|
||||
exynos_drm_fbdev_fini(dev);
|
||||
drm_kms_helper_poll_fini(dev);
|
||||
|
||||
drm_vblank_cleanup(dev);
|
||||
component_unbind_all(dev->dev, dev);
|
||||
drm_mode_config_cleanup(dev);
|
||||
drm_release_iommu_mapping(dev);
|
||||
|
||||
kfree(dev->dev_private);
|
||||
dev->dev_private = NULL;
|
||||
}
|
||||
|
||||
int exynos_atomic_check(struct drm_device *dev,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
@ -256,8 +144,6 @@ static const struct file_operations exynos_drm_driver_fops = {
|
||||
static struct drm_driver exynos_drm_driver = {
|
||||
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME
|
||||
| DRIVER_ATOMIC | DRIVER_RENDER,
|
||||
.load = exynos_drm_load,
|
||||
.unload = exynos_drm_unload,
|
||||
.open = exynos_drm_open,
|
||||
.preclose = exynos_drm_preclose,
|
||||
.lastclose = exynos_drm_lastclose,
|
||||
@ -432,12 +318,135 @@ static struct component_match *exynos_drm_match_add(struct device *dev)
|
||||
|
||||
static int exynos_drm_bind(struct device *dev)
|
||||
{
|
||||
return drm_platform_init(&exynos_drm_driver, to_platform_device(dev));
|
||||
struct exynos_drm_private *private;
|
||||
struct drm_encoder *encoder;
|
||||
struct drm_device *drm;
|
||||
unsigned int clone_mask;
|
||||
int cnt, ret;
|
||||
|
||||
drm = drm_dev_alloc(&exynos_drm_driver, dev);
|
||||
if (IS_ERR(drm))
|
||||
return PTR_ERR(drm);
|
||||
|
||||
private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL);
|
||||
if (!private) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free_drm;
|
||||
}
|
||||
|
||||
init_waitqueue_head(&private->wait);
|
||||
spin_lock_init(&private->lock);
|
||||
|
||||
dev_set_drvdata(dev, drm);
|
||||
drm->dev_private = (void *)private;
|
||||
|
||||
/* the first real CRTC device is used for all dma mapping operations */
|
||||
private->dma_dev = exynos_drm_get_dma_device();
|
||||
if (!private->dma_dev) {
|
||||
DRM_ERROR("no device found for DMA mapping operations.\n");
|
||||
ret = -ENODEV;
|
||||
goto err_free_private;
|
||||
}
|
||||
DRM_INFO("Exynos DRM: using %s device for DMA mapping operations\n",
|
||||
dev_name(private->dma_dev));
|
||||
|
||||
/* create common IOMMU mapping for all devices attached to Exynos DRM */
|
||||
ret = drm_create_iommu_mapping(drm);
|
||||
if (ret < 0) {
|
||||
DRM_ERROR("failed to create iommu mapping.\n");
|
||||
goto err_free_private;
|
||||
}
|
||||
|
||||
drm_mode_config_init(drm);
|
||||
|
||||
exynos_drm_mode_config_init(drm);
|
||||
|
||||
/* setup possible_clones. */
|
||||
cnt = 0;
|
||||
clone_mask = 0;
|
||||
list_for_each_entry(encoder, &drm->mode_config.encoder_list, head)
|
||||
clone_mask |= (1 << (cnt++));
|
||||
|
||||
list_for_each_entry(encoder, &drm->mode_config.encoder_list, head)
|
||||
encoder->possible_clones = clone_mask;
|
||||
|
||||
/* Try to bind all sub drivers. */
|
||||
ret = component_bind_all(drm->dev, drm);
|
||||
if (ret)
|
||||
goto err_mode_config_cleanup;
|
||||
|
||||
ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
|
||||
if (ret)
|
||||
goto err_unbind_all;
|
||||
|
||||
/* Probe non kms sub drivers and virtual display driver. */
|
||||
ret = exynos_drm_device_subdrv_probe(drm);
|
||||
if (ret)
|
||||
goto err_cleanup_vblank;
|
||||
|
||||
drm_mode_config_reset(drm);
|
||||
|
||||
/*
|
||||
* enable drm irq mode.
|
||||
* - with irq_enabled = true, we can use the vblank feature.
|
||||
*
|
||||
* P.S. note that we wouldn't use drm irq handler but
|
||||
* just specific driver own one instead because
|
||||
* drm framework supports only one irq handler.
|
||||
*/
|
||||
drm->irq_enabled = true;
|
||||
|
||||
/* init kms poll for handling hpd */
|
||||
drm_kms_helper_poll_init(drm);
|
||||
|
||||
/* force connectors detection */
|
||||
drm_helper_hpd_irq_event(drm);
|
||||
|
||||
/* register the DRM device */
|
||||
ret = drm_dev_register(drm, 0);
|
||||
if (ret < 0)
|
||||
goto err_cleanup_fbdev;
|
||||
|
||||
return 0;
|
||||
|
||||
err_cleanup_fbdev:
|
||||
exynos_drm_fbdev_fini(drm);
|
||||
drm_kms_helper_poll_fini(drm);
|
||||
exynos_drm_device_subdrv_remove(drm);
|
||||
err_cleanup_vblank:
|
||||
drm_vblank_cleanup(drm);
|
||||
err_unbind_all:
|
||||
component_unbind_all(drm->dev, drm);
|
||||
err_mode_config_cleanup:
|
||||
drm_mode_config_cleanup(drm);
|
||||
drm_release_iommu_mapping(drm);
|
||||
err_free_private:
|
||||
kfree(private);
|
||||
err_free_drm:
|
||||
drm_dev_unref(drm);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void exynos_drm_unbind(struct device *dev)
|
||||
{
|
||||
drm_put_dev(dev_get_drvdata(dev));
|
||||
struct drm_device *drm = dev_get_drvdata(dev);
|
||||
|
||||
drm_dev_unregister(drm);
|
||||
|
||||
exynos_drm_device_subdrv_remove(drm);
|
||||
|
||||
exynos_drm_fbdev_fini(drm);
|
||||
drm_kms_helper_poll_fini(drm);
|
||||
|
||||
component_unbind_all(drm->dev, drm);
|
||||
drm_mode_config_cleanup(drm);
|
||||
drm_release_iommu_mapping(drm);
|
||||
|
||||
kfree(drm->dev_private);
|
||||
drm->dev_private = NULL;
|
||||
|
||||
drm_dev_unref(drm);
|
||||
}
|
||||
|
||||
static const struct component_master_ops exynos_drm_ops = {
|
||||
|
@ -1587,7 +1587,6 @@ static int exynos_dsi_create_connector(struct drm_encoder *encoder)
|
||||
}
|
||||
|
||||
drm_connector_helper_add(connector, &exynos_dsi_connector_helper_funcs);
|
||||
drm_connector_register(connector);
|
||||
drm_mode_connector_attach_encoder(connector, encoder);
|
||||
|
||||
return 0;
|
||||
|
@ -119,7 +119,6 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
|
||||
struct exynos_drm_gem *exynos_gem;
|
||||
struct drm_device *dev = helper->dev;
|
||||
struct drm_mode_fb_cmd2 mode_cmd = { 0 };
|
||||
struct platform_device *pdev = dev->platformdev;
|
||||
unsigned long size;
|
||||
int ret;
|
||||
|
||||
@ -142,7 +141,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
|
||||
* memory area.
|
||||
*/
|
||||
if (IS_ERR(exynos_gem) && is_drm_iommu_supported(dev)) {
|
||||
dev_warn(&pdev->dev, "contiguous FB allocation failed, falling back to non-contiguous\n");
|
||||
dev_warn(dev->dev, "contiguous FB allocation failed, falling back to non-contiguous\n");
|
||||
exynos_gem = exynos_drm_gem_create(dev, EXYNOS_BO_NONCONTIG,
|
||||
size);
|
||||
}
|
||||
|
@ -359,7 +359,6 @@ static int vidi_create_connector(struct drm_encoder *encoder)
|
||||
}
|
||||
|
||||
drm_connector_helper_add(connector, &vidi_connector_helper_funcs);
|
||||
drm_connector_register(connector);
|
||||
drm_mode_connector_attach_encoder(connector, encoder);
|
||||
|
||||
return 0;
|
||||
|
@ -920,7 +920,6 @@ static int hdmi_create_connector(struct drm_encoder *encoder)
|
||||
}
|
||||
|
||||
drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
|
||||
drm_connector_register(connector);
|
||||
drm_mode_connector_attach_encoder(connector, encoder);
|
||||
|
||||
if (hdata->bridge) {
|
||||
|
@ -434,7 +434,7 @@ fail:
|
||||
|
||||
struct msm_kms *mdp4_kms_init(struct drm_device *dev)
|
||||
{
|
||||
struct platform_device *pdev = dev->platformdev;
|
||||
struct platform_device *pdev = to_platform_device(dev->dev);
|
||||
struct mdp4_platform_config *config = mdp4_get_config(pdev);
|
||||
struct mdp4_kms *mdp4_kms;
|
||||
struct msm_kms *kms = NULL;
|
||||
|
@ -505,7 +505,7 @@ struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms,
|
||||
uint32_t major, uint32_t minor)
|
||||
{
|
||||
struct drm_device *dev = mdp5_kms->dev;
|
||||
struct platform_device *pdev = dev->platformdev;
|
||||
struct platform_device *pdev = to_platform_device(dev->dev);
|
||||
struct mdp5_cfg_handler *cfg_handler;
|
||||
struct mdp5_cfg_platform *pconfig;
|
||||
int i, ret = 0;
|
||||
|
@ -160,7 +160,7 @@ void msm_mdss_destroy(struct drm_device *dev)
|
||||
|
||||
int msm_mdss_init(struct drm_device *dev)
|
||||
{
|
||||
struct platform_device *pdev = dev->platformdev;
|
||||
struct platform_device *pdev = to_platform_device(dev->dev);
|
||||
struct msm_drm_private *priv = dev->dev_private;
|
||||
struct msm_mdss *mdss;
|
||||
int ret;
|
||||
|
@ -386,7 +386,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, ddev);
|
||||
ddev->platformdev = pdev;
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv) {
|
||||
|
@ -108,7 +108,7 @@ nouveau_name(struct drm_device *dev)
|
||||
if (dev->pdev)
|
||||
return nouveau_pci_name(dev->pdev);
|
||||
else
|
||||
return nouveau_platform_name(dev->platformdev);
|
||||
return nouveau_platform_name(to_platform_device(dev->dev));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1095,7 +1095,6 @@ nouveau_platform_device_create(const struct nvkm_device_tegra_func *func,
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
drm->platformdev = pdev;
|
||||
platform_set_drvdata(pdev, drm);
|
||||
|
||||
return drm;
|
||||
|
@ -711,13 +711,10 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,
|
||||
return ret;
|
||||
|
||||
drm_connector_helper_add(connector, &connector_helper_funcs);
|
||||
ret = drm_connector_register(connector);
|
||||
if (ret < 0)
|
||||
goto err_cleanup;
|
||||
|
||||
ret = shmob_drm_backlight_init(&sdev->connector);
|
||||
if (ret < 0)
|
||||
goto err_sysfs;
|
||||
goto err_cleanup;
|
||||
|
||||
ret = drm_mode_connector_attach_encoder(connector, encoder);
|
||||
if (ret < 0)
|
||||
@ -731,8 +728,6 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,
|
||||
|
||||
err_backlight:
|
||||
shmob_drm_backlight_exit(&sdev->connector);
|
||||
err_sysfs:
|
||||
drm_connector_unregister(connector);
|
||||
err_cleanup:
|
||||
drm_connector_cleanup(connector);
|
||||
return ret;
|
||||
|
@ -103,100 +103,6 @@ static int shmob_drm_setup_clocks(struct shmob_drm_device *sdev,
|
||||
* DRM operations
|
||||
*/
|
||||
|
||||
static void shmob_drm_unload(struct drm_device *dev)
|
||||
{
|
||||
drm_kms_helper_poll_fini(dev);
|
||||
drm_mode_config_cleanup(dev);
|
||||
drm_vblank_cleanup(dev);
|
||||
drm_irq_uninstall(dev);
|
||||
|
||||
dev->dev_private = NULL;
|
||||
}
|
||||
|
||||
static int shmob_drm_load(struct drm_device *dev, unsigned long flags)
|
||||
{
|
||||
struct shmob_drm_platform_data *pdata = dev->dev->platform_data;
|
||||
struct platform_device *pdev = dev->platformdev;
|
||||
struct shmob_drm_device *sdev;
|
||||
struct resource *res;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
if (pdata == NULL) {
|
||||
dev_err(dev->dev, "no platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sdev = devm_kzalloc(&pdev->dev, sizeof(*sdev), GFP_KERNEL);
|
||||
if (sdev == NULL) {
|
||||
dev_err(dev->dev, "failed to allocate private data\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
sdev->dev = &pdev->dev;
|
||||
sdev->pdata = pdata;
|
||||
spin_lock_init(&sdev->irq_lock);
|
||||
|
||||
sdev->ddev = dev;
|
||||
dev->dev_private = sdev;
|
||||
|
||||
/* I/O resources and clocks */
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (res == NULL) {
|
||||
dev_err(&pdev->dev, "failed to get memory resource\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sdev->mmio = devm_ioremap_nocache(&pdev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (sdev->mmio == NULL) {
|
||||
dev_err(&pdev->dev, "failed to remap memory resource\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = shmob_drm_setup_clocks(sdev, pdata->clk_source);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = shmob_drm_init_interface(sdev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = shmob_drm_modeset_init(sdev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to initialize mode setting\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
ret = shmob_drm_plane_create(sdev, i);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to create plane %u\n", i);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
ret = drm_vblank_init(dev, 1);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to initialize vblank\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = drm_irq_install(dev, platform_get_irq(dev->platformdev, 0));
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to install IRQ handler\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, sdev);
|
||||
|
||||
done:
|
||||
if (ret)
|
||||
shmob_drm_unload(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static irqreturn_t shmob_drm_irq(int irq, void *arg)
|
||||
{
|
||||
struct drm_device *dev = arg;
|
||||
@ -236,8 +142,6 @@ static const struct file_operations shmob_drm_fops = {
|
||||
static struct drm_driver shmob_drm_driver = {
|
||||
.driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET
|
||||
| DRIVER_PRIME,
|
||||
.load = shmob_drm_load,
|
||||
.unload = shmob_drm_unload,
|
||||
.irq_handler = shmob_drm_irq,
|
||||
.gem_free_object_unlocked = drm_gem_cma_free_object,
|
||||
.gem_vm_ops = &drm_gem_cma_vm_ops,
|
||||
@ -297,20 +201,118 @@ static const struct dev_pm_ops shmob_drm_pm_ops = {
|
||||
* Platform driver
|
||||
*/
|
||||
|
||||
static int shmob_drm_probe(struct platform_device *pdev)
|
||||
{
|
||||
return drm_platform_init(&shmob_drm_driver, pdev);
|
||||
}
|
||||
|
||||
static int shmob_drm_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct shmob_drm_device *sdev = platform_get_drvdata(pdev);
|
||||
struct drm_device *ddev = sdev->ddev;
|
||||
|
||||
drm_put_dev(sdev->ddev);
|
||||
drm_dev_unregister(ddev);
|
||||
drm_kms_helper_poll_fini(ddev);
|
||||
drm_mode_config_cleanup(ddev);
|
||||
drm_irq_uninstall(ddev);
|
||||
drm_dev_unref(ddev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shmob_drm_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct shmob_drm_platform_data *pdata = pdev->dev.platform_data;
|
||||
struct shmob_drm_device *sdev;
|
||||
struct drm_device *ddev;
|
||||
struct resource *res;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
if (pdata == NULL) {
|
||||
dev_err(&pdev->dev, "no platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and initialize the driver private data, I/O resources and
|
||||
* clocks.
|
||||
*/
|
||||
sdev = devm_kzalloc(&pdev->dev, sizeof(*sdev), GFP_KERNEL);
|
||||
if (sdev == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
sdev->dev = &pdev->dev;
|
||||
sdev->pdata = pdata;
|
||||
spin_lock_init(&sdev->irq_lock);
|
||||
|
||||
platform_set_drvdata(pdev, sdev);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
sdev->mmio = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (sdev->mmio == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = shmob_drm_setup_clocks(sdev, pdata->clk_source);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = shmob_drm_init_interface(sdev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Allocate and initialize the DRM device. */
|
||||
ddev = drm_dev_alloc(&shmob_drm_driver, &pdev->dev);
|
||||
if (IS_ERR(ddev))
|
||||
return PTR_ERR(ddev);
|
||||
|
||||
sdev->ddev = ddev;
|
||||
ddev->dev_private = sdev;
|
||||
|
||||
ret = shmob_drm_modeset_init(sdev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to initialize mode setting\n");
|
||||
goto err_free_drm_dev;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
ret = shmob_drm_plane_create(sdev, i);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to create plane %u\n", i);
|
||||
goto err_modeset_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
ret = drm_vblank_init(ddev, 1);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to initialize vblank\n");
|
||||
goto err_modeset_cleanup;
|
||||
}
|
||||
|
||||
ret = drm_irq_install(ddev, platform_get_irq(pdev, 0));
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to install IRQ handler\n");
|
||||
goto err_vblank_cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register the DRM device with the core and the connectors with
|
||||
* sysfs.
|
||||
*/
|
||||
ret = drm_dev_register(ddev, 0);
|
||||
if (ret < 0)
|
||||
goto err_irq_uninstall;
|
||||
|
||||
return 0;
|
||||
|
||||
err_irq_uninstall:
|
||||
drm_irq_uninstall(ddev);
|
||||
err_vblank_cleanup:
|
||||
drm_vblank_cleanup(ddev);
|
||||
err_modeset_cleanup:
|
||||
drm_kms_helper_poll_fini(ddev);
|
||||
drm_mode_config_cleanup(ddev);
|
||||
err_free_drm_dev:
|
||||
drm_dev_unref(ddev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver shmob_drm_platform_driver = {
|
||||
.probe = shmob_drm_probe,
|
||||
.remove = shmob_drm_remove,
|
||||
|
@ -263,8 +263,6 @@ static int sti_bind(struct device *dev)
|
||||
if (IS_ERR(ddev))
|
||||
return PTR_ERR(ddev);
|
||||
|
||||
ddev->platformdev = to_platform_device(dev);
|
||||
|
||||
ret = sti_init(ddev);
|
||||
if (ret)
|
||||
goto err_drm_dev_unref;
|
||||
|
@ -245,7 +245,6 @@ static int tilcdc_init(struct drm_driver *ddrv, struct device *dev)
|
||||
if (IS_ERR(ddev))
|
||||
return PTR_ERR(ddev);
|
||||
|
||||
ddev->platformdev = pdev;
|
||||
ddev->dev_private = priv;
|
||||
platform_set_drvdata(pdev, ddev);
|
||||
drm_mode_config_init(ddev);
|
||||
|
@ -501,7 +501,6 @@ struct drm_device {
|
||||
struct pci_controller *hose;
|
||||
#endif
|
||||
|
||||
struct platform_device *platformdev; /**< Platform device struture */
|
||||
struct virtio_device *virtdev;
|
||||
|
||||
struct drm_sg_mem *sg; /**< Scatter gather memory */
|
||||
|
@ -72,7 +72,4 @@ static inline int drm_pci_set_busid(struct drm_device *dev,
|
||||
extern int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *speed_mask);
|
||||
extern int drm_pcie_get_max_link_width(struct drm_device *dev, u32 *mlw);
|
||||
|
||||
/* platform section */
|
||||
extern int drm_platform_init(struct drm_driver *driver, struct platform_device *platform_device);
|
||||
|
||||
#endif /* _DRM_PCI_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user