Commit cb5f226e authored by Dmitry Torokhov's avatar Dmitry Torokhov Committed by Greg Kroah-Hartman

[PATCH] Driver core: add driver_probe_device

Driver core: rename bus_match into driver_probe_device and export
             it so subsystems can bind an individual device to a
             specific driver without getting involved with driver
             core internals.
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent 0d116d5f
...@@ -250,34 +250,35 @@ void device_bind_driver(struct device * dev) ...@@ -250,34 +250,35 @@ void device_bind_driver(struct device * dev)
/** /**
* bus_match - check compatibility between device & driver. * driver_probe_device - attempt to bind device & driver.
* @dev: device.
* @drv: driver. * @drv: driver.
* @dev: device.
* *
* First, we call the bus's match function, which should compare * First, we call the bus's match function, if one present, which
* the device IDs the driver supports with the device IDs of the * should compare the device IDs the driver supports with the
* device. Note we don't do this ourselves because we don't know * device IDs of the device. Note we don't do this ourselves
* the format of the ID structures, nor what is to be considered * because we don't know the format of the ID structures, nor what
* a match and what is not. * is to be considered a match and what is not.
* *
* If we find a match, we call @drv->probe(@dev) if it exists, and * If we find a match, we call @drv->probe(@dev) if it exists, and
* call attach() above. * call device_bind_driver() above.
*/ */
static int bus_match(struct device * dev, struct device_driver * drv) int driver_probe_device(struct device_driver * drv, struct device * dev)
{ {
int error = -ENODEV; if (drv->bus->match && !drv->bus->match(dev, drv))
if (dev->bus->match(dev, drv)) { return -ENODEV;
dev->driver = drv; dev->driver = drv;
if (drv->probe) { if (drv->probe) {
if ((error = drv->probe(dev))) { int error = drv->probe(dev);
if (error) {
dev->driver = NULL; dev->driver = NULL;
return error; return error;
} }
} }
device_bind_driver(dev); device_bind_driver(dev);
error = 0; return 0;
}
return error;
} }
...@@ -285,8 +286,9 @@ static int bus_match(struct device * dev, struct device_driver * drv) ...@@ -285,8 +286,9 @@ static int bus_match(struct device * dev, struct device_driver * drv)
* device_attach - try to attach device to a driver. * device_attach - try to attach device to a driver.
* @dev: device. * @dev: device.
* *
* Walk the list of drivers that the bus has and call bus_match() * Walk the list of drivers that the bus has and call
* for each pair. If a compatible pair is found, break out and return. * driver_probe_device() for each pair. If a compatible
* pair is found, break out and return.
*/ */
int device_attach(struct device * dev) int device_attach(struct device * dev)
{ {
...@@ -302,7 +304,7 @@ int device_attach(struct device * dev) ...@@ -302,7 +304,7 @@ int device_attach(struct device * dev)
if (bus->match) { if (bus->match) {
list_for_each(entry, &bus->drivers.list) { list_for_each(entry, &bus->drivers.list) {
struct device_driver * drv = to_drv(entry); struct device_driver * drv = to_drv(entry);
error = bus_match(dev, drv); error = driver_probe_device(drv, dev);
if (!error) if (!error)
/* success, driver matched */ /* success, driver matched */
return 1; return 1;
...@@ -327,8 +329,8 @@ int device_attach(struct device * dev) ...@@ -327,8 +329,8 @@ int device_attach(struct device * dev)
* If bus_match() returns 0 and the @dev->driver is set, we've found * If bus_match() returns 0 and the @dev->driver is set, we've found
* a compatible pair. * a compatible pair.
* *
* Note that we ignore the -ENODEV error from bus_match(), since it's * Note that we ignore the -ENODEV error from driver_probe_device(),
* perfectly valid for a driver not to bind to any devices. * since it's perfectly valid for a driver not to bind to any devices.
*/ */
void driver_attach(struct device_driver * drv) void driver_attach(struct device_driver * drv)
{ {
...@@ -342,7 +344,7 @@ void driver_attach(struct device_driver * drv) ...@@ -342,7 +344,7 @@ void driver_attach(struct device_driver * drv)
list_for_each(entry, &bus->devices.list) { list_for_each(entry, &bus->devices.list) {
struct device * dev = container_of(entry, struct device, bus_list); struct device * dev = container_of(entry, struct device, bus_list);
if (!dev->driver) { if (!dev->driver) {
error = bus_match(dev, drv); error = driver_probe_device(drv, dev);
if (error && (error != -ENODEV)) if (error && (error != -ENODEV))
/* driver matched but the probe failed */ /* driver matched but the probe failed */
printk(KERN_WARNING printk(KERN_WARNING
...@@ -726,6 +728,7 @@ int __init buses_init(void) ...@@ -726,6 +728,7 @@ int __init buses_init(void)
EXPORT_SYMBOL_GPL(bus_for_each_dev); EXPORT_SYMBOL_GPL(bus_for_each_dev);
EXPORT_SYMBOL_GPL(bus_for_each_drv); EXPORT_SYMBOL_GPL(bus_for_each_drv);
EXPORT_SYMBOL_GPL(driver_probe_device);
EXPORT_SYMBOL_GPL(device_bind_driver); EXPORT_SYMBOL_GPL(device_bind_driver);
EXPORT_SYMBOL_GPL(device_release_driver); EXPORT_SYMBOL_GPL(device_release_driver);
EXPORT_SYMBOL_GPL(device_attach); EXPORT_SYMBOL_GPL(device_attach);
......
...@@ -325,6 +325,7 @@ extern int device_for_each_child(struct device *, void *, ...@@ -325,6 +325,7 @@ extern int device_for_each_child(struct device *, void *,
* Manual binding of a device to driver. See drivers/base/bus.c * Manual binding of a device to driver. See drivers/base/bus.c
* for information on use. * for information on use.
*/ */
extern int driver_probe_device(struct device_driver * drv, struct device * dev);
extern void device_bind_driver(struct device * dev); extern void device_bind_driver(struct device * dev);
extern void device_release_driver(struct device * dev); extern void device_release_driver(struct device * dev);
extern int device_attach(struct device * dev); extern int device_attach(struct device * dev);
......
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