mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
drm/rockchip: dw_hdmi_qp: Fix rk3588 hdmitx suspend crash
Signed-off-by: Algea Cao <algea.cao@rock-chips.com> Change-Id: I5f7771dbcbcfb13fb556b84ba147711fbde689e5
This commit is contained in:
@@ -247,9 +247,6 @@ struct dw_hdmi_qp {
|
||||
bool sink_has_audio;
|
||||
bool hpd_state;
|
||||
|
||||
struct delayed_work work;
|
||||
struct workqueue_struct *workqueue;
|
||||
|
||||
struct mutex mutex; /* for state below and previous_mode */
|
||||
struct drm_connector *curr_conn;/* current connector (only valid when !disabled) */
|
||||
enum drm_connector_force force; /* mutex-protected force state */
|
||||
@@ -2322,8 +2319,6 @@ void dw_hdmi_qp_suspend(struct device *dev, struct dw_hdmi_qp *hdmi)
|
||||
if (hdmi->earc_irq)
|
||||
disable_irq(hdmi->earc_irq);
|
||||
|
||||
cancel_delayed_work(&hdmi->work);
|
||||
flush_workqueue(hdmi->workqueue);
|
||||
pinctrl_pm_select_sleep_state(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dw_hdmi_qp_suspend);
|
||||
@@ -2335,6 +2330,10 @@ void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi)
|
||||
return;
|
||||
}
|
||||
|
||||
hdmi_writel(hdmi, 0, MAINUNIT_0_INT_MASK_N);
|
||||
hdmi_writel(hdmi, 0, MAINUNIT_1_INT_MASK_N);
|
||||
hdmi_writel(hdmi, 428571429, TIMER_BASE_CONFIG0);
|
||||
|
||||
pinctrl_pm_select_default_state(dev);
|
||||
mutex_lock(&hdmi->mutex);
|
||||
if (hdmi->i2c)
|
||||
@@ -2347,21 +2346,7 @@ void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi)
|
||||
|
||||
if (hdmi->earc_irq)
|
||||
enable_irq(hdmi->earc_irq);
|
||||
/*
|
||||
* HDMI status maybe incorrect in the following condition:
|
||||
* HDMI plug in -> system sleep -> HDMI plug out -> system wake up.
|
||||
* At this time, cat /sys/class/drm/card 0-HDMI-A-1/status is connected.
|
||||
* There is no hpd interrupt, because HDMI is powerdown during suspend.
|
||||
* So we need check the current HDMI status in this case.
|
||||
*/
|
||||
if (hdmi->connector.status == connector_status_connected) {
|
||||
if (hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data) ==
|
||||
connector_status_disconnected) {
|
||||
hdmi->hpd_state = false;
|
||||
mod_delayed_work(hdmi->workqueue, &hdmi->work,
|
||||
msecs_to_jiffies(20));
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&hdmi->mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dw_hdmi_qp_resume);
|
||||
|
||||
@@ -3184,7 +3184,10 @@ static int dw_hdmi_rockchip_suspend(struct device *dev)
|
||||
{
|
||||
struct rockchip_hdmi *hdmi = dev_get_drvdata(dev);
|
||||
|
||||
dw_hdmi_suspend(hdmi->hdmi);
|
||||
if (hdmi->is_hdmi_qp)
|
||||
dw_hdmi_qp_suspend(dev, hdmi->hdmi_qp);
|
||||
else
|
||||
dw_hdmi_suspend(hdmi->hdmi);
|
||||
pm_runtime_put_sync(dev);
|
||||
|
||||
return 0;
|
||||
@@ -3194,7 +3197,12 @@ static int dw_hdmi_rockchip_resume(struct device *dev)
|
||||
{
|
||||
struct rockchip_hdmi *hdmi = dev_get_drvdata(dev);
|
||||
|
||||
dw_hdmi_resume(hdmi->hdmi);
|
||||
if (hdmi->is_hdmi_qp) {
|
||||
dw_hdmi_qp_resume(dev, hdmi->hdmi_qp);
|
||||
drm_helper_hpd_irq_event(hdmi->encoder.dev);
|
||||
} else {
|
||||
dw_hdmi_resume(hdmi->hdmi);
|
||||
}
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user