summaryrefslogtreecommitdiff
path: root/sys/arch/arm64
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2022-12-21 22:30:43 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2022-12-21 22:30:43 +0000
commit3a75616d8b190745a9c672239773bb4a18581404 (patch)
tree25035347db2cd2d3ed0d21db55109ee17cbbcaf7 /sys/arch/arm64
parent9046446e8ab7dbbaaee5f8f848184dcbf2853c6b (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.c8
-rw-r--r--sys/arch/arm64/arm64/intr.c31
-rw-r--r--sys/arch/arm64/dev/agintc.c4
-rw-r--r--sys/arch/arm64/dev/ampintc.c4
-rw-r--r--sys/arch/arm64/dev/aplintc.c86
-rw-r--r--sys/arch/arm64/dev/aplmbox.c4
-rw-r--r--sys/arch/arm64/dev/bcm2836_intr.c5
-rw-r--r--sys/arch/arm64/include/intr.h13
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;