aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeikki Krogerus <heikki.krogerus@linux.intel.com>2018-09-19 03:58:05 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-09-20 07:20:24 -0400
commit5c54fcac9a9de559b444ac63ec3cd82f1d157a0b (patch)
tree06e3af99439cd5ca1fe7700f88b74d2bee2cc079
parentc9a4cb204e9eb7fa7dfbe3f7d3a674fa530aa193 (diff)
usb: roles: Take care of driver module reference counting
This fixes potential "BUG: unable to handle kernel paging request at ..." from happening. Fixes: fde0aa6c175a ("usb: common: Small class for USB role switches") Cc: <stable@vger.kernel.org> 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/common/roles.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/usb/common/roles.c b/drivers/usb/common/roles.c
index 15cc76e22123..99116af07f1d 100644
--- a/drivers/usb/common/roles.c
+++ b/drivers/usb/common/roles.c
@@ -109,8 +109,15 @@ static void *usb_role_switch_match(struct device_connection *con, int ep,
109 */ 109 */
110struct usb_role_switch *usb_role_switch_get(struct device *dev) 110struct usb_role_switch *usb_role_switch_get(struct device *dev)
111{ 111{
112 return device_connection_find_match(dev, "usb-role-switch", NULL, 112 struct usb_role_switch *sw;
113 usb_role_switch_match); 113
114 sw = device_connection_find_match(dev, "usb-role-switch", NULL,
115 usb_role_switch_match);
116
117 if (!IS_ERR_OR_NULL(sw))
118 WARN_ON(!try_module_get(sw->dev.parent->driver->owner));
119
120 return sw;
114} 121}
115EXPORT_SYMBOL_GPL(usb_role_switch_get); 122EXPORT_SYMBOL_GPL(usb_role_switch_get);
116 123
@@ -122,8 +129,10 @@ EXPORT_SYMBOL_GPL(usb_role_switch_get);
122 */ 129 */
123void usb_role_switch_put(struct usb_role_switch *sw) 130void usb_role_switch_put(struct usb_role_switch *sw)
124{ 131{
125 if (!IS_ERR_OR_NULL(sw)) 132 if (!IS_ERR_OR_NULL(sw)) {
126 put_device(&sw->dev); 133 put_device(&sw->dev);
134 module_put(sw->dev.parent->driver->owner);
135 }
127} 136}
128EXPORT_SYMBOL_GPL(usb_role_switch_put); 137EXPORT_SYMBOL_GPL(usb_role_switch_put);
129 138