Skip to content

Commit

Permalink
usb: typec: mux: Take care of driver module reference counting
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Heikki Krogerus authored and Greg Kroah-Hartman committed Sep 20, 2018
1 parent 16c4cb1 commit 3e3b819
Showing 1 changed file with 13 additions and 4 deletions.
17 changes: 13 additions & 4 deletions drivers/usb/typec/mux.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <linux/device.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/usb/typec_mux.h>

Expand Down Expand Up @@ -49,8 +50,10 @@ struct typec_switch *typec_switch_get(struct device *dev)
mutex_lock(&switch_lock);
sw = device_connection_find_match(dev, "typec-switch", NULL,
typec_switch_match);
if (!IS_ERR_OR_NULL(sw))
if (!IS_ERR_OR_NULL(sw)) {
WARN_ON(!try_module_get(sw->dev->driver->owner));
get_device(sw->dev);
}
mutex_unlock(&switch_lock);

return sw;
Expand All @@ -65,8 +68,10 @@ EXPORT_SYMBOL_GPL(typec_switch_get);
*/
void typec_switch_put(struct typec_switch *sw)
{
if (!IS_ERR_OR_NULL(sw))
if (!IS_ERR_OR_NULL(sw)) {
module_put(sw->dev->driver->owner);
put_device(sw->dev);
}
}
EXPORT_SYMBOL_GPL(typec_switch_put);

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

mutex_lock(&mux_lock);
mux = device_connection_find_match(dev, name, NULL, typec_mux_match);
if (!IS_ERR_OR_NULL(mux))
if (!IS_ERR_OR_NULL(mux)) {
WARN_ON(!try_module_get(mux->dev->driver->owner));
get_device(mux->dev);
}
mutex_unlock(&mux_lock);

return mux;
Expand All @@ -152,8 +159,10 @@ EXPORT_SYMBOL_GPL(typec_mux_get);
*/
void typec_mux_put(struct typec_mux *mux)
{
if (!IS_ERR_OR_NULL(mux))
if (!IS_ERR_OR_NULL(mux)) {
module_put(mux->dev->driver->owner);
put_device(mux->dev);
}
}
EXPORT_SYMBOL_GPL(typec_mux_put);

Expand Down

0 comments on commit 3e3b819

Please sign in to comment.