aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeikki Krogerus <heikki.krogerus@linux.intel.com>2018-09-19 03:58:04 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-09-20 07:35:01 -0400
commit3e3b81965cbfa01fda6d77750feedc3c46fc28d0 (patch)
tree9a3a56da7e1730bbc93f16b23bdd28a08f356f18
parent16c4cb19fa85c648a803752eb63cac0ef69231c2 (diff)
usb: typec: mux: Take care of driver module reference counting
Functions typec_mux_get() and typec_switch_get() already make sure that the mux device reference count is incremented, but the same must be done to the driver module as well to prevent the drivers from being unloaded in the middle of operation. This fixes a potential "BUG: unable to handle kernel paging request at ..." from happening. Fixes: 93dd2112c7b2 ("usb: typec: mux: Get the mux identifier from function parameter") Acked-by: Hans de Goede <hdegoede@redhat.com> Tested-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/typec/mux.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c
index ddaac63ecf12..d990aa510fab 100644
--- a/drivers/usb/typec/mux.c
+++ b/drivers/usb/typec/mux.c
@@ -9,6 +9,7 @@
9 9
10#include <linux/device.h> 10#include <linux/device.h>
11#include <linux/list.h> 11#include <linux/list.h>
12#include <linux/module.h>
12#include <linux/mutex.h> 13#include <linux/mutex.h>
13#include <linux/usb/typec_mux.h> 14#include <linux/usb/typec_mux.h>
14 15
@@ -49,8 +50,10 @@ struct typec_switch *typec_switch_get(struct device *dev)
49 mutex_lock(&switch_lock); 50 mutex_lock(&switch_lock);
50 sw = device_connection_find_match(dev, "typec-switch", NULL, 51 sw = device_connection_find_match(dev, "typec-switch", NULL,
51 typec_switch_match); 52 typec_switch_match);
52 if (!IS_ERR_OR_NULL(sw)) 53 if (!IS_ERR_OR_NULL(sw)) {
54 WARN_ON(!try_module_get(sw->dev->driver->owner));
53 get_device(sw->dev); 55 get_device(sw->dev);
56 }
54 mutex_unlock(&switch_lock); 57 mutex_unlock(&switch_lock);
55 58
56 return sw; 59 return sw;
@@ -65,8 +68,10 @@ EXPORT_SYMBOL_GPL(typec_switch_get);
65 */ 68 */
66void typec_switch_put(struct typec_switch *sw) 69void typec_switch_put(struct typec_switch *sw)
67{ 70{
68 if (!IS_ERR_OR_NULL(sw)) 71 if (!IS_ERR_OR_NULL(sw)) {
72 module_put(sw->dev->driver->owner);
69 put_device(sw->dev); 73 put_device(sw->dev);
74 }
70} 75}
71EXPORT_SYMBOL_GPL(typec_switch_put); 76EXPORT_SYMBOL_GPL(typec_switch_put);
72 77
@@ -136,8 +141,10 @@ struct typec_mux *typec_mux_get(struct device *dev, const char *name)
136 141
137 mutex_lock(&mux_lock); 142 mutex_lock(&mux_lock);
138 mux = device_connection_find_match(dev, name, NULL, typec_mux_match); 143 mux = device_connection_find_match(dev, name, NULL, typec_mux_match);
139 if (!IS_ERR_OR_NULL(mux)) 144 if (!IS_ERR_OR_NULL(mux)) {
145 WARN_ON(!try_module_get(mux->dev->driver->owner));
140 get_device(mux->dev); 146 get_device(mux->dev);
147 }
141 mutex_unlock(&mux_lock); 148 mutex_unlock(&mux_lock);
142 149
143 return mux; 150 return mux;
@@ -152,8 +159,10 @@ EXPORT_SYMBOL_GPL(typec_mux_get);
152 */ 159 */
153void typec_mux_put(struct typec_mux *mux) 160void typec_mux_put(struct typec_mux *mux)
154{ 161{
155 if (!IS_ERR_OR_NULL(mux)) 162 if (!IS_ERR_OR_NULL(mux)) {
163 module_put(mux->dev->driver->owner);
156 put_device(mux->dev); 164 put_device(mux->dev);
165 }
157} 166}
158EXPORT_SYMBOL_GPL(typec_mux_put); 167EXPORT_SYMBOL_GPL(typec_mux_put);
159 168