1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 21da177e4SLinus Torvalds #include <linux/init.h> 31da177e4SLinus Torvalds #include <linux/list.h> 4fced80c7SRussell King #include <linux/io.h> 51da177e4SLinus Torvalds 61da177e4SLinus Torvalds #include <asm/mach/irq.h> 71da177e4SLinus Torvalds #include <asm/hardware/iomd.h> 81da177e4SLinus Torvalds #include <asm/irq.h> 978cbaacaSRob Herring #include <asm/fiq.h> 101da177e4SLinus Torvalds 119a364da7SLennert Buytenhek static void iomd_ack_irq_a(struct irq_data *d) 121da177e4SLinus Torvalds { 131da177e4SLinus Torvalds unsigned int val, mask; 141da177e4SLinus Torvalds 159a364da7SLennert Buytenhek mask = 1 << d->irq; 161da177e4SLinus Torvalds val = iomd_readb(IOMD_IRQMASKA); 171da177e4SLinus Torvalds iomd_writeb(val & ~mask, IOMD_IRQMASKA); 181da177e4SLinus Torvalds iomd_writeb(mask, IOMD_IRQCLRA); 191da177e4SLinus Torvalds } 201da177e4SLinus Torvalds 219a364da7SLennert Buytenhek static void iomd_mask_irq_a(struct irq_data *d) 221da177e4SLinus Torvalds { 231da177e4SLinus Torvalds unsigned int val, mask; 241da177e4SLinus Torvalds 259a364da7SLennert Buytenhek mask = 1 << d->irq; 261da177e4SLinus Torvalds val = iomd_readb(IOMD_IRQMASKA); 271da177e4SLinus Torvalds iomd_writeb(val & ~mask, IOMD_IRQMASKA); 281da177e4SLinus Torvalds } 291da177e4SLinus Torvalds 309a364da7SLennert Buytenhek static void iomd_unmask_irq_a(struct irq_data *d) 311da177e4SLinus Torvalds { 321da177e4SLinus Torvalds unsigned int val, mask; 331da177e4SLinus Torvalds 349a364da7SLennert Buytenhek mask = 1 << d->irq; 351da177e4SLinus Torvalds val = iomd_readb(IOMD_IRQMASKA); 361da177e4SLinus Torvalds iomd_writeb(val | mask, IOMD_IRQMASKA); 371da177e4SLinus Torvalds } 381da177e4SLinus Torvalds 3910dd5ce2SRussell King static struct irq_chip iomd_a_chip = { 409a364da7SLennert Buytenhek .irq_ack = iomd_ack_irq_a, 419a364da7SLennert Buytenhek .irq_mask = iomd_mask_irq_a, 429a364da7SLennert Buytenhek .irq_unmask = iomd_unmask_irq_a, 431da177e4SLinus Torvalds }; 441da177e4SLinus Torvalds 459a364da7SLennert Buytenhek static void iomd_mask_irq_b(struct irq_data *d) 461da177e4SLinus Torvalds { 471da177e4SLinus Torvalds unsigned int val, mask; 481da177e4SLinus Torvalds 499a364da7SLennert Buytenhek mask = 1 << (d->irq & 7); 501da177e4SLinus Torvalds val = iomd_readb(IOMD_IRQMASKB); 511da177e4SLinus Torvalds iomd_writeb(val & ~mask, IOMD_IRQMASKB); 521da177e4SLinus Torvalds } 531da177e4SLinus Torvalds 549a364da7SLennert Buytenhek static void iomd_unmask_irq_b(struct irq_data *d) 551da177e4SLinus Torvalds { 561da177e4SLinus Torvalds unsigned int val, mask; 571da177e4SLinus Torvalds 589a364da7SLennert Buytenhek mask = 1 << (d->irq & 7); 591da177e4SLinus Torvalds val = iomd_readb(IOMD_IRQMASKB); 601da177e4SLinus Torvalds iomd_writeb(val | mask, IOMD_IRQMASKB); 611da177e4SLinus Torvalds } 621da177e4SLinus Torvalds 6310dd5ce2SRussell King static struct irq_chip iomd_b_chip = { 649a364da7SLennert Buytenhek .irq_ack = iomd_mask_irq_b, 659a364da7SLennert Buytenhek .irq_mask = iomd_mask_irq_b, 669a364da7SLennert Buytenhek .irq_unmask = iomd_unmask_irq_b, 671da177e4SLinus Torvalds }; 681da177e4SLinus Torvalds 699a364da7SLennert Buytenhek static void iomd_mask_irq_dma(struct irq_data *d) 701da177e4SLinus Torvalds { 711da177e4SLinus Torvalds unsigned int val, mask; 721da177e4SLinus Torvalds 739a364da7SLennert Buytenhek mask = 1 << (d->irq & 7); 741da177e4SLinus Torvalds val = iomd_readb(IOMD_DMAMASK); 751da177e4SLinus Torvalds iomd_writeb(val & ~mask, IOMD_DMAMASK); 761da177e4SLinus Torvalds } 771da177e4SLinus Torvalds 789a364da7SLennert Buytenhek static void iomd_unmask_irq_dma(struct irq_data *d) 791da177e4SLinus Torvalds { 801da177e4SLinus Torvalds unsigned int val, mask; 811da177e4SLinus Torvalds 829a364da7SLennert Buytenhek mask = 1 << (d->irq & 7); 831da177e4SLinus Torvalds val = iomd_readb(IOMD_DMAMASK); 841da177e4SLinus Torvalds iomd_writeb(val | mask, IOMD_DMAMASK); 851da177e4SLinus Torvalds } 861da177e4SLinus Torvalds 8710dd5ce2SRussell King static struct irq_chip iomd_dma_chip = { 889a364da7SLennert Buytenhek .irq_ack = iomd_mask_irq_dma, 899a364da7SLennert Buytenhek .irq_mask = iomd_mask_irq_dma, 909a364da7SLennert Buytenhek .irq_unmask = iomd_unmask_irq_dma, 911da177e4SLinus Torvalds }; 921da177e4SLinus Torvalds 939a364da7SLennert Buytenhek static void iomd_mask_irq_fiq(struct irq_data *d) 941da177e4SLinus Torvalds { 951da177e4SLinus Torvalds unsigned int val, mask; 961da177e4SLinus Torvalds 979a364da7SLennert Buytenhek mask = 1 << (d->irq & 7); 981da177e4SLinus Torvalds val = iomd_readb(IOMD_FIQMASK); 991da177e4SLinus Torvalds iomd_writeb(val & ~mask, IOMD_FIQMASK); 1001da177e4SLinus Torvalds } 1011da177e4SLinus Torvalds 1029a364da7SLennert Buytenhek static void iomd_unmask_irq_fiq(struct irq_data *d) 1031da177e4SLinus Torvalds { 1041da177e4SLinus Torvalds unsigned int val, mask; 1051da177e4SLinus Torvalds 1069a364da7SLennert Buytenhek mask = 1 << (d->irq & 7); 1071da177e4SLinus Torvalds val = iomd_readb(IOMD_FIQMASK); 1081da177e4SLinus Torvalds iomd_writeb(val | mask, IOMD_FIQMASK); 1091da177e4SLinus Torvalds } 1101da177e4SLinus Torvalds 11110dd5ce2SRussell King static struct irq_chip iomd_fiq_chip = { 1129a364da7SLennert Buytenhek .irq_ack = iomd_mask_irq_fiq, 1139a364da7SLennert Buytenhek .irq_mask = iomd_mask_irq_fiq, 1149a364da7SLennert Buytenhek .irq_unmask = iomd_unmask_irq_fiq, 1151da177e4SLinus Torvalds }; 1161da177e4SLinus Torvalds 11778cbaacaSRob Herring extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end; 11878cbaacaSRob Herring 1191da177e4SLinus Torvalds void __init rpc_init_irq(void) 1201da177e4SLinus Torvalds { 12163a0666bSRussell King unsigned int irq, clr, set; 1221da177e4SLinus Torvalds 1231da177e4SLinus Torvalds iomd_writeb(0, IOMD_IRQMASKA); 1241da177e4SLinus Torvalds iomd_writeb(0, IOMD_IRQMASKB); 1251da177e4SLinus Torvalds iomd_writeb(0, IOMD_FIQMASK); 1261da177e4SLinus Torvalds iomd_writeb(0, IOMD_DMAMASK); 1271da177e4SLinus Torvalds 12878cbaacaSRob Herring set_fiq_handler(&rpc_default_fiq_start, 12978cbaacaSRob Herring &rpc_default_fiq_end - &rpc_default_fiq_start); 13078cbaacaSRob Herring 1311da177e4SLinus Torvalds for (irq = 0; irq < NR_IRQS; irq++) { 132e8d36d5dSRob Herring clr = IRQ_NOREQUEST; 13363a0666bSRussell King set = 0; 1341da177e4SLinus Torvalds 1351da177e4SLinus Torvalds if (irq <= 6 || (irq >= 9 && irq <= 15)) 136e8d36d5dSRob Herring clr |= IRQ_NOPROBE; 1371da177e4SLinus Torvalds 1381da177e4SLinus Torvalds if (irq == 21 || (irq >= 16 && irq <= 19) || 1391da177e4SLinus Torvalds irq == IRQ_KEYBOARDTX) 140e8d36d5dSRob Herring set |= IRQ_NOAUTOEN; 1411da177e4SLinus Torvalds 1421da177e4SLinus Torvalds switch (irq) { 1431da177e4SLinus Torvalds case 0 ... 7: 144f38c02f3SThomas Gleixner irq_set_chip_and_handler(irq, &iomd_a_chip, 145f38c02f3SThomas Gleixner handle_level_irq); 146e8d36d5dSRob Herring irq_modify_status(irq, clr, set); 1471da177e4SLinus Torvalds break; 1481da177e4SLinus Torvalds 1491da177e4SLinus Torvalds case 8 ... 15: 150f38c02f3SThomas Gleixner irq_set_chip_and_handler(irq, &iomd_b_chip, 151f38c02f3SThomas Gleixner handle_level_irq); 152e8d36d5dSRob Herring irq_modify_status(irq, clr, set); 1531da177e4SLinus Torvalds break; 1541da177e4SLinus Torvalds 1551da177e4SLinus Torvalds case 16 ... 21: 156f38c02f3SThomas Gleixner irq_set_chip_and_handler(irq, &iomd_dma_chip, 157f38c02f3SThomas Gleixner handle_level_irq); 158e8d36d5dSRob Herring irq_modify_status(irq, clr, set); 1591da177e4SLinus Torvalds break; 1601da177e4SLinus Torvalds 1611da177e4SLinus Torvalds case 64 ... 71: 1626845664aSThomas Gleixner irq_set_chip(irq, &iomd_fiq_chip); 163e8d36d5dSRob Herring irq_modify_status(irq, clr, set); 1641da177e4SLinus Torvalds break; 1651da177e4SLinus Torvalds } 1661da177e4SLinus Torvalds } 1671da177e4SLinus Torvalds 168bc89663aSShawn Guo init_FIQ(FIQ_START); 1691da177e4SLinus Torvalds } 1701da177e4SLinus Torvalds 171