diff options
Diffstat (limited to 'drivers/gpu/drm/bridge/analogix/anx7625.c')
-rw-r--r-- | drivers/gpu/drm/bridge/analogix/anx7625.c | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 0b97b66de577..8a9079c2ed5c 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1257,10 +1257,10 @@ static void anx7625_power_on(struct anx7625_data *ctx) usleep_range(11000, 12000); /* Power on pin enable */ - gpiod_set_value(ctx->pdata.gpio_p_on, 1); + gpiod_set_value_cansleep(ctx->pdata.gpio_p_on, 1); usleep_range(10000, 11000); /* Power reset pin enable */ - gpiod_set_value(ctx->pdata.gpio_reset, 1); + gpiod_set_value_cansleep(ctx->pdata.gpio_reset, 1); usleep_range(10000, 11000); DRM_DEV_DEBUG_DRIVER(dev, "power on !\n"); @@ -1280,9 +1280,9 @@ static void anx7625_power_standby(struct anx7625_data *ctx) return; } - gpiod_set_value(ctx->pdata.gpio_reset, 0); + gpiod_set_value_cansleep(ctx->pdata.gpio_reset, 0); usleep_range(1000, 1100); - gpiod_set_value(ctx->pdata.gpio_p_on, 0); + gpiod_set_value_cansleep(ctx->pdata.gpio_p_on, 0); usleep_range(1000, 1100); ret = regulator_bulk_disable(ARRAY_SIZE(ctx->pdata.supplies), @@ -1814,9 +1814,6 @@ static enum drm_connector_status anx7625_sink_detect(struct anx7625_data *ctx) DRM_DEV_DEBUG_DRIVER(dev, "sink detect\n"); - if (ctx->pdata.panel_bridge) - return connector_status_connected; - return ctx->hpd_status ? connector_status_connected : connector_status_disconnected; } @@ -2141,6 +2138,7 @@ static void hdcp_check_work_func(struct work_struct *work) } static int anx7625_bridge_attach(struct drm_bridge *bridge, + struct drm_encoder *encoder, enum drm_bridge_attach_flags flags) { struct anx7625_data *ctx = bridge_to_anx7625(bridge); @@ -2159,7 +2157,7 @@ static int anx7625_bridge_attach(struct drm_bridge *bridge, } if (ctx->pdata.panel_bridge) { - err = drm_bridge_attach(bridge->encoder, + err = drm_bridge_attach(encoder, ctx->pdata.panel_bridge, &ctx->bridge, flags); if (err) @@ -2474,6 +2472,22 @@ static const struct drm_edid *anx7625_bridge_edid_read(struct drm_bridge *bridge return anx7625_edid_read(ctx); } +static void anx7625_bridge_hpd_enable(struct drm_bridge *bridge) +{ + struct anx7625_data *ctx = bridge_to_anx7625(bridge); + struct device *dev = ctx->dev; + + pm_runtime_get_sync(dev); +} + +static void anx7625_bridge_hpd_disable(struct drm_bridge *bridge) +{ + struct anx7625_data *ctx = bridge_to_anx7625(bridge); + struct device *dev = ctx->dev; + + pm_runtime_put_sync(dev); +} + static const struct drm_bridge_funcs anx7625_bridge_funcs = { .attach = anx7625_bridge_attach, .detach = anx7625_bridge_detach, @@ -2487,6 +2501,8 @@ static const struct drm_bridge_funcs anx7625_bridge_funcs = { .atomic_reset = drm_atomic_helper_bridge_reset, .detect = anx7625_bridge_detect, .edid_read = anx7625_bridge_edid_read, + .hpd_enable = anx7625_bridge_hpd_enable, + .hpd_disable = anx7625_bridge_hpd_disable, }; static int anx7625_register_i2c_dummy_clients(struct anx7625_data *ctx, @@ -2568,12 +2584,6 @@ static const struct dev_pm_ops anx7625_pm_ops = { anx7625_runtime_pm_resume, NULL) }; -static void anx7625_runtime_disable(void *data) -{ - pm_runtime_dont_use_autosuspend(data); - pm_runtime_disable(data); -} - static int anx7625_link_bridge(struct drm_dp_aux *aux) { struct anx7625_data *platform = container_of(aux, struct anx7625_data, aux); @@ -2590,9 +2600,8 @@ static int anx7625_link_bridge(struct drm_dp_aux *aux) platform->bridge.of_node = dev->of_node; if (!anx7625_of_panel_on_aux_bus(dev)) platform->bridge.ops |= DRM_BRIDGE_OP_EDID; - if (!platform->pdata.panel_bridge) - platform->bridge.ops |= DRM_BRIDGE_OP_HPD | - DRM_BRIDGE_OP_DETECT; + if (!platform->pdata.panel_bridge || !anx7625_of_panel_on_aux_bus(dev)) + platform->bridge.ops |= DRM_BRIDGE_OP_HPD | DRM_BRIDGE_OP_DETECT; platform->bridge.type = platform->pdata.panel_bridge ? DRM_MODE_CONNECTOR_eDP : DRM_MODE_CONNECTOR_DisplayPort; @@ -2707,11 +2716,10 @@ static int anx7625_i2c_probe(struct i2c_client *client) goto free_wq; } - pm_runtime_enable(dev); pm_runtime_set_autosuspend_delay(dev, 1000); pm_runtime_use_autosuspend(dev); pm_suspend_ignore_children(dev, true); - ret = devm_add_action_or_reset(dev, anx7625_runtime_disable, dev); + ret = devm_pm_runtime_enable(dev); if (ret) goto free_wq; @@ -2771,7 +2779,6 @@ static void anx7625_i2c_remove(struct i2c_client *client) if (platform->hdcp_workqueue) { cancel_delayed_work(&platform->hdcp_work); - flush_workqueue(platform->hdcp_workqueue); destroy_workqueue(platform->hdcp_workqueue); } |