1 /* 2 * Copyright (C) 2013 Altera Corporation 3 * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch> 4 * Copyright (C) 2008 Thomas Chou <thomas@wytron.com.tw> 5 * 6 * based on irq.c from m68k which is: 7 * 8 * Copyright (C) 2007 Greg Ungerer <gerg@snapgear.com> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program. If not, see <http://www.gnu.org/licenses/>. 22 * 23 */ 24 25 #include <linux/init.h> 26 #include <linux/interrupt.h> 27 #include <linux/of.h> 28 29 static u32 ienable; 30 31 asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs) 32 { 33 struct pt_regs *oldregs = set_irq_regs(regs); 34 int irq; 35 36 irq_enter(); 37 irq = irq_find_mapping(NULL, hwirq); 38 generic_handle_irq(irq); 39 irq_exit(); 40 41 set_irq_regs(oldregs); 42 } 43 44 static void chip_unmask(struct irq_data *d) 45 { 46 ienable |= (1 << d->hwirq); 47 WRCTL(CTL_IENABLE, ienable); 48 } 49 50 static void chip_mask(struct irq_data *d) 51 { 52 ienable &= ~(1 << d->hwirq); 53 WRCTL(CTL_IENABLE, ienable); 54 } 55 56 static struct irq_chip m_irq_chip = { 57 .name = "NIOS2-INTC", 58 .irq_unmask = chip_unmask, 59 .irq_mask = chip_mask, 60 }; 61 62 static int irq_map(struct irq_domain *h, unsigned int virq, 63 irq_hw_number_t hw_irq_num) 64 { 65 irq_set_chip_and_handler(virq, &m_irq_chip, handle_level_irq); 66 67 return 0; 68 } 69 70 static struct irq_domain_ops irq_ops = { 71 .map = irq_map, 72 .xlate = irq_domain_xlate_onecell, 73 }; 74 75 void __init init_IRQ(void) 76 { 77 struct irq_domain *domain; 78 struct device_node *node; 79 80 node = of_find_compatible_node(NULL, NULL, "altr,nios2-1.0"); 81 if (!node) 82 node = of_find_compatible_node(NULL, NULL, "altr,nios2-1.1"); 83 84 BUG_ON(!node); 85 86 domain = irq_domain_add_linear(node, NIOS2_CPU_NR_IRQS, &irq_ops, NULL); 87 BUG_ON(!domain); 88 89 irq_set_default_host(domain); 90 of_node_put(node); 91 /* Load the initial ienable value */ 92 ienable = RDCTL(CTL_IENABLE); 93 } 94