summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2022-03-10 08:28:40 -0500
committerTom Rini <[email protected]>2022-03-10 08:28:40 -0500
commitcb83a7a0c360d58a3a9bf2ba3828e576eafecb91 (patch)
tree23eeff85c6606bece47b2d99611786a3392416dc /drivers
parent0bf4e0bb935e5c7fc016142e0228882610ecbf39 (diff)
parentabe5d1184f276a0789365316061a14834dbc8dc4 (diff)
Merge branch '2022-03-09-events-subsystem' into next
To quote the author: It is a common need in U-Boot to have one subsystem notify another when something happens. An example is reading a partition table when a new block device is set up. It is also common to add weak functions and 'hook' functions to modify how U-Boot works. See for example ft_board_setup() and the like. U-Boot would benefit from a generic mechanism to handle these cases, with the ability to hook into various 'events' in a subsystem-independent and transparent way. This series provides a way to create and dispatch events, with a way of registering a 'spy' which watches for events of different types. This allows 'hook' functions to be created in a generic way. It also includes a script to list the hooks in an image, which is a bit easier to debug than weak functions, as well as an 'event' command to do the same from within U-Boot. These 'static' events can be used to replace hooks like misc_init_f(), for example. Also included is basic support for 'dynamic' events, where a spy can be registered at runtime. The need for this is still being figured out.
Diffstat (limited to 'drivers')
-rw-r--r--drivers/core/Kconfig10
-rw-r--r--drivers/core/device-remove.c8
-rw-r--r--drivers/core/device.c9
-rw-r--r--drivers/core/root.c5
4 files changed, 32 insertions, 0 deletions
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index 8f7703c8b58..5c3400417f9 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -77,6 +77,16 @@ config DM_DEVICE_REMOVE
it causes unplugged devices to linger around in the dm-tree, and it
causes USB host controllers to not be stopped when booting the OS.
+config DM_EVENT
+ bool "Support events with driver model"
+ depends on DM
+ imply EVENT
+ default y if SANDBOX
+ help
+ This enables support for generating events related to driver model
+ operations, such as prbing or removing a device. Subsystems can
+ register a 'spy' function that is called when the event occurs.
+
config SPL_DM_DEVICE_REMOVE
bool "Support device removal in SPL"
depends on SPL_DM
diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c
index e6ec6ff4212..73d2e9e4208 100644
--- a/drivers/core/device-remove.c
+++ b/drivers/core/device-remove.c
@@ -207,6 +207,10 @@ int device_remove(struct udevice *dev, uint flags)
if (!(dev_get_flags(dev) & DM_FLAG_ACTIVATED))
return 0;
+ ret = device_notify(dev, EVT_DM_PRE_REMOVE);
+ if (ret)
+ return ret;
+
/*
* If the child returns EKEYREJECTED, continue. It just means that it
* didn't match the flags.
@@ -256,6 +260,10 @@ int device_remove(struct udevice *dev, uint flags)
dev_bic_flags(dev, DM_FLAG_ACTIVATED);
+ ret = device_notify(dev, EVT_DM_POST_REMOVE);
+ if (ret)
+ goto err_remove;
+
return 0;
err_remove:
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 901c1e2f7db..1b356f12dd8 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -10,6 +10,7 @@
#include <common.h>
#include <cpu_func.h>
+#include <event.h>
#include <log.h>
#include <asm/global_data.h>
#include <asm/io.h>
@@ -493,6 +494,10 @@ int device_probe(struct udevice *dev)
if (dev_get_flags(dev) & DM_FLAG_ACTIVATED)
return 0;
+ ret = device_notify(dev, EVT_DM_PRE_PROBE);
+ if (ret)
+ return ret;
+
drv = dev->driver;
assert(drv);
@@ -597,6 +602,10 @@ int device_probe(struct udevice *dev)
dev->name, ret, errno_str(ret));
}
+ ret = device_notify(dev, EVT_DM_POST_PROBE);
+ if (ret)
+ return ret;
+
return 0;
fail_uclass:
if (device_remove(dev, DM_REMOVE_NORMAL)) {
diff --git a/drivers/core/root.c b/drivers/core/root.c
index e3f87956d86..8efb4256b27 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -404,6 +404,11 @@ int dm_init_and_scan(bool pre_reloc_only)
return ret;
}
}
+ if (CONFIG_IS_ENABLED(DM_EVENT)) {
+ ret = event_notify_null(EVT_DM_POST_INIT);
+ if (ret)
+ return log_msg_ret("ev", ret);
+ }
return 0;
}