diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2022-12-21 22:30:43 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2022-12-21 22:30:43 +0000 |
commit | 3a75616d8b190745a9c672239773bb4a18581404 (patch) | |
tree | 25035347db2cd2d3ed0d21db55109ee17cbbcaf7 /sys/arch/arm64 | |
parent | 9046446e8ab7dbbaaee5f8f848184dcbf2853c6b (diff) |
Pull enabling/disabling wakeup interrupt handling out of the aplintc(4)
DVACT_SUSPEND/DVACT_RESUME handling and push it into the MD code that
handles "suspend-to-idle". This way a failure in DVACT_SUSPEND handling
will not result in hosed interrupts on the primary interrupt controller
if we abort the suspend operation.
requested by deraadt@
ok patrick@
Diffstat (limited to 'sys/arch/arm64')
-rw-r--r-- | sys/arch/arm64/arm64/cpu.c | 8 | ||||
-rw-r--r-- | sys/arch/arm64/arm64/intr.c | 31 | ||||
-rw-r--r-- | sys/arch/arm64/dev/agintc.c | 4 | ||||
-rw-r--r-- | sys/arch/arm64/dev/ampintc.c | 4 | ||||
-rw-r--r-- | sys/arch/arm64/dev/aplintc.c | 86 | ||||
-rw-r--r-- | sys/arch/arm64/dev/aplmbox.c | 4 | ||||
-rw-r--r-- | sys/arch/arm64/dev/bcm2836_intr.c | 5 | ||||
-rw-r--r-- | sys/arch/arm64/include/intr.h | 13 |
8 files changed, 91 insertions, 64 deletions
diff --git a/sys/arch/arm64/arm64/cpu.c b/sys/arch/arm64/arm64/cpu.c index 6dbdb8e4097..0aa5623b342 100644 --- a/sys/arch/arm64/arm64/cpu.c +++ b/sys/arch/arm64/arm64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.76 2022/12/10 10:13:58 patrick Exp $ */ +/* $OpenBSD: cpu.c,v 1.77 2022/12/21 22:30:42 kettenis Exp $ */ /* * Copyright (c) 2016 Dale Rahn <drahn@dalerahn.com> @@ -1168,16 +1168,14 @@ cpu_suspend_primary(void) * by clearing the flag. */ cpu_suspended = 1; - arm_intr_func.setipl(IPL_NONE); - intr_enable(); + intr_enable_wakeup(); while (cpu_suspended) { __asm volatile("wfi"); count++; } - intr_disable(); - arm_intr_func.setipl(IPL_HIGH); + intr_disable_wakeup(); /* Unmask clock interrupts. */ WRITE_SPECIALREG(cntv_ctl_el0, diff --git a/sys/arch/arm64/arm64/intr.c b/sys/arch/arm64/arm64/intr.c index 9a95f91be6b..34dd9c53624 100644 --- a/sys/arch/arm64/arm64/intr.c +++ b/sys/arch/arm64/arm64/intr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.c,v 1.26 2022/11/09 19:18:11 kettenis Exp $ */ +/* $OpenBSD: intr.c,v 1.27 2022/12/21 22:30:42 kettenis Exp $ */ /* * Copyright (c) 2011 Dale Rahn <drahn@openbsd.org> * @@ -701,12 +701,15 @@ arm_do_pending_intr(int pcpl) void arm_set_intr_handler(int (*raise)(int), int (*lower)(int), void (*x)(int), void (*setipl)(int), void (*irq_dispatch)(void *), - void (*fiq_dispatch)(void *)) + void (*fiq_dispatch)(void *), void (*enable_wakeup)(void), + void (*disable_wakeup)(void)) { arm_intr_func.raise = raise; arm_intr_func.lower = lower; arm_intr_func.x = x; arm_intr_func.setipl = setipl; + arm_intr_func.enable_wakeup = enable_wakeup; + arm_intr_func.disable_wakeup = disable_wakeup; if (irq_dispatch) arm_irq_dispatch = irq_dispatch; @@ -871,13 +874,31 @@ intr_barrier(void *cookie) } void -intr_enable_wakeup(void *cookie) +intr_set_wakeup(void *cookie) { struct machine_intr_handle *ih = cookie; struct interrupt_controller *ic = ih->ih_ic; - if (ic->ic_enable_wakeup) - ic->ic_enable_wakeup(ih->ih_ih); + if (ic->ic_set_wakeup) + ic->ic_set_wakeup(ih->ih_ih); +} + +void +intr_enable_wakeup(void) +{ + if (arm_intr_func.enable_wakeup) + arm_intr_func.enable_wakeup(); + arm_intr_func.setipl(IPL_NONE); + intr_enable(); +} + +void +intr_disable_wakeup(void) +{ + intr_disable(); + arm_intr_func.setipl(IPL_HIGH); + if (arm_intr_func.disable_wakeup) + arm_intr_func.disable_wakeup(); } /* diff --git a/sys/arch/arm64/dev/agintc.c b/sys/arch/arm64/dev/agintc.c index dc5c899487f..a39badacbda 100644 --- a/sys/arch/arm64/dev/agintc.c +++ b/sys/arch/arm64/dev/agintc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: agintc.c,v 1.44 2022/10/13 18:34:56 kettenis Exp $ */ +/* $OpenBSD: agintc.c,v 1.45 2022/12/21 22:30:42 kettenis Exp $ */ /* * Copyright (c) 2007, 2009, 2011, 2017 Dale Rahn <drahn@dalerahn.com> * Copyright (c) 2018 Mark Kettenis <kettenis@openbsd.org> @@ -542,7 +542,7 @@ agintc_attach(struct device *parent, struct device *self, void *aux) /* insert self as interrupt handler */ arm_set_intr_handler(agintc_splraise, agintc_spllower, agintc_splx, - agintc_setipl, agintc_irq_handler, NULL); + agintc_setipl, agintc_irq_handler, NULL, NULL, NULL); /* enable interrupts */ ctrl = bus_space_read_4(sc->sc_iot, sc->sc_d_ioh, GICD_CTLR); diff --git a/sys/arch/arm64/dev/ampintc.c b/sys/arch/arm64/dev/ampintc.c index df59eaf8635..f7926fe1299 100644 --- a/sys/arch/arm64/dev/ampintc.c +++ b/sys/arch/arm64/dev/ampintc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ampintc.c,v 1.29 2022/07/16 12:07:55 kettenis Exp $ */ +/* $OpenBSD: ampintc.c,v 1.30 2022/12/21 22:30:42 kettenis Exp $ */ /* * Copyright (c) 2007,2009,2011 Dale Rahn <drahn@openbsd.org> * @@ -290,7 +290,7 @@ ampintc_attach(struct device *parent, struct device *self, void *aux) /* insert self as interrupt handler */ arm_set_intr_handler(ampintc_splraise, ampintc_spllower, ampintc_splx, - ampintc_setipl, ampintc_irq_handler, NULL); + ampintc_setipl, ampintc_irq_handler, NULL, NULL, NULL); #ifdef MULTIPROCESSOR /* setup IPI interrupts */ diff --git a/sys/arch/arm64/dev/aplintc.c b/sys/arch/arm64/dev/aplintc.c index 43f8254356d..2824f6c28ad 100644 --- a/sys/arch/arm64/dev/aplintc.c +++ b/sys/arch/arm64/dev/aplintc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aplintc.c,v 1.17 2022/11/09 19:18:11 kettenis Exp $ */ +/* $OpenBSD: aplintc.c,v 1.18 2022/12/21 22:30:42 kettenis Exp $ */ /* * Copyright (c) 2021 Mark Kettenis * @@ -163,11 +163,9 @@ struct aplintc_softc *aplintc_sc; int aplintc_match(struct device *, void *, void *); void aplintc_attach(struct device *, struct device *, void *); -int aplintc_activate(struct device *, int act); -const struct cfattach aplintc_ca = { - sizeof (struct aplintc_softc), aplintc_match, aplintc_attach, - NULL, aplintc_activate +const struct cfattach aplintc_ca = { + sizeof (struct aplintc_softc), aplintc_match, aplintc_attach }; struct cfdriver aplintc_cd = { @@ -182,11 +180,13 @@ int aplintc_splraise(int); int aplintc_spllower(int); void aplintc_splx(int); void aplintc_setipl(int); +void aplintc_enable_wakeup(void); +void aplintc_disable_wakeup(void); void *aplintc_intr_establish(void *, int *, int, struct cpu_info *, int (*)(void *), void *, char *); void aplintc_intr_disestablish(void *); -void aplintc_intr_enable_wakeup(void *); +void aplintc_intr_set_wakeup(void *); void aplintc_send_ipi(struct cpu_info *, int); void aplintc_handle_ipi(struct aplintc_softc *); @@ -272,7 +272,8 @@ aplintc_attach(struct device *parent, struct device *self, void *aux) evcount_attach(&sc->sc_ipi_count, "ipi", NULL); arm_set_intr_handler(aplintc_splraise, aplintc_spllower, aplintc_splx, - aplintc_setipl, aplintc_irq_handler, aplintc_fiq_handler); + aplintc_setipl, aplintc_irq_handler, aplintc_fiq_handler, + aplintc_enable_wakeup, aplintc_disable_wakeup); sc->sc_ic.ic_node = faa->fa_node; sc->sc_ic.ic_cookie = self; @@ -280,7 +281,7 @@ aplintc_attach(struct device *parent, struct device *self, void *aux) sc->sc_ic.ic_disestablish = aplintc_intr_disestablish; sc->sc_ic.ic_cpu_enable = aplintc_cpuinit; sc->sc_ic.ic_barrier = aplintc_intr_barrier; - sc->sc_ic.ic_enable_wakeup = aplintc_intr_enable_wakeup; + sc->sc_ic.ic_set_wakeup = aplintc_intr_set_wakeup; arm_intr_register_fdt(&sc->sc_ic); #ifdef MULTIPROCESSOR @@ -291,39 +292,6 @@ aplintc_attach(struct device *parent, struct device *self, void *aux) HSET4(sc, AIC2_CONFIG, AIC2_CONFIG_ENABLE); } -int -aplintc_activate(struct device *self, int act) -{ - struct aplintc_softc *sc = (struct aplintc_softc *)self; - struct intrhand *ih; - int die, irq; - - switch (act) { - case DVACT_SUSPEND: - for (die = 0; die < sc->sc_ndie; die++) { - for (irq = 0; irq < sc->sc_nirq; irq++) { - ih = sc->sc_irq_handler[die][irq]; - if (ih == NULL || (ih->ih_flags & IPL_WAKEUP)) - continue; - aplintc_mask_set(sc, die, irq); - } - } - break; - case DVACT_RESUME: - for (die = 0; die < sc->sc_ndie; die++) { - for (irq = 0; irq < sc->sc_nirq; irq++) { - ih = sc->sc_irq_handler[die][irq]; - if (ih == NULL || (ih->ih_flags & IPL_WAKEUP)) - continue; - aplintc_mask_clr(sc, die, irq); - } - } - break; - } - - return 0; -} - void aplintc_cpuinit(void) { @@ -543,6 +511,40 @@ aplintc_setipl(int ipl) ci->ci_cpl = ipl; } +void +aplintc_enable_wakeup(void) +{ + struct aplintc_softc *sc = aplintc_sc; + struct intrhand *ih; + int die, irq; + + for (die = 0; die < sc->sc_ndie; die++) { + for (irq = 0; irq < sc->sc_nirq; irq++) { + ih = sc->sc_irq_handler[die][irq]; + if (ih == NULL || (ih->ih_flags & IPL_WAKEUP)) + continue; + aplintc_mask_set(sc, die, irq); + } + } +} + +void +aplintc_disable_wakeup(void) +{ + struct aplintc_softc *sc = aplintc_sc; + struct intrhand *ih; + int die, irq; + + for (die = 0; die < sc->sc_ndie; die++) { + for (irq = 0; irq < sc->sc_nirq; irq++) { + ih = sc->sc_irq_handler[die][irq]; + if (ih == NULL || (ih->ih_flags & IPL_WAKEUP)) + continue; + aplintc_mask_clr(sc, die, irq); + } + } +} + void * aplintc_intr_establish(void *cookie, int *cell, int level, struct cpu_info *ci, int (*func)(void *), void *arg, char *name) @@ -638,7 +640,7 @@ aplintc_intr_disestablish(void *cookie) } void -aplintc_intr_enable_wakeup(void *cookie) +aplintc_intr_set_wakeup(void *cookie) { struct intrhand *ih = cookie; diff --git a/sys/arch/arm64/dev/aplmbox.c b/sys/arch/arm64/dev/aplmbox.c index fe3a99d0e32..343730039d1 100644 --- a/sys/arch/arm64/dev/aplmbox.c +++ b/sys/arch/arm64/dev/aplmbox.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aplmbox.c,v 1.4 2022/12/03 13:42:23 kettenis Exp $ */ +/* $OpenBSD: aplmbox.c,v 1.5 2022/12/21 22:30:42 kettenis Exp $ */ /* * Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org> * @@ -149,7 +149,7 @@ aplmbox_channel(void *cookie, uint32_t *cells, struct mbox_client *mc) sc->sc_rx_arg = mc->mc_rx_arg; if (mc->mc_flags & MC_WAKEUP) - intr_enable_wakeup(sc->sc_ih); + intr_set_wakeup(sc->sc_ih); } return sc; diff --git a/sys/arch/arm64/dev/bcm2836_intr.c b/sys/arch/arm64/dev/bcm2836_intr.c index 8467420c565..c244dd3da02 100644 --- a/sys/arch/arm64/dev/bcm2836_intr.c +++ b/sys/arch/arm64/dev/bcm2836_intr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bcm2836_intr.c,v 1.14 2022/01/02 20:00:21 kettenis Exp $ */ +/* $OpenBSD: bcm2836_intr.c,v 1.15 2022/12/21 22:30:42 kettenis Exp $ */ /* * Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org> * Copyright (c) 2015 Patrick Wildt <patrick@blueri.se> @@ -211,7 +211,8 @@ bcm_intc_attach(struct device *parent, struct device *self, void *aux) /* insert self as interrupt handler */ arm_set_intr_handler(bcm_intc_splraise, bcm_intc_spllower, - bcm_intc_splx, bcm_intc_setipl, bcm_intc_irq_handler, NULL); + bcm_intc_splx, bcm_intc_setipl, bcm_intc_irq_handler, NULL, + NULL, NULL); sc->sc_intc.ic_node = faa->fa_node; sc->sc_intc.ic_cookie = sc; diff --git a/sys/arch/arm64/include/intr.h b/sys/arch/arm64/include/intr.h index c42518a9f55..0f1da4d05eb 100644 --- a/sys/arch/arm64/include/intr.h +++ b/sys/arch/arm64/include/intr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.h,v 1.20 2022/11/09 19:18:11 kettenis Exp $ */ +/* $OpenBSD: intr.h,v 1.21 2022/12/21 22:30:42 kettenis Exp $ */ /* * Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com) @@ -88,7 +88,8 @@ void splx(int); void arm_do_pending_intr(int); void arm_set_intr_handler(int (*)(int), int (*)(int), void (*)(int), - void (*)(int), void (*)(void *), void (*)(void *)); + void (*)(int), void (*)(void *), void (*)(void *), + void (*)(void), void (*)(void)); struct machine_intr_handle { struct interrupt_controller *ih_ic; @@ -100,6 +101,8 @@ struct arm_intr_func { int (*lower)(int); void (*x)(int); void (*setipl)(int); + void (*enable_wakeup)(void); + void (*disable_wakeup)(void); }; extern struct arm_intr_func arm_intr_func; @@ -126,7 +129,9 @@ extern struct arm_intr_func arm_intr_func; #define spl0() spllower(IPL_NONE) void intr_barrier(void *); -void intr_enable_wakeup(void *); +void intr_set_wakeup(void *); +void intr_enable_wakeup(void); +void intr_disable_wakeup(void); void arm_init_smask(void); /* XXX */ extern uint32_t arm_smask[NIPL]; @@ -152,7 +157,7 @@ struct interrupt_controller { void (*ic_route)(void *, int, struct cpu_info *); void (*ic_cpu_enable)(void); void (*ic_barrier)(void *); - void (*ic_enable_wakeup)(void *); + void (*ic_set_wakeup)(void *); LIST_ENTRY(interrupt_controller) ic_list; uint32_t ic_phandle; |