From 18c2d85760f5290bbc76291e4ea687775a39a727 Mon Sep 17 00:00:00 2001 From: xuhuicong Date: Mon, 19 Jun 2017 15:27:15 +0800 Subject: [PATCH] drm: bridge: dw-hdmi: fix panic when misc_deregister() Change-Id: I6ab7eb4e8a756e5ae62b181e36b9bff4f6dc7ebf Signed-off-by: xuhuicong --- drivers/gpu/drm/bridge/dw-hdmi-hdcp.c | 42 +++++++++++++-------------- drivers/gpu/drm/bridge/dw-hdmi-hdcp.h | 1 + 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/bridge/dw-hdmi-hdcp.c b/drivers/gpu/drm/bridge/dw-hdmi-hdcp.c index e50ee5bf541b..05401f85ad15 100644 --- a/drivers/gpu/drm/bridge/dw-hdmi-hdcp.c +++ b/drivers/gpu/drm/bridge/dw-hdmi-hdcp.c @@ -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); diff --git a/drivers/gpu/drm/bridge/dw-hdmi-hdcp.h b/drivers/gpu/drm/bridge/dw-hdmi-hdcp.h index 197f55561fa1..e63c1dcb68b1 100644 --- a/drivers/gpu/drm/bridge/dw-hdmi-hdcp.h +++ b/drivers/gpu/drm/bridge/dw-hdmi-hdcp.h @@ -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; -- 2.34.1