From ae63f11992747d8645f3595abc110cd692f98787 Mon Sep 17 00:00:00 2001 From: Joseph Chen Date: Fri, 9 Aug 2019 14:59:06 +0800 Subject: [PATCH] irq: add trigger count and enable/disable stat Change-Id: I3f29c4e3e420be0fe545a2f55f238345a17eaa6a Signed-off-by: Joseph Chen --- drivers/irq/irq-generic.c | 37 +++++++++++++++++++++++++++++-------- drivers/irq/irq-gpio.c | 12 +++++++++++- drivers/irq/irq-internal.h | 5 +++++ drivers/irq/virq.c | 12 +++++++++++- 4 files changed, 56 insertions(+), 10 deletions(-) diff --git a/drivers/irq/irq-generic.c b/drivers/irq/irq-generic.c index 9d3c75ab60..fc2695bbe5 100644 --- a/drivers/irq/irq-generic.c +++ b/drivers/irq/irq-generic.c @@ -6,6 +6,7 @@ #include #include +#include #include #include "irq-internal.h" @@ -14,6 +15,8 @@ DECLARE_GLOBAL_DATA_PTR; struct irq_desc { interrupt_handler_t *handle_irq; void *data; + u32 flag; + u32 count; }; struct irqchip_desc { @@ -60,8 +63,10 @@ void __generic_gpio_handle_irq(int irq) return; } - if (irq_desc[irq].handle_irq) + if (irq_desc[irq].handle_irq) { + irq_desc[irq].count++; irq_desc[irq].handle_irq(irq, irq_desc[irq].data); + } } void __do_generic_irq_handler(void) @@ -74,8 +79,10 @@ void __do_generic_irq_handler(void) irq = irqchip.gic->irq_get(); if (irq < PLATFORM_GIC_MAX_IRQ) { - if (irq_desc[irq].handle_irq) + if (irq_desc[irq].handle_irq) { + irq_desc[irq].count++; irq_desc[irq].handle_irq(irq, irq_desc[irq].data); + } } irqchip.gic->irq_eoi(irq); @@ -155,28 +162,42 @@ out: int irq_handler_enable(int irq) { + int ret; + if (bad_irq(irq)) return -EINVAL; if (irq < PLATFORM_GIC_MAX_IRQ) - return irqchip.gic->irq_enable(irq); + ret = irqchip.gic->irq_enable(irq); else if (irq < PLATFORM_GPIO_MAX_IRQ) - return irqchip.gpio->irq_enable(irq); + ret = irqchip.gpio->irq_enable(irq); else - return irqchip.virq->irq_enable(irq); + ret = irqchip.virq->irq_enable(irq); + + if (!ret && irq < PLATFORM_MAX_IRQ) + irq_desc[irq].flag |= IRQ_FLG_ENABLE; + + return ret; } int irq_handler_disable(int irq) { + int ret; + if (bad_irq(irq)) return -EINVAL; if (irq < PLATFORM_GIC_MAX_IRQ) - return irqchip.gic->irq_disable(irq); + ret = irqchip.gic->irq_disable(irq); else if (irq < PLATFORM_GPIO_MAX_IRQ) - return irqchip.gpio->irq_disable(irq); + ret = irqchip.gpio->irq_disable(irq); else - return irqchip.virq->irq_disable(irq); + ret = irqchip.virq->irq_disable(irq); + + if (!ret && irq < PLATFORM_MAX_IRQ) + irq_desc[irq].flag &= ~IRQ_FLG_ENABLE; + + return ret; } int irq_set_irq_type(int irq, unsigned int type) diff --git a/drivers/irq/irq-gpio.c b/drivers/irq/irq-gpio.c index 403feae7b3..0fbb40752b 100644 --- a/drivers/irq/irq-gpio.c +++ b/drivers/irq/irq-gpio.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: GPL-2.0+ */ +#include +#include #include "irq-internal.h" typedef enum GPIOIntType { @@ -307,14 +309,22 @@ static int gpio_irq_init(void) int i = 0; for (i = 0; i < GPIO_BANK_NUM; i++) { + struct udevice *dev; + + dev = malloc(sizeof(*dev)); + if (!dev) + return -ENOMEM; + bank = gpio_id_to_bank(i); if (bank) { + dev->name = bank->name; + /* disable gpio pin interrupt */ writel(0, bank->regbase + GPIO_INTEN); /* register gpio group irq handler */ irq_install_handler(IRQ_GPIO0 + bank->id, - (interrupt_handler_t *)generic_gpio_handle_irq, NULL); + (interrupt_handler_t *)generic_gpio_handle_irq, dev); /* default disable all gpio group interrupt */ irq_handler_disable(IRQ_GPIO0 + bank->id); diff --git a/drivers/irq/irq-internal.h b/drivers/irq/irq-internal.h index cb00efa268..0b03815b18 100644 --- a/drivers/irq/irq-internal.h +++ b/drivers/irq/irq-internal.h @@ -12,6 +12,11 @@ #include #include "irq-internal.h" +/* + * IRQ FLAG + */ +#define IRQ_FLG_ENABLE BIT(0) + /* * IRQ-NUMBERS */ diff --git a/drivers/irq/virq.c b/drivers/irq/virq.c index 3e5c23f90a..24756a1b4e 100644 --- a/drivers/irq/virq.c +++ b/drivers/irq/virq.c @@ -25,6 +25,9 @@ static u32 virq_id_alloc(void) struct virq_data { int irq; + u32 flag; + u32 count; + void *data; interrupt_handler_t *handle_irq; }; @@ -190,8 +193,10 @@ void virq_chip_generic_handler(int pirq, void *pdata) irq = vdata[i].irq; data = vdata[i].data; - if (vdata[i].handle_irq) + if (vdata[i].handle_irq) { + vdata[i].count++; vdata[i].handle_irq(irq, data); + } } } @@ -315,6 +320,11 @@ static int __virq_enable(int irq, int enable) return ret; } + if (enable) + desc->virqs[virq].flag |= IRQ_FLG_ENABLE; + else + desc->virqs[virq].flag &= ~IRQ_FLG_ENABLE; + return 0; }