1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Actions Semi Owl SoCs SIRQ interrupt controller driver
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2014 Actions Semi Inc.
6*4882a593Smuzhiyun * David Liu <liuwei@actions-semi.com>
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * Author: Parthiban Nallathambi <pn@denx.de>
9*4882a593Smuzhiyun * Author: Saravanan Sekar <sravanhome@gmail.com>
10*4882a593Smuzhiyun * Author: Cristian Ciocaltea <cristian.ciocaltea@gmail.com>
11*4882a593Smuzhiyun */
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #include <linux/bitfield.h>
14*4882a593Smuzhiyun #include <linux/interrupt.h>
15*4882a593Smuzhiyun #include <linux/irqchip.h>
16*4882a593Smuzhiyun #include <linux/of_address.h>
17*4882a593Smuzhiyun #include <linux/of_irq.h>
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #include <dt-bindings/interrupt-controller/arm-gic.h>
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun #define NUM_SIRQ 3
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun #define INTC_EXTCTL_PENDING BIT(0)
24*4882a593Smuzhiyun #define INTC_EXTCTL_CLK_SEL BIT(4)
25*4882a593Smuzhiyun #define INTC_EXTCTL_EN BIT(5)
26*4882a593Smuzhiyun #define INTC_EXTCTL_TYPE_MASK GENMASK(7, 6)
27*4882a593Smuzhiyun #define INTC_EXTCTL_TYPE_HIGH 0
28*4882a593Smuzhiyun #define INTC_EXTCTL_TYPE_LOW BIT(6)
29*4882a593Smuzhiyun #define INTC_EXTCTL_TYPE_RISING BIT(7)
30*4882a593Smuzhiyun #define INTC_EXTCTL_TYPE_FALLING (BIT(6) | BIT(7))
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun /* S500 & S700 SIRQ control register masks */
33*4882a593Smuzhiyun #define INTC_EXTCTL_SIRQ0_MASK GENMASK(23, 16)
34*4882a593Smuzhiyun #define INTC_EXTCTL_SIRQ1_MASK GENMASK(15, 8)
35*4882a593Smuzhiyun #define INTC_EXTCTL_SIRQ2_MASK GENMASK(7, 0)
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun /* S900 SIRQ control register offsets, relative to controller base address */
38*4882a593Smuzhiyun #define INTC_EXTCTL0 0x0000
39*4882a593Smuzhiyun #define INTC_EXTCTL1 0x0328
40*4882a593Smuzhiyun #define INTC_EXTCTL2 0x032c
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun struct owl_sirq_params {
43*4882a593Smuzhiyun /* INTC_EXTCTL reg shared for all three SIRQ lines */
44*4882a593Smuzhiyun bool reg_shared;
45*4882a593Smuzhiyun /* INTC_EXTCTL reg offsets relative to controller base address */
46*4882a593Smuzhiyun u16 reg_offset[NUM_SIRQ];
47*4882a593Smuzhiyun };
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun struct owl_sirq_chip_data {
50*4882a593Smuzhiyun const struct owl_sirq_params *params;
51*4882a593Smuzhiyun void __iomem *base;
52*4882a593Smuzhiyun raw_spinlock_t lock;
53*4882a593Smuzhiyun u32 ext_irqs[NUM_SIRQ];
54*4882a593Smuzhiyun };
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun /* S500 & S700 SoCs */
57*4882a593Smuzhiyun static const struct owl_sirq_params owl_sirq_s500_params = {
58*4882a593Smuzhiyun .reg_shared = true,
59*4882a593Smuzhiyun .reg_offset = { 0, 0, 0 },
60*4882a593Smuzhiyun };
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun /* S900 SoC */
63*4882a593Smuzhiyun static const struct owl_sirq_params owl_sirq_s900_params = {
64*4882a593Smuzhiyun .reg_shared = false,
65*4882a593Smuzhiyun .reg_offset = { INTC_EXTCTL0, INTC_EXTCTL1, INTC_EXTCTL2 },
66*4882a593Smuzhiyun };
67*4882a593Smuzhiyun
owl_field_get(u32 val,u32 index)68*4882a593Smuzhiyun static u32 owl_field_get(u32 val, u32 index)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun switch (index) {
71*4882a593Smuzhiyun case 0:
72*4882a593Smuzhiyun return FIELD_GET(INTC_EXTCTL_SIRQ0_MASK, val);
73*4882a593Smuzhiyun case 1:
74*4882a593Smuzhiyun return FIELD_GET(INTC_EXTCTL_SIRQ1_MASK, val);
75*4882a593Smuzhiyun case 2:
76*4882a593Smuzhiyun default:
77*4882a593Smuzhiyun return FIELD_GET(INTC_EXTCTL_SIRQ2_MASK, val);
78*4882a593Smuzhiyun }
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun
owl_field_prep(u32 val,u32 index)81*4882a593Smuzhiyun static u32 owl_field_prep(u32 val, u32 index)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun switch (index) {
84*4882a593Smuzhiyun case 0:
85*4882a593Smuzhiyun return FIELD_PREP(INTC_EXTCTL_SIRQ0_MASK, val);
86*4882a593Smuzhiyun case 1:
87*4882a593Smuzhiyun return FIELD_PREP(INTC_EXTCTL_SIRQ1_MASK, val);
88*4882a593Smuzhiyun case 2:
89*4882a593Smuzhiyun default:
90*4882a593Smuzhiyun return FIELD_PREP(INTC_EXTCTL_SIRQ2_MASK, val);
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun }
93*4882a593Smuzhiyun
owl_sirq_read_extctl(struct owl_sirq_chip_data * data,u32 index)94*4882a593Smuzhiyun static u32 owl_sirq_read_extctl(struct owl_sirq_chip_data *data, u32 index)
95*4882a593Smuzhiyun {
96*4882a593Smuzhiyun u32 val;
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun val = readl_relaxed(data->base + data->params->reg_offset[index]);
99*4882a593Smuzhiyun if (data->params->reg_shared)
100*4882a593Smuzhiyun val = owl_field_get(val, index);
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun return val;
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun
owl_sirq_write_extctl(struct owl_sirq_chip_data * data,u32 extctl,u32 index)105*4882a593Smuzhiyun static void owl_sirq_write_extctl(struct owl_sirq_chip_data *data,
106*4882a593Smuzhiyun u32 extctl, u32 index)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun u32 val;
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun if (data->params->reg_shared) {
111*4882a593Smuzhiyun val = readl_relaxed(data->base + data->params->reg_offset[index]);
112*4882a593Smuzhiyun val &= ~owl_field_prep(0xff, index);
113*4882a593Smuzhiyun extctl = owl_field_prep(extctl, index) | val;
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun writel_relaxed(extctl, data->base + data->params->reg_offset[index]);
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun
owl_sirq_clear_set_extctl(struct owl_sirq_chip_data * d,u32 clear,u32 set,u32 index)119*4882a593Smuzhiyun static void owl_sirq_clear_set_extctl(struct owl_sirq_chip_data *d,
120*4882a593Smuzhiyun u32 clear, u32 set, u32 index)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun unsigned long flags;
123*4882a593Smuzhiyun u32 val;
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun raw_spin_lock_irqsave(&d->lock, flags);
126*4882a593Smuzhiyun val = owl_sirq_read_extctl(d, index);
127*4882a593Smuzhiyun val &= ~clear;
128*4882a593Smuzhiyun val |= set;
129*4882a593Smuzhiyun owl_sirq_write_extctl(d, val, index);
130*4882a593Smuzhiyun raw_spin_unlock_irqrestore(&d->lock, flags);
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun
owl_sirq_eoi(struct irq_data * data)133*4882a593Smuzhiyun static void owl_sirq_eoi(struct irq_data *data)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun struct owl_sirq_chip_data *chip_data = irq_data_get_irq_chip_data(data);
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun /*
138*4882a593Smuzhiyun * Software must clear external interrupt pending, when interrupt type
139*4882a593Smuzhiyun * is edge triggered, so we need per SIRQ based clearing.
140*4882a593Smuzhiyun */
141*4882a593Smuzhiyun if (!irqd_is_level_type(data))
142*4882a593Smuzhiyun owl_sirq_clear_set_extctl(chip_data, 0, INTC_EXTCTL_PENDING,
143*4882a593Smuzhiyun data->hwirq);
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun irq_chip_eoi_parent(data);
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun
owl_sirq_mask(struct irq_data * data)148*4882a593Smuzhiyun static void owl_sirq_mask(struct irq_data *data)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun struct owl_sirq_chip_data *chip_data = irq_data_get_irq_chip_data(data);
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun owl_sirq_clear_set_extctl(chip_data, INTC_EXTCTL_EN, 0, data->hwirq);
153*4882a593Smuzhiyun irq_chip_mask_parent(data);
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun
owl_sirq_unmask(struct irq_data * data)156*4882a593Smuzhiyun static void owl_sirq_unmask(struct irq_data *data)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun struct owl_sirq_chip_data *chip_data = irq_data_get_irq_chip_data(data);
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun owl_sirq_clear_set_extctl(chip_data, 0, INTC_EXTCTL_EN, data->hwirq);
161*4882a593Smuzhiyun irq_chip_unmask_parent(data);
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun /*
165*4882a593Smuzhiyun * GIC does not handle falling edge or active low, hence SIRQ shall be
166*4882a593Smuzhiyun * programmed to convert falling edge to rising edge signal and active
167*4882a593Smuzhiyun * low to active high signal.
168*4882a593Smuzhiyun */
owl_sirq_set_type(struct irq_data * data,unsigned int type)169*4882a593Smuzhiyun static int owl_sirq_set_type(struct irq_data *data, unsigned int type)
170*4882a593Smuzhiyun {
171*4882a593Smuzhiyun struct owl_sirq_chip_data *chip_data = irq_data_get_irq_chip_data(data);
172*4882a593Smuzhiyun u32 sirq_type;
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun switch (type) {
175*4882a593Smuzhiyun case IRQ_TYPE_LEVEL_LOW:
176*4882a593Smuzhiyun sirq_type = INTC_EXTCTL_TYPE_LOW;
177*4882a593Smuzhiyun type = IRQ_TYPE_LEVEL_HIGH;
178*4882a593Smuzhiyun break;
179*4882a593Smuzhiyun case IRQ_TYPE_LEVEL_HIGH:
180*4882a593Smuzhiyun sirq_type = INTC_EXTCTL_TYPE_HIGH;
181*4882a593Smuzhiyun break;
182*4882a593Smuzhiyun case IRQ_TYPE_EDGE_FALLING:
183*4882a593Smuzhiyun sirq_type = INTC_EXTCTL_TYPE_FALLING;
184*4882a593Smuzhiyun type = IRQ_TYPE_EDGE_RISING;
185*4882a593Smuzhiyun break;
186*4882a593Smuzhiyun case IRQ_TYPE_EDGE_RISING:
187*4882a593Smuzhiyun sirq_type = INTC_EXTCTL_TYPE_RISING;
188*4882a593Smuzhiyun break;
189*4882a593Smuzhiyun default:
190*4882a593Smuzhiyun return -EINVAL;
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun owl_sirq_clear_set_extctl(chip_data, INTC_EXTCTL_TYPE_MASK, sirq_type,
194*4882a593Smuzhiyun data->hwirq);
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun return irq_chip_set_type_parent(data, type);
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun static struct irq_chip owl_sirq_chip = {
200*4882a593Smuzhiyun .name = "owl-sirq",
201*4882a593Smuzhiyun .irq_mask = owl_sirq_mask,
202*4882a593Smuzhiyun .irq_unmask = owl_sirq_unmask,
203*4882a593Smuzhiyun .irq_eoi = owl_sirq_eoi,
204*4882a593Smuzhiyun .irq_set_type = owl_sirq_set_type,
205*4882a593Smuzhiyun .irq_retrigger = irq_chip_retrigger_hierarchy,
206*4882a593Smuzhiyun #ifdef CONFIG_SMP
207*4882a593Smuzhiyun .irq_set_affinity = irq_chip_set_affinity_parent,
208*4882a593Smuzhiyun #endif
209*4882a593Smuzhiyun };
210*4882a593Smuzhiyun
owl_sirq_domain_translate(struct irq_domain * d,struct irq_fwspec * fwspec,unsigned long * hwirq,unsigned int * type)211*4882a593Smuzhiyun static int owl_sirq_domain_translate(struct irq_domain *d,
212*4882a593Smuzhiyun struct irq_fwspec *fwspec,
213*4882a593Smuzhiyun unsigned long *hwirq,
214*4882a593Smuzhiyun unsigned int *type)
215*4882a593Smuzhiyun {
216*4882a593Smuzhiyun if (!is_of_node(fwspec->fwnode))
217*4882a593Smuzhiyun return -EINVAL;
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun if (fwspec->param_count != 2 || fwspec->param[0] >= NUM_SIRQ)
220*4882a593Smuzhiyun return -EINVAL;
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun *hwirq = fwspec->param[0];
223*4882a593Smuzhiyun *type = fwspec->param[1];
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun return 0;
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun
owl_sirq_domain_alloc(struct irq_domain * domain,unsigned int virq,unsigned int nr_irqs,void * data)228*4882a593Smuzhiyun static int owl_sirq_domain_alloc(struct irq_domain *domain, unsigned int virq,
229*4882a593Smuzhiyun unsigned int nr_irqs, void *data)
230*4882a593Smuzhiyun {
231*4882a593Smuzhiyun struct owl_sirq_chip_data *chip_data = domain->host_data;
232*4882a593Smuzhiyun struct irq_fwspec *fwspec = data;
233*4882a593Smuzhiyun struct irq_fwspec parent_fwspec;
234*4882a593Smuzhiyun irq_hw_number_t hwirq;
235*4882a593Smuzhiyun unsigned int type;
236*4882a593Smuzhiyun int ret;
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun if (WARN_ON(nr_irqs != 1))
239*4882a593Smuzhiyun return -EINVAL;
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun ret = owl_sirq_domain_translate(domain, fwspec, &hwirq, &type);
242*4882a593Smuzhiyun if (ret)
243*4882a593Smuzhiyun return ret;
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun switch (type) {
246*4882a593Smuzhiyun case IRQ_TYPE_EDGE_RISING:
247*4882a593Smuzhiyun case IRQ_TYPE_LEVEL_HIGH:
248*4882a593Smuzhiyun break;
249*4882a593Smuzhiyun case IRQ_TYPE_EDGE_FALLING:
250*4882a593Smuzhiyun type = IRQ_TYPE_EDGE_RISING;
251*4882a593Smuzhiyun break;
252*4882a593Smuzhiyun case IRQ_TYPE_LEVEL_LOW:
253*4882a593Smuzhiyun type = IRQ_TYPE_LEVEL_HIGH;
254*4882a593Smuzhiyun break;
255*4882a593Smuzhiyun default:
256*4882a593Smuzhiyun return -EINVAL;
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun irq_domain_set_hwirq_and_chip(domain, virq, hwirq, &owl_sirq_chip,
260*4882a593Smuzhiyun chip_data);
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun parent_fwspec.fwnode = domain->parent->fwnode;
263*4882a593Smuzhiyun parent_fwspec.param_count = 3;
264*4882a593Smuzhiyun parent_fwspec.param[0] = GIC_SPI;
265*4882a593Smuzhiyun parent_fwspec.param[1] = chip_data->ext_irqs[hwirq];
266*4882a593Smuzhiyun parent_fwspec.param[2] = type;
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun return irq_domain_alloc_irqs_parent(domain, virq, 1, &parent_fwspec);
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun static const struct irq_domain_ops owl_sirq_domain_ops = {
272*4882a593Smuzhiyun .translate = owl_sirq_domain_translate,
273*4882a593Smuzhiyun .alloc = owl_sirq_domain_alloc,
274*4882a593Smuzhiyun .free = irq_domain_free_irqs_common,
275*4882a593Smuzhiyun };
276*4882a593Smuzhiyun
owl_sirq_init(const struct owl_sirq_params * params,struct device_node * node,struct device_node * parent)277*4882a593Smuzhiyun static int __init owl_sirq_init(const struct owl_sirq_params *params,
278*4882a593Smuzhiyun struct device_node *node,
279*4882a593Smuzhiyun struct device_node *parent)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun struct irq_domain *domain, *parent_domain;
282*4882a593Smuzhiyun struct owl_sirq_chip_data *chip_data;
283*4882a593Smuzhiyun int ret, i;
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun parent_domain = irq_find_host(parent);
286*4882a593Smuzhiyun if (!parent_domain) {
287*4882a593Smuzhiyun pr_err("%pOF: failed to find sirq parent domain\n", node);
288*4882a593Smuzhiyun return -ENXIO;
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL);
292*4882a593Smuzhiyun if (!chip_data)
293*4882a593Smuzhiyun return -ENOMEM;
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun raw_spin_lock_init(&chip_data->lock);
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun chip_data->params = params;
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun chip_data->base = of_iomap(node, 0);
300*4882a593Smuzhiyun if (!chip_data->base) {
301*4882a593Smuzhiyun pr_err("%pOF: failed to map sirq registers\n", node);
302*4882a593Smuzhiyun ret = -ENXIO;
303*4882a593Smuzhiyun goto out_free;
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun for (i = 0; i < NUM_SIRQ; i++) {
307*4882a593Smuzhiyun struct of_phandle_args irq;
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun ret = of_irq_parse_one(node, i, &irq);
310*4882a593Smuzhiyun if (ret) {
311*4882a593Smuzhiyun pr_err("%pOF: failed to parse interrupt %d\n", node, i);
312*4882a593Smuzhiyun goto out_unmap;
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun if (WARN_ON(irq.args_count != 3)) {
316*4882a593Smuzhiyun ret = -EINVAL;
317*4882a593Smuzhiyun goto out_unmap;
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun chip_data->ext_irqs[i] = irq.args[1];
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun /* Set 24MHz external interrupt clock freq */
323*4882a593Smuzhiyun owl_sirq_clear_set_extctl(chip_data, 0, INTC_EXTCTL_CLK_SEL, i);
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun domain = irq_domain_add_hierarchy(parent_domain, 0, NUM_SIRQ, node,
327*4882a593Smuzhiyun &owl_sirq_domain_ops, chip_data);
328*4882a593Smuzhiyun if (!domain) {
329*4882a593Smuzhiyun pr_err("%pOF: failed to add domain\n", node);
330*4882a593Smuzhiyun ret = -ENOMEM;
331*4882a593Smuzhiyun goto out_unmap;
332*4882a593Smuzhiyun }
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun return 0;
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun out_unmap:
337*4882a593Smuzhiyun iounmap(chip_data->base);
338*4882a593Smuzhiyun out_free:
339*4882a593Smuzhiyun kfree(chip_data);
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun return ret;
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun
owl_sirq_s500_of_init(struct device_node * node,struct device_node * parent)344*4882a593Smuzhiyun static int __init owl_sirq_s500_of_init(struct device_node *node,
345*4882a593Smuzhiyun struct device_node *parent)
346*4882a593Smuzhiyun {
347*4882a593Smuzhiyun return owl_sirq_init(&owl_sirq_s500_params, node, parent);
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun IRQCHIP_DECLARE(owl_sirq_s500, "actions,s500-sirq", owl_sirq_s500_of_init);
351*4882a593Smuzhiyun IRQCHIP_DECLARE(owl_sirq_s700, "actions,s700-sirq", owl_sirq_s500_of_init);
352*4882a593Smuzhiyun
owl_sirq_s900_of_init(struct device_node * node,struct device_node * parent)353*4882a593Smuzhiyun static int __init owl_sirq_s900_of_init(struct device_node *node,
354*4882a593Smuzhiyun struct device_node *parent)
355*4882a593Smuzhiyun {
356*4882a593Smuzhiyun return owl_sirq_init(&owl_sirq_s900_params, node, parent);
357*4882a593Smuzhiyun }
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun IRQCHIP_DECLARE(owl_sirq_s900, "actions,s900-sirq", owl_sirq_s900_of_init);
360