drm: bridge: dw-hdmi: fixup kernel crash when reboot with hdmi connected
authoralgea.cao <algea.cao@rock-chips.com>
Tue, 2 May 2017 01:03:19 +0000 (09:03 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Fri, 2 Jun 2017 06:12:24 +0000 (14:12 +0800)
when other devices bind failed,drm will unbind and re-bind all devices.
if don't cancel the delayed work but flush and destroy workqueue directly,
kernel point is likely to become NULL.

Change-Id: Ib48704186ee298cbd4daac1cdbbac5fb3906b6bb
Signed-off-by: algea.cao <algea.cao@rock-chips.com>
drivers/gpu/drm/bridge/dw-hdmi.c

index 7feb580bce1f55978069e8c31e71a132c7c9deae..c4af0fc3a17a719c2d36b07a24bca20a5a71b81e 100644 (file)
@@ -2828,6 +2828,13 @@ void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
 {
        struct dw_hdmi *hdmi = dev_get_drvdata(dev);
 
+       if (hdmi->irq)
+               disable_irq(hdmi->irq);
+
+       cancel_delayed_work(&hdmi->work);
+       flush_workqueue(hdmi->workqueue);
+       destroy_workqueue(hdmi->workqueue);
+
        if (hdmi->audio && !IS_ERR(hdmi->audio))
                platform_device_unregister(hdmi->audio);
 
@@ -2847,9 +2854,6 @@ void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
                i2c_del_adapter(&hdmi->i2c->adap);
        else
                i2c_put_adapter(hdmi->ddc);
-
-       flush_workqueue(hdmi->workqueue);
-       destroy_workqueue(hdmi->workqueue);
 }
 EXPORT_SYMBOL_GPL(dw_hdmi_unbind);