keventd: add class/<subsystem>/<name> and driver/<name> conditions

dev/<X> only fires when a device gets a /dev node, which leaves a lot of
embedded-relevant hardware uncoverable: DSA switch cores, IIO sensors,
LEDs, backlight, PHYs, regulators -- all live purely under sysfs.

Two new condition namespaces:

  class/<subsystem>/<sysname>  asserted on every sysfs class device add
                                (e.g. <class/leds/blue>)
  driver/<name>                 asserted while the driver is bound to at
                                least one device (e.g. <driver/mt7530>)

A driver can bind to several devices, so driver/ conditions are
refcounted: asserted on first bind, cleared when the last device is
unbound.

dev_cond() is generalized into a static cond_emit(prefix, rel, set) so
class_cond() and driver_cond() share the same mkpath + symlink/erase
code.  The name avoids colliding with src/cond.h's public cond_path()
helper (unrelated function that returns a condition's filesystem path).

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg committed 2026-08-16 22:03:34 +02:00
1 parent e4d9193f06
commit f3461ce2ba
6 files changed
+174 -13

No files matched your search

+12 -1
View File
@@ -334,11 +334,17 @@ static void handle_uevent(char *buf, size_t len)
/* Create symlinks */
symlink_add(&ev);
/* class/<subsystem>/<sysname> -- covers sysfs-only
* devices that don't get a /dev node. */
class_cond(&ev, 1);
}
break;
case ACT_REMOVE:
if (!passive) {
class_cond(&ev, 0);
/* Remove symlinks first */
symlink_del(&ev);
@@ -356,8 +362,13 @@ static void handle_uevent(char *buf, size_t len)
break;
case ACT_BIND:
if (!passive)
driver_cond(&ev, 1);
break;
case ACT_UNBIND:
/* Driver bind/unbind - could trigger conditions */
if (!passive)
driver_cond(&ev, 0);
break;
default: