Skip to content

Commit 3e3b819

Browse files
Heikki Krogerusgregkh
authored andcommitted
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: 93dd211 ("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>
1 parent 16c4cb1 commit 3e3b819

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

drivers/usb/typec/mux.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <linux/device.h>
1111
#include <linux/list.h>
12+
#include <linux/module.h>
1213
#include <linux/mutex.h>
1314
#include <linux/usb/typec_mux.h>
1415

@@ -49,8 +50,10 @@ struct typec_switch *typec_switch_get(struct device *dev)
4950
mutex_lock(&switch_lock);
5051
sw = device_connection_find_match(dev, "typec-switch", NULL,
5152
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));
5355
get_device(sw->dev);
56+
}
5457
mutex_unlock(&switch_lock);
5558

5659
return sw;
@@ -65,8 +68,10 @@ EXPORT_SYMBOL_GPL(typec_switch_get);
6568
*/
6669
void typec_switch_put(struct typec_switch *sw)
6770
{
68-
if (!IS_ERR_OR_NULL(sw))
71+
if (!IS_ERR_OR_NULL(sw)) {
72+
module_put(sw->dev->driver->owner);
6973
put_device(sw->dev);
74+
}
7075
}
7176
EXPORT_SYMBOL_GPL(typec_switch_put);
7277

@@ -136,8 +141,10 @@ struct typec_mux *typec_mux_get(struct device *dev, const char *name)
136141

137142
mutex_lock(&mux_lock);
138143
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));
140146
get_device(mux->dev);
147+
}
141148
mutex_unlock(&mux_lock);
142149

143150
return mux;
@@ -152,8 +159,10 @@ EXPORT_SYMBOL_GPL(typec_mux_get);
152159
*/
153160
void typec_mux_put(struct typec_mux *mux)
154161
{
155-
if (!IS_ERR_OR_NULL(mux))
162+
if (!IS_ERR_OR_NULL(mux)) {
163+
module_put(mux->dev->driver->owner);
156164
put_device(mux->dev);
165+
}
157166
}
158167
EXPORT_SYMBOL_GPL(typec_mux_put);
159168

0 commit comments

Comments
 (0)