driver core: emit uevents when device is bound to a driver
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Thu, 20 Jul 2017 00:24:30 +0000 (17:24 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 22 Jul 2017 09:59:23 +0000 (11:59 +0200)
There are certain touch controllers that may come up in either normal
(application) or boot mode, depending on whether firmware/configuration is
corrupted when they are powered on. In boot mode the kernel does not create
input device instance (because it does not necessarily know the
characteristics of the input device in question).

Another number of controllers does not store firmware in a non-volatile
memory, and they similarly need to have firmware loaded before input device
instance is created. There are also other types of devices with similar
behavior.

There is a desire to be able to trigger firmware loading via udev, but it
has to happen only when driver is bound to a physical device (i2c or spi).
These udev actions can not use ADD events, as those happen too early, so we
are introducing BIND and UNBIND events that are emitted at the right
moment.

Also, many drivers create additional driver-specific device attributes
when binding to the device, to provide userspace with additional controls.
The new events allow userspace to adjust these driver-specific attributes
without worrying that they are not there yet.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/base/dd.c
include/linux/kobject.h
lib/kobject_uevent.c

index 4882f06d12dfe3b6e8ab7393a5e95c0ab7892d20..c17fefc7734567005be8af2866e3ba967f7ef5aa 100644 (file)
@@ -259,6 +259,8 @@ static void driver_bound(struct device *dev)
        if (dev->bus)
                blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
                                             BUS_NOTIFY_BOUND_DRIVER, dev);
+
+       kobject_uevent(&dev->kobj, KOBJ_BIND);
 }
 
 static int driver_sysfs_add(struct device *dev)
@@ -848,6 +850,8 @@ static void __device_release_driver(struct device *dev, struct device *parent)
                        blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
                                                     BUS_NOTIFY_UNBOUND_DRIVER,
                                                     dev);
+
+               kobject_uevent(&dev->kobj, KOBJ_UNBIND);
        }
 }
 
index ca85cb80e99a60e33df79e2ed0d8815953d1d21d..12f5ddccb97c2701edb80bb6f9d7ca3be43b36c5 100644 (file)
@@ -57,6 +57,8 @@ enum kobject_action {
        KOBJ_MOVE,
        KOBJ_ONLINE,
        KOBJ_OFFLINE,
+       KOBJ_BIND,
+       KOBJ_UNBIND,
        KOBJ_MAX
 };
 
index 9a2b811966ebfe82088030db637d0b98ecb99b5c..4682e8545b5c1a702999664332e6b98c0dabe9ce 100644 (file)
@@ -50,6 +50,8 @@ static const char *kobject_actions[] = {
        [KOBJ_MOVE] =           "move",
        [KOBJ_ONLINE] =         "online",
        [KOBJ_OFFLINE] =        "offline",
+       [KOBJ_BIND] =           "bind",
+       [KOBJ_UNBIND] =         "unbind",
 };
 
 /**