diff options
Diffstat (limited to 'drivers/gpu/drm/bridge/lontium-lt9611uxc.c')
-rw-r--r-- | drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 75 |
1 files changed, 44 insertions, 31 deletions
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index 2a848e14181b..c4454d0f6cad 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -258,18 +258,17 @@ static struct mipi_dsi_device *lt9611uxc_attach_dsi(struct lt9611uxc *lt9611uxc, const struct mipi_dsi_device_info info = { "lt9611uxc", 0, NULL }; struct mipi_dsi_device *dsi; struct mipi_dsi_host *host; - struct device *dev = lt9611uxc->dev; int ret; host = of_find_mipi_dsi_host_by_node(dsi_node); if (!host) { - dev_err(dev, "failed to find dsi host\n"); + dev_err(lt9611uxc->dev, "failed to find dsi host\n"); return ERR_PTR(-EPROBE_DEFER); } - dsi = devm_mipi_dsi_device_register_full(dev, host, &info); + dsi = mipi_dsi_device_register_full(host, &info); if (IS_ERR(dsi)) { - dev_err(dev, "failed to create dsi device\n"); + dev_err(lt9611uxc->dev, "failed to create dsi device\n"); return dsi; } @@ -278,9 +277,10 @@ static struct mipi_dsi_device *lt9611uxc_attach_dsi(struct lt9611uxc *lt9611uxc, dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_VIDEO_HSE; - ret = devm_mipi_dsi_attach(dev, dsi); + ret = mipi_dsi_attach(dsi); if (ret < 0) { - dev_err(dev, "failed to attach dsi to host\n"); + dev_err(lt9611uxc->dev, "failed to attach dsi to host\n"); + mipi_dsi_device_unregister(dsi); return ERR_PTR(ret); } @@ -355,6 +355,19 @@ static int lt9611uxc_connector_init(struct drm_bridge *bridge, struct lt9611uxc return drm_connector_attach_encoder(<9611uxc->connector, bridge->encoder); } +static void lt9611uxc_bridge_detach(struct drm_bridge *bridge) +{ + struct lt9611uxc *lt9611uxc = bridge_to_lt9611uxc(bridge); + + if (lt9611uxc->dsi1) { + mipi_dsi_detach(lt9611uxc->dsi1); + mipi_dsi_device_unregister(lt9611uxc->dsi1); + } + + mipi_dsi_detach(lt9611uxc->dsi0); + mipi_dsi_device_unregister(lt9611uxc->dsi0); +} + static int lt9611uxc_bridge_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags) { @@ -367,7 +380,27 @@ static int lt9611uxc_bridge_attach(struct drm_bridge *bridge, return ret; } + /* Attach primary DSI */ + lt9611uxc->dsi0 = lt9611uxc_attach_dsi(lt9611uxc, lt9611uxc->dsi0_node); + if (IS_ERR(lt9611uxc->dsi0)) + return PTR_ERR(lt9611uxc->dsi0); + + /* Attach secondary DSI, if specified */ + if (lt9611uxc->dsi1_node) { + lt9611uxc->dsi1 = lt9611uxc_attach_dsi(lt9611uxc, lt9611uxc->dsi1_node); + if (IS_ERR(lt9611uxc->dsi1)) { + ret = PTR_ERR(lt9611uxc->dsi1); + goto err_unregister_dsi0; + } + } + return 0; + +err_unregister_dsi0: + mipi_dsi_detach(lt9611uxc->dsi0); + mipi_dsi_device_unregister(lt9611uxc->dsi0); + + return ret; } static enum drm_mode_status @@ -511,6 +544,7 @@ static struct edid *lt9611uxc_bridge_get_edid(struct drm_bridge *bridge, static const struct drm_bridge_funcs lt9611uxc_bridge_funcs = { .attach = lt9611uxc_bridge_attach, + .detach = lt9611uxc_bridge_detach, .mode_valid = lt9611uxc_bridge_mode_valid, .mode_set = lt9611uxc_bridge_mode_set, .detect = lt9611uxc_bridge_detect, @@ -927,9 +961,9 @@ retry: init_waitqueue_head(<9611uxc->wq); INIT_WORK(<9611uxc->work, lt9611uxc_hpd_work); - ret = request_threaded_irq(client->irq, NULL, - lt9611uxc_irq_thread_handler, - IRQF_ONESHOT, "lt9611uxc", lt9611uxc); + ret = devm_request_threaded_irq(dev, client->irq, NULL, + lt9611uxc_irq_thread_handler, + IRQF_ONESHOT, "lt9611uxc", lt9611uxc); if (ret) { dev_err(dev, "failed to request irq\n"); goto err_disable_regulators; @@ -946,29 +980,8 @@ retry: drm_bridge_add(<9611uxc->bridge); - /* Attach primary DSI */ - lt9611uxc->dsi0 = lt9611uxc_attach_dsi(lt9611uxc, lt9611uxc->dsi0_node); - if (IS_ERR(lt9611uxc->dsi0)) { - ret = PTR_ERR(lt9611uxc->dsi0); - goto err_remove_bridge; - } - - /* Attach secondary DSI, if specified */ - if (lt9611uxc->dsi1_node) { - lt9611uxc->dsi1 = lt9611uxc_attach_dsi(lt9611uxc, lt9611uxc->dsi1_node); - if (IS_ERR(lt9611uxc->dsi1)) { - ret = PTR_ERR(lt9611uxc->dsi1); - goto err_remove_bridge; - } - } - return lt9611uxc_audio_init(dev, lt9611uxc); -err_remove_bridge: - free_irq(client->irq, lt9611uxc); - cancel_work_sync(<9611uxc->work); - drm_bridge_remove(<9611uxc->bridge); - err_disable_regulators: regulator_bulk_disable(ARRAY_SIZE(lt9611uxc->supplies), lt9611uxc->supplies); @@ -983,7 +996,7 @@ static int lt9611uxc_remove(struct i2c_client *client) { struct lt9611uxc *lt9611uxc = i2c_get_clientdata(client); - free_irq(client->irq, lt9611uxc); + disable_irq(client->irq); cancel_work_sync(<9611uxc->work); lt9611uxc_audio_exit(lt9611uxc); drm_bridge_remove(<9611uxc->bridge); |