The i2c subsystem currently blocks during adapter deregistration
whenever there are consumers holding a reference.

Switch to using of_get_i2c_adapter_by_node() which also takes a
reference to the adapter module so that an attempt to unload the module
while in use fails gracefully instead of blocking uninterruptibly.

Signed-off-by: Johan Hovold <[email protected]>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index a161d3b00a25..40c28e23ea46 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -3208,11 +3208,11 @@ static int vc4_hdmi_runtime_resume(struct device *dev)
        return ret;
 }
 
-static void vc4_hdmi_put_ddc_device(void *ptr)
+static void vc4_hdmi_put_ddc(void *ptr)
 {
        struct vc4_hdmi *vc4_hdmi = ptr;
 
-       put_device(&vc4_hdmi->ddc->dev);
+       i2c_put_adapter(vc4_hdmi->ddc);
 }
 
 static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
@@ -3266,14 +3266,14 @@ static int vc4_hdmi_bind(struct device *dev, struct 
device *master, void *data)
                return -ENODEV;
        }
 
-       vc4_hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
+       vc4_hdmi->ddc = of_get_i2c_adapter_by_node(ddc_node);
        of_node_put(ddc_node);
        if (!vc4_hdmi->ddc) {
                drm_err(drm, "Failed to get ddc i2c adapter by node\n");
                return -EPROBE_DEFER;
        }
 
-       ret = devm_add_action_or_reset(dev, vc4_hdmi_put_ddc_device, vc4_hdmi);
+       ret = devm_add_action_or_reset(dev, vc4_hdmi_put_ddc, vc4_hdmi);
        if (ret)
                return ret;
 
-- 
2.54.0

Reply via email to