struct dw_dsi {
        struct drm_encoder encoder;
-       struct drm_bridge *bridge;
+       struct device *dev;
        struct mipi_dsi_host host;
        struct drm_display_mode cur_mode;
        struct dsi_hw_ctx *ctx;
        return 0;
 }
 
+static const struct component_ops dsi_ops;
 static int dsi_host_attach(struct mipi_dsi_host *host,
                           struct mipi_dsi_device *mdsi)
 {
        struct dw_dsi *dsi = host_to_dsi(host);
+       struct device *dev = host->dev;
+       int ret;
 
        if (mdsi->lanes < 1 || mdsi->lanes > 4) {
                DRM_ERROR("dsi device params invalid\n");
        dsi->format = mdsi->format;
        dsi->mode_flags = mdsi->mode_flags;
 
+       ret = component_add(dev, &dsi_ops);
+       if (ret)
+               return ret;
+
        return 0;
 }
 
 static int dsi_host_detach(struct mipi_dsi_host *host,
                           struct mipi_dsi_device *mdsi)
 {
-       /* do nothing */
+       struct device *dev = host->dev;
+
+       component_del(dev, &dsi_ops);
+
        return 0;
 }
 
 static int dsi_bridge_init(struct drm_device *dev, struct dw_dsi *dsi)
 {
        struct drm_encoder *encoder = &dsi->encoder;
-       struct drm_bridge *bridge = dsi->bridge;
+       struct drm_bridge *bridge;
+       struct device_node *np = dsi->dev->of_node;
+       int ret;
+
+       /*
+        * Get the endpoint node. In our case, dsi has one output port1
+        * to which the external HDMI bridge is connected.
+        */
+       ret = drm_of_find_panel_or_bridge(np, 1, 0, NULL, &bridge);
+       if (ret)
+               return ret;
 
        /* associate the bridge to dsi encoder */
        return drm_bridge_attach(encoder, bridge, NULL, 0);
        if (ret)
                return ret;
 
-       ret = dsi_host_init(dev, dsi);
-       if (ret)
-               return ret;
-
        ret = dsi_bridge_init(drm_dev, dsi);
        if (ret)
                return ret;
 static int dsi_parse_dt(struct platform_device *pdev, struct dw_dsi *dsi)
 {
        struct dsi_hw_ctx *ctx = dsi->ctx;
-       struct device_node *np = pdev->dev.of_node;
        struct resource *res;
-       int ret;
-
-       /*
-        * Get the endpoint node. In our case, dsi has one output port1
-        * to which the external HDMI bridge is connected.
-        */
-       ret = drm_of_find_panel_or_bridge(np, 1, 0, NULL, &dsi->bridge);
-       if (ret)
-               return ret;
 
        ctx->pclk = devm_clk_get(&pdev->dev, "pclk");
        if (IS_ERR(ctx->pclk)) {
        dsi = &data->dsi;
        ctx = &data->ctx;
        dsi->ctx = ctx;
+       dsi->dev = &pdev->dev;
 
        ret = dsi_parse_dt(pdev, dsi);
        if (ret)
 
        platform_set_drvdata(pdev, data);
 
-       return component_add(&pdev->dev, &dsi_ops);
+       ret = dsi_host_init(&pdev->dev, dsi);
+       if (ret)
+               return ret;
+
+       return 0;
 }
 
 static int dsi_remove(struct platform_device *pdev)
 {
-       component_del(&pdev->dev, &dsi_ops);
+       struct dsi_data *data = platform_get_drvdata(pdev);
+       struct dw_dsi *dsi = &data->dsi;
+
+       mipi_dsi_host_unregister(&dsi->host);
 
        return 0;
 }