diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 4db241345d06..2c5dd47c489e 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -3900,6 +3900,21 @@ void dw_hdmi_suspend(struct device *dev) { struct dw_hdmi *hdmi = dev_get_drvdata(dev); + mutex_lock(&hdmi->mutex); + + /* + * When system shutdown, hdmi should be disabled. + * When system suspend, dw_hdmi_bridge_disable will disable hdmi first. + * To prevent duplicate operation, we should determine whether hdmi + * has been disabled. + */ + if (!hdmi->disabled) { + hdmi->disabled = true; + dw_hdmi_update_power(hdmi); + dw_hdmi_update_phy_mask(hdmi); + } + mutex_unlock(&hdmi->mutex); + if (hdmi->irq) disable_irq(hdmi->irq); cancel_delayed_work(&hdmi->work); diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index a8fb7fd56a28..a0fe59409923 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -1324,6 +1324,12 @@ static int dw_hdmi_rockchip_probe(struct platform_device *pdev) return component_add(&pdev->dev, &dw_hdmi_rockchip_ops); } +static void dw_hdmi_rockchip_shutdown(struct platform_device *pdev) +{ + dw_hdmi_suspend(&pdev->dev); + pm_runtime_put_sync(&pdev->dev); +} + static int dw_hdmi_rockchip_remove(struct platform_device *pdev) { component_del(&pdev->dev, &dw_hdmi_rockchip_ops); @@ -1356,6 +1362,7 @@ static const struct dev_pm_ops dw_hdmi_pm_ops = { struct platform_driver dw_hdmi_rockchip_pltfm_driver = { .probe = dw_hdmi_rockchip_probe, .remove = dw_hdmi_rockchip_remove, + .shutdown = dw_hdmi_rockchip_shutdown, .driver = { .name = "dwhdmi-rockchip", .of_match_table = dw_hdmi_rockchip_dt_ids,