diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 3bb1f1500f6be3b76b2c70e1a7a76c74c07e2131..b67f15b5306749cf18656078fa3727672652a2d9 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -541,6 +541,37 @@ int mei_cldev_disable(struct mei_cl_device *cldev) } EXPORT_SYMBOL_GPL(mei_cldev_disable); +/** + * mei_cl_bus_module_get - acquire module of the underlying + * hw module. + * + * @cl: host client + * + * Return: true on success; false if the module was removed. + */ +bool mei_cl_bus_module_get(struct mei_cl *cl) +{ + struct mei_cl_device *cldev = cl->cldev; + + if (!cldev) + return true; + + return try_module_get(cldev->bus->dev->driver->owner); +} + +/** + * mei_cl_bus_module_put - release the underlying hw module. + * + * @cl: host client + */ +void mei_cl_bus_module_put(struct mei_cl *cl) +{ + struct mei_cl_device *cldev = cl->cldev; + + if (cldev) + module_put(cldev->bus->dev->driver->owner); +} + /** * mei_cl_device_find - find matching entry in the driver id table * diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index da1c0703910a4d1d7def39156df2f73ef30b0902..619b4702347f8a528a28e4040bb26d1dfde43a2b 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -774,6 +774,8 @@ static void mei_cl_set_disconnected(struct mei_cl *cl) cl->tx_flow_ctrl_creds = 0; cl->timer_count = 0; + mei_cl_bus_module_put(cl); + if (!cl->me_cl) return; @@ -1077,13 +1079,17 @@ int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl, dev = cl->dev; + if (!mei_cl_bus_module_get(cl)) + return -ENODEV; + rets = mei_cl_set_connecting(cl, me_cl); if (rets) - return rets; + goto nortpm; if (mei_cl_is_fixed_address(cl)) { cl->state = MEI_FILE_CONNECTED; - return 0; + rets = 0; + goto nortpm; } rets = pm_runtime_get(dev->dev); diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 8dadb98662a9e61da14ed8d95268bc9b4ec23d2b..33ff4b7e356d6d9c833a82d62e88c9b854665b81 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -328,6 +328,8 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, bool mei_cl_bus_rx_event(struct mei_cl *cl); bool mei_cl_bus_notify_event(struct mei_cl *cl); void mei_cl_bus_remove_devices(struct mei_device *bus); +bool mei_cl_bus_module_get(struct mei_cl *cl); +void mei_cl_bus_module_put(struct mei_cl *cl); int mei_cl_bus_init(void); void mei_cl_bus_exit(void);