aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/bus.c34
-rw-r--r--drivers/base/driver.c35
-rw-r--r--include/linux/device.h5
3 files changed, 74 insertions, 0 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index c3fac7fd555e..2c64b792d074 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -177,6 +177,39 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start,
177 return error; 177 return error;
178} 178}
179 179
180/**
181 * bus_find_device - device iterator for locating a particular device.
182 * @bus: bus type
183 * @start: Device to begin with
184 * @data: Data to pass to match function
185 * @match: Callback function to check device
186 *
187 * This is similar to the bus_for_each_dev() function above, but it
188 * returns a reference to a device that is 'found' for later use, as
189 * determined by the @match callback.
190 *
191 * The callback should return 0 if the device doesn't match and non-zero
192 * if it does. If the callback returns non-zero, this function will
193 * return to the caller and not iterate over any more devices.
194 */
195struct device * bus_find_device(struct bus_type *bus,
196 struct device *start, void *data,
197 int (*match)(struct device *, void *))
198{
199 struct klist_iter i;
200 struct device *dev;
201
202 if (!bus)
203 return NULL;
204
205 klist_iter_init_node(&bus->klist_devices, &i,
206 (start ? &start->knode_bus : NULL));
207 while ((dev = next_device(&i)))
208 if (match(dev, data) && get_device(dev))
209 break;
210 klist_iter_exit(&i);
211 return dev;
212}
180 213
181 214
182static struct device_driver * next_driver(struct klist_iter * i) 215static struct device_driver * next_driver(struct klist_iter * i)
@@ -557,6 +590,7 @@ int __init buses_init(void)
557 590
558 591
559EXPORT_SYMBOL_GPL(bus_for_each_dev); 592EXPORT_SYMBOL_GPL(bus_for_each_dev);
593EXPORT_SYMBOL_GPL(bus_find_device);
560EXPORT_SYMBOL_GPL(bus_for_each_drv); 594EXPORT_SYMBOL_GPL(bus_for_each_drv);
561 595
562EXPORT_SYMBOL_GPL(bus_add_device); 596EXPORT_SYMBOL_GPL(bus_add_device);
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 1b645886e9eb..291c5954a3af 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -56,6 +56,41 @@ EXPORT_SYMBOL_GPL(driver_for_each_device);
56 56
57 57
58/** 58/**
59 * driver_find_device - device iterator for locating a particular device.
60 * @driver: The device's driver
61 * @start: Device to begin with
62 * @data: Data to pass to match function
63 * @match: Callback function to check device
64 *
65 * This is similar to the driver_for_each_device() function above, but
66 * it returns a reference to a device that is 'found' for later use, as
67 * determined by the @match callback.
68 *
69 * The callback should return 0 if the device doesn't match and non-zero
70 * if it does. If the callback returns non-zero, this function will
71 * return to the caller and not iterate over any more devices.
72 */
73struct device * driver_find_device(struct device_driver *drv,
74 struct device * start, void * data,
75 int (*match)(struct device *, void *))
76{
77 struct klist_iter i;
78 struct device *dev;
79
80 if (!drv)
81 return NULL;
82
83 klist_iter_init_node(&drv->klist_devices, &i,
84 (start ? &start->knode_driver : NULL));
85 while ((dev = next_device(&i)))
86 if (match(dev, data) && get_device(dev))
87 break;
88 klist_iter_exit(&i);
89 return dev;
90}
91EXPORT_SYMBOL_GPL(driver_find_device);
92
93/**
59 * driver_create_file - create sysfs file for driver. 94 * driver_create_file - create sysfs file for driver.
60 * @drv: driver. 95 * @drv: driver.
61 * @attr: driver attribute descriptor. 96 * @attr: driver attribute descriptor.
diff --git a/include/linux/device.h b/include/linux/device.h
index 7b781a72b293..07222c531d37 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -80,6 +80,8 @@ extern struct bus_type * find_bus(char * name);
80 80
81int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data, 81int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data,
82 int (*fn)(struct device *, void *)); 82 int (*fn)(struct device *, void *));
83struct device * bus_find_device(struct bus_type *bus, struct device *start,
84 void *data, int (*match)(struct device *, void *));
83 85
84int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, 86int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
85 void * data, int (*fn)(struct device_driver *, void *)); 87 void * data, int (*fn)(struct device_driver *, void *));
@@ -142,6 +144,9 @@ extern void driver_remove_file(struct device_driver *, struct driver_attribute *
142 144
143extern int driver_for_each_device(struct device_driver * drv, struct device * start, 145extern int driver_for_each_device(struct device_driver * drv, struct device * start,
144 void * data, int (*fn)(struct device *, void *)); 146 void * data, int (*fn)(struct device *, void *));
147struct device * driver_find_device(struct device_driver *drv,
148 struct device *start, void *data,
149 int (*match)(struct device *, void *));
145 150
146 151
147/* 152/*