struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder);
        struct vc4_dsi *dsi = vc4_encoder->dsi;
        struct device *dev = &dsi->pdev->dev;
+       struct drm_bridge *iter;
+
+       list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
+               if (iter->funcs->disable)
+                       iter->funcs->disable(iter);
+       }
 
-       drm_bridge_chain_disable(dsi->bridge);
        vc4_dsi_ulps(dsi, true);
-       drm_bridge_chain_post_disable(dsi->bridge);
+
+       list_for_each_entry_from(iter, &dsi->bridge_chain, chain_node) {
+               if (iter->funcs->post_disable)
+                       iter->funcs->post_disable(iter);
+       }
 
        clk_disable_unprepare(dsi->pll_phy_clock);
        clk_disable_unprepare(dsi->escape_clock);
        struct vc4_dsi *dsi = vc4_encoder->dsi;
        struct device *dev = &dsi->pdev->dev;
        bool debug_dump_regs = false;
+       struct drm_bridge *iter;
        unsigned long hs_clock;
        u32 ui_ns;
        /* Minimum LP state duration in escape clock cycles. */
 
        vc4_dsi_ulps(dsi, false);
 
-       drm_bridge_chain_pre_enable(dsi->bridge);
+       list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
+               if (iter->funcs->pre_enable)
+                       iter->funcs->pre_enable(iter);
+       }
 
        if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
                DSI_PORT_WRITE(DISP0_CTRL,
                               DSI_DISP0_ENABLE);
        }
 
-       drm_bridge_chain_enable(dsi->bridge);
+       list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
+               if (iter->funcs->enable)
+                       iter->funcs->enable(iter);
+       }
 
        if (debug_dump_regs) {
                struct drm_printer p = drm_info_printer(&dsi->pdev->dev);
         * from our driver, since we need to sequence them within the
         * encoder's enable/disable paths.
         */
-       list_splice(&dsi->encoder->bridge_chain, &dsi->bridge_chain);
+       list_splice_init(&dsi->encoder->bridge_chain, &dsi->bridge_chain);
 
        if (dsi->port == 0)
                vc4_debugfs_add_regset32(drm, "dsi0_regs", &dsi->regset);
         * Restore the bridge_chain so the bridge detach procedure can happen
         * normally.
         */
-       list_splice(&dsi->bridge_chain, &dsi->encoder->bridge_chain);
+       list_splice_init(&dsi->bridge_chain, &dsi->encoder->bridge_chain);
        vc4_dsi_encoder_destroy(dsi->encoder);
 
        if (dsi->port == 1)