drm/tilcdc: remove submodule destroy calls
authorGuido Martínez <guido@vanguardiasur.com.ar>
Tue, 17 Jun 2014 14:17:10 +0000 (11:17 -0300)
committerDave Airlie <airlied@redhat.com>
Tue, 8 Jul 2014 01:25:32 +0000 (11:25 +1000)
The TI tilcdc driver is designed with a notion of submodules. Currently,
at unload time, these submodules are iterated and destroyed.

Now that the tilcdc remove order is fixed, this can be handled perfectly
by the kernel using the device infrastructure, since each submodule
is a kernel driver itself, and they are only destroy()'ed at unload
time. Therefore we move the destroy() functionality to each submodule's
remove().

Also, remove some checks in the unloading process since the new code
guarantees the resources are allocated and need a release.

Signed-off-by: Guido Martínez <guido@vanguardiasur.com.ar>
Tested-by: Darren Etheridge <detheridge@ti.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/tilcdc/Module.symvers [new file with mode: 0644]
drivers/gpu/drm/tilcdc/tilcdc_drv.c
drivers/gpu/drm/tilcdc/tilcdc_drv.h
drivers/gpu/drm/tilcdc/tilcdc_panel.c
drivers/gpu/drm/tilcdc/tilcdc_slave.c
drivers/gpu/drm/tilcdc/tilcdc_tfp410.c

diff --git a/drivers/gpu/drm/tilcdc/Module.symvers b/drivers/gpu/drm/tilcdc/Module.symvers
new file mode 100644 (file)
index 0000000..e69de29
index 006a30e90390f0d752465d99d539288805732d3f..2c860c41dfdbdaccd38f38d1dab64acc8340b67e 100644 (file)
@@ -120,7 +120,6 @@ static int cpufreq_transition(struct notifier_block *nb,
 static int tilcdc_unload(struct drm_device *dev)
 {
        struct tilcdc_drm_private *priv = dev->dev_private;
-       struct tilcdc_module *mod, *cur;
 
        drm_fbdev_cma_fini(priv->fbdev);
        drm_kms_helper_poll_fini(dev);
@@ -149,11 +148,6 @@ static int tilcdc_unload(struct drm_device *dev)
 
        pm_runtime_disable(dev->dev);
 
-       list_for_each_entry_safe(mod, cur, &module_list, list) {
-               DBG("destroying module: %s", mod->name);
-               mod->funcs->destroy(mod);
-       }
-
        kfree(priv);
 
        return 0;
index 093803683b25241dc86ff9124fed081b7b54fd81..7596c144a9fb54d45e313588cddc9ec7e1836c79 100644 (file)
@@ -98,7 +98,6 @@ struct tilcdc_module;
 struct tilcdc_module_ops {
        /* create appropriate encoders/connectors: */
        int (*modeset_init)(struct tilcdc_module *mod, struct drm_device *dev);
-       void (*destroy)(struct tilcdc_module *mod);
 #ifdef CONFIG_DEBUG_FS
        /* create debugfs nodes (can be NULL): */
        int (*debugfs_init)(struct tilcdc_module *mod, struct drm_minor *minor);
index b0b9396f41a626c55cf5815dbdded2e4a6e39e91..8ff72c8ad06b0b8d2a5f36ba3c832f58cf46d20c 100644 (file)
@@ -282,21 +282,8 @@ static int panel_modeset_init(struct tilcdc_module *mod, struct drm_device *dev)
        return 0;
 }
 
-static void panel_destroy(struct tilcdc_module *mod)
-{
-       struct panel_module *panel_mod = to_panel_module(mod);
-
-       if (panel_mod->timings)
-               display_timings_release(panel_mod->timings);
-
-       tilcdc_module_cleanup(mod);
-       kfree(panel_mod->info);
-       kfree(panel_mod);
-}
-
 static const struct tilcdc_module_ops panel_module_ops = {
                .modeset_init = panel_modeset_init,
-               .destroy = panel_destroy,
 };
 
 /*
@@ -372,6 +359,7 @@ static int panel_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        mod = &panel_mod->base;
+       pdev->dev.platform_data = mod;
 
        tilcdc_module_init(mod, "panel", &panel_module_ops);
 
@@ -379,17 +367,16 @@ static int panel_probe(struct platform_device *pdev)
        if (IS_ERR(pinctrl))
                dev_warn(&pdev->dev, "pins are not configured\n");
 
-
        panel_mod->timings = of_get_display_timings(node);
        if (!panel_mod->timings) {
                dev_err(&pdev->dev, "could not get panel timings\n");
-               goto fail;
+               goto fail_free;
        }
 
        panel_mod->info = of_get_panel_info(node);
        if (!panel_mod->info) {
                dev_err(&pdev->dev, "could not get panel info\n");
-               goto fail;
+               goto fail_timings;
        }
 
        mod->preferred_bpp = panel_mod->info->bpp;
@@ -400,13 +387,26 @@ static int panel_probe(struct platform_device *pdev)
 
        return 0;
 
-fail:
-       panel_destroy(mod);
+fail_timings:
+       display_timings_release(panel_mod->timings);
+
+fail_free:
+       kfree(panel_mod);
+       tilcdc_module_cleanup(mod);
        return ret;
 }
 
 static int panel_remove(struct platform_device *pdev)
 {
+       struct tilcdc_module *mod = dev_get_platdata(&pdev->dev);
+       struct panel_module *panel_mod = to_panel_module(mod);
+
+       display_timings_release(panel_mod->timings);
+
+       tilcdc_module_cleanup(mod);
+       kfree(panel_mod->info);
+       kfree(panel_mod);
+
        return 0;
 }
 
index a5a22454acad52b9a518d28d83e70af402d3ec96..f02cb7c02f7fc821f86a7b0c09aba984c879c94c 100644 (file)
@@ -296,17 +296,8 @@ static int slave_modeset_init(struct tilcdc_module *mod, struct drm_device *dev)
        return 0;
 }
 
-static void slave_destroy(struct tilcdc_module *mod)
-{
-       struct slave_module *slave_mod = to_slave_module(mod);
-
-       tilcdc_module_cleanup(mod);
-       kfree(slave_mod);
-}
-
 static const struct tilcdc_module_ops slave_module_ops = {
                .modeset_init = slave_modeset_init,
-               .destroy = slave_destroy,
 };
 
 /*
@@ -356,10 +347,13 @@ static int slave_probe(struct platform_device *pdev)
        }
 
        slave_mod = kzalloc(sizeof(*slave_mod), GFP_KERNEL);
-       if (!slave_mod)
-               return -ENOMEM;
+       if (!slave_mod) {
+               ret = -ENOMEM;
+               goto fail_adapter;
+       }
 
        mod = &slave_mod->base;
+       pdev->dev.platform_data = mod;
 
        mod->preferred_bpp = slave_info.bpp;
 
@@ -374,10 +368,20 @@ static int slave_probe(struct platform_device *pdev)
        tilcdc_slave_probedefer(false);
 
        return 0;
+
+fail_adapter:
+       i2c_put_adapter(slavei2c);
+       return ret;
 }
 
 static int slave_remove(struct platform_device *pdev)
 {
+       struct tilcdc_module *mod = dev_get_platdata(&pdev->dev);
+       struct slave_module *slave_mod = to_slave_module(mod);
+
+       tilcdc_module_cleanup(mod);
+       kfree(slave_mod);
+
        return 0;
 }
 
index 630360621bac62f763e05d02f4e71131c9f47447..82fb5204565ffd5e80342d5eeb23ed425ac52265 100644 (file)
@@ -296,23 +296,8 @@ static int tfp410_modeset_init(struct tilcdc_module *mod, struct drm_device *dev
        return 0;
 }
 
-static void tfp410_destroy(struct tilcdc_module *mod)
-{
-       struct tfp410_module *tfp410_mod = to_tfp410_module(mod);
-
-       if (tfp410_mod->i2c)
-               i2c_put_adapter(tfp410_mod->i2c);
-
-       if (!IS_ERR_VALUE(tfp410_mod->gpio))
-               gpio_free(tfp410_mod->gpio);
-
-       tilcdc_module_cleanup(mod);
-       kfree(tfp410_mod);
-}
-
 static const struct tilcdc_module_ops tfp410_module_ops = {
                .modeset_init = tfp410_modeset_init,
-               .destroy = tfp410_destroy,
 };
 
 /*
@@ -342,6 +327,7 @@ static int tfp410_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        mod = &tfp410_mod->base;
+       pdev->dev.platform_data = mod;
 
        tilcdc_module_init(mod, "tfp410", &tfp410_module_ops);
 
@@ -365,6 +351,7 @@ static int tfp410_probe(struct platform_device *pdev)
        tfp410_mod->i2c = of_find_i2c_adapter_by_node(i2c_node);
        if (!tfp410_mod->i2c) {
                dev_err(&pdev->dev, "could not get i2c\n");
+               of_node_put(i2c_node);
                goto fail;
        }
 
@@ -378,19 +365,32 @@ static int tfp410_probe(struct platform_device *pdev)
                ret = gpio_request(tfp410_mod->gpio, "DVI_PDn");
                if (ret) {
                        dev_err(&pdev->dev, "could not get DVI_PDn gpio\n");
-                       goto fail;
+                       goto fail_adapter;
                }
        }
 
        return 0;
 
+fail_adapter:
+       i2c_put_adapter(tfp410_mod->i2c);
+
 fail:
-       tfp410_destroy(mod);
+       kfree(tfp410_mod);
+       tilcdc_module_cleanup(mod);
        return ret;
 }
 
 static int tfp410_remove(struct platform_device *pdev)
 {
+       struct tilcdc_module *mod = dev_get_platdata(&pdev->dev);
+       struct tfp410_module *tfp410_mod = to_tfp410_module(mod);
+
+       i2c_put_adapter(tfp410_mod->i2c);
+       gpio_free(tfp410_mod->gpio);
+
+       tilcdc_module_cleanup(mod);
+       kfree(tfp410_mod);
+
        return 0;
 }