Commit a253d1f3 authored by Alexander Usyskin's avatar Alexander Usyskin Committed by Greg Kroah-Hartman

mei: bus: move hw module get/put to probe/release

commit b5958faa upstream.

Fix unbalanced module reference counting during internal reset, which
prevents the drivers unloading.
Tracking mei_me/txe modules on mei client bus via
mei_cldev_enable/disable is error prone due to possible internal
reset flow, where clients are disconnected underneath.
Moving reference counting to probe and release of mei bus client
driver solves this issue in simplest way, as each client provides only
a single connection to a client bus driver.

Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarAlexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 02c0c70f
...@@ -541,17 +541,9 @@ int mei_cldev_enable(struct mei_cl_device *cldev) ...@@ -541,17 +541,9 @@ int mei_cldev_enable(struct mei_cl_device *cldev)
goto out; goto out;
} }
if (!mei_cl_bus_module_get(cldev)) {
dev_err(&cldev->dev, "get hw module failed");
ret = -ENODEV;
goto out;
}
ret = mei_cl_connect(cl, cldev->me_cl, NULL); ret = mei_cl_connect(cl, cldev->me_cl, NULL);
if (ret < 0) { if (ret < 0)
dev_err(&cldev->dev, "cannot connect\n"); dev_err(&cldev->dev, "cannot connect\n");
mei_cl_bus_module_put(cldev);
}
out: out:
mutex_unlock(&bus->device_lock); mutex_unlock(&bus->device_lock);
...@@ -614,7 +606,6 @@ int mei_cldev_disable(struct mei_cl_device *cldev) ...@@ -614,7 +606,6 @@ int mei_cldev_disable(struct mei_cl_device *cldev)
if (err < 0) if (err < 0)
dev_err(bus->dev, "Could not disconnect from the ME client\n"); dev_err(bus->dev, "Could not disconnect from the ME client\n");
mei_cl_bus_module_put(cldev);
out: out:
/* Flush queues and remove any pending read */ /* Flush queues and remove any pending read */
mei_cl_flush_queues(cl, NULL); mei_cl_flush_queues(cl, NULL);
...@@ -725,9 +716,16 @@ static int mei_cl_device_probe(struct device *dev) ...@@ -725,9 +716,16 @@ static int mei_cl_device_probe(struct device *dev)
if (!id) if (!id)
return -ENODEV; return -ENODEV;
if (!mei_cl_bus_module_get(cldev)) {
dev_err(&cldev->dev, "get hw module failed");
return -ENODEV;
}
ret = cldrv->probe(cldev, id); ret = cldrv->probe(cldev, id);
if (ret) if (ret) {
mei_cl_bus_module_put(cldev);
return ret; return ret;
}
__module_get(THIS_MODULE); __module_get(THIS_MODULE);
return 0; return 0;
...@@ -755,6 +753,7 @@ static int mei_cl_device_remove(struct device *dev) ...@@ -755,6 +753,7 @@ static int mei_cl_device_remove(struct device *dev)
mei_cldev_unregister_callbacks(cldev); mei_cldev_unregister_callbacks(cldev);
mei_cl_bus_module_put(cldev);
module_put(THIS_MODULE); module_put(THIS_MODULE);
dev->driver = NULL; dev->driver = NULL;
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment