drm: bridge: dw-hdmi: fix panic when misc_deregister()
authorxuhuicong <xhc@rock-chips.com>
Mon, 19 Jun 2017 07:27:15 +0000 (15:27 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Tue, 20 Jun 2017 02:20:09 +0000 (10:20 +0800)
Change-Id: I6ab7eb4e8a756e5ae62b181e36b9bff4f6dc7ebf
Signed-off-by: xuhuicong <xhc@rock-chips.com>
drivers/gpu/drm/bridge/dw-hdmi-hdcp.c
drivers/gpu/drm/bridge/dw-hdmi-hdcp.h

index e50ee5bf541bf648b8185441a642fcf2ea5059b4..05401f85ad151edd7ebb08762990a59a0e4911d0 100644 (file)
@@ -122,7 +122,7 @@ struct sha_t {
        unsigned int mdigest[5];
 };
 
-static struct miscdevice mdev;
+static struct dw_hdcp *g_hdcp;
 
 static inline unsigned int shacircularshift(unsigned int bits,
                                            unsigned int word)
@@ -573,7 +573,7 @@ static ssize_t hdcp_enable_read(struct device *device,
                                struct device_attribute *attr, char *buf)
 {
        int enable = 0;
-       struct dw_hdcp *hdcp = dev_get_drvdata(device);
+       struct dw_hdcp *hdcp = g_hdcp;
 
        if (hdcp)
                enable = hdcp->enable;
@@ -586,7 +586,7 @@ static ssize_t hdcp_enable_write(struct device *device,
                                 const char *buf, size_t count)
 {
        int enable;
-       struct dw_hdcp *hdcp = dev_get_drvdata(device);
+       struct dw_hdcp *hdcp = g_hdcp;
 
        if (!hdcp)
                return -EINVAL;
@@ -615,7 +615,7 @@ static ssize_t hdcp_trytimes_read(struct device *device,
                                  struct device_attribute *attr, char *buf)
 {
        int trytimes = 0;
-       struct dw_hdcp *hdcp = dev_get_drvdata(device);
+       struct dw_hdcp *hdcp = g_hdcp;
 
        if (hdcp)
                trytimes = hdcp->retry_times;
@@ -628,7 +628,7 @@ static ssize_t hdcp_trytimes_write(struct device *device,
                                   const char *buf, size_t count)
 {
        int trytimes;
-       struct dw_hdcp *hdcp = dev_get_drvdata(device);
+       struct dw_hdcp *hdcp = g_hdcp;
 
        if (!hdcp)
                return -EINVAL;
@@ -650,7 +650,7 @@ static ssize_t hdcp_status_read(struct device *device,
                                struct device_attribute *attr, char *buf)
 {
        int status = DW_HDCP_DISABLED;
-       struct dw_hdcp *hdcp = dev_get_drvdata(device);
+       struct dw_hdcp *hdcp = g_hdcp;
 
        if (hdcp)
                status = hdcp->status;
@@ -674,36 +674,36 @@ static int dw_hdmi_hdcp_probe(struct platform_device *pdev)
        int ret = 0;
        struct dw_hdcp *hdcp = pdev->dev.platform_data;
 
-       mdev.minor = MISC_DYNAMIC_MINOR;
-       mdev.name = "hdmi_hdcp1x";
-       mdev.mode = 0666;
+       g_hdcp = hdcp;
+       hdcp->mdev.minor = MISC_DYNAMIC_MINOR;
+       hdcp->mdev.name = "hdmi_hdcp1x";
+       hdcp->mdev.mode = 0666;
 
-       if (misc_register(&mdev)) {
+       if (misc_register(&hdcp->mdev)) {
                dev_err(&pdev->dev, "HDCP: Could not add character driver\n");
                return -EINVAL;
        }
 
-       ret = device_create_file(mdev.this_device, &dev_attr_enable);
+       ret = device_create_file(hdcp->mdev.this_device, &dev_attr_enable);
        if (ret) {
                dev_err(&pdev->dev, "HDCP: Could not add sys file enable\n");
                ret = -EINVAL;
                goto error0;
        }
 
-       ret = device_create_file(mdev.this_device, &dev_attr_trytimes);
+       ret = device_create_file(hdcp->mdev.this_device, &dev_attr_trytimes);
        if (ret) {
                dev_err(&pdev->dev, "HDCP: Could not add sys file trytimes\n");
                ret = -EINVAL;
                goto error1;
        }
 
-       ret = device_create_file(mdev.this_device, &dev_attr_status);
+       ret = device_create_file(hdcp->mdev.this_device, &dev_attr_status);
        if (ret) {
                dev_err(&pdev->dev, "HDCP: Could not add sys file status\n");
                ret = -EINVAL;
                goto error2;
        }
-       dev_set_drvdata(mdev.this_device, hdcp);
 
        if (!(hdcp->read(hdcp->hdmi, HDMI_MC_CLKDIS) &
            HDMI_MC_CLKDIS_HDCPCLK_MASK))
@@ -718,11 +718,11 @@ static int dw_hdmi_hdcp_probe(struct platform_device *pdev)
        return 0;
 
 error2:
-       device_remove_file(mdev.this_device, &dev_attr_trytimes);
+       device_remove_file(hdcp->mdev.this_device, &dev_attr_trytimes);
 error1:
-       device_remove_file(mdev.this_device, &dev_attr_enable);
+       device_remove_file(hdcp->mdev.this_device, &dev_attr_enable);
 error0:
-       misc_deregister(&mdev);
+       misc_deregister(&hdcp->mdev);
        return ret;
 }
 
@@ -730,10 +730,10 @@ static int dw_hdmi_hdcp_remove(struct platform_device *pdev)
 {
        struct dw_hdcp *hdcp = pdev->dev.platform_data;
 
-       device_remove_file(mdev.this_device, &dev_attr_trytimes);
-       device_remove_file(mdev.this_device, &dev_attr_enable);
-       device_remove_file(mdev.this_device, &dev_attr_status);
-       misc_deregister(&mdev);
+       device_remove_file(hdcp->mdev.this_device, &dev_attr_trytimes);
+       device_remove_file(hdcp->mdev.this_device, &dev_attr_enable);
+       device_remove_file(hdcp->mdev.this_device, &dev_attr_status);
+       misc_deregister(&hdcp->mdev);
 
        kfree(hdcp->keys);
        kfree(hdcp->seeds);
index 197f55561fa1e1095a807bfad55cf22eef88fbca..e63c1dcb68b17d076b8485ced4fd36228b274a84 100644 (file)
@@ -36,6 +36,7 @@ struct dw_hdcp {
        int status;
        u32 reg_io_width;
 
+       struct miscdevice mdev;
        struct hdcp_keys *keys;
        struct device *dev;
        struct dw_hdmi *hdmi;