diff options
Diffstat (limited to 'hw/core')
-rw-r--r-- | hw/core/clock.c | 24 | ||||
-rw-r--r-- | hw/core/qdev-clock.c | 8 |
2 files changed, 25 insertions, 7 deletions
diff --git a/hw/core/clock.c b/hw/core/clock.c index 76b5f468b6..fc5a99683f 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,18 +64,32 @@ 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; QLIST_FOREACH(child, &clk->children, sibling) { if (child->period != clk->period) { + if (call_callbacks) { + clock_call_callback(child, ClockPreUpdate); + } child->period = clk->period; trace_clock_update(CLOCK_PATH(child), CLOCK_PATH(clk), CLOCK_PERIOD_TO_HZ(clk->period), call_callbacks); - if (call_callbacks && child->callback) { - child->callback(child->callback_opaque); + if (call_callbacks) { + clock_call_callback(child, ClockUpdate); } clock_propagate_period(child, call_callbacks); } diff --git a/hw/core/qdev-clock.c b/hw/core/qdev-clock.c index eb05f2a13c..117f4c6ea4 100644 --- a/hw/core/qdev-clock.c +++ b/hw/core/qdev-clock.c @@ -111,7 +111,8 @@ Clock *qdev_init_clock_out(DeviceState *dev, const char *name) } Clock *qdev_init_clock_in(DeviceState *dev, const char *name, - ClockCallback *callback, void *opaque) + ClockCallback *callback, void *opaque, + unsigned int events) { NamedClockList *ncl; @@ -120,7 +121,7 @@ Clock *qdev_init_clock_in(DeviceState *dev, const char *name, ncl = qdev_init_clocklist(dev, name, false, NULL); if (callback) { - clock_set_callback(ncl->clock, callback, opaque); + clock_set_callback(ncl->clock, callback, opaque, events); } return ncl->clock; } @@ -137,7 +138,8 @@ void qdev_init_clocks(DeviceState *dev, const ClockPortInitArray clocks) if (elem->is_output) { *clkp = qdev_init_clock_out(dev, elem->name); } else { - *clkp = qdev_init_clock_in(dev, elem->name, elem->callback, dev); + *clkp = qdev_init_clock_in(dev, elem->name, elem->callback, dev, + elem->callback_events); } } } |