FROMLIST: drm/bridge: analogix: protect power when get_modes or detect

The drm callback ->detect and ->get_modes seems is not power safe,
they may be called when device is power off, do register access on
detect or get_modes will cause system die.

Here is the path call ->detect before analogix_dp power on
[<ffffff800843babc>] analogix_dp_detect+0x44/0xdc
[<ffffff80083fd840>] drm_helper_probe_single_connector_modes_merge_bits+0xe8/0x41c
[<ffffff80083fdb84>] drm_helper_probe_single_connector_modes+0x10/0x18
[<ffffff8008418d24>] drm_mode_getconnector+0xf4/0x304
[<ffffff800840cff0>] drm_ioctl+0x23c/0x390
[<ffffff80081a8adc>] do_vfs_ioctl+0x4b8/0x58c
[<ffffff80081a8c10>] SyS_ioctl+0x60/0x88

Change-Id: Ica3fda1f22f903ee9ba2f0caed40cdae9bdfa32b
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
(am from https://patchwork.kernel.org/patch/9374135)
This commit is contained in:
Mark Yao
2016-10-12 18:03:08 +08:00
committed by Huang, Tao
parent ec6b18cab9
commit 22e5631e63

View File

@@ -929,6 +929,8 @@ int analogix_dp_get_modes(struct drm_connector *connector)
struct edid *edid = (struct edid *)dp->edid;
int num_modes = 0;
pm_runtime_get_sync(dp->dev);
if (analogix_dp_handle_edid(dp) == 0) {
drm_mode_connector_update_edid_property(&dp->connector, edid);
num_modes += drm_add_edid_modes(&dp->connector, edid);
@@ -940,6 +942,8 @@ int analogix_dp_get_modes(struct drm_connector *connector)
if (dp->plat_data->get_modes)
num_modes += dp->plat_data->get_modes(dp->plat_data, connector);
pm_runtime_put(dp->dev);
return num_modes;
}
@@ -960,11 +964,16 @@ enum drm_connector_status
analogix_dp_detect(struct drm_connector *connector, bool force)
{
struct analogix_dp_device *dp = to_dp(connector);
enum drm_connector_status status = connector_status_connected;
pm_runtime_get_sync(dp->dev);
if (analogix_dp_detect_hpd(dp))
return connector_status_disconnected;
status = connector_status_disconnected;
return connector_status_connected;
pm_runtime_put(dp->dev);
return status;
}
static void analogix_dp_connector_destroy(struct drm_connector *connector)