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)
struct edid *edid = (struct edid *)dp->edid;
int num_modes = 0;
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);
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);
if (dp->plat_data->get_modes)
num_modes += dp->plat_data->get_modes(dp->plat_data, connector);
if (dp->plat_data->get_modes)
num_modes += dp->plat_data->get_modes(dp->plat_data, connector);
+ pm_runtime_put(dp->dev);
+
analogix_dp_detect(struct drm_connector *connector, bool force)
{
struct analogix_dp_device *dp = to_dp(connector);
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))
if (analogix_dp_detect_hpd(dp))
- return connector_status_disconnected;
+ status = connector_status_disconnected;
+
+ pm_runtime_put(dp->dev);
- return connector_status_connected;
}
static void analogix_dp_connector_destroy(struct drm_connector *connector)
}
static void analogix_dp_connector_destroy(struct drm_connector *connector)