irq: add trigger count and enable/disable stat
Change-Id: I3f29c4e3e420be0fe545a2f55f238345a17eaa6a Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
This commit is contained in:
parent
2c4e90c1f8
commit
ae63f11992
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/u-boot-arm.h>
|
#include <asm/u-boot-arm.h>
|
||||||
|
#include <dm.h>
|
||||||
#include <irq-generic.h>
|
#include <irq-generic.h>
|
||||||
#include "irq-internal.h"
|
#include "irq-internal.h"
|
||||||
|
|
||||||
|
|
@ -14,6 +15,8 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||||
struct irq_desc {
|
struct irq_desc {
|
||||||
interrupt_handler_t *handle_irq;
|
interrupt_handler_t *handle_irq;
|
||||||
void *data;
|
void *data;
|
||||||
|
u32 flag;
|
||||||
|
u32 count;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct irqchip_desc {
|
struct irqchip_desc {
|
||||||
|
|
@ -60,9 +63,11 @@ void __generic_gpio_handle_irq(int irq)
|
||||||
return;
|
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);
|
irq_desc[irq].handle_irq(irq, irq_desc[irq].data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void __do_generic_irq_handler(void)
|
void __do_generic_irq_handler(void)
|
||||||
{
|
{
|
||||||
|
|
@ -74,9 +79,11 @@ void __do_generic_irq_handler(void)
|
||||||
irq = irqchip.gic->irq_get();
|
irq = irqchip.gic->irq_get();
|
||||||
|
|
||||||
if (irq < PLATFORM_GIC_MAX_IRQ) {
|
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);
|
irq_desc[irq].handle_irq(irq, irq_desc[irq].data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
irqchip.gic->irq_eoi(irq);
|
irqchip.gic->irq_eoi(irq);
|
||||||
}
|
}
|
||||||
|
|
@ -155,28 +162,42 @@ out:
|
||||||
|
|
||||||
int irq_handler_enable(int irq)
|
int irq_handler_enable(int irq)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (bad_irq(irq))
|
if (bad_irq(irq))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (irq < PLATFORM_GIC_MAX_IRQ)
|
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)
|
else if (irq < PLATFORM_GPIO_MAX_IRQ)
|
||||||
return irqchip.gpio->irq_enable(irq);
|
ret = irqchip.gpio->irq_enable(irq);
|
||||||
else
|
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 irq_handler_disable(int irq)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (bad_irq(irq))
|
if (bad_irq(irq))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (irq < PLATFORM_GIC_MAX_IRQ)
|
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)
|
else if (irq < PLATFORM_GPIO_MAX_IRQ)
|
||||||
return irqchip.gpio->irq_disable(irq);
|
ret = irqchip.gpio->irq_disable(irq);
|
||||||
else
|
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)
|
int irq_set_irq_type(int irq, unsigned int type)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
* SPDX-License-Identifier: GPL-2.0+
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <dm.h>
|
||||||
|
#include <malloc.h>
|
||||||
#include "irq-internal.h"
|
#include "irq-internal.h"
|
||||||
|
|
||||||
typedef enum GPIOIntType {
|
typedef enum GPIOIntType {
|
||||||
|
|
@ -307,14 +309,22 @@ static int gpio_irq_init(void)
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for (i = 0; i < GPIO_BANK_NUM; i++) {
|
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);
|
bank = gpio_id_to_bank(i);
|
||||||
if (bank) {
|
if (bank) {
|
||||||
|
dev->name = bank->name;
|
||||||
|
|
||||||
/* disable gpio pin interrupt */
|
/* disable gpio pin interrupt */
|
||||||
writel(0, bank->regbase + GPIO_INTEN);
|
writel(0, bank->regbase + GPIO_INTEN);
|
||||||
|
|
||||||
/* register gpio group irq handler */
|
/* register gpio group irq handler */
|
||||||
irq_install_handler(IRQ_GPIO0 + bank->id,
|
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 */
|
/* default disable all gpio group interrupt */
|
||||||
irq_handler_disable(IRQ_GPIO0 + bank->id);
|
irq_handler_disable(IRQ_GPIO0 + bank->id);
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,11 @@
|
||||||
#include <irq-platform.h>
|
#include <irq-platform.h>
|
||||||
#include "irq-internal.h"
|
#include "irq-internal.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IRQ FLAG
|
||||||
|
*/
|
||||||
|
#define IRQ_FLG_ENABLE BIT(0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IRQ-NUMBERS
|
* IRQ-NUMBERS
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,9 @@ static u32 virq_id_alloc(void)
|
||||||
|
|
||||||
struct virq_data {
|
struct virq_data {
|
||||||
int irq;
|
int irq;
|
||||||
|
u32 flag;
|
||||||
|
u32 count;
|
||||||
|
|
||||||
void *data;
|
void *data;
|
||||||
interrupt_handler_t *handle_irq;
|
interrupt_handler_t *handle_irq;
|
||||||
};
|
};
|
||||||
|
|
@ -190,10 +193,12 @@ void virq_chip_generic_handler(int pirq, void *pdata)
|
||||||
irq = vdata[i].irq;
|
irq = vdata[i].irq;
|
||||||
data = vdata[i].data;
|
data = vdata[i].data;
|
||||||
|
|
||||||
if (vdata[i].handle_irq)
|
if (vdata[i].handle_irq) {
|
||||||
|
vdata[i].count++;
|
||||||
vdata[i].handle_irq(irq, data);
|
vdata[i].handle_irq(irq, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Clear all status register */
|
/* Clear all status register */
|
||||||
for (i = 0; i < chip->num_regs; i++) {
|
for (i = 0; i < chip->num_regs; i++) {
|
||||||
|
|
@ -315,6 +320,11 @@ static int __virq_enable(int irq, int enable)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
desc->virqs[virq].flag |= IRQ_FLG_ENABLE;
|
||||||
|
else
|
||||||
|
desc->virqs[virq].flag &= ~IRQ_FLG_ENABLE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue