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:
Daniel Vetter 2017-03-11 11:46:03 +01:00
Родитель 35dc8aabc8 76adb460fd
Коммит a45216547e
22 изменённых файлов: 237 добавлений и 337 удалений

Просмотреть файл

@ -240,9 +240,6 @@ drivers.
.. kernel-doc:: drivers/gpu/drm/drm_pci.c .. kernel-doc:: drivers/gpu/drm/drm_pci.c
:export: :export:
.. kernel-doc:: drivers/gpu/drm/drm_platform.c
:export:
Open/Close, File Operations and IOCTLs 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_file.o drm_gem.o drm_ioctl.o drm_irq.o \
drm_lock.o drm_memory.o drm_drv.o \ drm_lock.o drm_memory.o drm_drv.o \
drm_scatter.o drm_pci.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_crtc.o drm_fourcc.o drm_modes.o drm_edid.o \
drm_info.o drm_encoder_slave.o \ drm_info.o drm_encoder_slave.o \
drm_trace_points.o drm_global.o drm_prime.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; return ret;
} }
priv->drm.platformdev = to_platform_device(dev);
priv->drm.dev_private = priv; 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_WORK(&priv->fb_unref_work, armada_drm_unref_work);
INIT_KFIFO(priv->fb_unref); 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); struct exynos_dp_device *dp = to_dp(plat_data);
int ret; int ret;
drm_connector_register(connector);
dp->connector = connector; dp->connector = connector;
/* Pre-empt DP connector creation if there's a bridge */ /* 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_helper_add(connector, &exynos_dpi_connector_helper_funcs);
drm_connector_register(connector);
drm_mode_connector_attach_encoder(connector, encoder); drm_mode_connector_attach_encoder(connector, encoder);
return 0; return 0;

Просмотреть файл

@ -39,118 +39,6 @@
static struct device *exynos_drm_get_dma_device(void); 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, int exynos_atomic_check(struct drm_device *dev,
struct drm_atomic_state *state) 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 = { static struct drm_driver exynos_drm_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME
| DRIVER_ATOMIC | DRIVER_RENDER, | DRIVER_ATOMIC | DRIVER_RENDER,
.load = exynos_drm_load,
.unload = exynos_drm_unload,
.open = exynos_drm_open, .open = exynos_drm_open,
.preclose = exynos_drm_preclose, .preclose = exynos_drm_preclose,
.lastclose = exynos_drm_lastclose, .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) 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) 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 = { 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_helper_add(connector, &exynos_dsi_connector_helper_funcs);
drm_connector_register(connector);
drm_mode_connector_attach_encoder(connector, encoder); drm_mode_connector_attach_encoder(connector, encoder);
return 0; return 0;

Просмотреть файл

@ -119,7 +119,6 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
struct exynos_drm_gem *exynos_gem; struct exynos_drm_gem *exynos_gem;
struct drm_device *dev = helper->dev; struct drm_device *dev = helper->dev;
struct drm_mode_fb_cmd2 mode_cmd = { 0 }; struct drm_mode_fb_cmd2 mode_cmd = { 0 };
struct platform_device *pdev = dev->platformdev;
unsigned long size; unsigned long size;
int ret; int ret;
@ -142,7 +141,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
* memory area. * memory area.
*/ */
if (IS_ERR(exynos_gem) && is_drm_iommu_supported(dev)) { 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, exynos_gem = exynos_drm_gem_create(dev, EXYNOS_BO_NONCONTIG,
size); 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_helper_add(connector, &vidi_connector_helper_funcs);
drm_connector_register(connector);
drm_mode_connector_attach_encoder(connector, encoder); drm_mode_connector_attach_encoder(connector, encoder);
return 0; 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_helper_add(connector, &hdmi_connector_helper_funcs);
drm_connector_register(connector);
drm_mode_connector_attach_encoder(connector, encoder); drm_mode_connector_attach_encoder(connector, encoder);
if (hdata->bridge) { if (hdata->bridge) {

Просмотреть файл

@ -434,7 +434,7 @@ fail:
struct msm_kms *mdp4_kms_init(struct drm_device *dev) 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_platform_config *config = mdp4_get_config(pdev);
struct mdp4_kms *mdp4_kms; struct mdp4_kms *mdp4_kms;
struct msm_kms *kms = NULL; 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) uint32_t major, uint32_t minor)
{ {
struct drm_device *dev = mdp5_kms->dev; 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_handler *cfg_handler;
struct mdp5_cfg_platform *pconfig; struct mdp5_cfg_platform *pconfig;
int i, ret = 0; int i, ret = 0;

Просмотреть файл

@ -160,7 +160,7 @@ void msm_mdss_destroy(struct drm_device *dev)
int msm_mdss_init(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_drm_private *priv = dev->dev_private;
struct msm_mdss *mdss; struct msm_mdss *mdss;
int ret; int ret;

Просмотреть файл

@ -386,7 +386,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
} }
platform_set_drvdata(pdev, ddev); platform_set_drvdata(pdev, ddev);
ddev->platformdev = pdev;
priv = kzalloc(sizeof(*priv), GFP_KERNEL); priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv) { if (!priv) {

Просмотреть файл

@ -108,7 +108,7 @@ nouveau_name(struct drm_device *dev)
if (dev->pdev) if (dev->pdev)
return nouveau_pci_name(dev->pdev); return nouveau_pci_name(dev->pdev);
else else
return nouveau_platform_name(dev->platformdev); return nouveau_platform_name(to_platform_device(dev->dev));
} }
static void static void
@ -1095,7 +1095,6 @@ nouveau_platform_device_create(const struct nvkm_device_tegra_func *func,
goto err_free; goto err_free;
} }
drm->platformdev = pdev;
platform_set_drvdata(pdev, drm); platform_set_drvdata(pdev, drm);
return drm; return drm;

