@@ -496,6 +496,10 @@ config VCPU_STALL_DETECTOR
If you do not intend to run this kernel as a guest, say N.
+config NOTIFY_DEVICE
+ tristate "Notify device"
+ depends on OF
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
@@ -62,3 +62,4 @@ obj-$(CONFIG_HI6421V600_IRQ) += hi6421v600-irq.o
obj-$(CONFIG_OPEN_DICE) += open-dice.o
obj-$(CONFIG_GP_PCI1XXXX) += mchp_pci1xxxx/
obj-$(CONFIG_VCPU_STALL_DETECTOR) += vcpu_stall_detector.o
+obj-$(CONFIG_NOTIFY_DEVICE) += notify-device.o
new file mode 100644
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/device/class.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/notify-device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+static void notify_device_release(struct device *dev)
+{
+ of_node_put(dev->of_node);
+ kfree(dev);
+}
+
+static struct class notify_device_class = {
+ .name = "notify-device",
+ .owner = THIS_MODULE,
+ .dev_release = notify_device_release,
+};
+
+static struct platform_driver notify_device_driver = {
+ .driver = {
+ .name = "notify-device",
+ },
+};
+
+struct device *notify_device_create(struct device *parent, const char *child)
+{
+ struct device_node *node;
+ struct device *dev;
+ int err;
+
+ if (!parent->of_node)
+ return ERR_PTR(-EINVAL);
+
+ node = of_get_child_by_name(parent->of_node, child);
+ if (!node)
+ return NULL;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev) {
+ of_node_put(node);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ dev_set_name(dev, "%s:%s", dev_name(parent), child);
+ dev->class = ¬ify_device_class;
+ dev->parent = parent;
+ dev->of_node = node;
+ err = device_register(dev);
+ if (err) {
+ put_device(dev);
+ return ERR_PTR(err);
+ }
+
+ dev->driver = ¬ify_device_driver.driver;
+ err = device_bind_driver(dev);
+ if (err) {
+ device_unregister(dev);
+ return ERR_PTR(err);
+ }
+
+ return dev;
+}
+EXPORT_SYMBOL_GPL(notify_device_create);
+
+void notify_device_destroy(struct device *dev)
+{
+ if (!dev)
+ return;
+
+ device_release_driver(dev);
+ device_unregister(dev);
+}
+EXPORT_SYMBOL_GPL(notify_device_destroy);
+
+struct device *notify_device_find_by_of_node(struct device_node *node)
+{
+ return class_find_device_by_of_node(¬ify_device_class, node);
+}
+EXPORT_SYMBOL_GPL(notify_device_find_by_of_node);
+
+static int __init notify_device_init(void)
+{
+ int err;
+
+ err = class_register(¬ify_device_class);
+ if (err)
+ return err;
+
+ err = platform_driver_register(¬ify_device_driver);
+ if (err) {
+ class_unregister(¬ify_device_class);
+ return err;
+ }
+
+ return 0;
+}
+
+static void __exit notify_device_exit(void)
+{
+ platform_driver_unregister(¬ify_device_driver);
+ class_unregister(¬ify_device_class);
+}
+
+module_init(notify_device_init);
+module_exit(notify_device_exit);
+MODULE_LICENSE("GPL");
new file mode 100644
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _LINUX_NOTIFY_DEVICE_H
+#define _LINUX_NOTIFY_DEVICE_H
+#include <linux/device.h>
+#include <linux/of.h>
+
+#ifdef CONFIG_NOTIFY_DEVICE
+
+struct device *notify_device_create(struct device *parent, const char *child);
+void notify_device_destroy(struct device *dev);
+struct device *notify_device_find_by_of_node(struct device_node *node);
+
+#else
+
+static inline struct device *notify_device_create(struct device *parent,
+ const char *child)
+{
+ return NULL;
+}
+
+static inline void notify_device_destroy(struct device *dev)
+{
+}
+
+static inline struct device *notify_device_find_by_of_node(struct device_node *node)
+{
+ return NULL;
+}
+
+#endif
+
+#endif /* _LINUX_NOTIFY_DEVICE_H */
A notify-device is a synchronization facility that allows to query "readiness" across drivers, without creating a direct dependency between the driver modules. The notify-device can also be used to trigger deferred probes. Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com> --- drivers/misc/Kconfig | 4 ++ drivers/misc/Makefile | 1 + drivers/misc/notify-device.c | 109 ++++++++++++++++++++++++++++++++++ include/linux/notify-device.h | 33 ++++++++++ 4 files changed, 147 insertions(+) create mode 100644 drivers/misc/notify-device.c create mode 100644 include/linux/notify-device.h