aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2016-12-30 04:57:46 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-03-30 03:41:28 -0400
commit7b3c8b2a2e63f2ad0a16cda77b7698004640ad1a (patch)
treeed7821f3ef6cddc1ed84d4e19bd8726ef5649784
parenteae72468c45d827484a2c0980a519f5220b1985c (diff)
drm/bridge: analogix dp: Fix runtime PM state on driver bind
commit f0a8b49c03d22a511a601dc54b2a3425a41e35fa upstream. Analogix_dp_bind() can be called from component framework, which doesn't guarantee proper runtime PM state of the device during bind operation, so ensure that device is runtime active before doing any register access. This ensures that the power domain, to which DP module belongs, is turned on. While at it, also fix the unbalanced call to phy_power_on() in analogix_dp_bind() function. This patch solves the following kernel oops on Samsung Exynos5250 Snow board: Unhandled fault: imprecise external abort (0x406) at 0x00000000 pgd = c0004000 [00000000] *pgd=00000000 Internal error: : 406 [#1] PREEMPT SMP ARM Modules linked in: CPU: 0 PID: 75 Comm: kworker/0:2 Not tainted 4.9.0 #1046 Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) Workqueue: events deferred_probe_work_func task: ee272300 task.stack: ee312000 PC is at analogix_dp_enable_sw_function+0x18/0x2c LR is at analogix_dp_init_dp+0x2c/0x50 ... [<c03fcb38>] (analogix_dp_enable_sw_function) from [<c03fa9c4>] (analogix_dp_init_dp+0x2c/0x50) [<c03fa9c4>] (analogix_dp_init_dp) from [<c03fab6c>] (analogix_dp_bind+0x184/0x42c) [<c03fab6c>] (analogix_dp_bind) from [<c03fdb84>] (component_bind_all+0xf0/0x218) [<c03fdb84>] (component_bind_all) from [<c03ed64c>] (exynos_drm_load+0x134/0x200) [<c03ed64c>] (exynos_drm_load) from [<c03d5058>] (drm_dev_register+0xa0/0xd0) [<c03d5058>] (drm_dev_register) from [<c03d66b8>] (drm_platform_init+0x58/0xb0) [<c03d66b8>] (drm_platform_init) from [<c03fe0c4>] (try_to_bring_up_master+0x14c/0x188) [<c03fe0c4>] (try_to_bring_up_master) from [<c03fe188>] (component_add+0x88/0x138) [<c03fe188>] (component_add) from [<c0403a38>] (platform_drv_probe+0x50/0xb0) [<c0403a38>] (platform_drv_probe) from [<c0402470>] (driver_probe_device+0x1f0/0x2a8) [<c0402470>] (driver_probe_device) from [<c0400a54>] (bus_for_each_drv+0x44/0x8c) [<c0400a54>] (bus_for_each_drv) from [<c04021f8>] (__device_attach+0x9c/0x100) [<c04021f8>] (__device_attach) from [<c04018e8>] (bus_probe_device+0x84/0x8c) [<c04018e8>] (bus_probe_device) from [<c0401d1c>] (deferred_probe_work_func+0x60/0x8c) [<c0401d1c>] (deferred_probe_work_func) from [<c012fc14>] (process_one_work+0x120/0x318) [<c012fc14>] (process_one_work) from [<c012fe34>] (process_scheduled_works+0x28/0x38) [<c012fe34>] (process_scheduled_works) from [<c0130048>] (worker_thread+0x204/0x4ac) [<c0130048>] (worker_thread) from [<c01352c4>] (kthread+0xd8/0xf4) [<c01352c4>] (kthread) from [<c0107978>] (ret_from_fork+0x14/0x3c) Code: e59035f0 e5935018 f57ff04f e3c55001 (f57ff04e) ---[ end trace 3d1d0d87796de344 ]--- Reviewed-by: Sean Paul <seanpaul@chromium.org> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Archit Taneja <architt@codeaurora.org> Link: http://patchwork.freedesktop.org/patch/msgid/1483091866-1088-1-git-send-email-m.szyprowski@samsung.com Cc: Javier Martinez Canillas <javier@osg.samsung.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_core.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 6e0447f329a2..72ec93de0e76 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1382,6 +1382,7 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
1382 1382
1383 pm_runtime_enable(dev); 1383 pm_runtime_enable(dev);
1384 1384
1385 pm_runtime_get_sync(dev);
1385 phy_power_on(dp->phy); 1386 phy_power_on(dp->phy);
1386 1387
1387 analogix_dp_init_dp(dp); 1388 analogix_dp_init_dp(dp);
@@ -1414,9 +1415,15 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
1414 goto err_disable_pm_runtime; 1415 goto err_disable_pm_runtime;
1415 } 1416 }
1416 1417
1418 phy_power_off(dp->phy);
1419 pm_runtime_put(dev);
1420
1417 return 0; 1421 return 0;
1418 1422
1419err_disable_pm_runtime: 1423err_disable_pm_runtime:
1424
1425 phy_power_off(dp->phy);
1426 pm_runtime_put(dev);
1420 pm_runtime_disable(dev); 1427 pm_runtime_disable(dev);
1421 1428
1422 return ret; 1429 return ret;