2 * intc2.c -- support for the 2nd INTC controller of the 525x
4 * (C) Copyright 2012, Steven King <sfking@fdwdc.com>
5 * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file COPYING in the main directory of this archive
12 #include <linux/types.h>
13 #include <linux/init.h>
14 #include <linux/kernel.h>
15 #include <linux/interrupt.h>
16 #include <linux/irq.h>
18 #include <asm/coldfire.h>
19 #include <asm/mcfsim.h>
21 static void intc2_irq_gpio_mask(struct irq_data
*d
)
23 u32 imr
= readl(MCFSIM2_GPIOINTENABLE
);
24 u32 type
= irqd_get_trigger_type(d
);
25 int irq
= d
->irq
- MCF_IRQ_GPIO0
;
27 if (type
& IRQ_TYPE_EDGE_RISING
)
28 imr
&= ~(0x001 << irq
);
29 if (type
& IRQ_TYPE_EDGE_FALLING
)
30 imr
&= ~(0x100 << irq
);
31 writel(imr
, MCFSIM2_GPIOINTENABLE
);
34 static void intc2_irq_gpio_unmask(struct irq_data
*d
)
36 u32 imr
= readl(MCFSIM2_GPIOINTENABLE
);
37 u32 type
= irqd_get_trigger_type(d
);
38 int irq
= d
->irq
- MCF_IRQ_GPIO0
;
40 if (type
& IRQ_TYPE_EDGE_RISING
)
41 imr
|= (0x001 << irq
);
42 if (type
& IRQ_TYPE_EDGE_FALLING
)
43 imr
|= (0x100 << irq
);
44 writel(imr
, MCFSIM2_GPIOINTENABLE
);
47 static void intc2_irq_gpio_ack(struct irq_data
*d
)
50 u32 type
= irqd_get_trigger_type(d
);
51 int irq
= d
->irq
- MCF_IRQ_GPIO0
;
53 if (type
& IRQ_TYPE_EDGE_RISING
)
54 imr
|= (0x001 << irq
);
55 if (type
& IRQ_TYPE_EDGE_FALLING
)
56 imr
|= (0x100 << irq
);
57 writel(imr
, MCFSIM2_GPIOINTCLEAR
);
60 static int intc2_irq_gpio_set_type(struct irq_data
*d
, unsigned int f
)
62 if (f
& ~IRQ_TYPE_EDGE_BOTH
)
67 static struct irq_chip intc2_irq_gpio_chip
= {
69 .irq_mask
= intc2_irq_gpio_mask
,
70 .irq_unmask
= intc2_irq_gpio_unmask
,
71 .irq_ack
= intc2_irq_gpio_ack
,
72 .irq_set_type
= intc2_irq_gpio_set_type
,
75 static int __init
mcf_intc2_init(void)
79 /* set the interrupt base for the second interrupt controller */
80 writel(MCFINTC2_VECBASE
, MCFINTC2_INTBASE
);
82 /* GPIO interrupt sources */
83 for (irq
= MCF_IRQ_GPIO0
; (irq
<= MCF_IRQ_GPIO6
); irq
++) {
84 irq_set_chip(irq
, &intc2_irq_gpio_chip
);
85 irq_set_handler(irq
, handle_edge_irq
);
91 arch_initcall(mcf_intc2_init
);