summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2015-07-23 15:08:40 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-08-03 17:21:58 -0700
commitfeb8cd0fe7d63fd259c28f8a52fc88745717c9ec (patch)
treeccd469d0097a8c903be31ce88bf45e3cba7c41f5
parent688a9cce0c8e9116038586ae1cd6adabb10fa5aa (diff)
mei: bus: revamp probe and remove functions
Instead of generating device id on the fly during probing we find the matching id entry on the device id table. Get bus the module reference counter so it cannot be unloaded after the driver has bounded to the client device Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/misc/mei/bus.c41
1 files changed, 30 insertions, 11 deletions
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index 4955a0908d04..1d9ce9c491cf 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -446,30 +446,49 @@ static int mei_cl_device_match(struct device *dev, struct device_driver *drv)
return 0;
}
+/**
+ * mei_cl_device_probe - bus probe function
+ *
+ * @dev: device
+ *
+ * Return: 0 on success; < 0 otherwise
+ */
static int mei_cl_device_probe(struct device *dev)
{
- struct mei_cl_device *cldev = to_mei_cl_device(dev);
+ struct mei_cl_device *cldev;
struct mei_cl_driver *cldrv;
- struct mei_cl_device_id id;
+ const struct mei_cl_device_id *id;
+
+ cldev = to_mei_cl_device(dev);
+ cldrv = to_mei_cl_driver(dev->driver);
if (!cldev)
return 0;
- cldrv = to_mei_cl_driver(dev->driver);
if (!cldrv || !cldrv->probe)
return -ENODEV;
- dev_dbg(dev, "Device probe\n");
+ id = mei_cl_device_find(cldev, cldrv);
+ if (!id)
+ return -ENODEV;
- strlcpy(id.name, cldev->name, sizeof(id.name));
+ __module_get(THIS_MODULE);
- return cldrv->probe(cldev, &id);
+ return cldrv->probe(cldev, id);
}
+/**
+ * mei_cl_device_remove - remove device from the bus
+ *
+ * @dev: device
+ *
+ * Return: 0 on success; < 0 otherwise
+ */
static int mei_cl_device_remove(struct device *dev)
{
struct mei_cl_device *cldev = to_mei_cl_device(dev);
struct mei_cl_driver *cldrv;
+ int ret = 0;
if (!cldev || !dev->driver)
return 0;
@@ -480,13 +499,13 @@ static int mei_cl_device_remove(struct device *dev)
}
cldrv = to_mei_cl_driver(dev->driver);
- if (!cldrv->remove) {
- dev->driver = NULL;
+ if (cldrv->remove)
+ ret = cldrv->remove(cldev);
- return 0;
- }
+ module_put(THIS_MODULE);
+ dev->driver = NULL;
+ return ret;
- return cldrv->remove(cldev);
}
static ssize_t name_show(struct device *dev, struct device_attribute *a,