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 29static u32 ienable; 30 31asmlinkage 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 44static void chip_unmask(struct irq_data *d) 45{ 46 ienable |= (1 << d->hwirq); 47 WRCTL(CTL_IENABLE, ienable); 48} 49 50static void chip_mask(struct irq_data *d) 51{ 52 ienable &= ~(1 << d->hwirq); 53 WRCTL(CTL_IENABLE, ienable); 54} 55 56static struct irq_chip m_irq_chip = { 57 .name = "NIOS2-INTC", 58 .irq_unmask = chip_unmask, 59 .irq_mask = chip_mask, 60}; 61 62static 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 70static struct irq_domain_ops irq_ops = { 71 .map = irq_map, 72 .xlate = irq_domain_xlate_onecell, 73}; 74 75void __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