diff options
Diffstat (limited to 'drivers/gpu/drm/tilcdc/tilcdc_drv.c')
| -rw-r--r-- | drivers/gpu/drm/tilcdc/tilcdc_drv.c | 120 |
1 files changed, 72 insertions, 48 deletions
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index f1d3a9f919fd..7caec4d38ddf 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -13,14 +13,14 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <drm/clients/drm_client_setup.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_debugfs.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_dma.h> #include <drm/drm_fourcc.h> -#include <drm/drm_gem_cma_helper.h> +#include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> -#include <drm/drm_irq.h> #include <drm/drm_mm.h> #include <drm/drm_probe_helper.h> #include <drm/drm_vblank.h> @@ -61,8 +61,6 @@ void tilcdc_module_cleanup(struct tilcdc_module *mod) list_del(&mod->list); } -static struct of_device_id tilcdc_of_match[]; - static int tilcdc_atomic_check(struct drm_device *dev, struct drm_atomic_state *state) { @@ -124,6 +122,39 @@ static int cpufreq_transition(struct notifier_block *nb, } #endif +static irqreturn_t tilcdc_irq(int irq, void *arg) +{ + struct drm_device *dev = arg; + struct tilcdc_drm_private *priv = dev->dev_private; + + return tilcdc_crtc_irq(priv->crtc); +} + +static int tilcdc_irq_install(struct drm_device *dev, unsigned int irq) +{ + struct tilcdc_drm_private *priv = dev->dev_private; + int ret; + + ret = request_irq(irq, tilcdc_irq, 0, dev->driver->name, dev); + if (ret) + return ret; + + priv->irq_enabled = true; + + return 0; +} + +static void tilcdc_irq_uninstall(struct drm_device *dev) +{ + struct tilcdc_drm_private *priv = dev->dev_private; + + if (!priv->irq_enabled) + return; + + free_irq(priv->irq, dev); + priv->irq_enabled = false; +} + /* * DRM operations: */ @@ -145,19 +176,15 @@ static void tilcdc_fini(struct drm_device *dev) drm_dev_unregister(dev); drm_kms_helper_poll_fini(dev); - drm_irq_uninstall(dev); + drm_atomic_helper_shutdown(dev); + tilcdc_irq_uninstall(dev); drm_mode_config_cleanup(dev); if (priv->clk) clk_put(priv->clk); - if (priv->mmio) - iounmap(priv->mmio); - - if (priv->wq) { - flush_workqueue(priv->wq); + if (priv->wq) destroy_workqueue(priv->wq); - } dev->dev_private = NULL; @@ -172,7 +199,6 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct device_node *node = dev->of_node; struct tilcdc_drm_private *priv; - struct resource *res; u32 bpp = 0; int ret; @@ -197,17 +223,10 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) goto init_failed; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "failed to get memory resource\n"); - ret = -EINVAL; - goto init_failed; - } - - priv->mmio = ioremap(res->start, resource_size(res)); - if (!priv->mmio) { - dev_err(dev, "failed to ioremap\n"); - ret = -ENOMEM; + priv->mmio = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->mmio)) { + dev_err(dev, "failed to request / ioremap\n"); + ret = PTR_ERR(priv->mmio); goto init_failed; } @@ -336,7 +355,12 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) goto init_failed; } - ret = drm_irq_install(ddev, platform_get_irq(pdev, 0)); + ret = platform_get_irq(pdev, 0); + if (ret < 0) + goto init_failed; + priv->irq = ret; + + ret = tilcdc_irq_install(ddev, priv->irq); if (ret < 0) { dev_err(dev, "failed to install IRQ handler\n"); goto init_failed; @@ -351,22 +375,17 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) goto init_failed; priv->is_registered = true; - drm_fbdev_generic_setup(ddev, bpp); + drm_client_setup_with_color_mode(ddev, bpp); + return 0; init_failed: tilcdc_fini(ddev); + platform_set_drvdata(pdev, NULL); return ret; } -static irqreturn_t tilcdc_irq(int irq, void *arg) -{ - struct drm_device *dev = arg; - struct tilcdc_drm_private *priv = dev->dev_private; - return tilcdc_crtc_irq(priv->crtc); -} - #if defined(CONFIG_DEBUG_FS) static const struct { const char *name; @@ -450,19 +469,18 @@ static void tilcdc_debugfs_init(struct drm_minor *minor) } #endif -DEFINE_DRM_GEM_CMA_FOPS(fops); +DEFINE_DRM_GEM_DMA_FOPS(fops); static const struct drm_driver tilcdc_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, - .irq_handler = tilcdc_irq, - DRM_GEM_CMA_DRIVER_OPS, + DRM_GEM_DMA_DRIVER_OPS, + DRM_FBDEV_DMA_DRIVER_OPS, #ifdef CONFIG_DEBUG_FS .debugfs_init = tilcdc_debugfs_init, #endif .fops = &fops, .name = "tilcdc", .desc = "TI LCD Controller DRM", - .date = "20121205", .major = 1, .minor = 0, }; @@ -471,7 +489,6 @@ static const struct drm_driver tilcdc_driver = { * Power management: */ -#ifdef CONFIG_PM_SLEEP static int tilcdc_pm_suspend(struct device *dev) { struct drm_device *ddev = dev_get_drvdata(dev); @@ -493,11 +510,9 @@ static int tilcdc_pm_resume(struct device *dev) pinctrl_pm_select_default_state(dev); return drm_mode_config_helper_resume(ddev); } -#endif -static const struct dev_pm_ops tilcdc_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(tilcdc_pm_suspend, tilcdc_pm_resume) -}; +static DEFINE_SIMPLE_DEV_PM_OPS(tilcdc_pm_ops, + tilcdc_pm_suspend, tilcdc_pm_resume); /* * Platform driver: @@ -515,7 +530,8 @@ static void tilcdc_unbind(struct device *dev) if (!ddev->dev_private) return; - tilcdc_fini(dev_get_drvdata(dev)); + tilcdc_fini(ddev); + dev_set_drvdata(dev, NULL); } static const struct component_master_ops tilcdc_comp_ops = { @@ -545,22 +561,26 @@ static int tilcdc_pdev_probe(struct platform_device *pdev) match); } -static int tilcdc_pdev_remove(struct platform_device *pdev) +static void tilcdc_pdev_remove(struct platform_device *pdev) { int ret; ret = tilcdc_get_external_components(&pdev->dev, NULL); if (ret < 0) - return ret; + dev_err(&pdev->dev, "tilcdc_get_external_components() failed (%pe)\n", + ERR_PTR(ret)); else if (ret == 0) tilcdc_fini(platform_get_drvdata(pdev)); else component_master_del(&pdev->dev, &tilcdc_comp_ops); +} - return 0; +static void tilcdc_pdev_shutdown(struct platform_device *pdev) +{ + drm_atomic_helper_shutdown(platform_get_drvdata(pdev)); } -static struct of_device_id tilcdc_of_match[] = { +static const struct of_device_id tilcdc_of_match[] = { { .compatible = "ti,am33xx-tilcdc", }, { .compatible = "ti,da850-tilcdc", }, { }, @@ -570,15 +590,19 @@ MODULE_DEVICE_TABLE(of, tilcdc_of_match); static struct platform_driver tilcdc_platform_driver = { .probe = tilcdc_pdev_probe, .remove = tilcdc_pdev_remove, + .shutdown = tilcdc_pdev_shutdown, .driver = { .name = "tilcdc", - .pm = &tilcdc_pm_ops, + .pm = pm_sleep_ptr(&tilcdc_pm_ops), .of_match_table = tilcdc_of_match, }, }; static int __init tilcdc_drm_init(void) { + if (drm_firmware_drivers_only()) + return -ENODEV; + DBG("init"); tilcdc_panel_init(); return platform_driver_register(&tilcdc_platform_driver); |
