@@ -962,6 +962,53 @@ int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb)
}
EXPORT_SYMBOL_GPL(bus_register_notifier);
+/**
+ * bus_register_notifier_alldev_helper - internal support function
+ * Used by bus_register_notifier_alldev() to create ADD and BOUND events
+ * for devices.
+ */
+static int bus_register_notifier_alldev_helper(struct device *dev, void *data)
+{
+ struct notifier_block *nb = data;
+ nb->notifier_call(nb, BUS_NOTIFY_ADD_DEVICE, dev);
+ if (dev->driver)
+ nb->notifier_call(nb, BUS_NOTIFY_BOUND_DRIVER, dev);
+ return 0;
+}
+
+/**
+ * bus_register_notifier_alldev - Register for bus events; include existing devs
+ * @bus: pointer to bus_type
+ * @nb: pointer to notifier block to register with the bus
+ *
+ * Similar to bus_register_notifier() except it also generates events for
+ * devices already on the bus when the notifier is registered. When this
+ * function is called the notifier is called once for each device with
+ * the BUS_NOTIFY_ADD_DEVICE event, and once for each device registered to
+ * a driver * with the BUS_NOTIFY_BOUND_DRIVER event.
+ *
+ * There is a small chance that the notifier could be called more than once
+ * for a device. This would happen if a new device was registered on the bus
+ * or bound to a driver between the call to bus_register_notifier() and the
+ * call to bus_for_each_dev(). The only way I can see to protect against
+ * this would be to take the klist_devices spinlock while calling the
+ * notifier; but that would be a Very Bad Thing (tm). Caller needs to be
+ * aware that a notifier called before this function returns might get
+ * called a second time on the same device.
+ */
+int bus_register_notifier_alldev(struct bus_type *b, struct notifier_block *nb)
+{
+ int ret;
+
+ ret = bus_register_notifier(b, nb);
+ if (ret == 0) {
+ bus_for_each_dev(b, NULL, nb,
+ bus_register_notifier_alldev_helper);
+ }
+ return ret;
+}
+EXPORT_SYMBOL_GPL(bus_register_notifier_alldev);
+
int bus_unregister_notifier(struct bus_type *bus, struct notifier_block *nb)
{
return blocking_notifier_chain_unregister(&bus->p->bus_notifier, nb);
@@ -103,6 +103,8 @@ struct notifier_block;
extern int bus_register_notifier(struct bus_type *bus,
struct notifier_block *nb);
+extern int bus_register_notifier_alldev(struct bus_type *b,
+ struct notifier_block *nb);
extern int bus_unregister_notifier(struct bus_type *bus,
struct notifier_block *nb);