Skip to content

Commit 26db46b

Browse files
Pin-yen Lindianders
authored andcommitted
drm/bridge: parade-ps8640: Ensure bridge is suspended in .post_disable()
The ps8640 bridge seems to expect everything to be power cycled at the disable process, but sometimes ps8640_aux_transfer() holds the runtime PM reference and prevents the bridge from suspend. Prevent that by introducing a mutex lock between ps8640_aux_transfer() and .post_disable() to make sure the bridge is really powered off. Fixes: 826cff3 ("drm/bridge: parade-ps8640: Enable runtime power management") Signed-off-by: Pin-yen Lin <[email protected]> Reviewed-by: Douglas Anderson <[email protected]> Signed-off-by: Douglas Anderson <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 3eb791c commit 26db46b

File tree

1 file changed

+16
-0
lines changed

1 file changed

+16
-0
lines changed

drivers/gpu/drm/bridge/parade-ps8640.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ struct ps8640 {
107107
struct device_link *link;
108108
bool pre_enabled;
109109
bool need_post_hpd_delay;
110+
struct mutex aux_lock;
110111
};
111112

112113
static const struct regmap_config ps8640_regmap_config[] = {
@@ -345,6 +346,7 @@ static ssize_t ps8640_aux_transfer(struct drm_dp_aux *aux,
345346
struct device *dev = &ps_bridge->page[PAGE0_DP_CNTL]->dev;
346347
int ret;
347348

349+
mutex_lock(&ps_bridge->aux_lock);
348350
pm_runtime_get_sync(dev);
349351
ret = _ps8640_wait_hpd_asserted(ps_bridge, 200 * 1000);
350352
if (ret) {
@@ -354,6 +356,7 @@ static ssize_t ps8640_aux_transfer(struct drm_dp_aux *aux,
354356
ret = ps8640_aux_transfer_msg(aux, msg);
355357
pm_runtime_mark_last_busy(dev);
356358
pm_runtime_put_autosuspend(dev);
359+
mutex_unlock(&ps_bridge->aux_lock);
357360

358361
return ret;
359362
}
@@ -475,7 +478,18 @@ static void ps8640_atomic_post_disable(struct drm_bridge *bridge,
475478
ps_bridge->pre_enabled = false;
476479

477480
ps8640_bridge_vdo_control(ps_bridge, DISABLE);
481+
482+
/*
483+
* The bridge seems to expect everything to be power cycled at the
484+
* disable process, so grab a lock here to make sure
485+
* ps8640_aux_transfer() is not holding a runtime PM reference and
486+
* preventing the bridge from suspend.
487+
*/
488+
mutex_lock(&ps_bridge->aux_lock);
489+
478490
pm_runtime_put_sync_suspend(&ps_bridge->page[PAGE0_DP_CNTL]->dev);
491+
492+
mutex_unlock(&ps_bridge->aux_lock);
479493
}
480494

481495
static int ps8640_bridge_attach(struct drm_bridge *bridge,
@@ -624,6 +638,8 @@ static int ps8640_probe(struct i2c_client *client)
624638
if (!ps_bridge)
625639
return -ENOMEM;
626640

641+
mutex_init(&ps_bridge->aux_lock);
642+
627643
ps_bridge->supplies[0].supply = "vdd12";
628644
ps_bridge->supplies[1].supply = "vdd33";
629645
ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ps_bridge->supplies),

0 commit comments

Comments
 (0)