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