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",