summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/tilcdc/tilcdc_drv.c
diff options
context:
space:
mode:
authorJyri Sarha <jsarha@ti.com>2016-10-18 23:23:27 +0300
committerJyri Sarha <jsarha@ti.com>2016-11-29 21:03:19 +0200
commit9e79e062dc9b3aed541d6e47ac178aff815ab0e8 (patch)
tree18af796c4c0ea88b9810b6ffae7642c528b6014b /drivers/gpu/drm/tilcdc/tilcdc_drv.c
parent923310ba73d742450bb41bb017cb1b6704bd32b5 (diff)
drm/tilcdc: Use unload to handle initialization failures
Use unload to handle initialization failures instead of complex goto label mess. To do this the initialization sequence needed slight reordering and some unload functions needed to become conditional. Signed-off-by: Jyri Sarha <jsarha@ti.com>
Diffstat (limited to 'drivers/gpu/drm/tilcdc/tilcdc_drv.c')
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_drv.c101
1 files changed, 34 insertions, 67 deletions
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index c54e92a207fe..48757f1a1a59 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -158,8 +158,6 @@ static int modeset_init(struct drm_device *dev)
struct tilcdc_drm_private *priv = dev->dev_private;
struct tilcdc_module *mod;
- drm_mode_config_init(dev);
-
priv->crtc = tilcdc_crtc_create(dev);
list_for_each_entry(mod, &module_list, list) {
@@ -198,22 +196,25 @@ static void tilcdc_fini(struct drm_device *dev)
{
struct tilcdc_drm_private *priv = dev->dev_private;
- drm_modeset_lock_crtc(priv->crtc, NULL);
- tilcdc_crtc_disable(priv->crtc);
- drm_modeset_unlock_crtc(priv->crtc);
+ if (priv->crtc)
+ tilcdc_crtc_off(priv->crtc);
- drm_dev_unregister(dev);
+ if (priv->is_registered)
+ drm_dev_unregister(dev);
drm_kms_helper_poll_fini(dev);
- drm_fbdev_cma_fini(priv->fbdev);
+
+ if (priv->fbdev)
+ drm_fbdev_cma_fini(priv->fbdev);
+
drm_irq_uninstall(dev);
drm_mode_config_cleanup(dev);
-
tilcdc_remove_external_encoders(dev);
#ifdef CONFIG_CPU_FREQ
- cpufreq_unregister_notifier(&priv->freq_transition,
- CPUFREQ_TRANSITION_NOTIFIER);
+ if (priv->freq_transition.notifier_call)
+ cpufreq_unregister_notifier(&priv->freq_transition,
+ CPUFREQ_TRANSITION_NOTIFIER);
#endif
if (priv->clk)
@@ -222,8 +223,10 @@ static void tilcdc_fini(struct drm_device *dev)
if (priv->mmio)
iounmap(priv->mmio);
- flush_workqueue(priv->wq);
- destroy_workqueue(priv->wq);
+ if (priv->wq) {
+ flush_workqueue(priv->wq);
+ destroy_workqueue(priv->wq);
+ }
dev->dev_private = NULL;
@@ -254,6 +257,8 @@ static int tilcdc_init(struct drm_driver *ddrv, struct device *dev)
ddev->platformdev = pdev;
ddev->dev_private = priv;
+ platform_set_drvdata(pdev, ddev);
+ drm_mode_config_init(ddev);
priv->is_componentized =
tilcdc_get_external_components(dev, NULL) > 0;
@@ -261,28 +266,28 @@ static int tilcdc_init(struct drm_driver *ddrv, struct device *dev)
priv->wq = alloc_ordered_workqueue("tilcdc", 0);
if (!priv->wq) {
ret = -ENOMEM;
- goto fail_unset_priv;
+ 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 fail_free_wq;
+ goto init_failed;
}
priv->mmio = ioremap_nocache(res->start, resource_size(res));
if (!priv->mmio) {
dev_err(dev, "failed to ioremap\n");
ret = -ENOMEM;
- goto fail_free_wq;
+ goto init_failed;
}
priv->clk = clk_get(dev, "fck");
if (IS_ERR(priv->clk)) {
dev_err(dev, "failed to get functional clock\n");
ret = -ENODEV;
- goto fail_iounmap;
+ goto init_failed;
}
#ifdef CONFIG_CPU_FREQ
@@ -291,7 +296,8 @@ static int tilcdc_init(struct drm_driver *ddrv, struct device *dev)
CPUFREQ_TRANSITION_NOTIFIER);
if (ret) {
dev_err(dev, "failed to register cpufreq notifier\n");
- goto fail_put_clk;
+ priv->freq_transition.notifier_call = NULL;
+ goto init_failed;
}
#endif
@@ -367,37 +373,35 @@ static int tilcdc_init(struct drm_driver *ddrv, struct device *dev)
ret = modeset_init(ddev);
if (ret < 0) {
dev_err(dev, "failed to initialize mode setting\n");
- goto fail_cpufreq_unregister;
+ goto init_failed;
}
- platform_set_drvdata(pdev, ddev);
-
if (priv->is_componentized) {
ret = component_bind_all(dev, ddev);
if (ret < 0)
- goto fail_mode_config_cleanup;
+ goto init_failed;
ret = tilcdc_add_external_encoders(ddev);
if (ret < 0)
- goto fail_component_cleanup;
+ goto init_failed;
}
if ((priv->num_encoders == 0) || (priv->num_connectors == 0)) {
dev_err(dev, "no encoders/connectors found\n");
ret = -ENXIO;
- goto fail_external_cleanup;
+ goto init_failed;
}
ret = drm_vblank_init(ddev, 1);
if (ret < 0) {
dev_err(dev, "failed to initialize vblank\n");
- goto fail_external_cleanup;
+ goto init_failed;
}
ret = drm_irq_install(ddev, platform_get_irq(pdev, 0));
if (ret < 0) {
dev_err(dev, "failed to install IRQ handler\n");
- goto fail_vblank_cleanup;
+ goto init_failed;
}
drm_mode_config_reset(ddev);
@@ -407,57 +411,20 @@ static int tilcdc_init(struct drm_driver *ddrv, struct device *dev)
ddev->mode_config.num_connector);
if (IS_ERR(priv->fbdev)) {
ret = PTR_ERR(priv->fbdev);
- goto fail_irq_uninstall;
+ goto init_failed;
}
drm_kms_helper_poll_init(ddev);
ret = drm_dev_register(ddev, 0);
if (ret)
- goto fail_platform_init;
+ goto init_failed;
+ priv->is_registered = true;
return 0;
-fail_platform_init:
- drm_kms_helper_poll_fini(ddev);
- drm_fbdev_cma_fini(priv->fbdev);
-
-fail_irq_uninstall:
- drm_irq_uninstall(ddev);
-
-fail_vblank_cleanup:
- drm_vblank_cleanup(ddev);
-
-fail_component_cleanup:
- if (priv->is_componentized)
- component_unbind_all(dev, dev);
-
-fail_mode_config_cleanup:
- drm_mode_config_cleanup(ddev);
-
-fail_external_cleanup:
- tilcdc_remove_external_encoders(ddev);
-
-fail_cpufreq_unregister:
- pm_runtime_disable(dev);
-#ifdef CONFIG_CPU_FREQ
- cpufreq_unregister_notifier(&priv->freq_transition,
- CPUFREQ_TRANSITION_NOTIFIER);
-
-fail_put_clk:
-#endif
- clk_put(priv->clk);
-
-fail_iounmap:
- iounmap(priv->mmio);
-
-fail_free_wq:
- flush_workqueue(priv->wq);
- destroy_workqueue(priv->wq);
-
-fail_unset_priv:
- ddev->dev_private = NULL;
- drm_dev_unref(ddev);
+init_failed:
+ tilcdc_fini(ddev);
return ret;
}