1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Copyright (C) 2013 Altera Corporation |
4 | * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch> |
5 | * Copyright (C) 2008 Thomas Chou <thomas@wytron.com.tw> |
6 | * |
7 | * based on irq.c from m68k which is: |
8 | * |
9 | * Copyright (C) 2007 Greg Ungerer <gerg@snapgear.com> |
10 | */ |
11 | |
12 | #include <linux/init.h> |
13 | #include <linux/interrupt.h> |
14 | #include <linux/irqdomain.h> |
15 | #include <linux/of.h> |
16 | |
17 | static u32 ienable; |
18 | |
19 | asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs) |
20 | { |
21 | struct pt_regs *oldregs = set_irq_regs(regs); |
22 | |
23 | irq_enter(); |
24 | generic_handle_domain_irq(NULL, hwirq); |
25 | irq_exit(); |
26 | |
27 | set_irq_regs(oldregs); |
28 | } |
29 | |
30 | static void chip_unmask(struct irq_data *d) |
31 | { |
32 | ienable |= (1 << d->hwirq); |
33 | WRCTL(CTL_IENABLE, ienable); |
34 | } |
35 | |
36 | static void chip_mask(struct irq_data *d) |
37 | { |
38 | ienable &= ~(1 << d->hwirq); |
39 | WRCTL(CTL_IENABLE, ienable); |
40 | } |
41 | |
42 | static struct irq_chip m_irq_chip = { |
43 | .name = "NIOS2-INTC" , |
44 | .irq_unmask = chip_unmask, |
45 | .irq_mask = chip_mask, |
46 | }; |
47 | |
48 | static int irq_map(struct irq_domain *h, unsigned int virq, |
49 | irq_hw_number_t hw_irq_num) |
50 | { |
51 | irq_set_chip_and_handler(virq, &m_irq_chip, handle_level_irq); |
52 | |
53 | return 0; |
54 | } |
55 | |
56 | static const struct irq_domain_ops irq_ops = { |
57 | .map = irq_map, |
58 | .xlate = irq_domain_xlate_onecell, |
59 | }; |
60 | |
61 | void __init init_IRQ(void) |
62 | { |
63 | struct irq_domain *domain; |
64 | struct device_node *node; |
65 | |
66 | node = of_find_compatible_node(NULL, NULL, compat: "altr,nios2-1.0" ); |
67 | if (!node) |
68 | node = of_find_compatible_node(NULL, NULL, compat: "altr,nios2-1.1" ); |
69 | |
70 | BUG_ON(!node); |
71 | |
72 | domain = irq_domain_add_linear(of_node: node, size: NIOS2_CPU_NR_IRQS, ops: &irq_ops, NULL); |
73 | BUG_ON(!domain); |
74 | |
75 | irq_set_default_host(host: domain); |
76 | of_node_put(node); |
77 | /* Load the initial ienable value */ |
78 | ienable = RDCTL(CTL_IENABLE); |
79 | } |
80 | |