xref: /rk3399_rockchip-uboot/drivers/irq/virq.c (revision 1b461e2d3af6210f3e788aab491c8f89d9cfdd8e)
141766119SJoseph Chen /*
241766119SJoseph Chen  * (C) Copyright 2019 Rockchip Electronics Co., Ltd
341766119SJoseph Chen  *
441766119SJoseph Chen  * SPDX-License-Identifier:     GPL-2.0+
541766119SJoseph Chen  */
641766119SJoseph Chen 
741766119SJoseph Chen #include <common.h>
841766119SJoseph Chen #include <dm.h>
941766119SJoseph Chen #include <fdtdec.h>
1041766119SJoseph Chen #include <malloc.h>
1141766119SJoseph Chen #include <asm/io.h>
1241766119SJoseph Chen #include <asm/u-boot-arm.h>
1341766119SJoseph Chen #include <irq-generic.h>
1441766119SJoseph Chen #include "irq-internal.h"
1541766119SJoseph Chen 
1641766119SJoseph Chen DECLARE_GLOBAL_DATA_PTR;
1741766119SJoseph Chen 
1841766119SJoseph Chen static LIST_HEAD(virq_desc_head);
1941766119SJoseph Chen static u32 virq_id = PLATFORM_MAX_IRQ;
2041766119SJoseph Chen 
virq_id_alloc(void)2141766119SJoseph Chen static u32 virq_id_alloc(void)
2241766119SJoseph Chen {
2341766119SJoseph Chen 	return ++virq_id;
2441766119SJoseph Chen }
2541766119SJoseph Chen 
2641766119SJoseph Chen struct virq_data {
2741766119SJoseph Chen 	int irq;
28ae63f119SJoseph Chen 	u32 flag;
29ae63f119SJoseph Chen 	u32 count;
30ae63f119SJoseph Chen 
3141766119SJoseph Chen 	void *data;
3241766119SJoseph Chen 	interrupt_handler_t *handle_irq;
3341766119SJoseph Chen };
3441766119SJoseph Chen 
3541766119SJoseph Chen /* The structure to maintail the irqchip and child virqs */
3641766119SJoseph Chen struct virq_desc {
3741766119SJoseph Chen 	struct virq_chip *chip;		/* irq chip */
3841766119SJoseph Chen 	struct virq_data *virqs;	/* child irq data list */
3941766119SJoseph Chen 	struct udevice *parent;		/* parent device */
4041766119SJoseph Chen 	int pirq;			/* parent irq */
4125c13168SJoseph Chen 	int use_count;			/* enable count */
4241766119SJoseph Chen 	int irq_base;			/* child irq base */
4341766119SJoseph Chen 	int irq_end;			/* child irq end */
4441766119SJoseph Chen 	uint reg_stride;
4541766119SJoseph Chen 	uint unalign_reg_idx;
4641766119SJoseph Chen 	uint unalign_reg_stride;
4741766119SJoseph Chen 	uint *status_buf;
4841766119SJoseph Chen 
4941766119SJoseph Chen 	struct list_head node;
5041766119SJoseph Chen };
5141766119SJoseph Chen 
find_virq_desc(int irq)5241766119SJoseph Chen static struct virq_desc *find_virq_desc(int irq)
5341766119SJoseph Chen {
5441766119SJoseph Chen 	struct virq_desc *desc;
5541766119SJoseph Chen 	struct list_head *node;
5641766119SJoseph Chen 
5741766119SJoseph Chen 	list_for_each(node, &virq_desc_head) {
5841766119SJoseph Chen 		desc = list_entry(node, struct virq_desc, node);
5941766119SJoseph Chen 		if (irq >= desc->irq_base && irq <= desc->irq_end)
6041766119SJoseph Chen 			return desc;
6141766119SJoseph Chen 	}
6241766119SJoseph Chen 
6341766119SJoseph Chen 	return NULL;
6441766119SJoseph Chen }
6541766119SJoseph Chen 
find_virq_desc_by_pirq(int parent_irq)6641766119SJoseph Chen static struct virq_desc *find_virq_desc_by_pirq(int parent_irq)
6741766119SJoseph Chen {
6841766119SJoseph Chen 	struct virq_desc *desc;
6941766119SJoseph Chen 	struct list_head *node;
7041766119SJoseph Chen 
7141766119SJoseph Chen 	list_for_each(node, &virq_desc_head) {
7241766119SJoseph Chen 		desc = list_entry(node, struct virq_desc, node);
7341766119SJoseph Chen 		if (parent_irq == desc->pirq)
7441766119SJoseph Chen 			return desc;
7541766119SJoseph Chen 	}
7641766119SJoseph Chen 
7741766119SJoseph Chen 	return NULL;
7841766119SJoseph Chen }
7941766119SJoseph Chen 
virq_to_irq(struct virq_chip * chip,int virq)8041766119SJoseph Chen int virq_to_irq(struct virq_chip *chip, int virq)
8141766119SJoseph Chen {
8241766119SJoseph Chen 	struct virq_desc *desc;
8341766119SJoseph Chen 	struct list_head *node;
8441766119SJoseph Chen 	int irq;
8541766119SJoseph Chen 
8641766119SJoseph Chen 	if (!chip)
8741766119SJoseph Chen 		return -EINVAL;
8841766119SJoseph Chen 
8941766119SJoseph Chen 	list_for_each(node, &virq_desc_head) {
9041766119SJoseph Chen 		desc = list_entry(node, struct virq_desc, node);
9141766119SJoseph Chen 		if (desc->chip == chip) {
9241766119SJoseph Chen 			irq = desc->irq_base + virq;
9341766119SJoseph Chen 			if (irq >= desc->irq_base && irq <= desc->irq_end)
9441766119SJoseph Chen 				return irq;
9541766119SJoseph Chen 		}
9641766119SJoseph Chen 	}
9741766119SJoseph Chen 
9841766119SJoseph Chen 	return -ENONET;
9941766119SJoseph Chen }
10041766119SJoseph Chen 
bad_virq(int irq)10141766119SJoseph Chen int bad_virq(int irq)
10241766119SJoseph Chen {
10341766119SJoseph Chen 	return !find_virq_desc(irq);
10441766119SJoseph Chen }
10541766119SJoseph Chen 
virqs_show(int pirq)10692f4f090SJoseph Chen void virqs_show(int pirq)
10792f4f090SJoseph Chen {
10892f4f090SJoseph Chen 	struct virq_data *vdata;
10992f4f090SJoseph Chen 	struct virq_desc *desc;
11092f4f090SJoseph Chen 	struct udevice *dev;
11192f4f090SJoseph Chen 	int num;
11292f4f090SJoseph Chen 	int i;
11392f4f090SJoseph Chen 
11492f4f090SJoseph Chen 	desc = find_virq_desc_by_pirq(pirq);
11592f4f090SJoseph Chen 	if (!desc)
11692f4f090SJoseph Chen 	       return;
11792f4f090SJoseph Chen 
11892f4f090SJoseph Chen 	vdata = desc->virqs;
11992f4f090SJoseph Chen 	num = desc->irq_end - desc->irq_base;
12092f4f090SJoseph Chen 
12192f4f090SJoseph Chen 	for (i = 0; i < num; i++) {
12292f4f090SJoseph Chen 		if (!vdata[i].handle_irq)
12392f4f090SJoseph Chen 			continue;
12492f4f090SJoseph Chen 
12592f4f090SJoseph Chen 		dev = (struct udevice *)vdata[i].data;
12692f4f090SJoseph Chen 		printf(" %3d    %d     0x%08lx    %-12s    |-- %-12s   %d\n",
12792f4f090SJoseph Chen 		       vdata[i].irq,
12892f4f090SJoseph Chen 		       vdata[i].flag & IRQ_FLG_ENABLE ? 1 : 0,
12992f4f090SJoseph Chen 		       (ulong)vdata[i].handle_irq, dev->driver->name, dev->name,
13092f4f090SJoseph Chen 		       vdata[i].count);
13192f4f090SJoseph Chen 	}
13292f4f090SJoseph Chen }
13392f4f090SJoseph Chen 
virq_install_handler(int irq,interrupt_handler_t * handler,void * data)13441766119SJoseph Chen int virq_install_handler(int irq, interrupt_handler_t *handler, void *data)
13541766119SJoseph Chen {
13641766119SJoseph Chen 	struct virq_desc *desc;
13741766119SJoseph Chen 	int virq;
13841766119SJoseph Chen 
13941766119SJoseph Chen 	if (!handler)
14041766119SJoseph Chen 		return -EINVAL;
14141766119SJoseph Chen 
14241766119SJoseph Chen 	desc = find_virq_desc(irq);
14341766119SJoseph Chen 	if (!desc)
14441766119SJoseph Chen 		return -ENOENT;
14541766119SJoseph Chen 
14641766119SJoseph Chen 	virq = irq - desc->irq_base;
14741766119SJoseph Chen 	if (desc->virqs[virq].handle_irq)
14841766119SJoseph Chen 		return -EBUSY;
14941766119SJoseph Chen 
15041766119SJoseph Chen 	desc->virqs[virq].handle_irq = handler;
15141766119SJoseph Chen 	desc->virqs[virq].data = data;
15241766119SJoseph Chen 
15341766119SJoseph Chen 	return 0;
15441766119SJoseph Chen }
15541766119SJoseph Chen 
virq_free_handler(int irq)15641766119SJoseph Chen void virq_free_handler(int irq)
15741766119SJoseph Chen {
15841766119SJoseph Chen 	struct virq_desc *desc;
15941766119SJoseph Chen 	int virq;
16041766119SJoseph Chen 
16141766119SJoseph Chen 	desc = find_virq_desc(irq);
16241766119SJoseph Chen 	if (!desc)
16341766119SJoseph Chen 		return;
16441766119SJoseph Chen 
16541766119SJoseph Chen 	virq = irq - desc->irq_base;
16641766119SJoseph Chen 	desc->virqs[virq].handle_irq = NULL;
16741766119SJoseph Chen 	desc->virqs[virq].data = NULL;
16841766119SJoseph Chen }
16941766119SJoseph Chen 
reg_base_get(struct virq_desc * desc,uint reg_base,int idx)17041766119SJoseph Chen static uint reg_base_get(struct virq_desc *desc, uint reg_base, int idx)
17141766119SJoseph Chen {
17241766119SJoseph Chen 	int reg_addr;
17341766119SJoseph Chen 
17441766119SJoseph Chen 	if (idx <= desc->unalign_reg_idx) {
17541766119SJoseph Chen 		reg_addr = reg_base + (idx * desc->unalign_reg_stride);
17641766119SJoseph Chen 	} else {
17741766119SJoseph Chen 		reg_addr = reg_base +
17841766119SJoseph Chen 			   (desc->unalign_reg_idx * desc->unalign_reg_stride);
17941766119SJoseph Chen 		reg_addr += (idx - desc->unalign_reg_idx) * desc->reg_stride;
18041766119SJoseph Chen 	}
18141766119SJoseph Chen 
18241766119SJoseph Chen 	return reg_addr;
18341766119SJoseph Chen }
18441766119SJoseph Chen 
virq_chip_generic_handler(int pirq,void * pdata)18541766119SJoseph Chen void virq_chip_generic_handler(int pirq, void *pdata)
18641766119SJoseph Chen {
18741766119SJoseph Chen 	struct virq_chip *chip;
18841766119SJoseph Chen 	struct virq_desc *desc;
18941766119SJoseph Chen 	struct virq_data *vdata;
19041766119SJoseph Chen 	struct udevice *parent;
19141766119SJoseph Chen 	uint status_reg;
19241766119SJoseph Chen 	void *data;
19341766119SJoseph Chen 	int irq;
19441766119SJoseph Chen 	int ret;
19541766119SJoseph Chen 	int i;
19641766119SJoseph Chen 
19741766119SJoseph Chen 	desc = find_virq_desc_by_pirq(pirq);
19841766119SJoseph Chen 	if (!desc)
19941766119SJoseph Chen 		return;
20041766119SJoseph Chen 
20141766119SJoseph Chen 	chip = desc->chip;
20241766119SJoseph Chen 	vdata = desc->virqs;
20341766119SJoseph Chen 	parent = (struct udevice *)pdata;
20441766119SJoseph Chen 
20541766119SJoseph Chen 	if (!chip || !vdata || !parent)
20641766119SJoseph Chen 		return;
20741766119SJoseph Chen 
20841766119SJoseph Chen 	/* Read all status register */
20941766119SJoseph Chen 	for (i = 0; i < chip->num_regs; i++) {
21041766119SJoseph Chen 		status_reg = reg_base_get(desc, chip->status_base, i);
211*1b461e2dSJoseph Chen 		desc->status_buf[i] = chip->read(parent, status_reg);
21241766119SJoseph Chen 		if (desc->status_buf[i] < 0) {
21341766119SJoseph Chen 			printf("%s: Read status register 0x%x failed, ret=%d\n",
21441766119SJoseph Chen 			       __func__, status_reg, desc->status_buf[i]);
21541766119SJoseph Chen 		}
21641766119SJoseph Chen 	}
21741766119SJoseph Chen 
21841766119SJoseph Chen 	/* Handle all virq handler */
21941766119SJoseph Chen 	for (i = 0; i < chip->num_irqs; i++) {
22041766119SJoseph Chen 		if (desc->status_buf[chip->irqs[i].reg_offset] &
22141766119SJoseph Chen 		    chip->irqs[i].mask) {
22241766119SJoseph Chen 			irq = vdata[i].irq;
22341766119SJoseph Chen 			data = vdata[i].data;
22441766119SJoseph Chen 
225ae63f119SJoseph Chen 			if (vdata[i].handle_irq) {
226ae63f119SJoseph Chen 				vdata[i].count++;
22741766119SJoseph Chen 				vdata[i].handle_irq(irq, data);
22841766119SJoseph Chen 			}
22941766119SJoseph Chen 		}
230ae63f119SJoseph Chen 	}
23141766119SJoseph Chen 
23241766119SJoseph Chen 	/* Clear all status register */
23341766119SJoseph Chen 	for (i = 0; i < chip->num_regs; i++) {
23441766119SJoseph Chen 		status_reg = reg_base_get(desc, chip->status_base, i);
235*1b461e2dSJoseph Chen 		ret = chip->write(parent, status_reg, ~0U);
23641766119SJoseph Chen 		if (ret)
23741766119SJoseph Chen 			printf("%s: Clear status register 0x%x failed, ret=%d\n",
23841766119SJoseph Chen 			       __func__, status_reg, ret);
23941766119SJoseph Chen 	}
24041766119SJoseph Chen }
24141766119SJoseph Chen 
virq_add_chip(struct udevice * dev,struct virq_chip * chip,int irq)24225c13168SJoseph Chen int virq_add_chip(struct udevice *dev, struct virq_chip *chip, int irq)
24341766119SJoseph Chen {
24441766119SJoseph Chen 	struct virq_data *vdata;
24541766119SJoseph Chen 	struct virq_desc *desc;
24641766119SJoseph Chen 	uint *status_buf;
24725c13168SJoseph Chen 	uint status_reg;
24841766119SJoseph Chen 	uint mask_reg;
24941766119SJoseph Chen 	int ret;
25041766119SJoseph Chen 	int i;
25141766119SJoseph Chen 
25241766119SJoseph Chen 	if (irq < 0)
25341766119SJoseph Chen 		return -EINVAL;
25441766119SJoseph Chen 
25541766119SJoseph Chen 	desc = (struct virq_desc *)malloc(sizeof(*desc));
25641766119SJoseph Chen 	if (!desc)
25741766119SJoseph Chen 		return -ENOMEM;
25841766119SJoseph Chen 
25941766119SJoseph Chen 	vdata = (struct virq_data *)calloc(sizeof(*vdata), chip->num_irqs);
26041766119SJoseph Chen 	if (!vdata) {
26141766119SJoseph Chen 		ret = -ENOMEM;
26241766119SJoseph Chen 		goto free1;
26341766119SJoseph Chen 	}
26441766119SJoseph Chen 
26541766119SJoseph Chen 	status_buf = (uint *)calloc(sizeof(*status_buf), chip->num_irqs);
26641766119SJoseph Chen 	if (!status_buf) {
26741766119SJoseph Chen 		ret = -ENOMEM;
26841766119SJoseph Chen 		goto free2;
26941766119SJoseph Chen 	}
27041766119SJoseph Chen 
27141766119SJoseph Chen 	for (i = 0; i < chip->num_irqs; i++)
27241766119SJoseph Chen 		vdata[i].irq = virq_id_alloc();
27341766119SJoseph Chen 
27441766119SJoseph Chen 	desc->parent = dev;
27541766119SJoseph Chen 	desc->pirq = irq;
27641766119SJoseph Chen 	desc->chip = chip;
27741766119SJoseph Chen 	desc->virqs = vdata;
27825c13168SJoseph Chen 	desc->use_count = 0;
27941766119SJoseph Chen 	desc->irq_base = vdata[0].irq;
28041766119SJoseph Chen 	desc->irq_end = vdata[chip->num_irqs - 1].irq;
28141766119SJoseph Chen 	desc->status_buf = status_buf;
28241766119SJoseph Chen 	desc->reg_stride = chip->irq_reg_stride ? : 1;
28341766119SJoseph Chen 	desc->unalign_reg_stride = chip->irq_unalign_reg_stride ? : 1;
28441766119SJoseph Chen 	desc->unalign_reg_idx = chip->irq_unalign_reg_stride ?
28541766119SJoseph Chen 					chip->irq_unalign_reg_idx : 0;
28641766119SJoseph Chen 	list_add_tail(&desc->node, &virq_desc_head);
28741766119SJoseph Chen 
28841766119SJoseph Chen 	/* Mask all register */
28941766119SJoseph Chen 	for (i = 0; i < chip->num_regs; i++) {
29041766119SJoseph Chen 		mask_reg = reg_base_get(desc, chip->mask_base, i);
291*1b461e2dSJoseph Chen 		ret = chip->write(dev, mask_reg, ~0U);
29241766119SJoseph Chen 		if (ret)
29341766119SJoseph Chen 			printf("%s: Set mask register 0x%x failed, ret=%d\n",
29441766119SJoseph Chen 			       __func__, mask_reg, ret);
29541766119SJoseph Chen 	}
29641766119SJoseph Chen 
29725c13168SJoseph Chen 	/* Clear all status */
29825c13168SJoseph Chen 	for (i = 0; i < chip->num_regs; i++) {
29925c13168SJoseph Chen 		status_reg = reg_base_get(desc, chip->status_base, i);
300*1b461e2dSJoseph Chen 		ret = chip->write(dev, status_reg, ~0U);
30125c13168SJoseph Chen 		if (ret)
30225c13168SJoseph Chen 			printf("%s: Clear status register 0x%x failed, ret=%d\n",
30325c13168SJoseph Chen 			       __func__, status_reg, ret);
30425c13168SJoseph Chen 	}
30525c13168SJoseph Chen 
30641766119SJoseph Chen 	/* Add parent irq into interrupt framework with generic virq handler */
30741766119SJoseph Chen 	irq_install_handler(irq, virq_chip_generic_handler, dev);
30841766119SJoseph Chen 
30925c13168SJoseph Chen 	return irq_handler_disable(irq);
31041766119SJoseph Chen 
31141766119SJoseph Chen free1:
31241766119SJoseph Chen 	free(desc);
31341766119SJoseph Chen free2:
31441766119SJoseph Chen 	free(status_buf);
31541766119SJoseph Chen 
31641766119SJoseph Chen 	return ret;
31741766119SJoseph Chen }
31841766119SJoseph Chen 
virq_init(void)31941766119SJoseph Chen static int virq_init(void)
32041766119SJoseph Chen {
32141766119SJoseph Chen 	INIT_LIST_HEAD(&virq_desc_head);
32241766119SJoseph Chen 	return 0;
32341766119SJoseph Chen }
32441766119SJoseph Chen 
__virq_enable(int irq,int enable)32541766119SJoseph Chen static int __virq_enable(int irq, int enable)
32641766119SJoseph Chen {
32741766119SJoseph Chen 	struct virq_chip *chip;
32841766119SJoseph Chen 	struct virq_desc *desc;
32941766119SJoseph Chen 	uint mask_reg, mask_val;
33041766119SJoseph Chen 	uint reg_val;
33141766119SJoseph Chen 	int virq;
33241766119SJoseph Chen 	int ret;
33341766119SJoseph Chen 
33441766119SJoseph Chen 	desc = find_virq_desc(irq);
33541766119SJoseph Chen 	if (!desc) {
33641766119SJoseph Chen 		printf("%s: %s Invalid irq %d\n",
33741766119SJoseph Chen 		       __func__, enable ? "Enable" : "Disable", irq);
33841766119SJoseph Chen 		return -ENOENT;
33941766119SJoseph Chen 	}
34041766119SJoseph Chen 
34141766119SJoseph Chen 	chip = desc->chip;
34241766119SJoseph Chen 	if (!chip)
34341766119SJoseph Chen 		return -ENOENT;
34441766119SJoseph Chen 
34541766119SJoseph Chen 	virq = irq - desc->irq_base;
34641766119SJoseph Chen 	mask_val = chip->irqs[virq].mask;
34741766119SJoseph Chen 	mask_reg = reg_base_get(desc, chip->mask_base,
34841766119SJoseph Chen 				chip->irqs[virq].reg_offset);
349*1b461e2dSJoseph Chen 	reg_val = chip->read(desc->parent, mask_reg);
35041766119SJoseph Chen 	if (enable)
35141766119SJoseph Chen 		reg_val &= ~mask_val;
35241766119SJoseph Chen 	else
35341766119SJoseph Chen 		reg_val |= mask_val;
35441766119SJoseph Chen 
355*1b461e2dSJoseph Chen 	ret = chip->write(desc->parent, mask_reg, reg_val);
35641766119SJoseph Chen 	if (ret) {
35741766119SJoseph Chen 		printf("%s: Clear status register 0x%x failed, ret=%d\n",
35841766119SJoseph Chen 		       __func__, mask_reg, ret);
35941766119SJoseph Chen 		return ret;
36041766119SJoseph Chen 	}
36141766119SJoseph Chen 
362ae63f119SJoseph Chen 	if (enable)
363ae63f119SJoseph Chen 		desc->virqs[virq].flag |= IRQ_FLG_ENABLE;
364ae63f119SJoseph Chen 	else
365ae63f119SJoseph Chen 		desc->virqs[virq].flag &= ~IRQ_FLG_ENABLE;
366ae63f119SJoseph Chen 
36741766119SJoseph Chen 	return 0;
36841766119SJoseph Chen }
36941766119SJoseph Chen 
virq_enable(int irq)37041766119SJoseph Chen static int virq_enable(int irq)
37141766119SJoseph Chen {
37225c13168SJoseph Chen 	struct virq_desc *desc = find_virq_desc(irq);
37325c13168SJoseph Chen 	int ret;
37425c13168SJoseph Chen 
37541766119SJoseph Chen 	if (bad_virq(irq))
37641766119SJoseph Chen 		return -EINVAL;
37741766119SJoseph Chen 
37825c13168SJoseph Chen 	ret = __virq_enable(irq, 1);
37925c13168SJoseph Chen 	if (!ret) {
38025c13168SJoseph Chen 		if (desc->use_count == 0)
38125c13168SJoseph Chen 			irq_handler_enable(desc->pirq);
38225c13168SJoseph Chen 		desc->use_count++;
38325c13168SJoseph Chen 	}
38425c13168SJoseph Chen 
38525c13168SJoseph Chen 	return ret;
38641766119SJoseph Chen }
38741766119SJoseph Chen 
virq_disable(int irq)38841766119SJoseph Chen static int virq_disable(int irq)
38941766119SJoseph Chen {
39025c13168SJoseph Chen 	struct virq_desc *desc = find_virq_desc(irq);
39125c13168SJoseph Chen 	int ret;
39225c13168SJoseph Chen 
39341766119SJoseph Chen 	if (bad_virq(irq))
39441766119SJoseph Chen 		return -EINVAL;
39541766119SJoseph Chen 
39625c13168SJoseph Chen 	ret = __virq_enable(irq, 0);
39725c13168SJoseph Chen 	if (!ret) {
39825c13168SJoseph Chen 		if (desc->use_count <= 0)
39925c13168SJoseph Chen 			return ret;
40025c13168SJoseph Chen 
40125c13168SJoseph Chen 		if (desc->use_count == 1)
40225c13168SJoseph Chen 			irq_handler_disable(desc->pirq);
40325c13168SJoseph Chen 		desc->use_count--;
40425c13168SJoseph Chen 	}
40525c13168SJoseph Chen 
40625c13168SJoseph Chen 	return ret;
40741766119SJoseph Chen }
40841766119SJoseph Chen 
40941766119SJoseph Chen struct irq_chip virq_generic_chip = {
41041766119SJoseph Chen 	.name		= "virq-irq-chip",
41141766119SJoseph Chen 	.irq_init	= virq_init,
41241766119SJoseph Chen 	.irq_enable	= virq_enable,
41341766119SJoseph Chen 	.irq_disable	= virq_disable,
41441766119SJoseph Chen };
41541766119SJoseph Chen 
arch_virq_get_irqchip(void)41641766119SJoseph Chen struct irq_chip *arch_virq_get_irqchip(void)
41741766119SJoseph Chen {
41841766119SJoseph Chen 	return &virq_generic_chip;
41941766119SJoseph Chen }
420