xref: /openbmc/linux/arch/arm/plat-orion/irq.c (revision 6f088f1d)
101eb5698SLennert Buytenhek /*
201eb5698SLennert Buytenhek  * arch/arm/plat-orion/irq.c
301eb5698SLennert Buytenhek  *
401eb5698SLennert Buytenhek  * Marvell Orion SoC IRQ handling.
501eb5698SLennert Buytenhek  *
601eb5698SLennert Buytenhek  * This file is licensed under the terms of the GNU General Public
701eb5698SLennert Buytenhek  * License version 2.  This program is licensed "as is" without any
801eb5698SLennert Buytenhek  * warranty of any kind, whether express or implied.
901eb5698SLennert Buytenhek  */
1001eb5698SLennert Buytenhek 
1101eb5698SLennert Buytenhek #include <linux/kernel.h>
1201eb5698SLennert Buytenhek #include <linux/init.h>
1301eb5698SLennert Buytenhek #include <linux/irq.h>
1401eb5698SLennert Buytenhek #include <linux/io.h>
156f088f1dSLennert Buytenhek #include <plat/irq.h>
1601eb5698SLennert Buytenhek 
1701eb5698SLennert Buytenhek static void orion_irq_mask(u32 irq)
1801eb5698SLennert Buytenhek {
1901eb5698SLennert Buytenhek 	void __iomem *maskaddr = get_irq_chip_data(irq);
2001eb5698SLennert Buytenhek 	u32 mask;
2101eb5698SLennert Buytenhek 
2201eb5698SLennert Buytenhek 	mask = readl(maskaddr);
2301eb5698SLennert Buytenhek 	mask &= ~(1 << (irq & 31));
2401eb5698SLennert Buytenhek 	writel(mask, maskaddr);
2501eb5698SLennert Buytenhek }
2601eb5698SLennert Buytenhek 
2701eb5698SLennert Buytenhek static void orion_irq_unmask(u32 irq)
2801eb5698SLennert Buytenhek {
2901eb5698SLennert Buytenhek 	void __iomem *maskaddr = get_irq_chip_data(irq);
3001eb5698SLennert Buytenhek 	u32 mask;
3101eb5698SLennert Buytenhek 
3201eb5698SLennert Buytenhek 	mask = readl(maskaddr);
3301eb5698SLennert Buytenhek 	mask |= 1 << (irq & 31);
3401eb5698SLennert Buytenhek 	writel(mask, maskaddr);
3501eb5698SLennert Buytenhek }
3601eb5698SLennert Buytenhek 
3701eb5698SLennert Buytenhek static struct irq_chip orion_irq_chip = {
3801eb5698SLennert Buytenhek 	.name		= "orion_irq",
3901eb5698SLennert Buytenhek 	.mask		= orion_irq_mask,
40000e99c3SLennert Buytenhek 	.mask_ack	= orion_irq_mask,
4101eb5698SLennert Buytenhek 	.unmask		= orion_irq_unmask,
4201eb5698SLennert Buytenhek };
4301eb5698SLennert Buytenhek 
4401eb5698SLennert Buytenhek void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr)
4501eb5698SLennert Buytenhek {
4601eb5698SLennert Buytenhek 	unsigned int i;
4701eb5698SLennert Buytenhek 
4801eb5698SLennert Buytenhek 	/*
4901eb5698SLennert Buytenhek 	 * Mask all interrupts initially.
5001eb5698SLennert Buytenhek 	 */
5101eb5698SLennert Buytenhek 	writel(0, maskaddr);
5201eb5698SLennert Buytenhek 
5301eb5698SLennert Buytenhek 	/*
5401eb5698SLennert Buytenhek 	 * Register IRQ sources.
5501eb5698SLennert Buytenhek 	 */
5601eb5698SLennert Buytenhek 	for (i = 0; i < 32; i++) {
5701eb5698SLennert Buytenhek 		unsigned int irq = irq_start + i;
5801eb5698SLennert Buytenhek 
5901eb5698SLennert Buytenhek 		set_irq_chip(irq, &orion_irq_chip);
6001eb5698SLennert Buytenhek 		set_irq_chip_data(irq, maskaddr);
6101eb5698SLennert Buytenhek 		set_irq_handler(irq, handle_level_irq);
62000e99c3SLennert Buytenhek 		irq_desc[irq].status |= IRQ_LEVEL;
6301eb5698SLennert Buytenhek 		set_irq_flags(irq, IRQF_VALID);
6401eb5698SLennert Buytenhek 	}
6501eb5698SLennert Buytenhek }
66