~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm/mach-rpc/irq.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 // These are offsets from the stat register for each IRQ bank
 12 #define STAT    0x00
 13 #define REQ     0x04
 14 #define CLR     0x04
 15 #define MASK    0x08
 16 
 17 static const u8 irq_prio_h[256] = {
 18          0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10,
 19         12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10,
 20         13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
 21         13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
 22         14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10,
 23         14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10,
 24         13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
 25         13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
 26         15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
 27         15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
 28         13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
 29         13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
 30         15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
 31         15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
 32         13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
 33         13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
 34 };
 35 
 36 static const u8 irq_prio_d[256] = {
 37          0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 38         20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 39         21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 40         21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 41         22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 42         22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 43         21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 44         21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 45         23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 46         23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 47         21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 48         21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 49         22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 50         22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 51         21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 52         21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 53 };
 54 
 55 static const u8 irq_prio_l[256] = {
 56          0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
 57          4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
 58          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
 59          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
 60          6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3,
 61          6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3,
 62          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
 63          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
 64          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 65          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 66          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 67          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 68          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 69          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 70          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 71          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 72 };
 73 
 74 static int iomd_get_irq_nr(void)
 75 {
 76         int irq;
 77         u8 reg;
 78 
 79         /* get highest priority first */
 80         reg = readb(IOC_BASE + IOMD_IRQREQB);
 81         irq = irq_prio_h[reg];
 82         if (irq)
 83                 return irq;
 84 
 85         /* get DMA  */
 86         reg = readb(IOC_BASE + IOMD_DMAREQ);
 87         irq = irq_prio_d[reg];
 88         if (irq)
 89                 return irq;
 90 
 91         /* get low priority */
 92         reg = readb(IOC_BASE + IOMD_IRQREQA);
 93         irq = irq_prio_l[reg];
 94         if (irq)
 95                 return irq;
 96         return 0;
 97 }
 98 
 99 static void iomd_handle_irq(struct pt_regs *regs)
100 {
101         int irq;
102 
103         do {
104                 irq = iomd_get_irq_nr();
105                 if (irq)
106                         generic_handle_irq(irq);
107         } while (irq);
108 }
109 
110 static void __iomem *iomd_get_base(struct irq_data *d)
111 {
112         void *cd = irq_data_get_irq_chip_data(d);
113 
114         return (void __iomem *)(unsigned long)cd;
115 }
116 
117 static void iomd_set_base_mask(unsigned int irq, void __iomem *base, u32 mask)
118 {
119         struct irq_data *d = irq_get_irq_data(irq);
120 
121         d->mask = mask;
122         irq_set_chip_data(irq, (void *)(unsigned long)base);
123 }
124 
125 static void iomd_irq_mask_ack(struct irq_data *d)
126 {
127         void __iomem *base = iomd_get_base(d);
128         unsigned int val, mask = d->mask;
129 
130         val = readb(base + MASK);
131         writeb(val & ~mask, base + MASK);
132         writeb(mask, base + CLR);
133 }
134 
135 static void iomd_irq_mask(struct irq_data *d)
136 {
137         void __iomem *base = iomd_get_base(d);
138         unsigned int val, mask = d->mask;
139 
140         val = readb(base + MASK);
141         writeb(val & ~mask, base + MASK);
142 }
143 
144 static void iomd_irq_unmask(struct irq_data *d)
145 {
146         void __iomem *base = iomd_get_base(d);
147         unsigned int val, mask = d->mask;
148 
149         val = readb(base + MASK);
150         writeb(val | mask, base + MASK);
151 }
152 
153 static struct irq_chip iomd_chip_clr = {
154         .irq_mask_ack   = iomd_irq_mask_ack,
155         .irq_mask       = iomd_irq_mask,
156         .irq_unmask     = iomd_irq_unmask,
157 };
158 
159 static struct irq_chip iomd_chip_noclr = {
160         .irq_mask       = iomd_irq_mask,
161         .irq_unmask     = iomd_irq_unmask,
162 };
163 
164 extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end;
165 
166 void __init rpc_init_irq(void)
167 {
168         unsigned int irq, clr, set;
169 
170         iomd_writeb(0, IOMD_IRQMASKA);
171         iomd_writeb(0, IOMD_IRQMASKB);
172         iomd_writeb(0, IOMD_FIQMASK);
173         iomd_writeb(0, IOMD_DMAMASK);
174 
175         set_fiq_handler(&rpc_default_fiq_start,
176                 &rpc_default_fiq_end - &rpc_default_fiq_start);
177 
178         set_handle_irq(iomd_handle_irq);
179 
180         for (irq = 0; irq < NR_IRQS; irq++) {
181                 clr = IRQ_NOREQUEST;
182                 set = 0;
183 
184                 if (irq <= 6 || (irq >= 9 && irq <= 15))
185                         clr |= IRQ_NOPROBE;
186 
187                 if (irq == 21 || (irq >= 16 && irq <= 19) ||
188                     irq == IRQ_KEYBOARDTX)
189                         set |= IRQ_NOAUTOEN;
190 
191                 switch (irq) {
192                 case 0 ... 7:
193                         irq_set_chip_and_handler(irq, &iomd_chip_clr,
194                                                  handle_level_irq);
195                         irq_modify_status(irq, clr, set);
196                         iomd_set_base_mask(irq, IOMD_BASE + IOMD_IRQSTATA,
197                                            BIT(irq));
198                         break;
199 
200                 case 8 ... 15:
201                         irq_set_chip_and_handler(irq, &iomd_chip_noclr,
202                                                  handle_level_irq);
203                         irq_modify_status(irq, clr, set);
204                         iomd_set_base_mask(irq, IOMD_BASE + IOMD_IRQSTATB,
205                                            BIT(irq - 8));
206                         break;
207 
208                 case 16 ... 21:
209                         irq_set_chip_and_handler(irq, &iomd_chip_noclr,
210                                                  handle_level_irq);
211                         irq_modify_status(irq, clr, set);
212                         iomd_set_base_mask(irq, IOMD_BASE + IOMD_DMASTAT,
213                                            BIT(irq - 16));
214                         break;
215 
216                 case 64 ... 71:
217                         irq_set_chip(irq, &iomd_chip_noclr);
218                         irq_modify_status(irq, clr, set);
219                         iomd_set_base_mask(irq, IOMD_BASE + IOMD_FIQSTAT,
220                                            BIT(irq - 64));
221                         break;
222                 }
223         }
224 
225         init_FIQ(FIQ_START);
226 }
227 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php