Просмотреть файл

@ -711,13 +711,10 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,
return ret; return ret;
drm_connector_helper_add(connector, &connector_helper_funcs); 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); ret = shmob_drm_backlight_init(&sdev->connector);
if (ret < 0) if (ret < 0)
goto err_sysfs; goto err_cleanup;
ret = drm_mode_connector_attach_encoder(connector, encoder); ret = drm_mode_connector_attach_encoder(connector, encoder);
if (ret < 0) if (ret < 0)
@ -731,8 +728,6 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,
err_backlight: err_backlight:
shmob_drm_backlight_exit(&sdev->connector); shmob_drm_backlight_exit(&sdev->connector);
err_sysfs:
drm_connector_unregister(connector);
err_cleanup: err_cleanup:
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
return ret; return ret;

Просмотреть файл

@ -103,100 +103,6 @@ static int shmob_drm_setup_clocks(struct shmob_drm_device *sdev,
* DRM operations * 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) static irqreturn_t shmob_drm_irq(int irq, void *arg)
{ {
struct drm_device *dev = 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 = { static struct drm_driver shmob_drm_driver = {
.driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET
| DRIVER_PRIME, | DRIVER_PRIME,
.load = shmob_drm_load,
.unload = shmob_drm_unload,
.irq_handler = shmob_drm_irq, .irq_handler = shmob_drm_irq,
.gem_free_object_unlocked = drm_gem_cma_free_object, .gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops, .gem_vm_ops = &drm_gem_cma_vm_ops,
@ -297,20 +201,118 @@ static const struct dev_pm_ops shmob_drm_pm_ops = {
* Platform driver * 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) static int shmob_drm_remove(struct platform_device *pdev)
{ {
struct shmob_drm_device *sdev = platform_get_drvdata(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; 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 = { static struct platform_driver shmob_drm_platform_driver = {
.probe = shmob_drm_probe, .probe = shmob_drm_probe,
.remove = shmob_drm_remove, .remove = shmob_drm_remove,

Просмотреть файл

@ -263,8 +263,6 @@ static int sti_bind(struct device *dev)
if (IS_ERR(ddev)) if (IS_ERR(ddev))
return PTR_ERR(ddev); return PTR_ERR(ddev);
ddev->platformdev = to_platform_device(dev);
ret = sti_init(ddev); ret = sti_init(ddev);
if (ret) if (ret)
goto err_drm_dev_unref; goto err_drm_dev_unref;

Просмотреть файл

@ -245,7 +245,6 @@ static int tilcdc_init(struct drm_driver *ddrv, struct device *dev)
if (IS_ERR(ddev)) if (IS_ERR(ddev))
return PTR_ERR(ddev); return PTR_ERR(ddev);
ddev->platformdev = pdev;
ddev->dev_private = priv; ddev->dev_private = priv;
platform_set_drvdata(pdev, ddev); platform_set_drvdata(pdev, ddev);
drm_mode_config_init(ddev); drm_mode_config_init(ddev);

Просмотреть файл

@ -501,7 +501,6 @@ struct drm_device {
struct pci_controller *hose; struct pci_controller *hose;
#endif #endif
struct platform_device *platformdev; /**< Platform device struture */
struct virtio_device *virtdev; struct virtio_device *virtdev;
struct drm_sg_mem *sg; /**< Scatter gather memory */ 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_speed_cap_mask(struct drm_device *dev, u32 *speed_mask);
extern int drm_pcie_get_max_link_width(struct drm_device *dev, u32 *mlw); 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_ */ #endif /* _DRM_PCI_H_ */