diff options
Diffstat (limited to 'drivers/gpu/drm/bridge/analogix/anx7625.c')
-rw-r--r-- | drivers/gpu/drm/bridge/analogix/anx7625.c | 56 |
1 files changed, 31 insertions, 25 deletions
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 0b97b66de577..c0ad8f59e483 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) @@ -2450,7 +2448,7 @@ anx7625_audio_update_connector_status(struct anx7625_data *ctx, enum drm_connector_status status); static enum drm_connector_status -anx7625_bridge_detect(struct drm_bridge *bridge) +anx7625_bridge_detect(struct drm_bridge *bridge, struct drm_connector *connector) { struct anx7625_data *ctx = bridge_to_anx7625(bridge); struct device *dev = ctx->dev; @@ -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); @@ -2586,13 +2596,11 @@ static int anx7625_link_bridge(struct drm_dp_aux *aux) return ret; } - platform->bridge.funcs = &anx7625_bridge_funcs; 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; @@ -2621,10 +2629,10 @@ static int anx7625_i2c_probe(struct i2c_client *client) return -ENODEV; } - platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL); - if (!platform) { + platform = devm_drm_bridge_alloc(dev, struct anx7625_data, bridge, &anx7625_bridge_funcs); + if (IS_ERR(platform)) { DRM_DEV_ERROR(dev, "fail to allocate driver data\n"); - return -ENOMEM; + return PTR_ERR(platform); } pdata = &platform->pdata; @@ -2707,11 +2715,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 +2778,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); } |