• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
iomd_ack_irq_a(struct irq_data * d)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 
iomd_mask_irq_a(struct irq_data * d)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 
iomd_unmask_irq_a(struct irq_data * d)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 
iomd_mask_irq_b(struct irq_data * d)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 
iomd_unmask_irq_b(struct irq_data * d)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 
iomd_mask_irq_dma(struct irq_data * d)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 
iomd_unmask_irq_dma(struct irq_data * d)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 
iomd_mask_irq_fiq(struct irq_data * d)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 
iomd_unmask_irq_fiq(struct irq_data * d)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 
rpc_init_irq(void)119 void __init rpc_init_irq(void)
120 {
121 	unsigned int irq, clr, set;
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 		set = 0;
134 
135 		if (irq <= 6 || (irq >= 9 && irq <= 15))
136 			clr |= IRQ_NOPROBE;
137 
138 		if (irq == 21 || (irq >= 16 && irq <= 19) ||
139 		    irq == IRQ_KEYBOARDTX)
140 			set |= IRQ_NOAUTOEN;
141 
142 		switch (irq) {
143 		case 0 ... 7:
144 			irq_set_chip_and_handler(irq, &iomd_a_chip,
145 						 handle_level_irq);
146 			irq_modify_status(irq, clr, set);
147 			break;
148 
149 		case 8 ... 15:
150 			irq_set_chip_and_handler(irq, &iomd_b_chip,
151 						 handle_level_irq);
152 			irq_modify_status(irq, clr, set);
153 			break;
154 
155 		case 16 ... 21:
156 			irq_set_chip_and_handler(irq, &iomd_dma_chip,
157 						 handle_level_irq);
158 			irq_modify_status(irq, clr, set);
159 			break;
160 
161 		case 64 ... 71:
162 			irq_set_chip(irq, &iomd_fiq_chip);
163 			irq_modify_status(irq, clr, set);
164 			break;
165 		}
166 	}
167 
168 	init_FIQ(FIQ_START);
169 }
170 
171