2 * irqchip for the Cortina Systems Gemini Copyright (C) 2017 Linus
3 * Walleij <linus.walleij@linaro.org>
5 * Based on arch/arm/mach-gemini/irq.c
6 * Copyright (C) 2001-2006 Storlink, Corp.
7 * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
9 #include <linux/bitops.h>
10 #include <linux/irq.h>
12 #include <linux/irqchip.h>
13 #include <linux/irqchip/versatile-fpga.h>
14 #include <linux/irqdomain.h>
15 #include <linux/module.h>
17 #include <linux/of_address.h>
18 #include <linux/of_irq.h>
19 #include <linux/cpu.h>
21 #include <asm/exception.h>
22 #include <asm/mach/irq.h>
24 #define GEMINI_NUM_IRQS 32
26 #define GEMINI_IRQ_SOURCE(base_addr) (base_addr + 0x00)
27 #define GEMINI_IRQ_MASK(base_addr) (base_addr + 0x04)
28 #define GEMINI_IRQ_CLEAR(base_addr) (base_addr + 0x08)
29 #define GEMINI_IRQ_MODE(base_addr) (base_addr + 0x0C)
30 #define GEMINI_IRQ_POLARITY(base_addr) (base_addr + 0x10)
31 #define GEMINI_IRQ_STATUS(base_addr) (base_addr + 0x14)
32 #define GEMINI_FIQ_SOURCE(base_addr) (base_addr + 0x20)
33 #define GEMINI_FIQ_MASK(base_addr) (base_addr + 0x24)
34 #define GEMINI_FIQ_CLEAR(base_addr) (base_addr + 0x28)
35 #define GEMINI_FIQ_MODE(base_addr) (base_addr + 0x2C)
36 #define GEMINI_FIQ_POLARITY(base_addr) (base_addr + 0x30)
37 #define GEMINI_FIQ_STATUS(base_addr) (base_addr + 0x34)
40 * struct gemini_irq_data - irq data container for the Gemini IRQ controller
41 * @base: memory offset in virtual memory
42 * @chip: chip container for this instance
43 * @domain: IRQ domain for this instance
45 struct gemini_irq_data {
48 struct irq_domain *domain;
51 static void gemini_irq_mask(struct irq_data *d)
53 struct gemini_irq_data *g = irq_data_get_irq_chip_data(d);
56 mask = readl(GEMINI_IRQ_MASK(g->base));
57 mask &= ~BIT(irqd_to_hwirq(d));
58 writel(mask, GEMINI_IRQ_MASK(g->base));
61 static void gemini_irq_unmask(struct irq_data *d)
63 struct gemini_irq_data *g = irq_data_get_irq_chip_data(d);
66 mask = readl(GEMINI_IRQ_MASK(g->base));
67 mask |= BIT(irqd_to_hwirq(d));
68 writel(mask, GEMINI_IRQ_MASK(g->base));
71 static void gemini_irq_ack(struct irq_data *d)
73 struct gemini_irq_data *g = irq_data_get_irq_chip_data(d);
75 writel(BIT(irqd_to_hwirq(d)), GEMINI_IRQ_CLEAR(g->base));
78 static int gemini_irq_set_type(struct irq_data *d, unsigned int trigger)
80 struct gemini_irq_data *g = irq_data_get_irq_chip_data(d);
81 int offset = irqd_to_hwirq(d);
84 mode = readl(GEMINI_IRQ_MODE(g->base));
85 polarity = readl(GEMINI_IRQ_POLARITY(g->base));
87 if (trigger & (IRQ_TYPE_LEVEL_HIGH)) {
88 irq_set_handler_locked(d, handle_level_irq);
89 /* Disable edge detection */
91 polarity &= ~BIT(offset);
92 } else if (trigger & IRQ_TYPE_EDGE_RISING) {
93 irq_set_handler_locked(d, handle_edge_irq);
95 polarity |= BIT(offset);
96 } else if (trigger & IRQ_TYPE_EDGE_FALLING) {
97 irq_set_handler_locked(d, handle_edge_irq);
99 polarity &= ~BIT(offset);
101 irq_set_handler_locked(d, handle_bad_irq);
102 pr_warn("GEMINI IRQ: no supported trigger selected for line %d\n",
106 writel(mode, GEMINI_IRQ_MODE(g->base));
107 writel(polarity, GEMINI_IRQ_POLARITY(g->base));
112 static struct irq_chip gemini_irq_chip = {
114 .irq_ack = gemini_irq_ack,
115 .irq_mask = gemini_irq_mask,
116 .irq_unmask = gemini_irq_unmask,
117 .irq_set_type = gemini_irq_set_type,
120 /* Local static for the IRQ entry call */
121 static struct gemini_irq_data girq;
123 asmlinkage void __exception_irq_entry gemini_irqchip_handle_irq(struct pt_regs *regs)
125 struct gemini_irq_data *g = &girq;
129 while ((status = readl(GEMINI_IRQ_STATUS(g->base)))) {
130 irq = ffs(status) - 1;
131 handle_domain_irq(g->domain, irq, regs);
135 static int gemini_irqdomain_map(struct irq_domain *d, unsigned int irq,
136 irq_hw_number_t hwirq)
138 struct gemini_irq_data *g = d->host_data;
140 irq_set_chip_data(irq, g);
141 /* All IRQs should set up their type, flags as bad by default */
142 irq_set_chip_and_handler(irq, &gemini_irq_chip, handle_bad_irq);
148 static void gemini_irqdomain_unmap(struct irq_domain *d, unsigned int irq)
150 irq_set_chip_and_handler(irq, NULL, NULL);
151 irq_set_chip_data(irq, NULL);
154 static const struct irq_domain_ops gemini_irqdomain_ops = {
155 .map = gemini_irqdomain_map,
156 .unmap = gemini_irqdomain_unmap,
157 .xlate = irq_domain_xlate_onetwocell,
160 int __init gemini_of_init_irq(struct device_node *node,
161 struct device_node *parent)
163 struct gemini_irq_data *g = &girq;
166 * Disable the idle handler by default since it is buggy
167 * For more info see arch/arm/mach-gemini/idle.c
169 cpu_idle_poll_ctrl(true);
171 g->base = of_iomap(node, 0);
172 WARN(!g->base, "unable to map gemini irq registers\n");
174 /* Disable all interrupts */
175 writel(0, GEMINI_IRQ_MASK(g->base));
176 writel(0, GEMINI_FIQ_MASK(g->base));
178 g->domain = irq_domain_add_simple(node, GEMINI_NUM_IRQS, 0,
179 &gemini_irqdomain_ops, g);
180 set_handle_irq(gemini_irqchip_handle_irq);
184 IRQCHIP_DECLARE(gemini, "cortina,gemini-interrupt-controller",