From 34ea3d386347cd6de4c2fa2491dd85c9e753e7e4 Mon Sep 17 00:00:00 2001 From: Thomas Wood Date: Thu, 29 May 2014 16:57:41 +0100 Subject: drm: add register and unregister functions for connectors Introduce generic functions to register and unregister connectors. This provides a common place to add and remove associated user space interfaces. Signed-off-by: Thomas Wood Reviewed-by: David Herrmann Signed-off-by: Daniel Vetter --- drivers/gpu/drm/tilcdc/tilcdc_panel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/tilcdc/tilcdc_panel.c') diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index 86c67329b60..0c0bce7e900 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -247,7 +247,7 @@ static struct drm_connector *panel_connector_create(struct drm_device *dev, if (ret) goto fail; - drm_sysfs_connector_add(connector); + drm_connector_register(connector); return connector; -- cgit v1.2.3-70-g09d2 From e396900e649b0af31161634d87fe37076f46c12b Mon Sep 17 00:00:00 2001 From: Guido Martínez Date: Tue, 17 Jun 2014 11:17:04 -0300 Subject: drm/tilcdc: panel: fix dangling sysfs connector node MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a drm_sysfs_connector_remove call when we destroy the panel to make sure the connector node in sysfs gets deleted. This is required for proper unload and re-load of this driver as a module. Without this, we would get a warning at re-load time like so: ------------[ cut here ]------------ WARNING: CPU: 0 PID: 824 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x54/0x74() sysfs: cannot create duplicate filename '/class/drm/card0-LVDS-1' Modules linked in: [...] CPU: 0 PID: 824 Comm: modprobe Not tainted 3.15.0-rc4-00027-g6484f96-dirty #81 [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (warn_slowpath_common+0x68/0x88) [] (warn_slowpath_common) from [] (warn_slowpath_fmt+0x30/0x40) [] (warn_slowpath_fmt) from [] (sysfs_warn_dup+0x54/0x74) [] (sysfs_warn_dup) from [] (sysfs_do_create_link_sd.isra.2+0xb0/0xb8) [] (sysfs_do_create_link_sd.isra.2) from [] (device_add+0x338/0x520) [] (device_add) from [] (device_create_groups_vargs+0xa0/0xc4) [] (device_create_groups_vargs) from [] (device_create+0x24/0x2c) [] (device_create) from [] (drm_sysfs_connector_add+0x64/0x204) [] (drm_sysfs_connector_add) from [] (panel_modeset_init+0xb8/0x134 [tilcdc]) [] (panel_modeset_init [tilcdc]) from [] (tilcdc_load+0x214/0x4c0 [tilcdc]) [] (tilcdc_load [tilcdc]) from [] (drm_dev_register+0xa4/0x104) [ .. snip .. ] ---[ end trace b2d09cd9578b0497 ]--- [drm:drm_sysfs_connector_add] *ERROR* failed to register connector device: -17 Signed-off-by: Guido Martínez Tested-by: Darren Etheridge Cc: #v3.9+ Signed-off-by: Dave Airlie --- drivers/gpu/drm/tilcdc/tilcdc_panel.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/tilcdc/tilcdc_panel.c') diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index 0c0bce7e900..f5bed331e42 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -151,6 +151,7 @@ struct panel_connector { static void panel_connector_destroy(struct drm_connector *connector) { struct panel_connector *panel_connector = to_panel_connector(connector); + drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); kfree(panel_connector); } -- cgit v1.2.3-70-g09d2 From c9a3ad25eddfdb898114a9d73cdb4c3472d9dfca Mon Sep 17 00:00:00 2001 From: Guido Martínez Date: Tue, 17 Jun 2014 11:17:09 -0300 Subject: drm/tilcdc: fix double kfree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit display_timings_release calls kfree on the display_timings object passed to it. Calling kfree after it is wrong. SLUB debug showed the following warning: ============================================================================= BUG kmalloc-64 (Tainted: G W ): Object already free ----------------------------------------------------------------------------- Disabling lock debugging due to kernel taint INFO: Allocated in of_get_display_timings+0x2c/0x214 age=601 cpu=0 pid=884 __slab_alloc.constprop.79+0x2e0/0x33c kmem_cache_alloc+0xac/0xdc of_get_display_timings+0x2c/0x214 panel_probe+0x7c/0x314 [tilcdc] platform_drv_probe+0x18/0x48 [..snip..] INFO: Freed in panel_destroy+0x18/0x3c [tilcdc] age=0 cpu=0 pid=907 __slab_free+0x34/0x330 panel_destroy+0x18/0x3c [tilcdc] tilcdc_unload+0xd0/0x118 [tilcdc] drm_dev_unregister+0x24/0x98 [..snip..] Signed-off-by: Guido Martínez Tested-by: Darren Etheridge Cc: #v3.9+ Signed-off-by: Dave Airlie --- drivers/gpu/drm/tilcdc/tilcdc_panel.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpu/drm/tilcdc/tilcdc_panel.c') diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index f5bed331e42..b0b9396f41a 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -286,10 +286,8 @@ static void panel_destroy(struct tilcdc_module *mod) { struct panel_module *panel_mod = to_panel_module(mod); - if (panel_mod->timings) { + if (panel_mod->timings) display_timings_release(panel_mod->timings); - kfree(panel_mod->timings); - } tilcdc_module_cleanup(mod); kfree(panel_mod->info); -- cgit v1.2.3-70-g09d2 From 7cdcce9f8b4c15dc55f880307b844a49127db86e Mon Sep 17 00:00:00 2001 From: Guido Martínez Date: Tue, 17 Jun 2014 11:17:10 -0300 Subject: drm/tilcdc: remove submodule destroy calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Darren Etheridge Signed-off-by: Dave Airlie --- drivers/gpu/drm/tilcdc/Module.symvers | 0 drivers/gpu/drm/tilcdc/tilcdc_drv.c | 6 ------ drivers/gpu/drm/tilcdc/tilcdc_drv.h | 1 - drivers/gpu/drm/tilcdc/tilcdc_panel.c | 36 +++++++++++++++++----------------- drivers/gpu/drm/tilcdc/tilcdc_slave.c | 26 +++++++++++++----------- drivers/gpu/drm/tilcdc/tilcdc_tfp410.c | 34 ++++++++++++++++---------------- 6 files changed, 50 insertions(+), 53 deletions(-) create mode 100644 drivers/gpu/drm/tilcdc/Module.symvers (limited to 'drivers/gpu/drm/tilcdc/tilcdc_panel.c') diff --git a/drivers/gpu/drm/tilcdc/Module.symvers b/drivers/gpu/drm/tilcdc/Module.symvers new file mode 100644 index 00000000000..e69de29bb2d diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 006a30e9039..2c860c41dfd 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -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; diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h index 093803683b2..7596c144a9f 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h @@ -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); diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index b0b9396f41a..8ff72c8ad06 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -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; } diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave.c b/drivers/gpu/drm/tilcdc/tilcdc_slave.c index a5a22454aca..f02cb7c02f7 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_slave.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_slave.c @@ -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; } diff --git a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c index 630360621ba..82fb5204565 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c @@ -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; } -- cgit v1.2.3-70-g09d2 From 62eb3e20f8f3ca9de4a17f87effe534d6a691176 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 9 Jul 2014 17:12:57 +0530 Subject: drm/tilcdc: Fix build breakage Commit 34ea3d386347 ("drm: add register and unregister functions for connectors") probably missed out converting the drm_sysfs_connector_remove instances in the following files. Without this patch we get the following compilation error: ERROR: "drm_sysfs_connector_remove" [drivers/gpu/drm/tilcdc/tilcdc.ko] undefined! Signed-off-by: Sachin Kamat CC: Thomas Wood CC: David Herrmann CC: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/tilcdc/tilcdc_panel.c | 2 +- drivers/gpu/drm/tilcdc/tilcdc_slave.c | 2 +- drivers/gpu/drm/tilcdc/tilcdc_tfp410.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/tilcdc/tilcdc_panel.c') diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index 8ff72c8ad06..4c7aa1d8134 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -151,7 +151,7 @@ struct panel_connector { static void panel_connector_destroy(struct drm_connector *connector) { struct panel_connector *panel_connector = to_panel_connector(connector); - drm_sysfs_connector_remove(connector); + drm_connector_unregister(connector); drm_connector_cleanup(connector); kfree(panel_connector); } diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave.c b/drivers/gpu/drm/tilcdc/tilcdc_slave.c index f02cb7c02f7..3775fd49dac 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_slave.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_slave.c @@ -166,7 +166,7 @@ struct slave_connector { static void slave_connector_destroy(struct drm_connector *connector) { struct slave_connector *slave_connector = to_slave_connector(connector); - drm_sysfs_connector_remove(connector); + drm_connector_unregister(connector); drm_connector_cleanup(connector); kfree(slave_connector); } diff --git a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c index 82fb5204565..354c47ca637 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c @@ -167,7 +167,7 @@ struct tfp410_connector { static void tfp410_connector_destroy(struct drm_connector *connector) { struct tfp410_connector *tfp410_connector = to_tfp410_connector(connector); - drm_sysfs_connector_remove(connector); + drm_connector_unregister(connector); drm_connector_cleanup(connector); kfree(tfp410_connector); } -- cgit v1.2.3-70-g09d2 From 9430dfa67d7609b2d6c1ba1ce609c4db192fd78e Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 2 Sep 2014 09:51:16 -0300 Subject: drm/tilcdc: panel: Add missing of_node_put This commit adds the missing calls to of_node_put to release the node that's currently held by the of_get_child_by_name() call in the panel info parsing code. Tested-by: Darren Etheridge Tested-by: Johannes Pointner Signed-off-by: Ezequiel Garcia Signed-off-by: Dave Airlie --- drivers/gpu/drm/tilcdc/tilcdc_panel.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm/tilcdc/tilcdc_panel.c') diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index 4c7aa1d8134..d581c532790 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -311,6 +311,7 @@ static struct tilcdc_panel_info *of_get_panel_info(struct device_node *np) info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { pr_err("%s: allocation failed\n", __func__); + of_node_put(info_np); return NULL; } @@ -331,8 +332,10 @@ static struct tilcdc_panel_info *of_get_panel_info(struct device_node *np) if (ret) { pr_err("%s: error reading panel-info properties\n", __func__); kfree(info); + of_node_put(info_np); return NULL; } + of_node_put(info_np); return info; } -- cgit v1.2.3-70-g09d2 From 75ece7b788f37bf7a2c51ff199b2011ee5e631a4 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 2 Sep 2014 09:51:17 -0300 Subject: drm/tilcdc: panel: Remove unused variable Just a trivial cleanup to remove the variable. Tested-by: Darren Etheridge Tested-by: Johannes Pointner Signed-off-by: Ezequiel Garcia Signed-off-by: Dave Airlie --- drivers/gpu/drm/tilcdc/tilcdc_panel.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpu/drm/tilcdc/tilcdc_panel.c') diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index d581c532790..8f88bfd1482 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -340,8 +340,6 @@ static struct tilcdc_panel_info *of_get_panel_info(struct device_node *np) return info; } -static struct of_device_id panel_of_match[]; - static int panel_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; -- cgit v1.2.3-70-g09d2 From e3a9b04621681d0f07bc8e9935684e6400edef7c Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 2 Sep 2014 09:51:18 -0300 Subject: drm/tilcdc: panel: Spurious whitespace removal Just a cosmetic cleanup. Tested-by: Darren Etheridge Tested-by: Johannes Pointner Signed-off-by: Ezequiel Garcia Signed-off-by: Dave Airlie --- drivers/gpu/drm/tilcdc/tilcdc_panel.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm/tilcdc/tilcdc_panel.c') diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index 8f88bfd1482..4b36e68158b 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -348,7 +348,6 @@ static int panel_probe(struct platform_device *pdev) struct pinctrl *pinctrl; int ret = -EINVAL; - /* bail out early if no DT data: */ if (!node) { dev_err(&pdev->dev, "device-tree data is missing\n"); -- cgit v1.2.3-70-g09d2 From 971645d1fd734b8098a5113d61ab9ea93ce83921 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 2 Sep 2014 09:51:19 -0300 Subject: drm/tilcdc: panel: Use devm_kzalloc to simplify the error path Using the managed variant to allocate the resource makes the code simpler and less error-prone. Tested-by: Darren Etheridge Tested-by: Johannes Pointner Signed-off-by: Ezequiel Garcia Signed-off-by: Dave Airlie --- drivers/gpu/drm/tilcdc/tilcdc_panel.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpu/drm/tilcdc/tilcdc_panel.c') diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index 4b36e68158b..c716c128ded 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -354,7 +354,7 @@ static int panel_probe(struct platform_device *pdev) return -ENXIO; } - panel_mod = kzalloc(sizeof(*panel_mod), GFP_KERNEL); + panel_mod = devm_kzalloc(&pdev->dev, sizeof(*panel_mod), GFP_KERNEL); if (!panel_mod) return -ENOMEM; @@ -391,7 +391,6 @@ fail_timings: display_timings_release(panel_mod->timings); fail_free: - kfree(panel_mod); tilcdc_module_cleanup(mod); return ret; } @@ -405,7 +404,6 @@ static int panel_remove(struct platform_device *pdev) tilcdc_module_cleanup(mod); kfree(panel_mod->info); - kfree(panel_mod); return 0; } -- cgit v1.2.3-70-g09d2 From 18c44db8cafe9bda4fcb51bfc05c1f1d7cefc44c Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 2 Sep 2014 09:51:20 -0300 Subject: drm/tilcdc: panel: Fix backlight devicetree support The current backlight support is broken; the driver expects a backlight-class in the panel devicetree node. Fix this by implementing it properly, getting an optional backlight from a phandle. This shouldn't cause any backward-compatibility DT issue because the current implementation doesn't work and is not even documented. Tested-by: Darren Etheridge Tested-by: Johannes Pointner Signed-off-by: Ezequiel Garcia Signed-off-by: Dave Airlie --- .../devicetree/bindings/drm/tilcdc/panel.txt | 5 +++++ drivers/gpu/drm/tilcdc/tilcdc_panel.c | 23 +++++++++++++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/tilcdc/tilcdc_panel.c') diff --git a/Documentation/devicetree/bindings/drm/tilcdc/panel.txt b/Documentation/devicetree/bindings/drm/tilcdc/panel.txt index 9301c330d1a..10a06e826b4 100644 --- a/Documentation/devicetree/bindings/drm/tilcdc/panel.txt +++ b/Documentation/devicetree/bindings/drm/tilcdc/panel.txt @@ -18,6 +18,9 @@ Required properties: Documentation/devicetree/bindings/video/display-timing.txt for display timing binding details. +Optional properties: +- backlight: phandle of the backlight device attached to the panel + Recommended properties: - pinctrl-names, pinctrl-0: the pincontrol settings to configure muxing properly for pins that connect to TFP410 device @@ -29,6 +32,8 @@ Example: compatible = "ti,tilcdc,panel"; pinctrl-names = "default"; pinctrl-0 = <&bone_lcd3_cape_lcd_pins>; + backlight = <&backlight>; + panel-info { ac-bias = <255>; ac-bias-intrpt = <0>; diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index c716c128ded..3dcf08e4dc9 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -342,7 +342,7 @@ static struct tilcdc_panel_info *of_get_panel_info(struct device_node *np) static int panel_probe(struct platform_device *pdev) { - struct device_node *node = pdev->dev.of_node; + struct device_node *bl_node, *node = pdev->dev.of_node; struct panel_module *panel_mod; struct tilcdc_module *mod; struct pinctrl *pinctrl; @@ -358,6 +358,17 @@ static int panel_probe(struct platform_device *pdev) if (!panel_mod) return -ENOMEM; + bl_node = of_parse_phandle(node, "backlight", 0); + if (bl_node) { + panel_mod->backlight = of_find_backlight_by_node(bl_node); + of_node_put(bl_node); + + if (!panel_mod->backlight) + return -EPROBE_DEFER; + + dev_info(&pdev->dev, "found backlight\n"); + } + mod = &panel_mod->base; pdev->dev.platform_data = mod; @@ -381,10 +392,6 @@ static int panel_probe(struct platform_device *pdev) mod->preferred_bpp = panel_mod->info->bpp; - panel_mod->backlight = of_find_backlight_by_node(node); - if (panel_mod->backlight) - dev_info(&pdev->dev, "found backlight\n"); - return 0; fail_timings: @@ -392,6 +399,8 @@ fail_timings: fail_free: tilcdc_module_cleanup(mod); + if (panel_mod->backlight) + put_device(&panel_mod->backlight->dev); return ret; } @@ -399,6 +408,10 @@ 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); + struct backlight_device *backlight = panel_mod->backlight; + + if (backlight) + put_device(&backlight->dev); display_timings_release(panel_mod->timings); -- cgit v1.2.3-70-g09d2 From 12778fc14301cf24d79cd89b0129874c319d0a38 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 2 Sep 2014 09:51:21 -0300 Subject: drm/tilcdc: panel: Set return value explicitly Instead of setting an initial value for the return code, set it explicitly on each error path. This is just a cosmetic cleanup, as preparation for the enable GPIO support. Tested-by: Darren Etheridge Tested-by: Johannes Pointner Signed-off-by: Ezequiel Garcia Signed-off-by: Dave Airlie --- drivers/gpu/drm/tilcdc/tilcdc_panel.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/tilcdc/tilcdc_panel.c') diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index 3dcf08e4dc9..f2a5b23782f 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -346,7 +346,7 @@ static int panel_probe(struct platform_device *pdev) struct panel_module *panel_mod; struct tilcdc_module *mod; struct pinctrl *pinctrl; - int ret = -EINVAL; + int ret; /* bail out early if no DT data: */ if (!node) { @@ -381,12 +381,14 @@ static int panel_probe(struct platform_device *pdev) panel_mod->timings = of_get_display_timings(node); if (!panel_mod->timings) { dev_err(&pdev->dev, "could not get panel timings\n"); + ret = -EINVAL; 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"); + ret = -EINVAL; goto fail_timings; } -- cgit v1.2.3-70-g09d2 From d898ce03675fc061f89a347a22d41271ed75c436 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 2 Sep 2014 09:51:22 -0300 Subject: drm/tilcdc: panel: Add support for enable GPIO In order to support the "enable GPIO" available in many panel devices, this commit adds a proper devicetree binding. By providing an enable GPIO in the devicetree, the driver can now turn off and on the panel device, and/or the backlight device. Both the backlight and the GPIO are optional properties. Tested-by: Darren Etheridge Tested-by: Johannes Pointner Signed-off-by: Ezequiel Garcia Signed-off-by: Dave Airlie --- .../devicetree/bindings/drm/tilcdc/panel.txt | 2 ++ drivers/gpu/drm/tilcdc/tilcdc_panel.c | 37 +++++++++++++++++++--- 2 files changed, 34 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/tilcdc/tilcdc_panel.c') diff --git a/Documentation/devicetree/bindings/drm/tilcdc/panel.txt b/Documentation/devicetree/bindings/drm/tilcdc/panel.txt index 10a06e826b4..4ab9e230090 100644 --- a/Documentation/devicetree/bindings/drm/tilcdc/panel.txt +++ b/Documentation/devicetree/bindings/drm/tilcdc/panel.txt @@ -20,6 +20,7 @@ Required properties: Optional properties: - backlight: phandle of the backlight device attached to the panel +- enable-gpios: GPIO pin to enable or disable the panel Recommended properties: - pinctrl-names, pinctrl-0: the pincontrol settings to configure @@ -33,6 +34,7 @@ Example: pinctrl-names = "default"; pinctrl-0 = <&bone_lcd3_cape_lcd_pins>; backlight = <&backlight>; + enable-gpios = <&gpio3 19 0>; panel-info { ac-bias = <255>; diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index f2a5b23782f..7a0315855e9 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -18,6 +18,7 @@ #include #include #include +#include #include