summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/tilcdc/tilcdc_drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/tilcdc/tilcdc_drv.c')
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_drv.c120
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);