diff options
author | Heikki Krogerus <heikki.krogerus@linux.intel.com> | 2018-09-19 03:58:05 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-09-20 07:20:24 -0400 |
commit | 5c54fcac9a9de559b444ac63ec3cd82f1d157a0b (patch) | |
tree | 06e3af99439cd5ca1fe7700f88b74d2bee2cc079 | |
parent | c9a4cb204e9eb7fa7dfbe3f7d3a674fa530aa193 (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.c | 15 |
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 | */ |
110 | struct usb_role_switch *usb_role_switch_get(struct device *dev) | 110 | struct 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 | } |
115 | EXPORT_SYMBOL_GPL(usb_role_switch_get); | 122 | EXPORT_SYMBOL_GPL(usb_role_switch_get); |
116 | 123 | ||
@@ -122,8 +129,10 @@ EXPORT_SYMBOL_GPL(usb_role_switch_get); | |||
122 | */ | 129 | */ |
123 | void usb_role_switch_put(struct usb_role_switch *sw) | 130 | void 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 | } |
128 | EXPORT_SYMBOL_GPL(usb_role_switch_put); | 137 | EXPORT_SYMBOL_GPL(usb_role_switch_put); |
129 | 138 | ||