1*da5607f6Sjsg /* $OpenBSD: intc.c,v 1.15 2024/06/26 01:40:49 jsg Exp $ */
28eda2d14Spatrick /*
38eda2d14Spatrick * Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org>
48eda2d14Spatrick *
58eda2d14Spatrick * Permission to use, copy, modify, and distribute this software for any
68eda2d14Spatrick * purpose with or without fee is hereby granted, provided that the above
78eda2d14Spatrick * copyright notice and this permission notice appear in all copies.
88eda2d14Spatrick *
98eda2d14Spatrick * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
108eda2d14Spatrick * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
118eda2d14Spatrick * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
128eda2d14Spatrick * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
138eda2d14Spatrick * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
148eda2d14Spatrick * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
158eda2d14Spatrick * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
168eda2d14Spatrick */
178eda2d14Spatrick
188eda2d14Spatrick #include <sys/param.h>
198eda2d14Spatrick #include <sys/systm.h>
208eda2d14Spatrick #include <sys/queue.h>
218eda2d14Spatrick #include <sys/malloc.h>
228eda2d14Spatrick #include <sys/device.h>
238eda2d14Spatrick #include <sys/evcount.h>
247d7522cbSjsg
258eda2d14Spatrick #include <machine/bus.h>
267d7522cbSjsg #include <machine/fdt.h>
277d7522cbSjsg
288d957e1aSsyl #include <armv7/armv7/armv7var.h>
295e3bd5f0Sjsg
307d7522cbSjsg #include <dev/ofw/openfirm.h>
315e3bd5f0Sjsg #include <dev/ofw/fdt.h>
325e3bd5f0Sjsg
338eda2d14Spatrick #include "intc.h"
348eda2d14Spatrick
358eda2d14Spatrick #define INTC_NUM_IRQ intc_nirq
368eda2d14Spatrick #define INTC_NUM_BANKS (intc_nirq/32)
378eda2d14Spatrick #define INTC_MAX_IRQ 128
388eda2d14Spatrick #define INTC_MAX_BANKS (INTC_MAX_IRQ/32)
398eda2d14Spatrick
408eda2d14Spatrick /* registers */
418eda2d14Spatrick #define INTC_REVISION 0x00 /* R */
428eda2d14Spatrick #define INTC_SYSCONFIG 0x10 /* RW */
438eda2d14Spatrick #define INTC_SYSCONFIG_AUTOIDLE 0x1
448eda2d14Spatrick #define INTC_SYSCONFIG_SOFTRESET 0x2
458eda2d14Spatrick #define INTC_SYSSTATUS 0x14 /* R */
468eda2d14Spatrick #define INTC_SYSSYSTATUS_RESETDONE 0x1
478eda2d14Spatrick #define INTC_SIR_IRQ 0x40 /* R */
488eda2d14Spatrick #define INTC_SIR_FIQ 0x44 /* R */
498eda2d14Spatrick #define INTC_CONTROL 0x48 /* RW */
508eda2d14Spatrick #define INTC_CONTROL_NEWIRQ 0x1
518eda2d14Spatrick #define INTC_CONTROL_NEWFIQ 0x2
528eda2d14Spatrick #define INTC_CONTROL_GLOBALMASK 0x1
538eda2d14Spatrick #define INTC_PROTECTION 0x4c /* RW */
548eda2d14Spatrick #define INTC_PROTECTION_PROT 1 /* only privileged mode */
558eda2d14Spatrick #define INTC_IDLE 0x50 /* RW */
568eda2d14Spatrick
578eda2d14Spatrick #define INTC_IRQ_TO_REG(i) (((i) >> 5) & 0x3)
588eda2d14Spatrick #define INTC_IRQ_TO_REGi(i) ((i) & 0x1f)
598eda2d14Spatrick #define INTC_ITRn(i) 0x80+(0x20*i)+0x00 /* R */
608eda2d14Spatrick #define INTC_MIRn(i) 0x80+(0x20*i)+0x04 /* RW */
618eda2d14Spatrick #define INTC_CLEARn(i) 0x80+(0x20*i)+0x08 /* RW */
628eda2d14Spatrick #define INTC_SETn(i) 0x80+(0x20*i)+0x0c /* RW */
638eda2d14Spatrick #define INTC_ISR_SETn(i) 0x80+(0x20*i)+0x10 /* RW */
648eda2d14Spatrick #define INTC_ISR_CLEARn(i) 0x80+(0x20*i)+0x14 /* RW */
658eda2d14Spatrick #define INTC_PENDING_IRQn(i) 0x80+(0x20*i)+0x18 /* R */
668eda2d14Spatrick #define INTC_PENDING_FIQn(i) 0x80+(0x20*i)+0x1c /* R */
678eda2d14Spatrick
688eda2d14Spatrick #define INTC_ILRn(i) 0x100+(4*i)
698eda2d14Spatrick #define INTC_ILR_IRQ 0x0 /* not of FIQ */
708eda2d14Spatrick #define INTC_ILR_FIQ 0x1
718eda2d14Spatrick #define INTC_ILR_PRIs(pri) ((pri) << 2)
728eda2d14Spatrick #define INTC_ILR_PRI(reg) (((reg) >> 2) & 0x2f)
738eda2d14Spatrick #define INTC_MIN_PRI 63
748eda2d14Spatrick #define INTC_STD_PRI 32
758eda2d14Spatrick #define INTC_MAX_PRI 0
768eda2d14Spatrick
778eda2d14Spatrick struct intrhand {
788eda2d14Spatrick TAILQ_ENTRY(intrhand) ih_list; /* link on intrq list */
798eda2d14Spatrick int (*ih_func)(void *); /* handler */
808eda2d14Spatrick void *ih_arg; /* arg for handler */
818eda2d14Spatrick int ih_ipl; /* IPL_* */
828eda2d14Spatrick int ih_irq; /* IRQ number */
838eda2d14Spatrick struct evcount ih_count;
848eda2d14Spatrick char *ih_name;
858eda2d14Spatrick };
868eda2d14Spatrick
878eda2d14Spatrick struct intrq {
888eda2d14Spatrick TAILQ_HEAD(, intrhand) iq_list; /* handler list */
898eda2d14Spatrick int iq_irq; /* IRQ to mask while handling */
908eda2d14Spatrick int iq_levels; /* IPL_*'s this IRQ has */
918eda2d14Spatrick int iq_ist; /* share type */
928eda2d14Spatrick };
938eda2d14Spatrick
948eda2d14Spatrick struct intrq intc_handler[INTC_MAX_IRQ];
958eda2d14Spatrick u_int32_t intc_smask[NIPL];
968eda2d14Spatrick u_int32_t intc_imask[INTC_MAX_BANKS][NIPL];
977d7522cbSjsg struct interrupt_controller intc_ic;
988eda2d14Spatrick
998eda2d14Spatrick bus_space_tag_t intc_iot;
1008eda2d14Spatrick bus_space_handle_t intc_ioh;
1018eda2d14Spatrick int intc_nirq;
1028eda2d14Spatrick
1037d7522cbSjsg int intc_match(struct device *, void *, void *);
1048eda2d14Spatrick void intc_attach(struct device *, struct device *, void *);
1058eda2d14Spatrick int intc_spllower(int new);
1068eda2d14Spatrick int intc_splraise(int new);
1078eda2d14Spatrick void intc_setipl(int new);
1088eda2d14Spatrick void intc_calc_mask(void);
109789e88a4Spatrick void *intc_intr_establish_fdt(void *, int *, int, struct cpu_info *,
110789e88a4Spatrick int (*)(void *), void *, char *);
1118eda2d14Spatrick
1129fdf0c62Smpi const struct cfattach intc_ca = {
1137d7522cbSjsg sizeof (struct device), intc_match, intc_attach
1148eda2d14Spatrick };
1158eda2d14Spatrick
1168eda2d14Spatrick struct cfdriver intc_cd = {
1178eda2d14Spatrick NULL, "intc", DV_DULL
1188eda2d14Spatrick };
1198eda2d14Spatrick
1208eda2d14Spatrick int intc_attached = 0;
1218eda2d14Spatrick
1227d7522cbSjsg int
intc_match(struct device * parent,void * match,void * aux)1237d7522cbSjsg intc_match(struct device *parent, void *match, void *aux)
1248eda2d14Spatrick {
1257d7522cbSjsg struct fdt_attach_args *faa = aux;
1267d7522cbSjsg
1277d7522cbSjsg return (OF_is_compatible(faa->fa_node, "ti,omap3-intc") ||
1287d7522cbSjsg OF_is_compatible(faa->fa_node, "ti,am33xx-intc"));
1297d7522cbSjsg }
1307d7522cbSjsg
1317d7522cbSjsg void
intc_attach(struct device * parent,struct device * self,void * aux)1327d7522cbSjsg intc_attach(struct device *parent, struct device *self, void *aux)
1337d7522cbSjsg {
1347d7522cbSjsg struct fdt_attach_args *faa = aux;
1358eda2d14Spatrick int i;
1368eda2d14Spatrick u_int32_t rev;
1375e3bd5f0Sjsg
1387d7522cbSjsg intc_iot = faa->fa_iot;
1397d7522cbSjsg if (bus_space_map(intc_iot, faa->fa_reg[0].addr,
1407d7522cbSjsg faa->fa_reg[0].size, 0, &intc_ioh))
1418eda2d14Spatrick panic("intc_attach: bus_space_map failed!");
1428eda2d14Spatrick
1438eda2d14Spatrick rev = bus_space_read_4(intc_iot, intc_ioh, INTC_REVISION);
1448eda2d14Spatrick
1458eda2d14Spatrick printf(" rev %d.%d\n", rev >> 4 & 0xf, rev & 0xf);
1468eda2d14Spatrick
1478eda2d14Spatrick /* software reset of the part? */
1488eda2d14Spatrick /* set protection bit (kernel only)? */
1498eda2d14Spatrick #if 0
1508eda2d14Spatrick bus_space_write_4(intc_iot, intc_ioh, INTC_PROTECTION,
1518eda2d14Spatrick INTC_PROTECTION_PROT);
1528eda2d14Spatrick #endif
1538eda2d14Spatrick
1548eda2d14Spatrick /* enable interface clock power saving mode */
1558eda2d14Spatrick bus_space_write_4(intc_iot, intc_ioh, INTC_SYSCONFIG,
1568eda2d14Spatrick INTC_SYSCONFIG_AUTOIDLE);
1578eda2d14Spatrick
1587d7522cbSjsg if (OF_is_compatible(faa->fa_node, "ti,am33xx-intc"))
1598eda2d14Spatrick intc_nirq = 128;
1605e3bd5f0Sjsg else
1618eda2d14Spatrick intc_nirq = 96;
1628eda2d14Spatrick
1638eda2d14Spatrick /* mask all interrupts */
1648eda2d14Spatrick for (i = 0; i < INTC_NUM_BANKS; i++)
1658eda2d14Spatrick bus_space_write_4(intc_iot, intc_ioh, INTC_MIRn(i), 0xffffffff);
1668eda2d14Spatrick
1678eda2d14Spatrick for (i = 0; i < INTC_NUM_IRQ; i++) {
1688eda2d14Spatrick bus_space_write_4(intc_iot, intc_ioh, INTC_ILRn(i),
1698eda2d14Spatrick INTC_ILR_PRIs(INTC_MIN_PRI)|INTC_ILR_IRQ);
1708eda2d14Spatrick
1718eda2d14Spatrick TAILQ_INIT(&intc_handler[i].iq_list);
1728eda2d14Spatrick }
1738eda2d14Spatrick
1748eda2d14Spatrick intc_calc_mask();
1758eda2d14Spatrick bus_space_write_4(intc_iot, intc_ioh, INTC_CONTROL,
1768eda2d14Spatrick INTC_CONTROL_NEWIRQ);
1778eda2d14Spatrick
1788eda2d14Spatrick intc_attached = 1;
1798eda2d14Spatrick
1808eda2d14Spatrick /* insert self as interrupt handler */
1818eda2d14Spatrick arm_set_intr_handler(intc_splraise, intc_spllower, intc_splx,
1828eda2d14Spatrick intc_setipl,
1838eda2d14Spatrick intc_intr_establish, intc_intr_disestablish, intc_intr_string,
1848eda2d14Spatrick intc_irq_handler);
1858eda2d14Spatrick
1868eda2d14Spatrick intc_setipl(IPL_HIGH); /* XXX ??? */
187ebd24745Sjsg enable_interrupts(PSR_I);
1887d7522cbSjsg
1897d7522cbSjsg intc_ic.ic_node = faa->fa_node;
1907d7522cbSjsg intc_ic.ic_establish = intc_intr_establish_fdt;
1917d7522cbSjsg arm_intr_register_fdt(&intc_ic);
1928eda2d14Spatrick }
1938eda2d14Spatrick
1948eda2d14Spatrick void
intc_calc_mask(void)1958eda2d14Spatrick intc_calc_mask(void)
1968eda2d14Spatrick {
1978eda2d14Spatrick struct cpu_info *ci = curcpu();
1988eda2d14Spatrick int irq;
1998eda2d14Spatrick struct intrhand *ih;
2008eda2d14Spatrick int i;
2018eda2d14Spatrick
2028eda2d14Spatrick for (irq = 0; irq < INTC_NUM_IRQ; irq++) {
2038eda2d14Spatrick int max = IPL_NONE;
2048eda2d14Spatrick int min = IPL_HIGH;
2058eda2d14Spatrick TAILQ_FOREACH(ih, &intc_handler[irq].iq_list, ih_list) {
2068eda2d14Spatrick if (ih->ih_ipl > max)
2078eda2d14Spatrick max = ih->ih_ipl;
2088eda2d14Spatrick
2098eda2d14Spatrick if (ih->ih_ipl < min)
2108eda2d14Spatrick min = ih->ih_ipl;
2118eda2d14Spatrick }
2128eda2d14Spatrick
2138eda2d14Spatrick intc_handler[irq].iq_irq = max;
2148eda2d14Spatrick
2158eda2d14Spatrick if (max == IPL_NONE)
2168eda2d14Spatrick min = IPL_NONE;
2178eda2d14Spatrick
2188eda2d14Spatrick #ifdef DEBUG_INTC
2198eda2d14Spatrick if (min != IPL_NONE) {
2208eda2d14Spatrick printf("irq %d to block at %d %d reg %d bit %d\n",
2218eda2d14Spatrick irq, max, min, INTC_IRQ_TO_REG(irq),
2228eda2d14Spatrick INTC_IRQ_TO_REGi(irq));
2238eda2d14Spatrick }
2248eda2d14Spatrick #endif
2258eda2d14Spatrick /* Enable interrupts at lower levels, clear -> enable */
2268eda2d14Spatrick for (i = 0; i < min; i++)
2278eda2d14Spatrick intc_imask[INTC_IRQ_TO_REG(irq)][i] &=
2288eda2d14Spatrick ~(1 << INTC_IRQ_TO_REGi(irq));
2298eda2d14Spatrick for (; i <= IPL_HIGH; i++)
2308eda2d14Spatrick intc_imask[INTC_IRQ_TO_REG(irq)][i] |=
2318eda2d14Spatrick 1 << INTC_IRQ_TO_REGi(irq);
2328eda2d14Spatrick /* XXX - set enable/disable, priority */
2338eda2d14Spatrick bus_space_write_4(intc_iot, intc_ioh, INTC_ILRn(irq),
2348eda2d14Spatrick INTC_ILR_PRIs(NIPL-max)|INTC_ILR_IRQ);
2358eda2d14Spatrick }
2368eda2d14Spatrick arm_init_smask();
2378eda2d14Spatrick intc_setipl(ci->ci_cpl);
2388eda2d14Spatrick }
2398eda2d14Spatrick
2408eda2d14Spatrick void
intc_splx(int new)2418eda2d14Spatrick intc_splx(int new)
2428eda2d14Spatrick {
2438eda2d14Spatrick struct cpu_info *ci = curcpu();
2448eda2d14Spatrick intc_setipl(new);
2458eda2d14Spatrick
2468eda2d14Spatrick if (ci->ci_ipending & arm_smask[ci->ci_cpl])
2478eda2d14Spatrick arm_do_pending_intr(ci->ci_cpl);
2488eda2d14Spatrick }
2498eda2d14Spatrick
2508eda2d14Spatrick int
intc_spllower(int new)2518eda2d14Spatrick intc_spllower(int new)
2528eda2d14Spatrick {
2538eda2d14Spatrick struct cpu_info *ci = curcpu();
2548eda2d14Spatrick int old = ci->ci_cpl;
2558eda2d14Spatrick intc_splx(new);
2568eda2d14Spatrick return (old);
2578eda2d14Spatrick }
2588eda2d14Spatrick
2598eda2d14Spatrick int
intc_splraise(int new)2608eda2d14Spatrick intc_splraise(int new)
2618eda2d14Spatrick {
2628eda2d14Spatrick struct cpu_info *ci = curcpu();
2638eda2d14Spatrick int old;
2648eda2d14Spatrick old = ci->ci_cpl;
2658eda2d14Spatrick
2668eda2d14Spatrick /*
2678eda2d14Spatrick * setipl must always be called because there is a race window
2688eda2d14Spatrick * where the variable is updated before the mask is set
2698eda2d14Spatrick * an interrupt occurs in that window without the mask always
2708eda2d14Spatrick * being set, the hardware might not get updated on the next
2718eda2d14Spatrick * splraise completely messing up spl protection.
2728eda2d14Spatrick */
2738eda2d14Spatrick if (old > new)
2748eda2d14Spatrick new = old;
2758eda2d14Spatrick
2768eda2d14Spatrick intc_setipl(new);
2778eda2d14Spatrick
2788eda2d14Spatrick return (old);
2798eda2d14Spatrick }
2808eda2d14Spatrick
2818eda2d14Spatrick void
intc_setipl(int new)2828eda2d14Spatrick intc_setipl(int new)
2838eda2d14Spatrick {
2848eda2d14Spatrick struct cpu_info *ci = curcpu();
2858eda2d14Spatrick int i;
2868eda2d14Spatrick int psw;
2878eda2d14Spatrick if (intc_attached == 0)
2888eda2d14Spatrick return;
2898eda2d14Spatrick
290ebd24745Sjsg psw = disable_interrupts(PSR_I);
2918eda2d14Spatrick #if 0
2928eda2d14Spatrick {
2938eda2d14Spatrick volatile static int recursed = 0;
2948eda2d14Spatrick if (recursed == 0) {
2958eda2d14Spatrick recursed = 1;
2968eda2d14Spatrick if (new != 12)
2978eda2d14Spatrick printf("setipl %d\n", new);
2988eda2d14Spatrick recursed = 0;
2998eda2d14Spatrick }
3008eda2d14Spatrick }
3018eda2d14Spatrick #endif
3028eda2d14Spatrick ci->ci_cpl = new;
3038eda2d14Spatrick for (i = 0; i < INTC_NUM_BANKS; i++)
3048eda2d14Spatrick bus_space_write_4(intc_iot, intc_ioh,
3058eda2d14Spatrick INTC_MIRn(i), intc_imask[i][new]);
3068eda2d14Spatrick bus_space_write_4(intc_iot, intc_ioh, INTC_CONTROL,
3078eda2d14Spatrick INTC_CONTROL_NEWIRQ);
3088eda2d14Spatrick restore_interrupts(psw);
3098eda2d14Spatrick }
3108eda2d14Spatrick
3118eda2d14Spatrick void
intc_irq_handler(void * frame)3128eda2d14Spatrick intc_irq_handler(void *frame)
3138eda2d14Spatrick {
3148eda2d14Spatrick int irq, pri, s;
3158eda2d14Spatrick struct intrhand *ih;
3168eda2d14Spatrick void *arg;
3178eda2d14Spatrick
3188eda2d14Spatrick irq = bus_space_read_4(intc_iot, intc_ioh, INTC_SIR_IRQ);
3198eda2d14Spatrick #ifdef DEBUG_INTC
3208eda2d14Spatrick printf("irq %d fired\n", irq);
3218eda2d14Spatrick #endif
3228eda2d14Spatrick
3238eda2d14Spatrick pri = intc_handler[irq].iq_irq;
3248eda2d14Spatrick s = intc_splraise(pri);
3258eda2d14Spatrick TAILQ_FOREACH(ih, &intc_handler[irq].iq_list, ih_list) {
326fe0d117cSjsg if (ih->ih_arg)
3278eda2d14Spatrick arg = ih->ih_arg;
3288eda2d14Spatrick else
3298eda2d14Spatrick arg = frame;
3308eda2d14Spatrick
3318eda2d14Spatrick if (ih->ih_func(arg))
3328eda2d14Spatrick ih->ih_count.ec_count++;
3338eda2d14Spatrick
3348eda2d14Spatrick }
3358eda2d14Spatrick bus_space_write_4(intc_iot, intc_ioh, INTC_CONTROL,
3368eda2d14Spatrick INTC_CONTROL_NEWIRQ);
3378eda2d14Spatrick
3388eda2d14Spatrick intc_splx(s);
3398eda2d14Spatrick }
3408eda2d14Spatrick
3418eda2d14Spatrick void *
intc_intr_establish(int irqno,int level,struct cpu_info * ci,int (* func)(void *),void * arg,char * name)342789e88a4Spatrick intc_intr_establish(int irqno, int level, struct cpu_info *ci,
343789e88a4Spatrick int (*func)(void *), void *arg, char *name)
3448eda2d14Spatrick {
3458eda2d14Spatrick int psw;
3468eda2d14Spatrick struct intrhand *ih;
3478eda2d14Spatrick
3488eda2d14Spatrick if (irqno < 0 || irqno >= INTC_NUM_IRQ)
3498eda2d14Spatrick panic("intc_intr_establish: bogus irqnumber %d: %s",
3508eda2d14Spatrick irqno, name);
351789e88a4Spatrick
352789e88a4Spatrick if (ci == NULL)
353789e88a4Spatrick ci = &cpu_info_primary;
354789e88a4Spatrick else if (!CPU_IS_PRIMARY(ci))
355789e88a4Spatrick return NULL;
356789e88a4Spatrick
357ebd24745Sjsg psw = disable_interrupts(PSR_I);
3588eda2d14Spatrick
359a8511e66Spatrick ih = malloc(sizeof(*ih), M_DEVBUF, M_WAITOK);
3608eda2d14Spatrick ih->ih_func = func;
3618eda2d14Spatrick ih->ih_arg = arg;
36272784ddaSkettenis ih->ih_ipl = level & IPL_IRQMASK;
3638eda2d14Spatrick ih->ih_irq = irqno;
3648eda2d14Spatrick ih->ih_name = name;
3658eda2d14Spatrick
3668eda2d14Spatrick TAILQ_INSERT_TAIL(&intc_handler[irqno].iq_list, ih, ih_list);
3678eda2d14Spatrick
3688eda2d14Spatrick if (name != NULL)
3698eda2d14Spatrick evcount_attach(&ih->ih_count, name, &ih->ih_irq);
3708eda2d14Spatrick
3718eda2d14Spatrick #ifdef DEBUG_INTC
3728eda2d14Spatrick printf("intc_intr_establish irq %d level %d [%s]\n", irqno, level,
3738eda2d14Spatrick name);
3748eda2d14Spatrick #endif
3758eda2d14Spatrick intc_calc_mask();
3768eda2d14Spatrick
3778eda2d14Spatrick restore_interrupts(psw);
3788eda2d14Spatrick return (ih);
3798eda2d14Spatrick }
3808eda2d14Spatrick
3817d7522cbSjsg void *
intc_intr_establish_fdt(void * cookie,int * cell,int level,struct cpu_info * ci,int (* func)(void *),void * arg,char * name)3827d7522cbSjsg intc_intr_establish_fdt(void *cookie, int *cell, int level,
383789e88a4Spatrick struct cpu_info *ci, int (*func)(void *), void *arg, char *name)
3847d7522cbSjsg {
385789e88a4Spatrick return intc_intr_establish(cell[0], level, ci, func, arg, name);
3867d7522cbSjsg }
3877d7522cbSjsg
3888eda2d14Spatrick void
intc_intr_disestablish(void * cookie)3898eda2d14Spatrick intc_intr_disestablish(void *cookie)
3908eda2d14Spatrick {
3918eda2d14Spatrick int psw;
3928eda2d14Spatrick struct intrhand *ih = cookie;
3938eda2d14Spatrick int irqno = ih->ih_irq;
394ebd24745Sjsg psw = disable_interrupts(PSR_I);
3958eda2d14Spatrick TAILQ_REMOVE(&intc_handler[irqno].iq_list, ih, ih_list);
3968eda2d14Spatrick if (ih->ih_name != NULL)
3978eda2d14Spatrick evcount_detach(&ih->ih_count);
398f8e6c425Stedu free(ih, M_DEVBUF, 0);
3998eda2d14Spatrick restore_interrupts(psw);
4008eda2d14Spatrick }
4018eda2d14Spatrick
4028eda2d14Spatrick const char *
intc_intr_string(void * cookie)4038eda2d14Spatrick intc_intr_string(void *cookie)
4048eda2d14Spatrick {
4058eda2d14Spatrick return "huh?";
4068eda2d14Spatrick }
4078eda2d14Spatrick
4088eda2d14Spatrick
4098eda2d14Spatrick #if 0
4108eda2d14Spatrick int intc_tst(void *a);
4118eda2d14Spatrick
4128eda2d14Spatrick int
4138eda2d14Spatrick intc_tst(void *a)
4148eda2d14Spatrick {
4158eda2d14Spatrick printf("inct_tst called\n");
4168eda2d14Spatrick bus_space_write_4(intc_iot, intc_ioh, INTC_ISR_CLEARn(0), 2);
4178eda2d14Spatrick return 1;
4188eda2d14Spatrick }
4198eda2d14Spatrick
4208eda2d14Spatrick void intc_test(void);
421*da5607f6Sjsg void
422*da5607f6Sjsg intc_test(void)
4238eda2d14Spatrick {
4248eda2d14Spatrick void * ih;
4258eda2d14Spatrick printf("about to register handler\n");
4268eda2d14Spatrick ih = intc_intr_establish(1, IPL_BIO, intc_tst, NULL, "intctst");
4278eda2d14Spatrick
4288eda2d14Spatrick printf("about to set bit\n");
4298eda2d14Spatrick bus_space_write_4(intc_iot, intc_ioh, INTC_ISR_SETn(0), 2);
4308eda2d14Spatrick
4318eda2d14Spatrick printf("about to clear bit\n");
4328eda2d14Spatrick bus_space_write_4(intc_iot, intc_ioh, INTC_ISR_CLEARn(0), 2);
4338eda2d14Spatrick
4348eda2d14Spatrick printf("about to remove handler\n");
4358eda2d14Spatrick intc_intr_disestablish(ih);
4368eda2d14Spatrick
4378eda2d14Spatrick printf("done\n");
4388eda2d14Spatrick }
4398eda2d14Spatrick #endif
440