199651Sbenno/*- 299651Sbenno * Copyright (c) 1991 The Regents of the University of California. 399651Sbenno * All rights reserved. 499651Sbenno * 599651Sbenno * This code is derived from software contributed to Berkeley by 699651Sbenno * William Jolitz. 799651Sbenno * 899651Sbenno * Redistribution and use in source and binary forms, with or without 999651Sbenno * modification, are permitted provided that the following conditions 1099651Sbenno * are met: 1199651Sbenno * 1. Redistributions of source code must retain the above copyright 1299651Sbenno * notice, this list of conditions and the following disclaimer. 1399651Sbenno * 2. Redistributions in binary form must reproduce the above copyright 1499651Sbenno * notice, this list of conditions and the following disclaimer in the 1599651Sbenno * documentation and/or other materials provided with the distribution. 1699651Sbenno * 4. Neither the name of the University nor the names of its contributors 1799651Sbenno * may be used to endorse or promote products derived from this software 1899651Sbenno * without specific prior written permission. 1999651Sbenno * 2099651Sbenno * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2199651Sbenno * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2299651Sbenno * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2399651Sbenno * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2499651Sbenno * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2599651Sbenno * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2699651Sbenno * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2799651Sbenno * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2899651Sbenno * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2999651Sbenno * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3099651Sbenno * SUCH DAMAGE. 3199651Sbenno */ 3299651Sbenno/*- 3399651Sbenno * Copyright (c) 2002 Benno Rice. 3499651Sbenno * All rights reserved. 3599651Sbenno * 3699651Sbenno * Redistribution and use in source and binary forms, with or without 3799651Sbenno * modification, are permitted provided that the following conditions 3899651Sbenno * are met: 3999651Sbenno * 1. Redistributions of source code must retain the above copyright 4099651Sbenno * notice, this list of conditions and the following disclaimer. 4199651Sbenno * 2. Redistributions in binary form must reproduce the above copyright 4299651Sbenno * notice, this list of conditions and the following disclaimer in the 4399651Sbenno * documentation and/or other materials provided with the distribution. 4499651Sbenno * 4599651Sbenno * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 4699651Sbenno * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4799651Sbenno * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4899651Sbenno * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4999651Sbenno * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 5099651Sbenno * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 5199651Sbenno * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 5299651Sbenno * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 5399651Sbenno * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5499651Sbenno * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5599651Sbenno * SUCH DAMAGE. 5699651Sbenno * 5799651Sbenno * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 5899651Sbenno * form: src/sys/i386/isa/intr_machdep.c,v 1.57 2001/07/20 5999651Sbenno * 6099651Sbenno * $FreeBSD$ 6199651Sbenno */ 6299651Sbenno 63218075Smarcel#include "opt_isa.h" 64218075Smarcel 6599651Sbenno#include <sys/param.h> 6699651Sbenno#include <sys/systm.h> 6799651Sbenno#include <sys/kernel.h> 6899651Sbenno#include <sys/queue.h> 6999651Sbenno#include <sys/bus.h> 70222813Sattilio#include <sys/cpuset.h> 7199651Sbenno#include <sys/interrupt.h> 72164987Smarcel#include <sys/ktr.h> 7399651Sbenno#include <sys/lock.h> 7499651Sbenno#include <sys/malloc.h> 7599651Sbenno#include <sys/mutex.h> 7699651Sbenno#include <sys/pcpu.h> 77209486Snwhitehorn#include <sys/smp.h> 78171805Smarcel#include <sys/syslog.h> 7999651Sbenno#include <sys/vmmeter.h> 80125708Sgrehan#include <sys/proc.h> 8199651Sbenno 8299651Sbenno#include <machine/frame.h> 8399651Sbenno#include <machine/intr_machdep.h> 84171805Smarcel#include <machine/md_var.h> 85178628Smarcel#include <machine/smp.h> 8699651Sbenno#include <machine/trap.h> 8799651Sbenno 88171805Smarcel#include "pic_if.h" 89171805Smarcel 9099651Sbenno#define MAX_STRAY_LOG 5 9199651Sbenno 92249132Smavstatic MALLOC_DEFINE(M_INTR, "intr", "interrupt handler data"); 9399651Sbenno 94171805Smarcelstruct powerpc_intr { 95164987Smarcel struct intr_event *event; 96164987Smarcel long *cntp; 97191450Smarcel u_int irq; 98191450Smarcel device_t pic; 99191450Smarcel u_int intline; 100191450Smarcel u_int vector; 101212453Smav u_int cntindex; 102222813Sattilio cpuset_t cpu; 103176918Smarcel enum intr_trigger trig; 104176918Smarcel enum intr_polarity pol; 105164987Smarcel}; 10699651Sbenno 107209298Snwhitehornstruct pic { 108218075Smarcel device_t dev; 109218075Smarcel uint32_t node; 110218075Smarcel u_int irqs; 111218075Smarcel u_int ipis; 112218075Smarcel int base; 113209298Snwhitehorn}; 114209298Snwhitehorn 115212453Smavstatic u_int intrcnt_index = 0; 116191307Srajstatic struct mtx intr_table_lock; 117171805Smarcelstatic struct powerpc_intr *powerpc_intrs[INTR_VECTORS]; 118209298Snwhitehornstatic struct pic piclist[MAX_PICS]; 119171805Smarcelstatic u_int nvectors; /* Allocated vectors */ 120209298Snwhitehornstatic u_int npics; /* PICs registered */ 121218075Smarcel#ifdef DEV_ISA 122218075Smarcelstatic u_int nirqs = 16; /* Allocated IRQS (ISA pre-allocated). */ 123218075Smarcel#else 124218075Smarcelstatic u_int nirqs = 0; /* Allocated IRQs. */ 125218075Smarcel#endif 126171805Smarcelstatic u_int stray_count; 12799651Sbenno 128209298Snwhitehorndevice_t root_pic; 129209298Snwhitehorn 130178628Smarcel#ifdef SMP 131178628Smarcelstatic void *ipi_cookie; 132178628Smarcel#endif 133178628Smarcel 134177068Smarcelstatic void 135191307Srajintr_init(void *dummy __unused) 136191307Sraj{ 137191307Sraj 138191307Sraj mtx_init(&intr_table_lock, "intr sources lock", NULL, MTX_DEF); 139191307Sraj} 140191307SrajSYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL); 141191307Sraj 142209486Snwhitehorn#ifdef SMP 143191307Srajstatic void 144209486Snwhitehornsmp_intr_init(void *dummy __unused) 145209486Snwhitehorn{ 146209486Snwhitehorn struct powerpc_intr *i; 147209486Snwhitehorn int vector; 148209486Snwhitehorn 149209486Snwhitehorn for (vector = 0; vector < nvectors; vector++) { 150209486Snwhitehorn i = powerpc_intrs[vector]; 151209486Snwhitehorn if (i != NULL && i->pic == root_pic) 152209486Snwhitehorn PIC_BIND(i->pic, i->intline, i->cpu); 153209486Snwhitehorn } 154209486Snwhitehorn} 155209486SnwhitehornSYSINIT(smp_intr_init, SI_SUB_SMP, SI_ORDER_ANY, smp_intr_init, NULL); 156209486Snwhitehorn#endif 157209486Snwhitehorn 158209486Snwhitehornstatic void 159177068Smarcelintrcnt_setname(const char *name, int index) 160177068Smarcel{ 161191307Sraj 162177068Smarcel snprintf(intrnames + (MAXCOMLEN + 1) * index, MAXCOMLEN + 1, "%-*s", 163177068Smarcel MAXCOMLEN, name); 164177068Smarcel} 165177068Smarcel 166212453Smavvoid 167212453Smavintrcnt_add(const char *name, u_long **countp) 168212453Smav{ 169212453Smav int idx; 170212453Smav 171212453Smav idx = atomic_fetchadd_int(&intrcnt_index, 1); 172212453Smav *countp = &intrcnt[idx]; 173212453Smav intrcnt_setname(name, idx); 174212453Smav} 175212453Smav 176176918Smarcelstatic struct powerpc_intr * 177176918Smarcelintr_lookup(u_int irq) 178176918Smarcel{ 179177068Smarcel char intrname[8]; 180176918Smarcel struct powerpc_intr *i, *iscan; 181176918Smarcel int vector; 182176918Smarcel 183191307Sraj mtx_lock(&intr_table_lock); 184176918Smarcel for (vector = 0; vector < nvectors; vector++) { 185176918Smarcel i = powerpc_intrs[vector]; 186191307Sraj if (i != NULL && i->irq == irq) { 187191307Sraj mtx_unlock(&intr_table_lock); 188176918Smarcel return (i); 189191307Sraj } 190176918Smarcel } 191176918Smarcel 192176918Smarcel i = malloc(sizeof(*i), M_INTR, M_NOWAIT); 193209486Snwhitehorn if (i == NULL) { 194209486Snwhitehorn mtx_unlock(&intr_table_lock); 195176918Smarcel return (NULL); 196209486Snwhitehorn } 197176918Smarcel 198176918Smarcel i->event = NULL; 199176918Smarcel i->cntp = NULL; 200176918Smarcel i->trig = INTR_TRIGGER_CONFORM; 201176918Smarcel i->pol = INTR_POLARITY_CONFORM; 202176918Smarcel i->irq = irq; 203208835Snwhitehorn i->pic = NULL; 204176918Smarcel i->vector = -1; 205176918Smarcel 206209486Snwhitehorn#ifdef SMP 207209486Snwhitehorn i->cpu = all_cpus; 208209486Snwhitehorn#else 209222813Sattilio CPU_SETOF(0, &i->cpu); 210209486Snwhitehorn#endif 211209486Snwhitehorn 212176918Smarcel for (vector = 0; vector < INTR_VECTORS && vector <= nvectors; 213176918Smarcel vector++) { 214176918Smarcel iscan = powerpc_intrs[vector]; 215176918Smarcel if (iscan != NULL && iscan->irq == irq) 216176918Smarcel break; 217176918Smarcel if (iscan == NULL && i->vector == -1) 218176918Smarcel i->vector = vector; 219176918Smarcel iscan = NULL; 220176918Smarcel } 221176918Smarcel 222176918Smarcel if (iscan == NULL && i->vector != -1) { 223176918Smarcel powerpc_intrs[i->vector] = i; 224212453Smav i->cntindex = atomic_fetchadd_int(&intrcnt_index, 1); 225212453Smav i->cntp = &intrcnt[i->cntindex]; 226177068Smarcel sprintf(intrname, "irq%u:", i->irq); 227212453Smav intrcnt_setname(intrname, i->cntindex); 228176918Smarcel nvectors++; 229176918Smarcel } 230191307Sraj mtx_unlock(&intr_table_lock); 231176918Smarcel 232176918Smarcel if (iscan != NULL || i->vector == -1) { 233176918Smarcel free(i, M_INTR); 234176918Smarcel i = iscan; 235176918Smarcel } 236176918Smarcel 237176918Smarcel return (i); 238176918Smarcel} 239176918Smarcel 240191450Smarcelstatic int 241191450Smarcelpowerpc_map_irq(struct powerpc_intr *i) 242191450Smarcel{ 243218075Smarcel struct pic *p; 244218075Smarcel u_int cnt; 245218075Smarcel int idx; 246191450Smarcel 247218075Smarcel for (idx = 0; idx < npics; idx++) { 248218075Smarcel p = &piclist[idx]; 249218075Smarcel cnt = p->irqs + p->ipis; 250218075Smarcel if (i->irq >= p->base && i->irq < p->base + cnt) 251218075Smarcel break; 252218075Smarcel } 253218075Smarcel if (idx == npics) 254218075Smarcel return (EINVAL); 255191450Smarcel 256218075Smarcel i->intline = i->irq - p->base; 257218075Smarcel i->pic = p->dev; 258218075Smarcel 259209298Snwhitehorn /* Try a best guess if that failed */ 260209298Snwhitehorn if (i->pic == NULL) 261209298Snwhitehorn i->pic = root_pic; 262209298Snwhitehorn 263191450Smarcel return (0); 264191450Smarcel} 265191450Smarcel 266171805Smarcelstatic void 267171805Smarcelpowerpc_intr_eoi(void *arg) 26899651Sbenno{ 269191450Smarcel struct powerpc_intr *i = arg; 27099651Sbenno 271191450Smarcel PIC_EOI(i->pic, i->intline); 272171805Smarcel} 27399651Sbenno 274171805Smarcelstatic void 275209724Snwhitehornpowerpc_intr_pre_ithread(void *arg) 276171805Smarcel{ 277191450Smarcel struct powerpc_intr *i = arg; 27899651Sbenno 279191450Smarcel PIC_MASK(i->pic, i->intline); 280209724Snwhitehorn PIC_EOI(i->pic, i->intline); 281171805Smarcel} 28299651Sbenno 283171805Smarcelstatic void 284209724Snwhitehornpowerpc_intr_post_ithread(void *arg) 285171805Smarcel{ 286191450Smarcel struct powerpc_intr *i = arg; 287164987Smarcel 288191450Smarcel PIC_UNMASK(i->pic, i->intline); 289171805Smarcel} 290125708Sgrehan 291209724Snwhitehornstatic int 292209724Snwhitehornpowerpc_assign_intr_cpu(void *arg, u_char cpu) 293209724Snwhitehorn{ 294209724Snwhitehorn#ifdef SMP 295209724Snwhitehorn struct powerpc_intr *i = arg; 296209724Snwhitehorn 297209724Snwhitehorn if (cpu == NOCPU) 298209724Snwhitehorn i->cpu = all_cpus; 299209724Snwhitehorn else 300222813Sattilio CPU_SETOF(cpu, &i->cpu); 301209724Snwhitehorn 302209724Snwhitehorn if (!cold && i->pic != NULL && i->pic == root_pic) 303209724Snwhitehorn PIC_BIND(i->pic, i->intline, i->cpu); 304209724Snwhitehorn 305209724Snwhitehorn return (0); 306209724Snwhitehorn#else 307209724Snwhitehorn return (EOPNOTSUPP); 308209724Snwhitehorn#endif 309209724Snwhitehorn} 310209724Snwhitehorn 311171805Smarcelvoid 312218075Smarcelpowerpc_register_pic(device_t dev, uint32_t node, u_int irqs, u_int ipis, 313218075Smarcel u_int atpic) 314171805Smarcel{ 315218075Smarcel struct pic *p; 316218075Smarcel u_int irq; 317218075Smarcel int idx; 318171805Smarcel 319209298Snwhitehorn mtx_lock(&intr_table_lock); 320209298Snwhitehorn 321218075Smarcel /* XXX see powerpc_get_irq(). */ 322218075Smarcel for (idx = 0; idx < npics; idx++) { 323218075Smarcel p = &piclist[idx]; 324218075Smarcel if (p->node != node) 325218075Smarcel continue; 326218075Smarcel if (node != 0 || p->dev == dev) 327209298Snwhitehorn break; 328209298Snwhitehorn } 329218075Smarcel p = &piclist[idx]; 330218075Smarcel 331218075Smarcel p->dev = dev; 332218075Smarcel p->node = node; 333218075Smarcel p->irqs = irqs; 334218075Smarcel p->ipis = ipis; 335218075Smarcel if (idx == npics) { 336218075Smarcel#ifdef DEV_ISA 337218075Smarcel p->base = (atpic) ? 0 : nirqs; 338218075Smarcel#else 339218075Smarcel p->base = nirqs; 340218075Smarcel#endif 341218075Smarcel irq = p->base + irqs + ipis; 342218075Smarcel nirqs = MAX(nirqs, irq); 343209298Snwhitehorn npics++; 344218075Smarcel } 345209298Snwhitehorn 346209298Snwhitehorn mtx_unlock(&intr_table_lock); 34799651Sbenno} 34899651Sbenno 349218075Smarcelu_int 350218075Smarcelpowerpc_get_irq(uint32_t node, u_int pin) 351191450Smarcel{ 352218075Smarcel int idx; 353191450Smarcel 354218075Smarcel if (node == 0) 355218075Smarcel return (pin); 356218075Smarcel 357209298Snwhitehorn mtx_lock(&intr_table_lock); 358218075Smarcel for (idx = 0; idx < npics; idx++) { 359218075Smarcel if (piclist[idx].node == node) { 360209298Snwhitehorn mtx_unlock(&intr_table_lock); 361218075Smarcel return (piclist[idx].base + pin); 362209298Snwhitehorn } 363209298Snwhitehorn } 364218075Smarcel 365218075Smarcel /* 366218075Smarcel * XXX we should never encounter an unregistered PIC, but that 367218075Smarcel * can only be done when we properly support bus enumeration 368218075Smarcel * using multiple passes. Until then, fake an entry and give it 369218075Smarcel * some adhoc maximum number of IRQs and IPIs. 370218075Smarcel */ 371218075Smarcel piclist[idx].dev = NULL; 372218075Smarcel piclist[idx].node = node; 373218075Smarcel piclist[idx].irqs = 124; 374218075Smarcel piclist[idx].ipis = 4; 375218075Smarcel piclist[idx].base = nirqs; 376218075Smarcel nirqs += 128; 377209298Snwhitehorn npics++; 378209298Snwhitehorn 379209298Snwhitehorn mtx_unlock(&intr_table_lock); 380209298Snwhitehorn 381218075Smarcel return (piclist[idx].base + pin); 382191450Smarcel} 383191450Smarcel 38499651Sbennoint 385171805Smarcelpowerpc_enable_intr(void) 38699651Sbenno{ 387171805Smarcel struct powerpc_intr *i; 388191450Smarcel int error, vector; 389209298Snwhitehorn#ifdef SMP 390209298Snwhitehorn int n; 391209298Snwhitehorn#endif 392171805Smarcel 393209298Snwhitehorn if (npics == 0) 394178628Smarcel panic("no PIC detected\n"); 395178628Smarcel 396218075Smarcel if (root_pic == NULL) 397218075Smarcel root_pic = piclist[0].dev; 398218075Smarcel 399178628Smarcel#ifdef SMP 400178628Smarcel /* Install an IPI handler. */ 401221738Snwhitehorn if (mp_ncpus > 1) { 402221738Snwhitehorn for (n = 0; n < npics; n++) { 403221738Snwhitehorn if (piclist[n].dev != root_pic) 404221738Snwhitehorn continue; 405209298Snwhitehorn 406221738Snwhitehorn KASSERT(piclist[n].ipis != 0, 407221738Snwhitehorn ("%s: SMP root PIC does not supply any IPIs", 408221738Snwhitehorn __func__)); 409221738Snwhitehorn error = powerpc_setup_intr("IPI", 410221738Snwhitehorn MAP_IRQ(piclist[n].node, piclist[n].irqs), 411221738Snwhitehorn powerpc_ipi_handler, NULL, NULL, 412221738Snwhitehorn INTR_TYPE_MISC | INTR_EXCL, &ipi_cookie); 413221738Snwhitehorn if (error) { 414221738Snwhitehorn printf("unable to setup IPI handler\n"); 415221738Snwhitehorn return (error); 416221738Snwhitehorn } 417209298Snwhitehorn } 418178628Smarcel } 419178628Smarcel#endif 420178628Smarcel 421171805Smarcel for (vector = 0; vector < nvectors; vector++) { 422171805Smarcel i = powerpc_intrs[vector]; 423171805Smarcel if (i == NULL) 424171805Smarcel continue; 425171805Smarcel 426191450Smarcel error = powerpc_map_irq(i); 427191450Smarcel if (error) 428191450Smarcel continue; 429191450Smarcel 430176918Smarcel if (i->trig != INTR_TRIGGER_CONFORM || 431176918Smarcel i->pol != INTR_POLARITY_CONFORM) 432191450Smarcel PIC_CONFIG(i->pic, i->intline, i->trig, i->pol); 433176918Smarcel 434176918Smarcel if (i->event != NULL) 435191450Smarcel PIC_ENABLE(i->pic, i->intline, vector); 436171805Smarcel } 437171805Smarcel 438171805Smarcel return (0); 439171805Smarcel} 440171805Smarcel 441171805Smarcelint 442209298Snwhitehornpowerpc_setup_intr(const char *name, u_int irq, driver_filter_t filter, 443171805Smarcel driver_intr_t handler, void *arg, enum intr_type flags, void **cookiep) 444171805Smarcel{ 445171805Smarcel struct powerpc_intr *i; 446187691Snwhitehorn int error, enable = 0; 44799651Sbenno 448176918Smarcel i = intr_lookup(irq); 449176918Smarcel if (i == NULL) 450176918Smarcel return (ENOMEM); 451164987Smarcel 452176918Smarcel if (i->event == NULL) { 453191450Smarcel error = intr_event_create(&i->event, (void *)i, 0, irq, 454209724Snwhitehorn powerpc_intr_pre_ithread, powerpc_intr_post_ithread, 455209724Snwhitehorn powerpc_intr_eoi, powerpc_assign_intr_cpu, "irq%u:", irq); 456176918Smarcel if (error) 45799651Sbenno return (error); 45899651Sbenno 459187691Snwhitehorn enable = 1; 46099651Sbenno } 46199651Sbenno 462166901Spiso error = intr_event_add_handler(i->event, name, filter, handler, arg, 463151658Sjhb intr_priority(flags), flags, cookiep); 464191307Sraj 465191307Sraj mtx_lock(&intr_table_lock); 466212453Smav intrcnt_setname(i->event->ie_fullname, i->cntindex); 467191307Sraj mtx_unlock(&intr_table_lock); 468187691Snwhitehorn 469191450Smarcel if (!cold) { 470191450Smarcel error = powerpc_map_irq(i); 471208835Snwhitehorn 472208835Snwhitehorn if (!error && (i->trig != INTR_TRIGGER_CONFORM || 473208835Snwhitehorn i->pol != INTR_POLARITY_CONFORM)) 474208835Snwhitehorn PIC_CONFIG(i->pic, i->intline, i->trig, i->pol); 475208835Snwhitehorn 476209486Snwhitehorn if (!error && i->pic == root_pic) 477209486Snwhitehorn PIC_BIND(i->pic, i->intline, i->cpu); 478209486Snwhitehorn 479191450Smarcel if (!error && enable) 480191450Smarcel PIC_ENABLE(i->pic, i->intline, i->vector); 481191450Smarcel } 482164987Smarcel return (error); 48399651Sbenno} 48499651Sbenno 48599651Sbennoint 486171805Smarcelpowerpc_teardown_intr(void *cookie) 48799651Sbenno{ 48899651Sbenno 489164987Smarcel return (intr_event_remove_handler(cookie)); 49099651Sbenno} 49199651Sbenno 492209486Snwhitehorn#ifdef SMP 493176918Smarcelint 494209486Snwhitehornpowerpc_bind_intr(u_int irq, u_char cpu) 495209486Snwhitehorn{ 496209486Snwhitehorn struct powerpc_intr *i; 497209486Snwhitehorn 498209486Snwhitehorn i = intr_lookup(irq); 499209486Snwhitehorn if (i == NULL) 500209486Snwhitehorn return (ENOMEM); 501209486Snwhitehorn 502209486Snwhitehorn return (intr_event_bind(i->event, cpu)); 503209486Snwhitehorn} 504209486Snwhitehorn#endif 505209486Snwhitehorn 506209486Snwhitehornint 507176918Smarcelpowerpc_config_intr(int irq, enum intr_trigger trig, enum intr_polarity pol) 508176918Smarcel{ 509176918Smarcel struct powerpc_intr *i; 510176918Smarcel 511176918Smarcel i = intr_lookup(irq); 512176918Smarcel if (i == NULL) 513176918Smarcel return (ENOMEM); 514176918Smarcel 515176918Smarcel i->trig = trig; 516176918Smarcel i->pol = pol; 517176918Smarcel 518208835Snwhitehorn if (!cold && i->pic != NULL) 519191450Smarcel PIC_CONFIG(i->pic, i->intline, trig, pol); 520176918Smarcel 521176918Smarcel return (0); 522176918Smarcel} 523176918Smarcel 52499651Sbennovoid 525171805Smarcelpowerpc_dispatch_intr(u_int vector, struct trapframe *tf) 52699651Sbenno{ 527171805Smarcel struct powerpc_intr *i; 528164987Smarcel struct intr_event *ie; 52999651Sbenno 530171805Smarcel i = powerpc_intrs[vector]; 531164987Smarcel if (i == NULL) 532164987Smarcel goto stray; 53399651Sbenno 534171805Smarcel (*i->cntp)++; 53599651Sbenno 536164987Smarcel ie = i->event; 537164987Smarcel KASSERT(ie != NULL, ("%s: interrupt without an event", __func__)); 53899651Sbenno 539171805Smarcel if (intr_event_handle(ie, tf) != 0) { 540164987Smarcel goto stray; 54199651Sbenno } 542164987Smarcel return; 54399651Sbenno 544164987Smarcelstray: 545171805Smarcel stray_count++; 546171805Smarcel if (stray_count <= MAX_STRAY_LOG) { 547177940Sjhb printf("stray irq %d\n", i ? i->irq : -1); 548171805Smarcel if (stray_count >= MAX_STRAY_LOG) { 549164987Smarcel printf("got %d stray interrupts, not logging anymore\n", 550171805Smarcel MAX_STRAY_LOG); 551164987Smarcel } 552164987Smarcel } 553171805Smarcel if (i != NULL) 554191450Smarcel PIC_MASK(i->pic, i->intline); 55599651Sbenno} 556