path: root/hw/core/clock.c
diff options
authorPeter Maydell <peter.maydell@linaro.org>2021-01-29 14:58:55 +0000
committerPeter Maydell <peter.maydell@linaro.org>2021-02-15 13:16:12 +0000
commitb7878f38a00806c221c51001509329105f48af1f (patch)
treefda83058d394e6a1139f93ec5145bcbd85921b6c /hw/core/clock.c
parent7191258e926306472876b000e17c7e2b9f1be3ca (diff)
clock: Add ClockEvent parameter to callbacks
The Clock framework allows users to specify a callback which is called after the clock's period has been updated. Some users need to also have a callback which is called before the clock period is updated. As the first step in adding support for notifying Clock users on pre-update events, add an argument to the ClockCallback to specify what event is being notified, and add an argument to the various functions for registering a callback to specify which events are of interest to that callback. Note that the documentation update renders correct the previously incorrect claim in 'Adding a new clock' that callbacks "will be explained in a following section". Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Luc Michel <luc@lmichel.fr> --- v2->v3: used 'unsigned int' instead of 'int' for parameters and struct fields containing an event mask, as suggested by Philippe; fixed events argument to qdev_init_clock_in() with NULL callback pointer in npcm7xx_adc.c (spotted by Hao)
Diffstat (limited to 'hw/core/clock.c')
1 files changed, 17 insertions, 4 deletions
diff --git a/hw/core/clock.c b/hw/core/clock.c
index 76b5f468b6..4479eff145 100644
--- a/hw/core/clock.c
+++ b/hw/core/clock.c
@@ -39,15 +39,17 @@ Clock *clock_new(Object *parent, const char *name)
return clk;
-void clock_set_callback(Clock *clk, ClockCallback *cb, void *opaque)
+void clock_set_callback(Clock *clk, ClockCallback *cb, void *opaque,
+ unsigned int events)
clk->callback = cb;
clk->callback_opaque = opaque;
+ clk->callback_events = events;
void clock_clear_callback(Clock *clk)
- clock_set_callback(clk, NULL, NULL);
+ clock_set_callback(clk, NULL, NULL, 0);
bool clock_set(Clock *clk, uint64_t period)
@@ -62,6 +64,17 @@ bool clock_set(Clock *clk, uint64_t period)
return true;
+static void clock_call_callback(Clock *clk, ClockEvent event)
+ /*
+ * Call the Clock's callback for this event, if it has one and
+ * is interested in this event.
+ */
+ if (clk->callback && (clk->callback_events & event)) {
+ clk->callback(clk->callback_opaque, event);
+ }
static void clock_propagate_period(Clock *clk, bool call_callbacks)
Clock *child;
@@ -72,8 +85,8 @@ static void clock_propagate_period(Clock *clk, bool call_callbacks)
trace_clock_update(CLOCK_PATH(child), CLOCK_PATH(clk),
- if (call_callbacks && child->callback) {
- child->callback(child->callback_opaque);
+ if (call_callbacks) {
+ clock_call_callback(child, ClockUpdate);
clock_propagate_period(child, call_callbacks);