diff options
author | Dmitry Baryshkov <dmitry.baryshkov@linaro.org> | 2021-10-02 04:08:30 +0300 |
---|---|---|
committer | Rob Clark <robdclark@chromium.org> | 2021-10-15 23:26:34 +0300 |
commit | bf94ec093d05e3ed3142d9291b876eeb9997ba5c (patch) | |
tree | fce7030b324ee810aef7afbab0caa973cd2f2c7f /drivers/gpu/drm/msm/dsi/dsi_manager.c | |
parent | fb25d4474fa009dab169be2eb11d122852dd0684 (diff) | |
download | linux-bf94ec093d05e3ed3142d9291b876eeb9997ba5c.tar.xz |
drm/msm/dsi: do not enable irq handler before powering up the host
The DSI host might be left in some state by the bootloader. If this
state generates an IRQ, it might hang the system by holding the
interrupt line before the driver sets up the DSI host to the known
state.
Move the request_irq into msm_dsi_host_init and pass IRQF_NO_AUTOEN to
it. Call enable/disable_irq after msm_dsi_host_power_on/_off()
functions, so that we can be sure that the interrupt is delivered when
the host is in the known state.
It is not possible to defer the interrupt enablement to a later point,
because drm_panel_prepare might need to communicate with the panel over
the DSI link and that requires working interrupt.
Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector support")
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Abhinav Kumar <abhinavk@codeaurora.org>
Link: https://lore.kernel.org/r/20211002010830.647416-1-dmitry.baryshkov@linaro.org
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Rob Clark <robdclark@chromium.org>
Diffstat (limited to 'drivers/gpu/drm/msm/dsi/dsi_manager.c')
-rw-r--r-- | drivers/gpu/drm/msm/dsi/dsi_manager.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index e25877073d31..20c4d650fd80 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -379,6 +379,14 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) } } + /* + * Enable before preparing the panel, disable after unpreparing, so + * that the panel can communicate over the DSI link. + */ + msm_dsi_host_enable_irq(host); + if (is_bonded_dsi && msm_dsi1) + msm_dsi_host_enable_irq(msm_dsi1->host); + /* Always call panel functions once, because even for dual panels, * there is only one drm_panel instance. */ @@ -413,6 +421,10 @@ host_en_fail: if (panel) drm_panel_unprepare(panel); panel_prep_fail: + msm_dsi_host_disable_irq(host); + if (is_bonded_dsi && msm_dsi1) + msm_dsi_host_disable_irq(msm_dsi1->host); + if (is_bonded_dsi && msm_dsi1) msm_dsi_host_power_off(msm_dsi1->host); host1_on_fail: @@ -525,6 +537,10 @@ static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge) id, ret); } + msm_dsi_host_disable_irq(host); + if (is_bonded_dsi && msm_dsi1) + msm_dsi_host_disable_irq(msm_dsi1->host); + /* Save PHY status if it is a clock source */ msm_dsi_phy_pll_save_state(msm_dsi->phy); |