summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/rockchip/cdn-dp-core.c
diff options
context:
space:
mode:
authorGuenter Roeck <groeck@chromium.org>2017-02-05 15:54:58 +0800
committerMark Yao <mark.yao@rock-chips.com>2017-02-05 16:29:46 +0800
commit5eb2e6ee97b5e9a8587143db339bc71b28a3e1ca (patch)
tree07aad5ee1fc248292ee4513687f9082c0c5995e9 /drivers/gpu/drm/rockchip/cdn-dp-core.c
parent83c132ed46a7e9c8ac17be436ef3892850df8695 (diff)
downloadblackbird-obmc-linux-5eb2e6ee97b5e9a8587143db339bc71b28a3e1ca.tar.gz
blackbird-obmc-linux-5eb2e6ee97b5e9a8587143db339bc71b28a3e1ca.zip
drm/rockchip: cdn-dp: Do not run worker while suspended
If the driver is in suspended mode, the dp block may be disabled, and chip registers may not be accessible. Yet, the worker may be triggered in this situation by an extcon event. If that happens, the following crash will be seen. cdn-dp fec00000.dp: [drm:cdn_dp_pd_event_work] *ERROR* Enable dp failed -19 cdn-dp fec00000.dp: [drm:cdn_dp_pd_event_work] Connected, not enabled. Enabling cdn Bad mode in Error handler detected, code 0xbf000002 -- SError CPU: 1 PID: 10357 Comm: kworker/1:2 Not tainted 4.4.21-05903-ge0514ea #1 Hardware name: Google Kevin (DT) Workqueue: events cdn_dp_pd_event_work task: ffffffc0cda67080 ti: ffffffc0b9b80000 task.ti: ffffffc0b9b80000 PC is at cdn_dp_clock_reset+0x30/0xa8 LR is at cdn_dp_enable+0x1e0/0x69c ... Call trace: [<ffffffc0005a7e24>] cdn_dp_pd_event_work+0x58/0x3f4 [<ffffffc0002397f0>] process_one_work+0x240/0x424 [<ffffffc00023a28c>] worker_thread+0x2fc/0x424 [<ffffffc00023f5fc>] kthread+0x10c/0x114 [<ffffffc000203dd0>] ret_from_fork+0x10/0x40 Problem is two-fold: The worker should not run while suspended, and the suspend function should not call cdn_dp_disable() while the worker is running. Signed-off-by: Guenter Roeck <groeck@chromium.org> Signed-off-by: Sean Paul <seanpaul@chromium.org> Signed-off-by: Chris Zhong <zyw@rock-chips.com>
Diffstat (limited to 'drivers/gpu/drm/rockchip/cdn-dp-core.c')
-rw-r--r--drivers/gpu/drm/rockchip/cdn-dp-core.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index b8d0dd7abc61..a70eedc88e1a 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -939,6 +939,10 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
u8 sink_count;
mutex_lock(&dp->lock);
+
+ if (dp->suspended)
+ goto out;
+
ret = cdn_dp_request_firmware(dp);
if (ret)
goto out;
@@ -1123,19 +1127,26 @@ static const struct component_ops cdn_dp_component_ops = {
int cdn_dp_suspend(struct device *dev)
{
struct cdn_dp_device *dp = dev_get_drvdata(dev);
+ int ret = 0;
+ mutex_lock(&dp->lock);
if (dp->active)
- return cdn_dp_disable(dp);
+ ret = cdn_dp_disable(dp);
+ dp->suspended = true;
+ mutex_unlock(&dp->lock);
- return 0;
+ return ret;
}
int cdn_dp_resume(struct device *dev)
{
struct cdn_dp_device *dp = dev_get_drvdata(dev);
+ mutex_lock(&dp->lock);
+ dp->suspended = false;
if (dp->fw_loaded)
schedule_work(&dp->event_work);
+ mutex_unlock(&dp->lock);
return 0;
}
OpenPOWER on IntegriCloud