11da177e4SLinus Torvalds #include <linux/init.h> 21da177e4SLinus Torvalds #include <linux/list.h> 3fced80c7SRussell King #include <linux/io.h> 41da177e4SLinus Torvalds 51da177e4SLinus Torvalds #include <asm/mach/irq.h> 61da177e4SLinus Torvalds #include <asm/hardware/iomd.h> 71da177e4SLinus Torvalds #include <asm/irq.h> 81da177e4SLinus Torvalds 99a364da7SLennert Buytenhek static void iomd_ack_irq_a(struct irq_data *d) 101da177e4SLinus Torvalds { 111da177e4SLinus Torvalds unsigned int val, mask; 121da177e4SLinus Torvalds 139a364da7SLennert Buytenhek mask = 1 << d->irq; 141da177e4SLinus Torvalds val = iomd_readb(IOMD_IRQMASKA); 151da177e4SLinus Torvalds iomd_writeb(val & ~mask, IOMD_IRQMASKA); 161da177e4SLinus Torvalds iomd_writeb(mask, IOMD_IRQCLRA); 171da177e4SLinus Torvalds } 181da177e4SLinus Torvalds 199a364da7SLennert Buytenhek static void iomd_mask_irq_a(struct irq_data *d) 201da177e4SLinus Torvalds { 211da177e4SLinus Torvalds unsigned int val, mask; 221da177e4SLinus Torvalds 239a364da7SLennert Buytenhek mask = 1 << d->irq; 241da177e4SLinus Torvalds val = iomd_readb(IOMD_IRQMASKA); 251da177e4SLinus Torvalds iomd_writeb(val & ~mask, IOMD_IRQMASKA); 261da177e4SLinus Torvalds } 271da177e4SLinus Torvalds 289a364da7SLennert Buytenhek static void iomd_unmask_irq_a(struct irq_data *d) 291da177e4SLinus Torvalds { 301da177e4SLinus Torvalds unsigned int val, mask; 311da177e4SLinus Torvalds 329a364da7SLennert Buytenhek mask = 1 << d->irq; 331da177e4SLinus Torvalds val = iomd_readb(IOMD_IRQMASKA); 341da177e4SLinus Torvalds iomd_writeb(val | mask, IOMD_IRQMASKA); 351da177e4SLinus Torvalds } 361da177e4SLinus Torvalds 3710dd5ce2SRussell King static struct irq_chip iomd_a_chip = { 389a364da7SLennert Buytenhek .irq_ack = iomd_ack_irq_a, 399a364da7SLennert Buytenhek .irq_mask = iomd_mask_irq_a, 409a364da7SLennert Buytenhek .irq_unmask = iomd_unmask_irq_a, 411da177e4SLinus Torvalds }; 421da177e4SLinus Torvalds 439a364da7SLennert Buytenhek static void iomd_mask_irq_b(struct irq_data *d) 441da177e4SLinus Torvalds { 451da177e4SLinus Torvalds unsigned int val, mask; 461da177e4SLinus Torvalds 479a364da7SLennert Buytenhek mask = 1 << (d->irq & 7); 481da177e4SLinus Torvalds val = iomd_readb(IOMD_IRQMASKB); 491da177e4SLinus Torvalds iomd_writeb(val & ~mask, IOMD_IRQMASKB); 501da177e4SLinus Torvalds } 511da177e4SLinus Torvalds 529a364da7SLennert Buytenhek static void iomd_unmask_irq_b(struct irq_data *d) 531da177e4SLinus Torvalds { 541da177e4SLinus Torvalds unsigned int val, mask; 551da177e4SLinus Torvalds 569a364da7SLennert Buytenhek mask = 1 << (d->irq & 7); 571da177e4SLinus Torvalds val = iomd_readb(IOMD_IRQMASKB); 581da177e4SLinus Torvalds iomd_writeb(val | mask, IOMD_IRQMASKB); 591da177e4SLinus Torvalds } 601da177e4SLinus Torvalds 6110dd5ce2SRussell King static struct irq_chip iomd_b_chip = { 629a364da7SLennert Buytenhek .irq_ack = iomd_mask_irq_b, 639a364da7SLennert Buytenhek .irq_mask = iomd_mask_irq_b, 649a364da7SLennert Buytenhek .irq_unmask = iomd_unmask_irq_b, 651da177e4SLinus Torvalds }; 661da177e4SLinus Torvalds 679a364da7SLennert Buytenhek static void iomd_mask_irq_dma(struct irq_data *d) 681da177e4SLinus Torvalds { 691da177e4SLinus Torvalds unsigned int val, mask; 701da177e4SLinus Torvalds 719a364da7SLennert Buytenhek mask = 1 << (d->irq & 7); 721da177e4SLinus Torvalds val = iomd_readb(IOMD_DMAMASK); 731da177e4SLinus Torvalds iomd_writeb(val & ~mask, IOMD_DMAMASK); 741da177e4SLinus Torvalds } 751da177e4SLinus Torvalds 769a364da7SLennert Buytenhek static void iomd_unmask_irq_dma(struct irq_data *d) 771da177e4SLinus Torvalds { 781da177e4SLinus Torvalds unsigned int val, mask; 791da177e4SLinus Torvalds 809a364da7SLennert Buytenhek mask = 1 << (d->irq & 7); 811da177e4SLinus Torvalds val = iomd_readb(IOMD_DMAMASK); 821da177e4SLinus Torvalds iomd_writeb(val | mask, IOMD_DMAMASK); 831da177e4SLinus Torvalds } 841da177e4SLinus Torvalds 8510dd5ce2SRussell King static struct irq_chip iomd_dma_chip = { 869a364da7SLennert Buytenhek .irq_ack = iomd_mask_irq_dma, 879a364da7SLennert Buytenhek .irq_mask = iomd_mask_irq_dma, 889a364da7SLennert Buytenhek .irq_unmask = iomd_unmask_irq_dma, 891da177e4SLinus Torvalds }; 901da177e4SLinus Torvalds 919a364da7SLennert Buytenhek static void iomd_mask_irq_fiq(struct irq_data *d) 921da177e4SLinus Torvalds { 931da177e4SLinus Torvalds unsigned int val, mask; 941da177e4SLinus Torvalds 959a364da7SLennert Buytenhek mask = 1 << (d->irq & 7); 961da177e4SLinus Torvalds val = iomd_readb(IOMD_FIQMASK); 971da177e4SLinus Torvalds iomd_writeb(val & ~mask, IOMD_FIQMASK); 981da177e4SLinus Torvalds } 991da177e4SLinus Torvalds 1009a364da7SLennert Buytenhek static void iomd_unmask_irq_fiq(struct irq_data *d) 1011da177e4SLinus Torvalds { 1021da177e4SLinus Torvalds unsigned int val, mask; 1031da177e4SLinus Torvalds 1049a364da7SLennert Buytenhek mask = 1 << (d->irq & 7); 1051da177e4SLinus Torvalds val = iomd_readb(IOMD_FIQMASK); 1061da177e4SLinus Torvalds iomd_writeb(val | mask, IOMD_FIQMASK); 1071da177e4SLinus Torvalds } 1081da177e4SLinus Torvalds 10910dd5ce2SRussell King static struct irq_chip iomd_fiq_chip = { 1109a364da7SLennert Buytenhek .irq_ack = iomd_mask_irq_fiq, 1119a364da7SLennert Buytenhek .irq_mask = iomd_mask_irq_fiq, 1129a364da7SLennert Buytenhek .irq_unmask = iomd_unmask_irq_fiq, 1131da177e4SLinus Torvalds }; 1141da177e4SLinus Torvalds 1151da177e4SLinus Torvalds void __init rpc_init_irq(void) 1161da177e4SLinus Torvalds { 1171da177e4SLinus Torvalds unsigned int irq, flags; 1181da177e4SLinus Torvalds 1191da177e4SLinus Torvalds iomd_writeb(0, IOMD_IRQMASKA); 1201da177e4SLinus Torvalds iomd_writeb(0, IOMD_IRQMASKB); 1211da177e4SLinus Torvalds iomd_writeb(0, IOMD_FIQMASK); 1221da177e4SLinus Torvalds iomd_writeb(0, IOMD_DMAMASK); 1231da177e4SLinus Torvalds 1241da177e4SLinus Torvalds for (irq = 0; irq < NR_IRQS; irq++) { 1251da177e4SLinus Torvalds flags = IRQF_VALID; 1261da177e4SLinus Torvalds 1271da177e4SLinus Torvalds if (irq <= 6 || (irq >= 9 && irq <= 15)) 1281da177e4SLinus Torvalds flags |= IRQF_PROBE; 1291da177e4SLinus Torvalds 1301da177e4SLinus Torvalds if (irq == 21 || (irq >= 16 && irq <= 19) || 1311da177e4SLinus Torvalds irq == IRQ_KEYBOARDTX) 1321da177e4SLinus Torvalds flags |= IRQF_NOAUTOEN; 1331da177e4SLinus Torvalds 1341da177e4SLinus Torvalds switch (irq) { 1351da177e4SLinus Torvalds case 0 ... 7: 1366845664aSThomas Gleixner irq_set_chip(irq, &iomd_a_chip); 1376845664aSThomas Gleixner irq_set_handler(irq, handle_level_irq); 1381da177e4SLinus Torvalds set_irq_flags(irq, flags); 1391da177e4SLinus Torvalds break; 1401da177e4SLinus Torvalds 1411da177e4SLinus Torvalds case 8 ... 15: 1426845664aSThomas Gleixner irq_set_chip(irq, &iomd_b_chip); 1436845664aSThomas Gleixner irq_set_handler(irq, handle_level_irq); 1441da177e4SLinus Torvalds set_irq_flags(irq, flags); 1451da177e4SLinus Torvalds break; 1461da177e4SLinus Torvalds 1471da177e4SLinus Torvalds case 16 ... 21: 1486845664aSThomas Gleixner irq_set_chip(irq, &iomd_dma_chip); 1496845664aSThomas Gleixner irq_set_handler(irq, handle_level_irq); 1501da177e4SLinus Torvalds set_irq_flags(irq, flags); 1511da177e4SLinus Torvalds break; 1521da177e4SLinus Torvalds 1531da177e4SLinus Torvalds case 64 ... 71: 1546845664aSThomas Gleixner irq_set_chip(irq, &iomd_fiq_chip); 1551da177e4SLinus Torvalds set_irq_flags(irq, IRQF_VALID); 1561da177e4SLinus Torvalds break; 1571da177e4SLinus Torvalds } 1581da177e4SLinus Torvalds } 1591da177e4SLinus Torvalds 1601da177e4SLinus Torvalds init_FIQ(); 1611da177e4SLinus Torvalds } 1621da177e4SLinus Torvalds 163