-/* $OpenBSD: adb.c,v 1.39 2013/08/10 08:13:32 mpi Exp $ */
+/* $OpenBSD: adb.c,v 1.40 2015/06/24 11:58:06 mpi Exp $ */
/* $NetBSD: adb.c,v 1.6 1999/08/16 06:28:09 tsubai Exp $ */
/* $NetBSD: adb_direct.c,v 1.14 2000/06/08 22:10:45 tsubai Exp $ */
}
printf("\n");
- mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_HIGH,
+ mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_TTY,
adb_intr, sc, sc->sc_dev.dv_xname);
/* init powerpc globals which control RTC functionality */
-/* $OpenBSD: macgpio.c,v 1.7 2013/06/03 20:10:50 mpi Exp $ */
+/* $OpenBSD: macgpio.c,v 1.8 2015/06/24 11:58:06 mpi Exp $ */
/* $NetBSD: gpio.c,v 1.2 2001/02/27 05:16:33 matt Exp $ */
/*-
sc->sc_port = ((struct gpio_softc *) parent)->sc_port;
- mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_HIGH,
+ mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_TTY,
gpio_intr, sc, sc->sc_dev.dv_xname);
printf(": irq %d\n", ca->ca_intr[0]);
-/* $OpenBSD: macintr.c,v 1.51 2015/04/02 11:12:24 mpi Exp $ */
+/* $OpenBSD: macintr.c,v 1.52 2015/06/24 11:58:06 mpi Exp $ */
/*-
* Copyright (c) 2008 Dale Rahn <drahn@openbsd.org>
struct cpu_info *ci = curcpu();
struct intrq *iq;
struct intrhand *ih;
- int s;
-
-#if 0
-printf("macintr_establish, hI %d L %d %s", irq, level, ppc_intr_typename(type));
-#endif
+ int s, flags;
if (!LEGAL_IRQ(irq) || type == IST_NONE) {
printf("%s: bogus irq %d or type %d", __func__, irq, type);
break;
}
+ flags = level & IPL_MPSAFE;
+ level &= ~IPL_MPSAFE;
+
+ KASSERT(level <= IPL_TTY || level >= IPL_CLOCK || flags & IPL_MPSAFE);
+
ih->ih_fun = ih_fun;
ih->ih_arg = ih_arg;
ih->ih_level = level;
+ ih->ih_flags = flags;
ih->ih_irq = irq;
evcount_attach(&ih->ih_count, name, &ih->ih_irq);
-/* $OpenBSD: openpic.c,v 1.80 2015/06/02 13:53:43 mpi Exp $ */
+/* $OpenBSD: openpic.c,v 1.81 2015/06/24 11:58:06 mpi Exp $ */
/*-
* Copyright (c) 2008 Dale Rahn <drahn@openbsd.org>
void openpic_intr_disestablish(void *, void *);
void openpic_collect_preconf_intr(void);
void openpic_ext_intr(void);
+int openpic_ext_intr_handler(struct intrhand *, int, int *);
/* Generic IRQ management routines. */
void openpic_gen_acknowledge_irq(int, int);
{
struct intrhand *ih;
struct intrq *iq;
- int s;
+ int s, flags;
if (!LEGAL_IRQ(irq) || type == IST_NONE) {
printf("%s: bogus irq %d or type %d", __func__, irq, type);
ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
if (ih == NULL)
panic("%s: can't malloc handler info", __func__);
- iq = &openpic_handler[irq];
+ iq = &openpic_handler[irq];
switch (iq->iq_ist) {
case IST_NONE:
iq->iq_ist = type;
break;
}
+ flags = level & IPL_MPSAFE;
+ level &= ~IPL_MPSAFE;
+
+ KASSERT(level <= IPL_TTY || level >= IPL_CLOCK || flags & IPL_MPSAFE);
+
ih->ih_fun = ih_fun;
ih->ih_arg = ih_arg;
ih->ih_level = level;
+ ih->ih_flags = flags;
ih->ih_irq = irq;
evcount_attach(&ih->ih_count, name, &ih->ih_irq);
#endif
iq = &openpic_handler[irq];
- if (iq->iq_ipl <= ci->ci_cpl)
+#ifdef OPENPIC_DEBUG
+ if (iq->iq_ipl <= pcpl)
printf("invalid interrupt %d lvl %d at %d hw %d\n",
- irq, iq->iq_ipl, ci->ci_cpl,
+ irq, iq->iq_ipl, pcpl,
openpic_read(OPENPIC_CPU_PRIORITY(ci->ci_cpuid)));
+#endif
+
if (iq->iq_ipl > maxipl)
maxipl = iq->iq_ipl;
openpic_splraise(iq->iq_ipl);
spurious = 1;
TAILQ_FOREACH(ih, &iq->iq_list, ih_list) {
ppc_intr_enable(1);
- KERNEL_LOCK();
- ret = (*ih->ih_fun)(ih->ih_arg);
- if (ret) {
- ih->ih_count.ec_count++;
- spurious = 0;
- }
- KERNEL_UNLOCK();
-
+ ret = openpic_ext_intr_handler(ih, pcpl, &spurious);
(void)ppc_intr_disable();
if (intr_shared_edge == 00 && ret == 1)
break;
openpic_irqnest[ci->ci_cpuid]--;
}
+int
+openpic_ext_intr_handler(struct intrhand *ih, int pcpl, int *spurious)
+{
+ int ret;
+#ifdef MULTIPROCESSOR
+ int need_lock;
+
+ if (ih->ih_flags & IPL_MPSAFE)
+ need_lock = 0;
+ else
+ need_lock = pcpl < IPL_SCHED;
+
+ if (need_lock)
+ KERNEL_LOCK();
+#endif
+
+ ret = (*ih->ih_fun)(ih->ih_arg);
+ if (ret) {
+ ih->ih_count.ec_count++;
+ *spurious = 0;
+ }
+
+#ifdef MULTIPROCESSOR
+ if (need_lock)
+ KERNEL_UNLOCK();
+#endif
+
+ return (ret);
+}
+
void
openpic_acknowledge_irq(int irq, int cpuid)
{
-/* $OpenBSD: xlights.c,v 1.6 2013/11/18 20:21:51 deraadt Exp $ */
+/* $OpenBSD: xlights.c,v 1.7 2015/06/24 11:58:06 mpi Exp $ */
/*
* Copyright (c) 2007 Gordon Willem Klok <gwk@openbsd,org>
*
}
mac_intr_establish(parent, sc->sc_intr, intr[3] ? IST_LEVEL :
- type, IPL_AUDIO, xlights_intr, sc, sc->sc_dev.dv_xname);
+ type, IPL_TTY, xlights_intr, sc, sc->sc_dev.dv_xname);
out32rb(sc->sc_reg + I2S_FORMAT, CLKSRC_VS);
macobio_enable(I2SClockOffset, I2S0CLKEN);
-/* $OpenBSD: intr.h,v 1.50 2015/01/04 13:01:42 mpi Exp $ */
+/* $OpenBSD: intr.h,v 1.51 2015/06/24 11:58:06 mpi Exp $ */
/*
* Copyright (c) 1997 Per Fogelstrom, Opsycon AB and RTMX Inc, USA.
#define IPL_SOFTNET 3
#define IPL_SOFTTTY 4
#define IPL_BIO 5
-#define IPL_AUDIO IPL_BIO /* XXX - was defined this val in audio_if.h */
#define IPL_NET 6
#define IPL_TTY 7
#define IPL_VM 8
-#define IPL_CLOCK 9
-#define IPL_SCHED 10
-#define IPL_HIGH 11
-#define IPL_NUM 12
+#define IPL_AUDIO 9
+#define IPL_CLOCK 10
+#define IPL_SCHED 11
+#define IPL_HIGH 12
+#define IPL_NUM 13
-#define IPL_MPSAFE 0 /* no "mpsafe" interrupts */
+#define IPL_MPSAFE 0x100
#define IST_NONE 0
#define IST_PULSE 1
void softintr_schedule(void *);
void dosoftint(int);
-#define set_sint(p) atomic_setbits_int(&curcpu()->ci_ipending, p)
-
#define setsoftclock() set_sint(SI_TO_IRQBIT(SI_SOFTCLOCK))
#define setsoftnet() set_sint(SI_TO_IRQBIT(SI_SOFTNET))
#define setsofttty() set_sint(SI_TO_IRQBIT(SI_SOFTTTY))
struct evcount ih_count;
int ih_type;
int ih_level;
+ int ih_flags;
int ih_irq;
const char *ih_what;
};
-/* $OpenBSD: ipic.c,v 1.17 2015/01/04 13:01:42 mpi Exp $ */
+/* $OpenBSD: ipic.c,v 1.18 2015/06/24 11:58:06 mpi Exp $ */
/*
* Copyright (c) 2008 Mark Kettenis
struct ipic_softc *sc = ipic_sc;
struct intrhand *ih;
struct intrq *iq;
- int s;
+ int s, flags;
if (ipic_preinit_done == 0)
ipic_preinit();
ipic_calc_masks();
}
+ flags = level & IPL_MPSAFE;
+ level &= ~IPL_MPSAFE;
+
+ KASSERT(level <= IPL_TTY || level >= IPL_CLOCK || flags & IPL_MPSAFE);
+
ih->ih_fun = ih_fun;
ih->ih_arg = ih_arg;
ih->ih_level = level;
+ ih->ih_flags = flags;
ih->ih_irq = ivec;
evcount_attach(&ih->ih_count, name, &ih->ih_irq);