mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 11:50:43 +09:00
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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user