From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 531b4e2c206e5f7dead04d9da84dfa693ac57481 ]
We must be sure that the HDMI controller is powered on, while performing the DDC transfer. Add corresponding runtime PM calls to msm_hdmi_i2c_xfer().
Reviewed-by: Jessica Zhang quic_jesszhan@quicinc.com Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/651727/ Link: https://lore.kernel.org/r/20250505-fd-hdmi-hpd-v5-8-48541f76318c@oss.qualcom... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@oss.qualcomm.com Signed-off-by: Sasha Levin sashal@kernel.org ---
**YES** This commit should be backported to stable kernel trees. Here's my detailed analysis: ## Bug Fix Analysis This commit addresses a **critical power management bug** in the MSM HDMI DDC (Display Data Channel) implementation. The issue is that DDC transfers can occur when the HDMI controller is not properly powered, leading to potential hardware access failures or system instability. ## Code Changes Analysis The changes in `drivers/gpu/drm/msm/hdmi/hdmi_i2c.c` are **minimal and well-contained**: 1. **Added runtime PM calls around DDC operations**: - `pm_runtime_resume_and_get()` at function start (line ~110) - `pm_runtime_put()` in success path (line ~206) - `pm_runtime_put()` in error path (line ~224) 2. **Fixed error handling flow**: - Changed direct returns to proper `goto fail` to ensure PM put operations - Lines 113-114 and 172 now use `goto fail` instead of direct returns ## Risk Assessment - LOW RISK **Minimal scope**: Only affects the `msm_hdmi_i2c_xfer()` function, which is the DDC transfer entry point. **Consistent with existing patterns**: The kernel tree analysis shows runtime PM is already used extensively in this driver: - `hdmi_bridge.c`: Uses `pm_runtime_get_sync()` and `pm_runtime_put()` - `hdmi_hpd.c`: Uses runtime PM in 4 locations for HPD operations **No architectural changes**: This follows the existing runtime PM pattern established in commit 6ed9ed484d04 from 2017. ## Comparison with Similar Commits This matches the characteristics of **Similar Commit #1** (marked YES for backport): - Fixes a resource management bug (runtime PM vs devres helper) - Small, contained change - Improves driver robustness - Follows existing patterns The commit is **unlike** the rejected commits (#2-#5) which were: - Code cleanups/refactoring - API modernization - Feature additions - Non-critical improvements ## Critical System Impact DDC is essential for HDMI functionality - it's used for: - Reading display EDID data - Monitor detection - Display capability negotiation Without proper power management, DDC operations could fail intermittently, causing display detection issues or system hangs when accessing unpowered hardware. ## Conclusion This is a **low- risk, high-value bugfix** that ensures hardware is properly powered during DDC operations. It follows established driver patterns, has minimal scope, and fixes a potentially serious power management issue that could affect display functionality.
drivers/gpu/drm/msm/hdmi/hdmi_i2c.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c b/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c index de182c0048434..9c78c6c528bea 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c @@ -107,11 +107,15 @@ static int msm_hdmi_i2c_xfer(struct i2c_adapter *i2c, if (num == 0) return num;
+ ret = pm_runtime_resume_and_get(&hdmi->pdev->dev); + if (ret) + return ret; + init_ddc(hdmi_i2c);
ret = ddc_clear_irq(hdmi_i2c); if (ret) - return ret; + goto fail;
for (i = 0; i < num; i++) { struct i2c_msg *p = &msgs[i]; @@ -169,7 +173,7 @@ static int msm_hdmi_i2c_xfer(struct i2c_adapter *i2c, hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS), hdmi_read(hdmi, REG_HDMI_DDC_HW_STATUS), hdmi_read(hdmi, REG_HDMI_DDC_INT_CTRL)); - return ret; + goto fail; }
ddc_status = hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS); @@ -202,7 +206,13 @@ static int msm_hdmi_i2c_xfer(struct i2c_adapter *i2c, } }
+ pm_runtime_put(&hdmi->pdev->dev); + return i; + +fail: + pm_runtime_put(&hdmi->pdev->dev); + return ret; }
static u32 msm_hdmi_i2c_func(struct i2c_adapter *adapter)