aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/adc/npcm7xx_adc.c2
-rw-r--r--hw/arm/armsse.c9
-rw-r--r--hw/char/cadence_uart.c4
-rw-r--r--hw/char/ibex_uart.c4
-rw-r--r--hw/char/pl011.c5
-rw-r--r--hw/core/clock.c21
-rw-r--r--hw/core/qdev-clock.c8
-rw-r--r--hw/mips/cps.c2
-rw-r--r--hw/misc/bcm2835_cprman.c23
-rw-r--r--hw/misc/npcm7xx_clk.c26
-rw-r--r--hw/misc/npcm7xx_pwm.c2
-rw-r--r--hw/misc/zynq_slcr.c5
-rw-r--r--hw/timer/cmsdk-apb-dualtimer.c5
-rw-r--r--hw/timer/cmsdk-apb-timer.c4
-rw-r--r--hw/timer/npcm7xx_timer.c2
-rw-r--r--hw/watchdog/cmsdk-apb-watchdog.c5
16 files changed, 85 insertions, 42 deletions
diff --git a/hw/adc/npcm7xx_adc.c b/hw/adc/npcm7xx_adc.c
index 870a6d50c2..0f0a9f63e2 100644
--- a/hw/adc/npcm7xx_adc.c
+++ b/hw/adc/npcm7xx_adc.c
@@ -238,7 +238,7 @@ static void npcm7xx_adc_init(Object *obj)
memory_region_init_io(&s->iomem, obj, &npcm7xx_adc_ops, s,
TYPE_NPCM7XX_ADC, 4 * KiB);
sysbus_init_mmio(sbd, &s->iomem);
- s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL);
+ s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL, 0);
for (i = 0; i < NPCM7XX_ADC_NUM_INPUTS; ++i) {
object_property_add_uint32_ptr(obj, "adci[*]",
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index 26e1a8c95b..fa155b7202 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -230,9 +230,10 @@ static void armsse_forward_sec_resp_cfg(ARMSSE *s)
qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
}
-static void armsse_mainclk_update(void *opaque)
+static void armsse_mainclk_update(void *opaque, ClockEvent event)
{
ARMSSE *s = ARM_SSE(opaque);
+
/*
* Set system_clock_scale from our Clock input; this is what
* controls the tick rate of the CPU SysTick timer.
@@ -251,8 +252,8 @@ static void armsse_init(Object *obj)
assert(info->num_cpus <= SSE_MAX_CPUS);
s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK",
- armsse_mainclk_update, s);
- s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL);
+ armsse_mainclk_update, s, ClockUpdate);
+ s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL, 0);
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
@@ -1120,7 +1121,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
/* Set initial system_clock_scale from MAINCLK */
- armsse_mainclk_update(s);
+ armsse_mainclk_update(s, ClockUpdate);
}
static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index c603e14012..ceb677bc5a 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -519,7 +519,7 @@ static void cadence_uart_realize(DeviceState *dev, Error **errp)
uart_event, NULL, s, NULL, true);
}
-static void cadence_uart_refclk_update(void *opaque)
+static void cadence_uart_refclk_update(void *opaque, ClockEvent event)
{
CadenceUARTState *s = opaque;
@@ -537,7 +537,7 @@ static void cadence_uart_init(Object *obj)
sysbus_init_irq(sbd, &s->irq);
s->refclk = qdev_init_clock_in(DEVICE(obj), "refclk",
- cadence_uart_refclk_update, s);
+ cadence_uart_refclk_update, s, ClockUpdate);
/* initialize the frequency in case the clock remains unconnected */
clock_set_hz(s->refclk, UART_DEFAULT_REF_CLK);
diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c
index 89f1182c9b..edcaa30ade 100644
--- a/hw/char/ibex_uart.c
+++ b/hw/char/ibex_uart.c
@@ -396,7 +396,7 @@ static void ibex_uart_write(void *opaque, hwaddr addr,
}
}
-static void ibex_uart_clk_update(void *opaque)
+static void ibex_uart_clk_update(void *opaque, ClockEvent event)
{
IbexUartState *s = opaque;
@@ -466,7 +466,7 @@ static void ibex_uart_init(Object *obj)
IbexUartState *s = IBEX_UART(obj);
s->f_clk = qdev_init_clock_in(DEVICE(obj), "f_clock",
- ibex_uart_clk_update, s);
+ ibex_uart_clk_update, s, ClockUpdate);
clock_set_hz(s->f_clk, IBEX_UART_CLOCK);
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_watermark);
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
index ea4a4e5235..c5621a195f 100644
--- a/hw/char/pl011.c
+++ b/hw/char/pl011.c
@@ -309,7 +309,7 @@ static void pl011_event(void *opaque, QEMUChrEvent event)
pl011_put_fifo(opaque, 0x400);
}
-static void pl011_clock_update(void *opaque)
+static void pl011_clock_update(void *opaque, ClockEvent event)
{
PL011State *s = PL011(opaque);
@@ -378,7 +378,8 @@ static void pl011_init(Object *obj)
sysbus_init_irq(sbd, &s->irq[i]);
}
- s->clk = qdev_init_clock_in(DEVICE(obj), "clk", pl011_clock_update, s);
+ s->clk = qdev_init_clock_in(DEVICE(obj), "clk", pl011_clock_update, s,
+ ClockUpdate);
s->read_trigger = 1;
s->ifl = 0x12;
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),
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);
}
}
}
diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index 7a0d289efa..2b436700ce 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -39,7 +39,7 @@ static void mips_cps_init(Object *obj)
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
MIPSCPSState *s = MIPS_CPS(obj);
- s->clock = qdev_init_clock_in(DEVICE(obj), "clk-in", NULL, NULL);
+ s->clock = qdev_init_clock_in(DEVICE(obj), "clk-in", NULL, NULL, 0);
/*
* Cover entire address space as there do not seem to be any
* constraints for the base address of CPC and GIC.
diff --git a/hw/misc/bcm2835_cprman.c b/hw/misc/bcm2835_cprman.c
index 7e415a017c..75e6c574d4 100644
--- a/hw/misc/bcm2835_cprman.c
+++ b/hw/misc/bcm2835_cprman.c
@@ -107,7 +107,7 @@ static void pll_update(CprmanPllState *pll)
clock_update_hz(pll->out, freq);
}
-static void pll_xosc_update(void *opaque)
+static void pll_xosc_update(void *opaque, ClockEvent event)
{
pll_update(CPRMAN_PLL(opaque));
}
@@ -116,7 +116,8 @@ static void pll_init(Object *obj)
{
CprmanPllState *s = CPRMAN_PLL(obj);
- s->xosc_in = qdev_init_clock_in(DEVICE(s), "xosc-in", pll_xosc_update, s);
+ s->xosc_in = qdev_init_clock_in(DEVICE(s), "xosc-in", pll_xosc_update,
+ s, ClockUpdate);
s->out = qdev_init_clock_out(DEVICE(s), "out");
}
@@ -209,7 +210,7 @@ static void pll_update_all_channels(BCM2835CprmanState *s,
}
}
-static void pll_channel_pll_in_update(void *opaque)
+static void pll_channel_pll_in_update(void *opaque, ClockEvent event)
{
pll_channel_update(CPRMAN_PLL_CHANNEL(opaque));
}
@@ -219,7 +220,8 @@ static void pll_channel_init(Object *obj)
CprmanPllChannelState *s = CPRMAN_PLL_CHANNEL(obj);
s->pll_in = qdev_init_clock_in(DEVICE(s), "pll-in",
- pll_channel_pll_in_update, s);
+ pll_channel_pll_in_update, s,
+ ClockUpdate);
s->out = qdev_init_clock_out(DEVICE(s), "out");
}
@@ -303,7 +305,7 @@ static void clock_mux_update(CprmanClockMuxState *mux)
clock_update_hz(mux->out, freq);
}
-static void clock_mux_src_update(void *opaque)
+static void clock_mux_src_update(void *opaque, ClockEvent event)
{
CprmanClockMuxState **backref = opaque;
CprmanClockMuxState *s = *backref;
@@ -335,7 +337,8 @@ static void clock_mux_init(Object *obj)
s->backref[i] = s;
s->srcs[i] = qdev_init_clock_in(DEVICE(s), name,
clock_mux_src_update,
- &s->backref[i]);
+ &s->backref[i],
+ ClockUpdate);
g_free(name);
}
@@ -380,7 +383,7 @@ static void dsi0hsck_mux_update(CprmanDsi0HsckMuxState *s)
clock_update(s->out, clock_get(src));
}
-static void dsi0hsck_mux_in_update(void *opaque)
+static void dsi0hsck_mux_in_update(void *opaque, ClockEvent event)
{
dsi0hsck_mux_update(CPRMAN_DSI0HSCK_MUX(opaque));
}
@@ -390,8 +393,10 @@ static void dsi0hsck_mux_init(Object *obj)
CprmanDsi0HsckMuxState *s = CPRMAN_DSI0HSCK_MUX(obj);
DeviceState *dev = DEVICE(obj);
- s->plla_in = qdev_init_clock_in(dev, "plla-in", dsi0hsck_mux_in_update, s);
- s->plld_in = qdev_init_clock_in(dev, "plld-in", dsi0hsck_mux_in_update, s);
+ s->plla_in = qdev_init_clock_in(dev, "plla-in", dsi0hsck_mux_in_update,
+ s, ClockUpdate);
+ s->plld_in = qdev_init_clock_in(dev, "plld-in", dsi0hsck_mux_in_update,
+ s, ClockUpdate);
s->out = qdev_init_clock_out(DEVICE(s), "out");
}
diff --git a/hw/misc/npcm7xx_clk.c b/hw/misc/npcm7xx_clk.c
index 0bcae9ce95..a1ee67dc9a 100644
--- a/hw/misc/npcm7xx_clk.c
+++ b/hw/misc/npcm7xx_clk.c
@@ -586,15 +586,26 @@ static const DividerInitInfo divider_init_info_list[] = {
},
};
+static void npcm7xx_clk_update_pll_cb(void *opaque, ClockEvent event)
+{
+ npcm7xx_clk_update_pll(opaque);
+}
+
static void npcm7xx_clk_pll_init(Object *obj)
{
NPCM7xxClockPLLState *pll = NPCM7XX_CLOCK_PLL(obj);
pll->clock_in = qdev_init_clock_in(DEVICE(pll), "clock-in",
- npcm7xx_clk_update_pll, pll);
+ npcm7xx_clk_update_pll_cb, pll,
+ ClockUpdate);
pll->clock_out = qdev_init_clock_out(DEVICE(pll), "clock-out");
}
+static void npcm7xx_clk_update_sel_cb(void *opaque, ClockEvent event)
+{
+ npcm7xx_clk_update_sel(opaque);
+}
+
static void npcm7xx_clk_sel_init(Object *obj)
{
int i;
@@ -603,16 +614,23 @@ static void npcm7xx_clk_sel_init(Object *obj)
for (i = 0; i < NPCM7XX_CLK_SEL_MAX_INPUT; ++i) {
sel->clock_in[i] = qdev_init_clock_in(DEVICE(sel),
g_strdup_printf("clock-in[%d]", i),
- npcm7xx_clk_update_sel, sel);
+ npcm7xx_clk_update_sel_cb, sel, ClockUpdate);
}
sel->clock_out = qdev_init_clock_out(DEVICE(sel), "clock-out");
}
+
+static void npcm7xx_clk_update_divider_cb(void *opaque, ClockEvent event)
+{
+ npcm7xx_clk_update_divider(opaque);
+}
+
static void npcm7xx_clk_divider_init(Object *obj)
{
NPCM7xxClockDividerState *div = NPCM7XX_CLOCK_DIVIDER(obj);
div->clock_in = qdev_init_clock_in(DEVICE(div), "clock-in",
- npcm7xx_clk_update_divider, div);
+ npcm7xx_clk_update_divider_cb,
+ div, ClockUpdate);
div->clock_out = qdev_init_clock_out(DEVICE(div), "clock-out");
}
@@ -875,7 +893,7 @@ static void npcm7xx_clk_init_clock_hierarchy(NPCM7xxCLKState *s)
{
int i;
- s->clkref = qdev_init_clock_in(DEVICE(s), "clkref", NULL, NULL);
+ s->clkref = qdev_init_clock_in(DEVICE(s), "clkref", NULL, NULL, 0);
/* First pass: init all converter modules */
QEMU_BUILD_BUG_ON(ARRAY_SIZE(pll_init_info_list) != NPCM7XX_CLOCK_NR_PLLS);
diff --git a/hw/misc/npcm7xx_pwm.c b/hw/misc/npcm7xx_pwm.c
index dabcb6c0f9..ce192bb274 100644
--- a/hw/misc/npcm7xx_pwm.c
+++ b/hw/misc/npcm7xx_pwm.c
@@ -493,7 +493,7 @@ static void npcm7xx_pwm_init(Object *obj)
memory_region_init_io(&s->iomem, obj, &npcm7xx_pwm_ops, s,
TYPE_NPCM7XX_PWM, 4 * KiB);
sysbus_init_mmio(sbd, &s->iomem);
- s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL);
+ s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL, 0);
for (i = 0; i < NPCM7XX_PWM_PER_MODULE; ++i) {
object_property_add_uint32_ptr(obj, "freq[*]",
diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
index 66504a9d3a..c66d7db177 100644
--- a/hw/misc/zynq_slcr.c
+++ b/hw/misc/zynq_slcr.c
@@ -307,9 +307,10 @@ static void zynq_slcr_propagate_clocks(ZynqSLCRState *s)
clock_propagate(s->uart1_ref_clk);
}
-static void zynq_slcr_ps_clk_callback(void *opaque)
+static void zynq_slcr_ps_clk_callback(void *opaque, ClockEvent event)
{
ZynqSLCRState *s = (ZynqSLCRState *) opaque;
+
zynq_slcr_compute_clocks(s);
zynq_slcr_propagate_clocks(s);
}
@@ -576,7 +577,7 @@ static const MemoryRegionOps slcr_ops = {
};
static const ClockPortInitArray zynq_slcr_clocks = {
- QDEV_CLOCK_IN(ZynqSLCRState, ps_clk, zynq_slcr_ps_clk_callback),
+ QDEV_CLOCK_IN(ZynqSLCRState, ps_clk, zynq_slcr_ps_clk_callback, ClockUpdate),
QDEV_CLOCK_OUT(ZynqSLCRState, uart0_ref_clk),
QDEV_CLOCK_OUT(ZynqSLCRState, uart1_ref_clk),
QDEV_CLOCK_END
diff --git a/hw/timer/cmsdk-apb-dualtimer.c b/hw/timer/cmsdk-apb-dualtimer.c
index ef49f5852d..d4a509c798 100644
--- a/hw/timer/cmsdk-apb-dualtimer.c
+++ b/hw/timer/cmsdk-apb-dualtimer.c
@@ -449,7 +449,7 @@ static void cmsdk_apb_dualtimer_reset(DeviceState *dev)
s->timeritop = 0;
}
-static void cmsdk_apb_dualtimer_clk_update(void *opaque)
+static void cmsdk_apb_dualtimer_clk_update(void *opaque, ClockEvent event)
{
CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(opaque);
int i;
@@ -478,7 +478,8 @@ static void cmsdk_apb_dualtimer_init(Object *obj)
sysbus_init_irq(sbd, &s->timermod[i].timerint);
}
s->timclk = qdev_init_clock_in(DEVICE(s), "TIMCLK",
- cmsdk_apb_dualtimer_clk_update, s);
+ cmsdk_apb_dualtimer_clk_update, s,
+ ClockUpdate);
}
static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp)
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
index ee51ce3369..68aa1a7636 100644
--- a/hw/timer/cmsdk-apb-timer.c
+++ b/hw/timer/cmsdk-apb-timer.c
@@ -204,7 +204,7 @@ static void cmsdk_apb_timer_reset(DeviceState *dev)
ptimer_transaction_commit(s->timer);
}
-static void cmsdk_apb_timer_clk_update(void *opaque)
+static void cmsdk_apb_timer_clk_update(void *opaque, ClockEvent event)
{
CMSDKAPBTimer *s = CMSDK_APB_TIMER(opaque);
@@ -223,7 +223,7 @@ static void cmsdk_apb_timer_init(Object *obj)
sysbus_init_mmio(sbd, &s->iomem);
sysbus_init_irq(sbd, &s->timerint);
s->pclk = qdev_init_clock_in(DEVICE(s), "pclk",
- cmsdk_apb_timer_clk_update, s);
+ cmsdk_apb_timer_clk_update, s, ClockUpdate);
}
static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
diff --git a/hw/timer/npcm7xx_timer.c b/hw/timer/npcm7xx_timer.c
index 36e2c07db2..4efdf135b8 100644
--- a/hw/timer/npcm7xx_timer.c
+++ b/hw/timer/npcm7xx_timer.c
@@ -627,7 +627,7 @@ static void npcm7xx_timer_init(Object *obj)
sysbus_init_mmio(sbd, &s->iomem);
qdev_init_gpio_out_named(dev, &w->reset_signal,
NPCM7XX_WATCHDOG_RESET_GPIO_OUT, 1);
- s->clock = qdev_init_clock_in(dev, "clock", NULL, NULL);
+ s->clock = qdev_init_clock_in(dev, "clock", NULL, NULL, 0);
}
static const VMStateDescription vmstate_npcm7xx_base_timer = {
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
index 302f171173..5a2cd46eb7 100644
--- a/hw/watchdog/cmsdk-apb-watchdog.c
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
@@ -310,7 +310,7 @@ static void cmsdk_apb_watchdog_reset(DeviceState *dev)
ptimer_transaction_commit(s->timer);
}
-static void cmsdk_apb_watchdog_clk_update(void *opaque)
+static void cmsdk_apb_watchdog_clk_update(void *opaque, ClockEvent event)
{
CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);
@@ -329,7 +329,8 @@ static void cmsdk_apb_watchdog_init(Object *obj)
sysbus_init_mmio(sbd, &s->iomem);
sysbus_init_irq(sbd, &s->wdogint);
s->wdogclk = qdev_init_clock_in(DEVICE(s), "WDOGCLK",
- cmsdk_apb_watchdog_clk_update, s);
+ cmsdk_apb_watchdog_clk_update, s,
+ ClockUpdate);
s->is_luminary = false;
s->id = cmsdk_apb_watchdog_id;