105 #include <asm/prom.h>
109 #define MPC52xx_IRQ_L1_CRIT (0)
110 #define MPC52xx_IRQ_L1_MAIN (1)
111 #define MPC52xx_IRQ_L1_PERP (2)
112 #define MPC52xx_IRQ_L1_SDMA (3)
114 #define MPC52xx_IRQ_L1_OFFSET (6)
115 #define MPC52xx_IRQ_L1_MASK (0x00c0)
116 #define MPC52xx_IRQ_L2_MASK (0x003f)
118 #define MPC52xx_IRQ_HIGHTESTHWIRQ (0xd0)
123 { .compatible =
"fsl,mpc5200-pic", },
124 { .compatible =
"mpc5200-pic", },
127 static struct of_device_id mpc52xx_sdma_ids[] __initdata = {
129 { .compatible =
"mpc5200-bestcomm", },
137 static unsigned char mpc52xx_map_senses[4] = {
150 static inline void io_be_clrbit(
u32 __iomem *addr,
int bitno)
158 static void mpc52xx_extirq_mask(
struct irq_data *
d)
161 io_be_clrbit(&intr->
ctrl, 11 - l2irq);
164 static void mpc52xx_extirq_unmask(
struct irq_data *
d)
167 io_be_setbit(&intr->
ctrl, 11 - l2irq);
170 static void mpc52xx_extirq_ack(
struct irq_data *
d)
173 io_be_setbit(&intr->
ctrl, 27-l2irq);
176 static int mpc52xx_extirq_set_type(
struct irq_data *
d,
unsigned int flow_type)
182 pr_debug(
"%s: irq=%x. l2=%d flow_type=%d\n", __func__,
183 (
int) irqd_to_hwirq(d), l2irq, flow_type);
195 ctrl_reg &= ~(0x3 << (22 - (l2irq * 2)));
196 ctrl_reg |= (type << (22 - (l2irq * 2)));
199 __irq_set_handler_locked(d->
irq, handler);
204 static struct irq_chip mpc52xx_extirq_irqchip = {
205 .name =
"MPC52xx External",
206 .irq_mask = mpc52xx_extirq_mask,
207 .irq_unmask = mpc52xx_extirq_unmask,
208 .irq_ack = mpc52xx_extirq_ack,
209 .irq_set_type = mpc52xx_extirq_set_type,
215 static int mpc52xx_null_set_type(
struct irq_data *d,
unsigned int flow_type)
220 static void mpc52xx_main_mask(
struct irq_data *d)
223 io_be_setbit(&intr->
main_mask, 16 - l2irq);
226 static void mpc52xx_main_unmask(
struct irq_data *d)
229 io_be_clrbit(&intr->
main_mask, 16 - l2irq);
232 static struct irq_chip mpc52xx_main_irqchip = {
233 .name =
"MPC52xx Main",
234 .irq_mask = mpc52xx_main_mask,
235 .irq_mask_ack = mpc52xx_main_mask,
236 .irq_unmask = mpc52xx_main_unmask,
237 .irq_set_type = mpc52xx_null_set_type,
243 static void mpc52xx_periph_mask(
struct irq_data *d)
246 io_be_setbit(&intr->
per_mask, 31 - l2irq);
249 static void mpc52xx_periph_unmask(
struct irq_data *d)
252 io_be_clrbit(&intr->
per_mask, 31 - l2irq);
255 static struct irq_chip mpc52xx_periph_irqchip = {
256 .name =
"MPC52xx Peripherals",
257 .irq_mask = mpc52xx_periph_mask,
258 .irq_mask_ack = mpc52xx_periph_mask,
259 .irq_unmask = mpc52xx_periph_unmask,
260 .irq_set_type = mpc52xx_null_set_type,
266 static void mpc52xx_sdma_mask(
struct irq_data *d)
269 io_be_setbit(&sdma->
IntMask, l2irq);
272 static void mpc52xx_sdma_unmask(
struct irq_data *d)
275 io_be_clrbit(&sdma->
IntMask, l2irq);
278 static void mpc52xx_sdma_ack(
struct irq_data *d)
284 static struct irq_chip mpc52xx_sdma_irqchip = {
285 .name =
"MPC52xx SDMA",
286 .irq_mask = mpc52xx_sdma_mask,
287 .irq_unmask = mpc52xx_sdma_unmask,
288 .irq_ack = mpc52xx_sdma_ack,
289 .irq_set_type = mpc52xx_null_set_type,
295 static int mpc52xx_is_extirq(
int l1,
int l2)
297 return ((l1 == 0) && (l2 == 0)) ||
298 ((l1 == 1) && (l2 >= 1) && (l2 <= 3));
305 const u32 *intspec,
unsigned int intsize,
307 unsigned int *out_flags)
317 intrvect_l1 = (
int)intspec[0];
318 intrvect_l2 = (
int)intspec[1];
319 intrvect_type = (
int)intspec[2] & 0x3;
325 *out_hwirq = intrvect_linux;
327 if (mpc52xx_is_extirq(intrvect_l1, intrvect_l2))
328 *out_flags = mpc52xx_map_senses[intrvect_type];
330 pr_debug(
"return %x, l1=%d, l2=%d\n", intrvect_linux, intrvect_l1,
338 static int mpc52xx_irqhost_map(
struct irq_domain *h,
unsigned int virq,
355 if (mpc52xx_is_extirq(l1irq, l2irq)) {
357 type = mpc52xx_map_senses[(reg >> (22 - l2irq * 2)) & 0x3];
364 irq_set_chip_and_handler(virq, &mpc52xx_extirq_irqchip, hndlr);
365 pr_debug(
"%s: External IRQ%i virq=%x, hw=%x. type=%x\n",
366 __func__, l2irq, virq, (
int)irq, type);
376 pr_warn(
"%s: Critical IRQ #%d is unsupported! Nopping it.\n",
383 pr_debug(
"%s: virq=%x, l1=%i, l2=%i\n", __func__, virq, l1irq, l2irq);
389 .xlate = mpc52xx_irqhost_xlate,
390 .map = mpc52xx_irqhost_map,
412 panic(__FILE__
": find_and_map failed on 'mpc5200-pic'. "
419 panic(__FILE__
": find_and_map failed on 'mpc5200-bestcomm'. "
422 pr_debug(
"MPC5200 IRQ controller mapped to 0x%p\n", intr);
430 intr_ctrl &= 0x00ff0000;
431 intr_ctrl |= 0x0f000000 |
450 &mpc52xx_irqhost_ops,
NULL);
452 if (!mpc52xx_irqhost)
453 panic(__FILE__
": Cannot allocate the IRQ host\n");
457 pr_info(
"MPC52xx PIC is up and running!\n");
493 if (status & 0x00000400) {
494 irq = (status >> 8) & 0x3;
498 }
else if (status & 0x00200000) {
499 irq = (status >> 16) & 0x1f;
503 }
else if (status & 0x20000000) {
505 irq = (status >> 24) & 0x1f;
508 irq =
ffs(status) - 1;