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 /drivers | |
| 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>
Diffstat (limited to 'drivers')
| -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 | ||
