1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * (C) Copyright 2019 Rockchip Electronics Co., Ltd
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun #include <common.h>
8*4882a593Smuzhiyun #include <dm.h>
9*4882a593Smuzhiyun #include <fdtdec.h>
10*4882a593Smuzhiyun #include <malloc.h>
11*4882a593Smuzhiyun #include <asm/io.h>
12*4882a593Smuzhiyun #include <asm/u-boot-arm.h>
13*4882a593Smuzhiyun #include <irq-generic.h>
14*4882a593Smuzhiyun #include "irq-internal.h"
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun static LIST_HEAD(virq_desc_head);
19*4882a593Smuzhiyun static u32 virq_id = PLATFORM_MAX_IRQ;
20*4882a593Smuzhiyun
virq_id_alloc(void)21*4882a593Smuzhiyun static u32 virq_id_alloc(void)
22*4882a593Smuzhiyun {
23*4882a593Smuzhiyun return ++virq_id;
24*4882a593Smuzhiyun }
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun struct virq_data {
27*4882a593Smuzhiyun int irq;
28*4882a593Smuzhiyun u32 flag;
29*4882a593Smuzhiyun u32 count;
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun void *data;
32*4882a593Smuzhiyun interrupt_handler_t *handle_irq;
33*4882a593Smuzhiyun };
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun /* The structure to maintail the irqchip and child virqs */
36*4882a593Smuzhiyun struct virq_desc {
37*4882a593Smuzhiyun struct virq_chip *chip; /* irq chip */
38*4882a593Smuzhiyun struct virq_data *virqs; /* child irq data list */
39*4882a593Smuzhiyun struct udevice *parent; /* parent device */
40*4882a593Smuzhiyun int pirq; /* parent irq */
41*4882a593Smuzhiyun int use_count; /* enable count */
42*4882a593Smuzhiyun int irq_base; /* child irq base */
43*4882a593Smuzhiyun int irq_end; /* child irq end */
44*4882a593Smuzhiyun uint reg_stride;
45*4882a593Smuzhiyun uint unalign_reg_idx;
46*4882a593Smuzhiyun uint unalign_reg_stride;
47*4882a593Smuzhiyun uint *status_buf;
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun struct list_head node;
50*4882a593Smuzhiyun };
51*4882a593Smuzhiyun
find_virq_desc(int irq)52*4882a593Smuzhiyun static struct virq_desc *find_virq_desc(int irq)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun struct virq_desc *desc;
55*4882a593Smuzhiyun struct list_head *node;
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun list_for_each(node, &virq_desc_head) {
58*4882a593Smuzhiyun desc = list_entry(node, struct virq_desc, node);
59*4882a593Smuzhiyun if (irq >= desc->irq_base && irq <= desc->irq_end)
60*4882a593Smuzhiyun return desc;
61*4882a593Smuzhiyun }
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun return NULL;
64*4882a593Smuzhiyun }
65*4882a593Smuzhiyun
find_virq_desc_by_pirq(int parent_irq)66*4882a593Smuzhiyun static struct virq_desc *find_virq_desc_by_pirq(int parent_irq)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun struct virq_desc *desc;
69*4882a593Smuzhiyun struct list_head *node;
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun list_for_each(node, &virq_desc_head) {
72*4882a593Smuzhiyun desc = list_entry(node, struct virq_desc, node);
73*4882a593Smuzhiyun if (parent_irq == desc->pirq)
74*4882a593Smuzhiyun return desc;
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun return NULL;
78*4882a593Smuzhiyun }
79*4882a593Smuzhiyun
virq_to_irq(struct virq_chip * chip,int virq)80*4882a593Smuzhiyun int virq_to_irq(struct virq_chip *chip, int virq)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun struct virq_desc *desc;
83*4882a593Smuzhiyun struct list_head *node;
84*4882a593Smuzhiyun int irq;
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun if (!chip)
87*4882a593Smuzhiyun return -EINVAL;
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun list_for_each(node, &virq_desc_head) {
90*4882a593Smuzhiyun desc = list_entry(node, struct virq_desc, node);
91*4882a593Smuzhiyun if (desc->chip == chip) {
92*4882a593Smuzhiyun irq = desc->irq_base + virq;
93*4882a593Smuzhiyun if (irq >= desc->irq_base && irq <= desc->irq_end)
94*4882a593Smuzhiyun return irq;
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun return -ENONET;
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun
bad_virq(int irq)101*4882a593Smuzhiyun int bad_virq(int irq)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun return !find_virq_desc(irq);
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
virqs_show(int pirq)106*4882a593Smuzhiyun void virqs_show(int pirq)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun struct virq_data *vdata;
109*4882a593Smuzhiyun struct virq_desc *desc;
110*4882a593Smuzhiyun struct udevice *dev;
111*4882a593Smuzhiyun int num;
112*4882a593Smuzhiyun int i;
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun desc = find_virq_desc_by_pirq(pirq);
115*4882a593Smuzhiyun if (!desc)
116*4882a593Smuzhiyun return;
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun vdata = desc->virqs;
119*4882a593Smuzhiyun num = desc->irq_end - desc->irq_base;
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun for (i = 0; i < num; i++) {
122*4882a593Smuzhiyun if (!vdata[i].handle_irq)
123*4882a593Smuzhiyun continue;
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun dev = (struct udevice *)vdata[i].data;
126*4882a593Smuzhiyun printf(" %3d %d 0x%08lx %-12s |-- %-12s %d\n",
127*4882a593Smuzhiyun vdata[i].irq,
128*4882a593Smuzhiyun vdata[i].flag & IRQ_FLG_ENABLE ? 1 : 0,
129*4882a593Smuzhiyun (ulong)vdata[i].handle_irq, dev->driver->name, dev->name,
130*4882a593Smuzhiyun vdata[i].count);
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun
virq_install_handler(int irq,interrupt_handler_t * handler,void * data)134*4882a593Smuzhiyun int virq_install_handler(int irq, interrupt_handler_t *handler, void *data)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun struct virq_desc *desc;
137*4882a593Smuzhiyun int virq;
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun if (!handler)
140*4882a593Smuzhiyun return -EINVAL;
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun desc = find_virq_desc(irq);
143*4882a593Smuzhiyun if (!desc)
144*4882a593Smuzhiyun return -ENOENT;
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun virq = irq - desc->irq_base;
147*4882a593Smuzhiyun if (desc->virqs[virq].handle_irq)
148*4882a593Smuzhiyun return -EBUSY;
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun desc->virqs[virq].handle_irq = handler;
151*4882a593Smuzhiyun desc->virqs[virq].data = data;
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun return 0;
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun
virq_free_handler(int irq)156*4882a593Smuzhiyun void virq_free_handler(int irq)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun struct virq_desc *desc;
159*4882a593Smuzhiyun int virq;
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun desc = find_virq_desc(irq);
162*4882a593Smuzhiyun if (!desc)
163*4882a593Smuzhiyun return;
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun virq = irq - desc->irq_base;
166*4882a593Smuzhiyun desc->virqs[virq].handle_irq = NULL;
167*4882a593Smuzhiyun desc->virqs[virq].data = NULL;
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun
reg_base_get(struct virq_desc * desc,uint reg_base,int idx)170*4882a593Smuzhiyun static uint reg_base_get(struct virq_desc *desc, uint reg_base, int idx)
171*4882a593Smuzhiyun {
172*4882a593Smuzhiyun int reg_addr;
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun if (idx <= desc->unalign_reg_idx) {
175*4882a593Smuzhiyun reg_addr = reg_base + (idx * desc->unalign_reg_stride);
176*4882a593Smuzhiyun } else {
177*4882a593Smuzhiyun reg_addr = reg_base +
178*4882a593Smuzhiyun (desc->unalign_reg_idx * desc->unalign_reg_stride);
179*4882a593Smuzhiyun reg_addr += (idx - desc->unalign_reg_idx) * desc->reg_stride;
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun return reg_addr;
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun
virq_chip_generic_handler(int pirq,void * pdata)185*4882a593Smuzhiyun void virq_chip_generic_handler(int pirq, void *pdata)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun struct virq_chip *chip;
188*4882a593Smuzhiyun struct virq_desc *desc;
189*4882a593Smuzhiyun struct virq_data *vdata;
190*4882a593Smuzhiyun struct udevice *parent;
191*4882a593Smuzhiyun uint status_reg;
192*4882a593Smuzhiyun void *data;
193*4882a593Smuzhiyun int irq;
194*4882a593Smuzhiyun int ret;
195*4882a593Smuzhiyun int i;
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun desc = find_virq_desc_by_pirq(pirq);
198*4882a593Smuzhiyun if (!desc)
199*4882a593Smuzhiyun return;
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun chip = desc->chip;
202*4882a593Smuzhiyun vdata = desc->virqs;
203*4882a593Smuzhiyun parent = (struct udevice *)pdata;
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun if (!chip || !vdata || !parent)
206*4882a593Smuzhiyun return;
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun /* Read all status register */
209*4882a593Smuzhiyun for (i = 0; i < chip->num_regs; i++) {
210*4882a593Smuzhiyun status_reg = reg_base_get(desc, chip->status_base, i);
211*4882a593Smuzhiyun desc->status_buf[i] = chip->read(parent, status_reg);
212*4882a593Smuzhiyun if (desc->status_buf[i] < 0) {
213*4882a593Smuzhiyun printf("%s: Read status register 0x%x failed, ret=%d\n",
214*4882a593Smuzhiyun __func__, status_reg, desc->status_buf[i]);
215*4882a593Smuzhiyun }
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun /* Handle all virq handler */
219*4882a593Smuzhiyun for (i = 0; i < chip->num_irqs; i++) {
220*4882a593Smuzhiyun if (desc->status_buf[chip->irqs[i].reg_offset] &
221*4882a593Smuzhiyun chip->irqs[i].mask) {
222*4882a593Smuzhiyun irq = vdata[i].irq;
223*4882a593Smuzhiyun data = vdata[i].data;
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun if (vdata[i].handle_irq) {
226*4882a593Smuzhiyun vdata[i].count++;
227*4882a593Smuzhiyun vdata[i].handle_irq(irq, data);
228*4882a593Smuzhiyun }
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun /* Clear all status register */
233*4882a593Smuzhiyun for (i = 0; i < chip->num_regs; i++) {
234*4882a593Smuzhiyun status_reg = reg_base_get(desc, chip->status_base, i);
235*4882a593Smuzhiyun ret = chip->write(parent, status_reg, ~0U);
236*4882a593Smuzhiyun if (ret)
237*4882a593Smuzhiyun printf("%s: Clear status register 0x%x failed, ret=%d\n",
238*4882a593Smuzhiyun __func__, status_reg, ret);
239*4882a593Smuzhiyun }
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun
virq_add_chip(struct udevice * dev,struct virq_chip * chip,int irq)242*4882a593Smuzhiyun int virq_add_chip(struct udevice *dev, struct virq_chip *chip, int irq)
243*4882a593Smuzhiyun {
244*4882a593Smuzhiyun struct virq_data *vdata;
245*4882a593Smuzhiyun struct virq_desc *desc;
246*4882a593Smuzhiyun uint *status_buf;
247*4882a593Smuzhiyun uint status_reg;
248*4882a593Smuzhiyun uint mask_reg;
249*4882a593Smuzhiyun int ret;
250*4882a593Smuzhiyun int i;
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun if (irq < 0)
253*4882a593Smuzhiyun return -EINVAL;
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun desc = (struct virq_desc *)malloc(sizeof(*desc));
256*4882a593Smuzhiyun if (!desc)
257*4882a593Smuzhiyun return -ENOMEM;
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun vdata = (struct virq_data *)calloc(sizeof(*vdata), chip->num_irqs);
260*4882a593Smuzhiyun if (!vdata) {
261*4882a593Smuzhiyun ret = -ENOMEM;
262*4882a593Smuzhiyun goto free1;
263*4882a593Smuzhiyun }
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun status_buf = (uint *)calloc(sizeof(*status_buf), chip->num_irqs);
266*4882a593Smuzhiyun if (!status_buf) {
267*4882a593Smuzhiyun ret = -ENOMEM;
268*4882a593Smuzhiyun goto free2;
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun for (i = 0; i < chip->num_irqs; i++)
272*4882a593Smuzhiyun vdata[i].irq = virq_id_alloc();
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun desc->parent = dev;
275*4882a593Smuzhiyun desc->pirq = irq;
276*4882a593Smuzhiyun desc->chip = chip;
277*4882a593Smuzhiyun desc->virqs = vdata;
278*4882a593Smuzhiyun desc->use_count = 0;
279*4882a593Smuzhiyun desc->irq_base = vdata[0].irq;
280*4882a593Smuzhiyun desc->irq_end = vdata[chip->num_irqs - 1].irq;
281*4882a593Smuzhiyun desc->status_buf = status_buf;
282*4882a593Smuzhiyun desc->reg_stride = chip->irq_reg_stride ? : 1;
283*4882a593Smuzhiyun desc->unalign_reg_stride = chip->irq_unalign_reg_stride ? : 1;
284*4882a593Smuzhiyun desc->unalign_reg_idx = chip->irq_unalign_reg_stride ?
285*4882a593Smuzhiyun chip->irq_unalign_reg_idx : 0;
286*4882a593Smuzhiyun list_add_tail(&desc->node, &virq_desc_head);
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun /* Mask all register */
289*4882a593Smuzhiyun for (i = 0; i < chip->num_regs; i++) {
290*4882a593Smuzhiyun mask_reg = reg_base_get(desc, chip->mask_base, i);
291*4882a593Smuzhiyun ret = chip->write(dev, mask_reg, ~0U);
292*4882a593Smuzhiyun if (ret)
293*4882a593Smuzhiyun printf("%s: Set mask register 0x%x failed, ret=%d\n",
294*4882a593Smuzhiyun __func__, mask_reg, ret);
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun /* Clear all status */
298*4882a593Smuzhiyun for (i = 0; i < chip->num_regs; i++) {
299*4882a593Smuzhiyun status_reg = reg_base_get(desc, chip->status_base, i);
300*4882a593Smuzhiyun ret = chip->write(dev, status_reg, ~0U);
301*4882a593Smuzhiyun if (ret)
302*4882a593Smuzhiyun printf("%s: Clear status register 0x%x failed, ret=%d\n",
303*4882a593Smuzhiyun __func__, status_reg, ret);
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun /* Add parent irq into interrupt framework with generic virq handler */
307*4882a593Smuzhiyun irq_install_handler(irq, virq_chip_generic_handler, dev);
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun return irq_handler_disable(irq);
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun free1:
312*4882a593Smuzhiyun free(desc);
313*4882a593Smuzhiyun free2:
314*4882a593Smuzhiyun free(status_buf);
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun return ret;
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun
virq_init(void)319*4882a593Smuzhiyun static int virq_init(void)
320*4882a593Smuzhiyun {
321*4882a593Smuzhiyun INIT_LIST_HEAD(&virq_desc_head);
322*4882a593Smuzhiyun return 0;
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun
__virq_enable(int irq,int enable)325*4882a593Smuzhiyun static int __virq_enable(int irq, int enable)
326*4882a593Smuzhiyun {
327*4882a593Smuzhiyun struct virq_chip *chip;
328*4882a593Smuzhiyun struct virq_desc *desc;
329*4882a593Smuzhiyun uint mask_reg, mask_val;
330*4882a593Smuzhiyun uint reg_val;
331*4882a593Smuzhiyun int virq;
332*4882a593Smuzhiyun int ret;
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun desc = find_virq_desc(irq);
335*4882a593Smuzhiyun if (!desc) {
336*4882a593Smuzhiyun printf("%s: %s Invalid irq %d\n",
337*4882a593Smuzhiyun __func__, enable ? "Enable" : "Disable", irq);
338*4882a593Smuzhiyun return -ENOENT;
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun chip = desc->chip;
342*4882a593Smuzhiyun if (!chip)
343*4882a593Smuzhiyun return -ENOENT;
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun virq = irq - desc->irq_base;
346*4882a593Smuzhiyun mask_val = chip->irqs[virq].mask;
347*4882a593Smuzhiyun mask_reg = reg_base_get(desc, chip->mask_base,
348*4882a593Smuzhiyun chip->irqs[virq].reg_offset);
349*4882a593Smuzhiyun reg_val = chip->read(desc->parent, mask_reg);
350*4882a593Smuzhiyun if (enable)
351*4882a593Smuzhiyun reg_val &= ~mask_val;
352*4882a593Smuzhiyun else
353*4882a593Smuzhiyun reg_val |= mask_val;
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun ret = chip->write(desc->parent, mask_reg, reg_val);
356*4882a593Smuzhiyun if (ret) {
357*4882a593Smuzhiyun printf("%s: Clear status register 0x%x failed, ret=%d\n",
358*4882a593Smuzhiyun __func__, mask_reg, ret);
359*4882a593Smuzhiyun return ret;
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun if (enable)
363*4882a593Smuzhiyun desc->virqs[virq].flag |= IRQ_FLG_ENABLE;
364*4882a593Smuzhiyun else
365*4882a593Smuzhiyun desc->virqs[virq].flag &= ~IRQ_FLG_ENABLE;
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun return 0;
368*4882a593Smuzhiyun }
369*4882a593Smuzhiyun
virq_enable(int irq)370*4882a593Smuzhiyun static int virq_enable(int irq)
371*4882a593Smuzhiyun {
372*4882a593Smuzhiyun struct virq_desc *desc = find_virq_desc(irq);
373*4882a593Smuzhiyun int ret;
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun if (bad_virq(irq))
376*4882a593Smuzhiyun return -EINVAL;
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun ret = __virq_enable(irq, 1);
379*4882a593Smuzhiyun if (!ret) {
380*4882a593Smuzhiyun if (desc->use_count == 0)
381*4882a593Smuzhiyun irq_handler_enable(desc->pirq);
382*4882a593Smuzhiyun desc->use_count++;
383*4882a593Smuzhiyun }
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun return ret;
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun
virq_disable(int irq)388*4882a593Smuzhiyun static int virq_disable(int irq)
389*4882a593Smuzhiyun {
390*4882a593Smuzhiyun struct virq_desc *desc = find_virq_desc(irq);
391*4882a593Smuzhiyun int ret;
392*4882a593Smuzhiyun
393*4882a593Smuzhiyun if (bad_virq(irq))
394*4882a593Smuzhiyun return -EINVAL;
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun ret = __virq_enable(irq, 0);
397*4882a593Smuzhiyun if (!ret) {
398*4882a593Smuzhiyun if (desc->use_count <= 0)
399*4882a593Smuzhiyun return ret;
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun if (desc->use_count == 1)
402*4882a593Smuzhiyun irq_handler_disable(desc->pirq);
403*4882a593Smuzhiyun desc->use_count--;
404*4882a593Smuzhiyun }
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun return ret;
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun struct irq_chip virq_generic_chip = {
410*4882a593Smuzhiyun .name = "virq-irq-chip",
411*4882a593Smuzhiyun .irq_init = virq_init,
412*4882a593Smuzhiyun .irq_enable = virq_enable,
413*4882a593Smuzhiyun .irq_disable = virq_disable,
414*4882a593Smuzhiyun };
415*4882a593Smuzhiyun
arch_virq_get_irqchip(void)416*4882a593Smuzhiyun struct irq_chip *arch_virq_get_irqchip(void)
417*4882a593Smuzhiyun {
418*4882a593Smuzhiyun return &virq_generic_chip;
419*4882a593Smuzhiyun }
420