2 * Copyright (C) 2015 - Ben Herrenschmidt, IBM Corp.
4 * Driver for Aspeed "new" VIC as found in SoC generation 3 and later
8 * Copyright (C) 1999 - 2003 ARM Limited
9 * Copyright (C) 2000 Deep Blue Solutions Ltd
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
23 #include <linux/export.h>
24 #include <linux/init.h>
25 #include <linux/list.h>
27 #include <linux/irq.h>
28 #include <linux/irqchip.h>
29 #include <linux/irqchip/chained_irq.h>
30 #include <linux/irqdomain.h>
32 #include <linux/of_address.h>
33 #include <linux/of_irq.h>
34 #include <linux/syscore_ops.h>
35 #include <linux/device.h>
36 #include <linux/slab.h>
38 #include <asm/exception.h>
41 /* These definitions correspond to the "new mapping" of the
42 * register set that interleaves "high" and "low". The offsets
43 * below are for the "low" register, add 4 to get to the high one
45 #define AVIC_IRQ_STATUS 0x00
46 #define AVIC_FIQ_STATUS 0x08
47 #define AVIC_RAW_STATUS 0x10
48 #define AVIC_INT_SELECT 0x18
49 #define AVIC_INT_ENABLE 0x20
50 #define AVIC_INT_ENABLE_CLR 0x28
51 #define AVIC_INT_TRIGGER 0x30
52 #define AVIC_INT_TRIGGER_CLR 0x38
53 #define AVIC_INT_SENSE 0x40
54 #define AVIC_INT_DUAL_EDGE 0x48
55 #define AVIC_INT_EVENT 0x50
56 #define AVIC_EDGE_CLR 0x58
57 #define AVIC_EDGE_STATUS 0x60
64 struct irq_domain
*dom
;
66 static struct aspeed_vic
*system_avic
;
68 static void vic_init_hw(struct aspeed_vic
*vic
)
72 /* Disable all interrupts */
73 writel(0xffffffff, vic
->base
+ AVIC_INT_ENABLE_CLR
);
74 writel(0xffffffff, vic
->base
+ AVIC_INT_ENABLE_CLR
+ 4);
76 /* Make sure no soft trigger is on */
77 writel(0xffffffff, vic
->base
+ AVIC_INT_TRIGGER_CLR
);
78 writel(0xffffffff, vic
->base
+ AVIC_INT_TRIGGER_CLR
+ 4);
80 /* Set everything to be IRQ */
81 writel(0, vic
->base
+ AVIC_INT_SELECT
);
82 writel(0, vic
->base
+ AVIC_INT_SELECT
+ 4);
84 /* Some interrupts have a programable high/low level trigger
85 * (4 GPIO direct inputs), for now we assume this was configured
86 * by firmware. We read which ones are edge now.
88 sense
= readl(vic
->base
+ AVIC_INT_SENSE
);
89 vic
->edge_sources
[0] = ~sense
;
90 sense
= readl(vic
->base
+ AVIC_INT_SENSE
+ 4);
91 vic
->edge_sources
[1] = ~sense
;
93 /* Clear edge detection latches */
94 writel(0xffffffff, vic
->base
+ AVIC_EDGE_CLR
);
95 writel(0xffffffff, vic
->base
+ AVIC_EDGE_CLR
+ 4);
98 static void __exception_irq_entry
avic_handle_irq(struct pt_regs
*regs
)
100 struct aspeed_vic
*vic
= system_avic
;
105 stat
= readl_relaxed(vic
->base
+ AVIC_IRQ_STATUS
);
107 stat
= readl_relaxed(vic
->base
+ AVIC_IRQ_STATUS
+ 4);
112 irq
+= ffs(stat
) - 1;
113 handle_domain_irq(vic
->dom
, irq
, regs
);
117 static void avic_ack_irq(struct irq_data
*d
)
119 struct aspeed_vic
*vic
= irq_data_get_irq_chip_data(d
);
120 unsigned int sidx
= d
->hwirq
>> 5;
121 unsigned int sbit
= 1u << (d
->hwirq
& 0x1f);
123 /* Clear edge latch for edge interrupts, nop for level */
124 if (vic
->edge_sources
[sidx
] & sbit
)
125 writel(sbit
, vic
->base
+ AVIC_EDGE_CLR
+ sidx
* 4);
128 static void avic_mask_irq(struct irq_data
*d
)
130 struct aspeed_vic
*vic
= irq_data_get_irq_chip_data(d
);
131 unsigned int sidx
= d
->hwirq
>> 5;
132 unsigned int sbit
= 1u << (d
->hwirq
& 0x1f);
134 writel(sbit
, vic
->base
+ AVIC_INT_ENABLE_CLR
+ sidx
* 4);
137 static void avic_unmask_irq(struct irq_data
*d
)
139 struct aspeed_vic
*vic
= irq_data_get_irq_chip_data(d
);
140 unsigned int sidx
= d
->hwirq
>> 5;
141 unsigned int sbit
= 1u << (d
->hwirq
& 0x1f);
143 writel(sbit
, vic
->base
+ AVIC_INT_ENABLE
+ sidx
* 4);
146 /* For level irq, faster than going through a nop "ack" and mask */
147 static void avic_mask_ack_irq(struct irq_data
*d
)
149 struct aspeed_vic
*vic
= irq_data_get_irq_chip_data(d
);
150 unsigned int sidx
= d
->hwirq
>> 5;
151 unsigned int sbit
= 1u << (d
->hwirq
& 0x1f);
154 writel(sbit
, vic
->base
+ AVIC_INT_ENABLE_CLR
+ sidx
* 4);
156 /* Then clear edge latch for edge interrupts */
157 if (vic
->edge_sources
[sidx
] & sbit
)
158 writel(sbit
, vic
->base
+ AVIC_EDGE_CLR
+ sidx
* 4);
161 static struct irq_chip avic_chip
= {
163 .irq_ack
= avic_ack_irq
,
164 .irq_mask
= avic_mask_irq
,
165 .irq_unmask
= avic_unmask_irq
,
166 .irq_mask_ack
= avic_mask_ack_irq
,
169 static int avic_map(struct irq_domain
*d
, unsigned int irq
,
170 irq_hw_number_t hwirq
)
172 struct aspeed_vic
*vic
= d
->host_data
;
173 unsigned int sidx
= hwirq
>> 5;
174 unsigned int sbit
= 1u << (hwirq
& 0x1f);
176 /* Check if interrupt exists */
180 if (vic
->edge_sources
[sidx
] & sbit
)
181 irq_set_chip_and_handler(irq
, &avic_chip
, handle_edge_irq
);
183 irq_set_chip_and_handler(irq
, &avic_chip
, handle_level_irq
);
184 irq_set_chip_data(irq
, vic
);
189 static struct irq_domain_ops avic_dom_ops
= {
191 .xlate
= irq_domain_xlate_onetwocell
,
194 static int __init
avic_of_init(struct device_node
*node
,
195 struct device_node
*parent
)
198 struct aspeed_vic
*vic
;
200 if (WARN(parent
, "non-root Aspeed VIC not supported"))
202 if (WARN(system_avic
, "duplicate Aspeed VIC not supported"))
205 regs
= of_iomap(node
, 0);
209 vic
= kzalloc(sizeof(struct aspeed_vic
), GFP_KERNEL
);
216 /* Initialize soures, all masked */
219 /* Ready to receive interrupts */
221 set_handle_irq(avic_handle_irq
);
223 /* Register our domain */
224 vic
->dom
= irq_domain_add_simple(node
, NUM_IRQS
, 0,
230 IRQCHIP_DECLARE(aspeed_new_vic
, "aspeed,ast2400-vic", avic_of_init
);