| Lennert Buytenhek | 01eb569 | 2008-03-27 14:51:40 -0400 | [diff] [blame] | 1 | /* | 
 | 2 |  * arch/arm/plat-orion/irq.c | 
 | 3 |  * | 
 | 4 |  * Marvell Orion SoC IRQ handling. | 
 | 5 |  * | 
 | 6 |  * This file is licensed under the terms of the GNU General Public | 
 | 7 |  * License version 2.  This program is licensed "as is" without any | 
 | 8 |  * warranty of any kind, whether express or implied. | 
 | 9 |  */ | 
 | 10 |  | 
 | 11 | #include <linux/kernel.h> | 
 | 12 | #include <linux/init.h> | 
 | 13 | #include <linux/irq.h> | 
 | 14 | #include <linux/io.h> | 
| Lennert Buytenhek | 6f088f1 | 2008-08-09 13:44:58 +0200 | [diff] [blame] | 15 | #include <plat/irq.h> | 
| Lennert Buytenhek | 01eb569 | 2008-03-27 14:51:40 -0400 | [diff] [blame] | 16 |  | 
| Lennert Buytenhek | 3b0c8d4 | 2010-11-29 11:17:38 +0100 | [diff] [blame] | 17 | static void orion_irq_mask(struct irq_data *d) | 
| Lennert Buytenhek | 01eb569 | 2008-03-27 14:51:40 -0400 | [diff] [blame] | 18 | { | 
| Lennert Buytenhek | 3b0c8d4 | 2010-11-29 11:17:38 +0100 | [diff] [blame] | 19 | 	void __iomem *maskaddr = irq_data_get_irq_chip_data(d); | 
| Lennert Buytenhek | 01eb569 | 2008-03-27 14:51:40 -0400 | [diff] [blame] | 20 | 	u32 mask; | 
 | 21 |  | 
 | 22 | 	mask = readl(maskaddr); | 
| Lennert Buytenhek | 3b0c8d4 | 2010-11-29 11:17:38 +0100 | [diff] [blame] | 23 | 	mask &= ~(1 << (d->irq & 31)); | 
| Lennert Buytenhek | 01eb569 | 2008-03-27 14:51:40 -0400 | [diff] [blame] | 24 | 	writel(mask, maskaddr); | 
 | 25 | } | 
 | 26 |  | 
| Lennert Buytenhek | 3b0c8d4 | 2010-11-29 11:17:38 +0100 | [diff] [blame] | 27 | static void orion_irq_unmask(struct irq_data *d) | 
| Lennert Buytenhek | 01eb569 | 2008-03-27 14:51:40 -0400 | [diff] [blame] | 28 | { | 
| Lennert Buytenhek | 3b0c8d4 | 2010-11-29 11:17:38 +0100 | [diff] [blame] | 29 | 	void __iomem *maskaddr = irq_data_get_irq_chip_data(d); | 
| Lennert Buytenhek | 01eb569 | 2008-03-27 14:51:40 -0400 | [diff] [blame] | 30 | 	u32 mask; | 
 | 31 |  | 
 | 32 | 	mask = readl(maskaddr); | 
| Lennert Buytenhek | 3b0c8d4 | 2010-11-29 11:17:38 +0100 | [diff] [blame] | 33 | 	mask |= 1 << (d->irq & 31); | 
| Lennert Buytenhek | 01eb569 | 2008-03-27 14:51:40 -0400 | [diff] [blame] | 34 | 	writel(mask, maskaddr); | 
 | 35 | } | 
 | 36 |  | 
 | 37 | static struct irq_chip orion_irq_chip = { | 
 | 38 | 	.name		= "orion_irq", | 
| Lennert Buytenhek | 3b0c8d4 | 2010-11-29 11:17:38 +0100 | [diff] [blame] | 39 | 	.irq_mask	= orion_irq_mask, | 
 | 40 | 	.irq_mask_ack	= orion_irq_mask, | 
 | 41 | 	.irq_unmask	= orion_irq_unmask, | 
| Lennert Buytenhek | 01eb569 | 2008-03-27 14:51:40 -0400 | [diff] [blame] | 42 | }; | 
 | 43 |  | 
 | 44 | void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr) | 
 | 45 | { | 
 | 46 | 	unsigned int i; | 
 | 47 |  | 
 | 48 | 	/* | 
 | 49 | 	 * Mask all interrupts initially. | 
 | 50 | 	 */ | 
 | 51 | 	writel(0, maskaddr); | 
 | 52 |  | 
 | 53 | 	/* | 
 | 54 | 	 * Register IRQ sources. | 
 | 55 | 	 */ | 
 | 56 | 	for (i = 0; i < 32; i++) { | 
 | 57 | 		unsigned int irq = irq_start + i; | 
 | 58 |  | 
| Thomas Gleixner | f38c02f | 2011-03-24 13:35:09 +0100 | [diff] [blame] | 59 | 		irq_set_chip_and_handler(irq, &orion_irq_chip, | 
 | 60 | 					 handle_level_irq); | 
| Thomas Gleixner | 9323f261 | 2011-03-24 13:29:39 +0100 | [diff] [blame] | 61 | 		irq_set_chip_data(irq, maskaddr); | 
| Thomas Gleixner | e83bbb1 | 2011-03-24 12:35:19 +0100 | [diff] [blame] | 62 | 		irq_set_status_flags(irq, IRQ_LEVEL); | 
| Lennert Buytenhek | 01eb569 | 2008-03-27 14:51:40 -0400 | [diff] [blame] | 63 | 		set_irq_flags(irq, IRQF_VALID); | 
 | 64 | 	} | 
 | 65 | } |