xref: /rk3399_rockchip-uboot/drivers/irq/irq-generic.c (revision 54cbaa17c088316914e003635f261642dca9b5a3)
14e6670feSJoseph Chen /*
24e6670feSJoseph Chen  * (C) Copyright 2017 Rockchip Electronics Co., Ltd
34e6670feSJoseph Chen  *
44e6670feSJoseph Chen  * SPDX-License-Identifier:     GPL-2.0+
54e6670feSJoseph Chen  */
64e6670feSJoseph Chen 
74e6670feSJoseph Chen #include <asm/io.h>
84e6670feSJoseph Chen #include <asm/u-boot-arm.h>
9ae63f119SJoseph Chen #include <dm.h>
104e6670feSJoseph Chen #include <irq-generic.h>
11cf344252SJoseph Chen #include "irq-internal.h"
124e6670feSJoseph Chen 
134e6670feSJoseph Chen DECLARE_GLOBAL_DATA_PTR;
144e6670feSJoseph Chen 
154e6670feSJoseph Chen struct irq_desc {
1642865eb5SJoseph Chen 	interrupt_handler_t *handle_irq;
1742865eb5SJoseph Chen 	void *data;
18ae63f119SJoseph Chen 	u32 flag;
19ae63f119SJoseph Chen 	u32 count;
204e6670feSJoseph Chen };
214e6670feSJoseph Chen 
22cf344252SJoseph Chen struct irqchip_desc {
23cf344252SJoseph Chen 	struct irq_chip *gic;
24cf344252SJoseph Chen 	struct irq_chip *gpio;
2541766119SJoseph Chen 	struct irq_chip *virq;
2641766119SJoseph Chen 
272c4e90c1SJoseph Chen 	int suspend_irq[PLATFORM_SUSPEND_MAX_IRQ];
282c4e90c1SJoseph Chen 	int suspend_num;
29cf344252SJoseph Chen };
304e6670feSJoseph Chen 
31cf344252SJoseph Chen static struct irq_desc irq_desc[PLATFORM_MAX_IRQ];
32cf344252SJoseph Chen static struct irqchip_desc irqchip;
33cf344252SJoseph Chen static bool intr_setup;
34cf344252SJoseph Chen 
bad_irq(int irq)35cf344252SJoseph Chen int bad_irq(int irq)
364e6670feSJoseph Chen {
37cf344252SJoseph Chen 	if (!intr_setup) {
38cf344252SJoseph Chen 		IRQ_W("Interrupt framework is not setup\n");
394e6670feSJoseph Chen 		return -EINVAL;
404e6670feSJoseph Chen 	}
414e6670feSJoseph Chen 
4241766119SJoseph Chen 	if (irq < PLATFORM_MAX_IRQ) {
4341766119SJoseph Chen 		if (!irq_desc[irq].handle_irq)
4441766119SJoseph Chen 			return -EINVAL;
4541766119SJoseph Chen 	} else {
4641766119SJoseph Chen 		if (bad_virq(irq)) {
4741766119SJoseph Chen 			IRQ_E("Unknown virq: %d\n", irq);
484e6670feSJoseph Chen 			return -EINVAL;
494e6670feSJoseph Chen 		}
5041766119SJoseph Chen 	}
514e6670feSJoseph Chen 
5241766119SJoseph Chen 	return 0;
534e6670feSJoseph Chen }
544e6670feSJoseph Chen 
554e6670feSJoseph Chen /* general interrupt handler for gpio chip */
__generic_gpio_handle_irq(int irq)56269512fdSJoseph Chen void __generic_gpio_handle_irq(int irq)
574e6670feSJoseph Chen {
58269512fdSJoseph Chen 	if (bad_irq(irq))
594e6670feSJoseph Chen 		return;
604e6670feSJoseph Chen 
61cf344252SJoseph Chen 	if (irq < PLATFORM_GIC_MAX_IRQ) {
62cf344252SJoseph Chen 		IRQ_W("IRQ %d: Invalid GPIO irq\n", irq);
634e6670feSJoseph Chen 		return;
644e6670feSJoseph Chen 	}
654e6670feSJoseph Chen 
66ae63f119SJoseph Chen 	if (irq_desc[irq].handle_irq) {
67ae63f119SJoseph Chen 		irq_desc[irq].count++;
68cf344252SJoseph Chen 		irq_desc[irq].handle_irq(irq, irq_desc[irq].data);
694e6670feSJoseph Chen 	}
70ae63f119SJoseph Chen }
714e6670feSJoseph Chen 
__do_generic_irq_handler(void)72269512fdSJoseph Chen void __do_generic_irq_handler(void)
734e6670feSJoseph Chen {
74cf344252SJoseph Chen 	u32 irq;
754e6670feSJoseph Chen 
76cf344252SJoseph Chen 	assert(irqchip.gic->irq_get);
77cf344252SJoseph Chen 	assert(irqchip.gic->irq_eoi);
78cf344252SJoseph Chen 
79cf344252SJoseph Chen 	irq = irqchip.gic->irq_get();
80cf344252SJoseph Chen 
81cf344252SJoseph Chen 	if (irq < PLATFORM_GIC_MAX_IRQ) {
82ae63f119SJoseph Chen 		if (irq_desc[irq].handle_irq) {
83ae63f119SJoseph Chen 			irq_desc[irq].count++;
84cf344252SJoseph Chen 			irq_desc[irq].handle_irq(irq, irq_desc[irq].data);
854e6670feSJoseph Chen 		}
86ae63f119SJoseph Chen 	}
874e6670feSJoseph Chen 
88cf344252SJoseph Chen 	irqchip.gic->irq_eoi(irq);
894e6670feSJoseph Chen }
904e6670feSJoseph Chen 
irq_is_busy(int irq)918696cc38SJoseph Chen int irq_is_busy(int irq)
928696cc38SJoseph Chen {
93cf344252SJoseph Chen 	return (irq >= 0 && irq_desc[irq].handle_irq) ? -EBUSY : 0;
948696cc38SJoseph Chen }
958696cc38SJoseph Chen 
bad_irq_chip(struct irq_chip * chip)96269512fdSJoseph Chen static int bad_irq_chip(struct irq_chip *chip)
974e6670feSJoseph Chen {
98cf344252SJoseph Chen 	return (!chip->name || !chip->irq_init || !chip->irq_enable ||
9941766119SJoseph Chen 		!chip->irq_disable) ? -EINVAL : 0;
1004e6670feSJoseph Chen }
1014e6670feSJoseph Chen 
__do_arch_irq_init(void)102269512fdSJoseph Chen static int __do_arch_irq_init(void)
1034e6670feSJoseph Chen {
104cf344252SJoseph Chen 	int ret = -EINVAL;
1054e6670feSJoseph Chen 
106cf344252SJoseph Chen 	/* After relocation done, bss data intr_setup */
1074e6670feSJoseph Chen 	if (!(gd->flags & GD_FLG_RELOC)) {
108269512fdSJoseph Chen 		IRQ_W("Interrupt framework should initialize after reloc\n");
1094e6670feSJoseph Chen 		return -EINVAL;
1104e6670feSJoseph Chen 	}
1114e6670feSJoseph Chen 
1124e6670feSJoseph Chen 	/*
113269512fdSJoseph Chen 	 * We set true before arch_gpio_irq_init() to avoid fail when
114269512fdSJoseph Chen 	 * request irq for gpio banks.
1154e6670feSJoseph Chen 	 */
116cf344252SJoseph Chen 	intr_setup = true;
117cf344252SJoseph Chen 	memset(irq_desc, 0, sizeof(irq_desc));
1184e6670feSJoseph Chen 
119cf344252SJoseph Chen 	irqchip.gic = arch_gic_get_irqchip();
120cf344252SJoseph Chen 	if (bad_irq_chip(irqchip.gic)) {
121269512fdSJoseph Chen 		IRQ_E("Bad gic irqchip\n");
1224e6670feSJoseph Chen 		goto out;
1234e6670feSJoseph Chen 	}
1244e6670feSJoseph Chen 
125cf344252SJoseph Chen 	irqchip.gpio = arch_gpio_get_irqchip();
126cf344252SJoseph Chen 	if (bad_irq_chip(irqchip.gpio)) {
127269512fdSJoseph Chen 		IRQ_E("Bad gpio irqchip\n");
1284e6670feSJoseph Chen 		goto out;
1294e6670feSJoseph Chen 	}
1304e6670feSJoseph Chen 
13141766119SJoseph Chen 	irqchip.virq = arch_virq_get_irqchip();
13241766119SJoseph Chen 	if (bad_irq_chip(irqchip.virq)) {
13341766119SJoseph Chen 		IRQ_E("Bad virq irqchip\n");
13441766119SJoseph Chen 		goto out;
13541766119SJoseph Chen 	}
13641766119SJoseph Chen 
137cf344252SJoseph Chen 	ret = irqchip.gic->irq_init();
138cf344252SJoseph Chen 	if (ret) {
139cf344252SJoseph Chen 		IRQ_E("GIC Interrupt setup failed, ret=%d\n", ret);
1404e6670feSJoseph Chen 		goto out;
1414e6670feSJoseph Chen 	}
1424e6670feSJoseph Chen 
143cf344252SJoseph Chen 	ret = irqchip.gpio->irq_init();
144cf344252SJoseph Chen 	if (ret) {
145cf344252SJoseph Chen 		IRQ_E("GPIO Interrupt setup failed, ret=%d\n", ret);
1464e6670feSJoseph Chen 		goto out;
1474e6670feSJoseph Chen 	}
1484e6670feSJoseph Chen 
14941766119SJoseph Chen 	ret = irqchip.virq->irq_init();
15041766119SJoseph Chen 	if (ret) {
15141766119SJoseph Chen 		IRQ_E("VIRQ Interrupt setup failed, ret=%d\n", ret);
15241766119SJoseph Chen 		goto out;
15341766119SJoseph Chen 	}
15441766119SJoseph Chen 
1554e6670feSJoseph Chen 	return 0;
1564e6670feSJoseph Chen 
1574e6670feSJoseph Chen out:
158cf344252SJoseph Chen 	intr_setup = false;
1594e6670feSJoseph Chen 
160cf344252SJoseph Chen 	return ret;
1614e6670feSJoseph Chen }
1624e6670feSJoseph Chen 
irq_handler_enable(int irq)1634e6670feSJoseph Chen int irq_handler_enable(int irq)
1644e6670feSJoseph Chen {
165ae63f119SJoseph Chen 	int ret;
166ae63f119SJoseph Chen 
167269512fdSJoseph Chen 	if (bad_irq(irq))
1684e6670feSJoseph Chen 		return -EINVAL;
1694e6670feSJoseph Chen 
170cf344252SJoseph Chen 	if (irq < PLATFORM_GIC_MAX_IRQ)
171ae63f119SJoseph Chen 		ret = irqchip.gic->irq_enable(irq);
17241766119SJoseph Chen 	else if (irq < PLATFORM_GPIO_MAX_IRQ)
173ae63f119SJoseph Chen 		ret = irqchip.gpio->irq_enable(irq);
17441766119SJoseph Chen 	else
175ae63f119SJoseph Chen 		ret = irqchip.virq->irq_enable(irq);
176ae63f119SJoseph Chen 
177ae63f119SJoseph Chen 	if (!ret && irq < PLATFORM_MAX_IRQ)
178ae63f119SJoseph Chen 		irq_desc[irq].flag |= IRQ_FLG_ENABLE;
179ae63f119SJoseph Chen 
180ae63f119SJoseph Chen 	return ret;
1814e6670feSJoseph Chen }
1824e6670feSJoseph Chen 
irq_handler_disable(int irq)1834e6670feSJoseph Chen int irq_handler_disable(int irq)
1844e6670feSJoseph Chen {
185ae63f119SJoseph Chen 	int ret;
186ae63f119SJoseph Chen 
187269512fdSJoseph Chen 	if (bad_irq(irq))
1884e6670feSJoseph Chen 		return -EINVAL;
1894e6670feSJoseph Chen 
190cf344252SJoseph Chen 	if (irq < PLATFORM_GIC_MAX_IRQ)
191ae63f119SJoseph Chen 		ret = irqchip.gic->irq_disable(irq);
19241766119SJoseph Chen 	else if (irq < PLATFORM_GPIO_MAX_IRQ)
193ae63f119SJoseph Chen 		ret = irqchip.gpio->irq_disable(irq);
19441766119SJoseph Chen 	else
195ae63f119SJoseph Chen 		ret = irqchip.virq->irq_disable(irq);
196ae63f119SJoseph Chen 
197ae63f119SJoseph Chen 	if (!ret && irq < PLATFORM_MAX_IRQ)
198ae63f119SJoseph Chen 		irq_desc[irq].flag &= ~IRQ_FLG_ENABLE;
199ae63f119SJoseph Chen 
200ae63f119SJoseph Chen 	return ret;
2014e6670feSJoseph Chen }
2024e6670feSJoseph Chen 
irq_set_irq_type(int irq,unsigned int type)2034e6670feSJoseph Chen int irq_set_irq_type(int irq, unsigned int type)
2044e6670feSJoseph Chen {
205269512fdSJoseph Chen 	if (bad_irq(irq))
2064e6670feSJoseph Chen 		return -EINVAL;
2074e6670feSJoseph Chen 
208cf344252SJoseph Chen 	if (irq < PLATFORM_GIC_MAX_IRQ)
209cf344252SJoseph Chen 		return irqchip.gic->irq_set_type(irq, type);
21041766119SJoseph Chen 	else if (irq < PLATFORM_GPIO_MAX_IRQ)
211cf344252SJoseph Chen 		return irqchip.gpio->irq_set_type(irq, type);
21241766119SJoseph Chen 	else
21341766119SJoseph Chen 		return -ENOSYS;
2144e6670feSJoseph Chen }
2154e6670feSJoseph Chen 
irq_revert_irq_type(int irq)216c234b81eSJoseph Chen int irq_revert_irq_type(int irq)
217c234b81eSJoseph Chen {
218269512fdSJoseph Chen 	if (bad_irq(irq))
219c234b81eSJoseph Chen 		return -EINVAL;
220c234b81eSJoseph Chen 
221cf344252SJoseph Chen 	if (irq < PLATFORM_GIC_MAX_IRQ)
222c234b81eSJoseph Chen 		return 0;
22341766119SJoseph Chen 	else if (irq < PLATFORM_GPIO_MAX_IRQ)
224cf344252SJoseph Chen 		return irqchip.gpio->irq_revert_type(irq);
22541766119SJoseph Chen 	else
22641766119SJoseph Chen 		return -ENOSYS;
227c234b81eSJoseph Chen }
228c234b81eSJoseph Chen 
irq_get_gpio_level(int irq)229c234b81eSJoseph Chen int irq_get_gpio_level(int irq)
230c234b81eSJoseph Chen {
231269512fdSJoseph Chen 	if (bad_irq(irq))
232c234b81eSJoseph Chen 		return -EINVAL;
233c234b81eSJoseph Chen 
234cf344252SJoseph Chen 	if (irq < PLATFORM_GIC_MAX_IRQ)
235c234b81eSJoseph Chen 		return 0;
23641766119SJoseph Chen 	else if (irq < PLATFORM_GPIO_MAX_IRQ)
237cf344252SJoseph Chen 		return irqchip.gpio->irq_get_gpio_level(irq);
23841766119SJoseph Chen 	else
23941766119SJoseph Chen 		return -ENOSYS;
240c234b81eSJoseph Chen }
241c234b81eSJoseph Chen 
irq_install_handler(int irq,interrupt_handler_t * handler,void * data)2424e6670feSJoseph Chen void irq_install_handler(int irq, interrupt_handler_t *handler, void *data)
2434e6670feSJoseph Chen {
244cf344252SJoseph Chen 	if (!intr_setup) {
245cf344252SJoseph Chen 		IRQ_W("Interrupt framework is not intr_setup\n");
2464e6670feSJoseph Chen 		return;
247269512fdSJoseph Chen 	}
248269512fdSJoseph Chen 
24941766119SJoseph Chen 	if (irq < PLATFORM_MAX_IRQ) {
250cf344252SJoseph Chen 		if (!handler || irq_desc[irq].handle_irq)
251cf344252SJoseph Chen 			return;
252cf344252SJoseph Chen 		irq_desc[irq].handle_irq = handler;
253cf344252SJoseph Chen 		irq_desc[irq].data = data;
25441766119SJoseph Chen 	} else {
25541766119SJoseph Chen 		virq_install_handler(irq, handler, data);
25641766119SJoseph Chen 	}
2574e6670feSJoseph Chen }
2584e6670feSJoseph Chen 
irq_free_handler(int irq)2594e6670feSJoseph Chen void irq_free_handler(int irq)
2604e6670feSJoseph Chen {
2610e508c4fSJoseph Chen 	if (irq_handler_disable(irq))
2624e6670feSJoseph Chen 		return;
2634e6670feSJoseph Chen 
26441766119SJoseph Chen 	if (irq < PLATFORM_MAX_IRQ) {
265cf344252SJoseph Chen 		irq_desc[irq].handle_irq = NULL;
266cf344252SJoseph Chen 		irq_desc[irq].data = NULL;
26741766119SJoseph Chen 	} else {
26841766119SJoseph Chen 		virq_free_handler(irq);
26941766119SJoseph Chen 	}
2704e6670feSJoseph Chen }
2714e6670feSJoseph Chen 
irq_handler_enable_suspend_only(int irq)2722c4e90c1SJoseph Chen int irq_handler_enable_suspend_only(int irq)
2732c4e90c1SJoseph Chen {
2742c4e90c1SJoseph Chen 	if (bad_irq(irq))
2752c4e90c1SJoseph Chen 		return -EINVAL;
2762c4e90c1SJoseph Chen 
2772c4e90c1SJoseph Chen 	if (irqchip.suspend_num >= PLATFORM_SUSPEND_MAX_IRQ) {
2782c4e90c1SJoseph Chen 		printf("Over max count(%d) of suspend irq\n",
2792c4e90c1SJoseph Chen 		       PLATFORM_SUSPEND_MAX_IRQ);
2802c4e90c1SJoseph Chen 		return -EPERM;
2812c4e90c1SJoseph Chen 	}
2822c4e90c1SJoseph Chen 
2832c4e90c1SJoseph Chen 	irqchip.suspend_irq[irqchip.suspend_num++] = irq;
2842c4e90c1SJoseph Chen 	return 0;
2852c4e90c1SJoseph Chen }
2862c4e90c1SJoseph Chen 
irqs_suspend(void)287ed837edfSJoseph Chen int irqs_suspend(void)
288ed837edfSJoseph Chen {
2892c4e90c1SJoseph Chen 	int i;
2902c4e90c1SJoseph Chen 
2912c4e90c1SJoseph Chen 	for (i = 0; i < irqchip.suspend_num; i++)
2922c4e90c1SJoseph Chen 		irq_handler_enable(irqchip.suspend_irq[i]);
2932c4e90c1SJoseph Chen 
294cf344252SJoseph Chen 	return irqchip.gic->irq_suspend();
295ed837edfSJoseph Chen }
296ed837edfSJoseph Chen 
irqs_resume(void)297ed837edfSJoseph Chen int irqs_resume(void)
298ed837edfSJoseph Chen {
2992c4e90c1SJoseph Chen 	int i;
3002c4e90c1SJoseph Chen 
3012c4e90c1SJoseph Chen 	for (i = 0; i < irqchip.suspend_num; i++)
3022c4e90c1SJoseph Chen 		irq_handler_disable(irqchip.suspend_irq[i]);
3032c4e90c1SJoseph Chen 
304cf344252SJoseph Chen 	return irqchip.gic->irq_resume();
305ed837edfSJoseph Chen }
306ed837edfSJoseph Chen 
3074e6670feSJoseph Chen #ifdef CONFIG_ARM64
do_irq(struct pt_regs * pt_regs,unsigned int esr)3084e6670feSJoseph Chen void do_irq(struct pt_regs *pt_regs, unsigned int esr)
3094e6670feSJoseph Chen {
310c563adc7SJoseph Chen #ifdef CONFIG_ROCKCHIP_DEBUGGER
311c563adc7SJoseph Chen 	printf("\n>>> Rockchip Debugger:\n");
312c563adc7SJoseph Chen 	show_regs(pt_regs);
313c563adc7SJoseph Chen #endif
314c563adc7SJoseph Chen 
315269512fdSJoseph Chen 	__do_generic_irq_handler();
3164e6670feSJoseph Chen }
3174e6670feSJoseph Chen #else
do_irq(struct pt_regs * pt_regs)3184e6670feSJoseph Chen void do_irq(struct pt_regs *pt_regs)
3194e6670feSJoseph Chen {
320c563adc7SJoseph Chen #ifdef CONFIG_ROCKCHIP_DEBUGGER
321c563adc7SJoseph Chen 	printf("\n>>> Rockchp Debugger:\n");
322c563adc7SJoseph Chen 	show_regs(pt_regs);
323c563adc7SJoseph Chen #endif
324c563adc7SJoseph Chen 
325269512fdSJoseph Chen 	__do_generic_irq_handler();
3264e6670feSJoseph Chen }
3274e6670feSJoseph Chen #endif
3284e6670feSJoseph Chen 
arch_interrupt_init(void)3294e6670feSJoseph Chen int arch_interrupt_init(void)
3304e6670feSJoseph Chen {
3314e6670feSJoseph Chen #ifndef CONFIG_ARM64
3324e6670feSJoseph Chen 	unsigned long cpsr __maybe_unused;
3334e6670feSJoseph Chen 
3344e6670feSJoseph Chen 	/* stack has been reserved in: arch_reserve_stacks() */
3354e6670feSJoseph Chen 	IRQ_STACK_START = gd->irq_sp;
336c15709b5SJoseph Chen 	IRQ_STACK_START_IN = gd->irq_sp;
3374e6670feSJoseph Chen 
3384e6670feSJoseph Chen 	__asm__ __volatile__("mrs %0, cpsr\n"
3394e6670feSJoseph Chen 			     : "=r" (cpsr)
3404e6670feSJoseph Chen 			     :
3414e6670feSJoseph Chen 			     : "memory");
3424e6670feSJoseph Chen 
3434e6670feSJoseph Chen 	__asm__ __volatile__("msr cpsr_c, %0\n"
3444e6670feSJoseph Chen 			     "mov sp, %1\n"
3454e6670feSJoseph Chen 			     :
3464e6670feSJoseph Chen 			     : "r" (IRQ_MODE | I_BIT |
3474e6670feSJoseph Chen 				    F_BIT | (cpsr & ~FIQ_MODE)),
3484e6670feSJoseph Chen 			       "r" (IRQ_STACK_START)
3494e6670feSJoseph Chen 			     : "memory");
3504e6670feSJoseph Chen 
3514e6670feSJoseph Chen 	__asm__ __volatile__("msr cpsr_c, %0"
3524e6670feSJoseph Chen 			     :
3534e6670feSJoseph Chen 			     : "r" (cpsr)
3544e6670feSJoseph Chen 			     : "memory");
3554e6670feSJoseph Chen #endif
356269512fdSJoseph Chen 	return __do_arch_irq_init();
3574e6670feSJoseph Chen }
3584e6670feSJoseph Chen 
interrupt_init(void)3594e6670feSJoseph Chen int interrupt_init(void)
3604e6670feSJoseph Chen {
3614e6670feSJoseph Chen 	return arch_interrupt_init();
3624e6670feSJoseph Chen }
3634e6670feSJoseph Chen 
enable_interrupts(void)3644e6670feSJoseph Chen void enable_interrupts(void)
3654e6670feSJoseph Chen {
366*54cbaa17SJoseph Chen 	local_irq_enable();
3674e6670feSJoseph Chen }
3684e6670feSJoseph Chen 
disable_interrupts(void)3694e6670feSJoseph Chen int disable_interrupts(void)
3704e6670feSJoseph Chen {
371*54cbaa17SJoseph Chen 	int flags;
372*54cbaa17SJoseph Chen 
373*54cbaa17SJoseph Chen 	local_irq_save(flags);
374*54cbaa17SJoseph Chen 	return flags;
3754e6670feSJoseph Chen }
37692f4f090SJoseph Chen 
do_dump_irqs(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])37792f4f090SJoseph Chen static int do_dump_irqs(cmd_tbl_t *cmdtp, int flag,
37892f4f090SJoseph Chen 			int argc, char * const argv[])
37992f4f090SJoseph Chen 
38092f4f090SJoseph Chen {
38192f4f090SJoseph Chen 	struct udevice *dev;
38292f4f090SJoseph Chen 	char *drv_name;
38392f4f090SJoseph Chen 	int pirq;
38492f4f090SJoseph Chen 
38525c13168SJoseph Chen 	printf(" IRQ    En    Handler       Driver         Name              Trig\n");
38692f4f090SJoseph Chen 	printf("----------------------------------------------------------------------\n");
38792f4f090SJoseph Chen 
38892f4f090SJoseph Chen 	for (pirq = 0; pirq < PLATFORM_MAX_IRQ; pirq++) {
38992f4f090SJoseph Chen 		if (!irq_desc[pirq].handle_irq)
39092f4f090SJoseph Chen 			continue;
39192f4f090SJoseph Chen 
39292f4f090SJoseph Chen 		dev = (struct udevice *)irq_desc[pirq].data;
39392f4f090SJoseph Chen 		if (strstr(dev->name, "gpio"))
39492f4f090SJoseph Chen 			drv_name = "IRQ";
39592f4f090SJoseph Chen 		else
39692f4f090SJoseph Chen 			drv_name = dev->driver->name;
39792f4f090SJoseph Chen 
39892f4f090SJoseph Chen 		printf(" %3d	%d     0x%08lx    %-12s    %-12s       %d\n",
39992f4f090SJoseph Chen 		       pirq, irq_desc[pirq].flag & IRQ_FLG_ENABLE ? 1 : 0,
40092f4f090SJoseph Chen 		       (ulong)irq_desc[pirq].handle_irq,
40192f4f090SJoseph Chen 		       drv_name, dev->name, irq_desc[pirq].count);
40292f4f090SJoseph Chen 
40392f4f090SJoseph Chen 		virqs_show(pirq);
40492f4f090SJoseph Chen 	}
40592f4f090SJoseph Chen 
40692f4f090SJoseph Chen 	return 0;
40792f4f090SJoseph Chen }
40892f4f090SJoseph Chen 
40992f4f090SJoseph Chen U_BOOT_CMD(
41092f4f090SJoseph Chen 	dump_irqs, 1, 1, do_dump_irqs, "Dump IRQs", ""
41192f4f090SJoseph Chen );
412