1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/init.h> 3 #include <linux/list.h> 4 #include <linux/io.h> 5 6 #include <asm/mach/irq.h> 7 #include <asm/hardware/iomd.h> 8 #include <asm/irq.h> 9 #include <asm/fiq.h> 10 11 static void iomd_ack_irq_a(struct irq_data *d) 12 { 13 unsigned int val, mask; 14 15 mask = 1 << d->irq; 16 val = iomd_readb(IOMD_IRQMASKA); 17 iomd_writeb(val & ~mask, IOMD_IRQMASKA); 18 iomd_writeb(mask, IOMD_IRQCLRA); 19 } 20 21 static void iomd_mask_irq_a(struct irq_data *d) 22 { 23 unsigned int val, mask; 24 25 mask = 1 << d->irq; 26 val = iomd_readb(IOMD_IRQMASKA); 27 iomd_writeb(val & ~mask, IOMD_IRQMASKA); 28 } 29 30 static void iomd_unmask_irq_a(struct irq_data *d) 31 { 32 unsigned int val, mask; 33 34 mask = 1 << d->irq; 35 val = iomd_readb(IOMD_IRQMASKA); 36 iomd_writeb(val | mask, IOMD_IRQMASKA); 37 } 38 39 static struct irq_chip iomd_a_chip = { 40 .irq_ack = iomd_ack_irq_a, 41 .irq_mask = iomd_mask_irq_a, 42 .irq_unmask = iomd_unmask_irq_a, 43 }; 44 45 static void iomd_mask_irq_b(struct irq_data *d) 46 { 47 unsigned int val, mask; 48 49 mask = 1 << (d->irq & 7); 50 val = iomd_readb(IOMD_IRQMASKB); 51 iomd_writeb(val & ~mask, IOMD_IRQMASKB); 52 } 53 54 static void iomd_unmask_irq_b(struct irq_data *d) 55 { 56 unsigned int val, mask; 57 58 mask = 1 << (d->irq & 7); 59 val = iomd_readb(IOMD_IRQMASKB); 60 iomd_writeb(val | mask, IOMD_IRQMASKB); 61 } 62 63 static struct irq_chip iomd_b_chip = { 64 .irq_ack = iomd_mask_irq_b, 65 .irq_mask = iomd_mask_irq_b, 66 .irq_unmask = iomd_unmask_irq_b, 67 }; 68 69 static void iomd_mask_irq_dma(struct irq_data *d) 70 { 71 unsigned int val, mask; 72 73 mask = 1 << (d->irq & 7); 74 val = iomd_readb(IOMD_DMAMASK); 75 iomd_writeb(val & ~mask, IOMD_DMAMASK); 76 } 77 78 static void iomd_unmask_irq_dma(struct irq_data *d) 79 { 80 unsigned int val, mask; 81 82 mask = 1 << (d->irq & 7); 83 val = iomd_readb(IOMD_DMAMASK); 84 iomd_writeb(val | mask, IOMD_DMAMASK); 85 } 86 87 static struct irq_chip iomd_dma_chip = { 88 .irq_ack = iomd_mask_irq_dma, 89 .irq_mask = iomd_mask_irq_dma, 90 .irq_unmask = iomd_unmask_irq_dma, 91 }; 92 93 static void iomd_mask_irq_fiq(struct irq_data *d) 94 { 95 unsigned int val, mask; 96 97 mask = 1 << (d->irq & 7); 98 val = iomd_readb(IOMD_FIQMASK); 99 iomd_writeb(val & ~mask, IOMD_FIQMASK); 100 } 101 102 static void iomd_unmask_irq_fiq(struct irq_data *d) 103 { 104 unsigned int val, mask; 105 106 mask = 1 << (d->irq & 7); 107 val = iomd_readb(IOMD_FIQMASK); 108 iomd_writeb(val | mask, IOMD_FIQMASK); 109 } 110 111 static struct irq_chip iomd_fiq_chip = { 112 .irq_ack = iomd_mask_irq_fiq, 113 .irq_mask = iomd_mask_irq_fiq, 114 .irq_unmask = iomd_unmask_irq_fiq, 115 }; 116 117 extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end; 118 119 void __init rpc_init_irq(void) 120 { 121 unsigned int irq, clr, set = 0; 122 123 iomd_writeb(0, IOMD_IRQMASKA); 124 iomd_writeb(0, IOMD_IRQMASKB); 125 iomd_writeb(0, IOMD_FIQMASK); 126 iomd_writeb(0, IOMD_DMAMASK); 127 128 set_fiq_handler(&rpc_default_fiq_start, 129 &rpc_default_fiq_end - &rpc_default_fiq_start); 130 131 for (irq = 0; irq < NR_IRQS; irq++) { 132 clr = IRQ_NOREQUEST; 133 134 if (irq <= 6 || (irq >= 9 && irq <= 15)) 135 clr |= IRQ_NOPROBE; 136 137 if (irq == 21 || (irq >= 16 && irq <= 19) || 138 irq == IRQ_KEYBOARDTX) 139 set |= IRQ_NOAUTOEN; 140 141 switch (irq) { 142 case 0 ... 7: 143 irq_set_chip_and_handler(irq, &iomd_a_chip, 144 handle_level_irq); 145 irq_modify_status(irq, clr, set); 146 break; 147 148 case 8 ... 15: 149 irq_set_chip_and_handler(irq, &iomd_b_chip, 150 handle_level_irq); 151 irq_modify_status(irq, clr, set); 152 break; 153 154 case 16 ... 21: 155 irq_set_chip_and_handler(irq, &iomd_dma_chip, 156 handle_level_irq); 157 irq_modify_status(irq, clr, set); 158 break; 159 160 case 64 ... 71: 161 irq_set_chip(irq, &iomd_fiq_chip); 162 irq_modify_status(irq, clr, set); 163 break; 164 } 165 } 166 167 init_FIQ(FIQ_START); 168 } 169 170