irq: clean up code

Change-Id: I51c2713b7c42fa798fee6971a2c91d867042ef70
Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
This commit is contained in:
Joseph Chen 2019-07-27 09:47:43 +08:00 committed by Jianhong Chen
parent 0b84b74a16
commit cf34425241
8 changed files with 122 additions and 160 deletions

View File

@ -7,8 +7,7 @@
#include <asm/io.h>
#include <asm/u-boot-arm.h>
#include <irq-generic.h>
#include "irq-gic.h"
#include "irq-gpio.h"
#include "irq-internal.h"
DECLARE_GLOBAL_DATA_PTR;
@ -17,27 +16,29 @@ struct irq_desc {
void *data;
};
static struct irq_desc irqs_desc[PLATFORM_MAX_IRQS_NR];
static struct irq_chip *gic_irq_chip, *gpio_irq_chip;
static bool initialized;
struct irqchip_desc {
struct irq_chip *gic;
struct irq_chip *gpio;
};
static int bad_irq(int irq)
static struct irq_desc irq_desc[PLATFORM_MAX_IRQ];
static struct irqchip_desc irqchip;
static bool intr_setup;
int bad_irq(int irq)
{
if (irq >= PLATFORM_MAX_IRQS_NR) {
IRQ_W("IRQ %d is out of max supported IRQ(%d)\n",
irq, PLATFORM_MAX_IRQS_NR);
if (!intr_setup) {
IRQ_W("Interrupt framework is not setup\n");
return -EINVAL;
}
if (!irqs_desc[irq].handle_irq)
return -EINVAL;
if (!initialized) {
IRQ_W("Interrupt framework is not initialized\n");
if (irq >= PLATFORM_MAX_IRQ) {
IRQ_W("IRQ %d: Out of max supported IRQ(%d)\n",
irq, PLATFORM_MAX_IRQ);
return -EINVAL;
}
return 0;
return irq_desc[irq].handle_irq ? 0 : -EINVAL;
}
/* general interrupt handler for gpio chip */
@ -46,49 +47,48 @@ void __generic_gpio_handle_irq(int irq)
if (bad_irq(irq))
return;
if (irq < PLATFORM_GIC_IRQS_NR) {
IRQ_W("IRQ %d is not a GPIO irq\n", irq);
if (irq < PLATFORM_GIC_MAX_IRQ) {
IRQ_W("IRQ %d: Invalid GPIO irq\n", irq);
return;
}
if (irqs_desc[irq].handle_irq)
irqs_desc[irq].handle_irq(irq, irqs_desc[irq].data);
if (irq_desc[irq].handle_irq)
irq_desc[irq].handle_irq(irq, irq_desc[irq].data);
}
void __do_generic_irq_handler(void)
{
u32 irq = gic_irq_chip->irq_get();
u32 irq;
if (irq < PLATFORM_GIC_IRQS_NR) {
if (irqs_desc[irq].handle_irq)
irqs_desc[irq].handle_irq(irq, irqs_desc[irq].data);
assert(irqchip.gic->irq_get);
assert(irqchip.gic->irq_eoi);
irq = irqchip.gic->irq_get();
if (irq < PLATFORM_GIC_MAX_IRQ) {
if (irq_desc[irq].handle_irq)
irq_desc[irq].handle_irq(irq, irq_desc[irq].data);
}
gic_irq_chip->irq_eoi(irq);
irqchip.gic->irq_eoi(irq);
}
int irq_is_busy(int irq)
{
return (irq >= 0 && irqs_desc[irq].handle_irq) ? -EBUSY : 0;
return (irq >= 0 && irq_desc[irq].handle_irq) ? -EBUSY : 0;
}
static int bad_irq_chip(struct irq_chip *chip)
{
if (!chip->name ||
!chip->irq_init ||
!chip->irq_enable ||
!chip->irq_disable ||
!chip->irq_set_type)
return -EINVAL;
return 0;
return (!chip->name || !chip->irq_init || !chip->irq_enable ||
!chip->irq_disable || !chip->irq_set_type) ? -EINVAL : 0;
}
static int __do_arch_irq_init(void)
{
int irq, err = -EINVAL;
int ret = -EINVAL;
/* After relocation done, bss data initialized */
/* After relocation done, bss data intr_setup */
if (!(gd->flags & GD_FLG_RELOC)) {
IRQ_W("Interrupt framework should initialize after reloc\n");
return -EINVAL;
@ -98,43 +98,39 @@ static int __do_arch_irq_init(void)
* We set true before arch_gpio_irq_init() to avoid fail when
* request irq for gpio banks.
*/
initialized = true;
intr_setup = true;
memset(irq_desc, 0, sizeof(irq_desc));
for (irq = 0; irq < PLATFORM_MAX_IRQS_NR; irq++) {
irqs_desc[irq].handle_irq = NULL;
irqs_desc[irq].data = NULL;
}
gic_irq_chip = arch_gic_irq_init();
if (bad_irq_chip(gic_irq_chip)) {
IRQ_E("Bad gic irq chip\n");
irqchip.gic = arch_gic_get_irqchip();
if (bad_irq_chip(irqchip.gic)) {
IRQ_E("Bad gic irqchip\n");
goto out;
}
gpio_irq_chip = arch_gpio_irq_init();
if (bad_irq_chip(gpio_irq_chip)) {
IRQ_E("Bad gpio irq chip\n");
irqchip.gpio = arch_gpio_get_irqchip();
if (bad_irq_chip(irqchip.gpio)) {
IRQ_E("Bad gpio irqchip\n");
goto out;
}
err = gic_irq_chip->irq_init();
if (err) {
IRQ_E("GIC interrupt initial failed, ret=%d\n", err);
ret = irqchip.gic->irq_init();
if (ret) {
IRQ_E("GIC Interrupt setup failed, ret=%d\n", ret);
goto out;
}
err = gpio_irq_chip->irq_init();
if (err) {
IRQ_E("GPIO interrupt initial failed, ret=%d\n", err);
ret = irqchip.gpio->irq_init();
if (ret) {
IRQ_E("GPIO Interrupt setup failed, ret=%d\n", ret);
goto out;
}
return 0;
out:
initialized = false;
intr_setup = false;
return err;
return ret;
}
int irq_handler_enable(int irq)
@ -142,10 +138,10 @@ int irq_handler_enable(int irq)
if (bad_irq(irq))
return -EINVAL;
if (irq < PLATFORM_GIC_IRQS_NR)
return gic_irq_chip->irq_enable(irq);
if (irq < PLATFORM_GIC_MAX_IRQ)
return irqchip.gic->irq_enable(irq);
else
return gpio_irq_chip->irq_enable(irq);
return irqchip.gpio->irq_enable(irq);
}
int irq_handler_disable(int irq)
@ -153,10 +149,10 @@ int irq_handler_disable(int irq)
if (bad_irq(irq))
return -EINVAL;
if (irq < PLATFORM_GIC_IRQS_NR)
return gic_irq_chip->irq_disable(irq);
if (irq < PLATFORM_GIC_MAX_IRQ)
return irqchip.gic->irq_disable(irq);
else
return gpio_irq_chip->irq_disable(irq);
return irqchip.gpio->irq_disable(irq);
}
int irq_set_irq_type(int irq, unsigned int type)
@ -164,10 +160,10 @@ int irq_set_irq_type(int irq, unsigned int type)
if (bad_irq(irq))
return -EINVAL;
if (irq < PLATFORM_GIC_IRQS_NR)
return gic_irq_chip->irq_set_type(irq, type);
if (irq < PLATFORM_GIC_MAX_IRQ)
return irqchip.gic->irq_set_type(irq, type);
else
return gpio_irq_chip->irq_set_type(irq, type);
return irqchip.gpio->irq_set_type(irq, type);
}
int irq_revert_irq_type(int irq)
@ -175,10 +171,10 @@ int irq_revert_irq_type(int irq)
if (bad_irq(irq))
return -EINVAL;
if (irq < PLATFORM_GIC_IRQS_NR)
if (irq < PLATFORM_GIC_MAX_IRQ)
return 0;
else
return gpio_irq_chip->irq_revert_type(irq);
return irqchip.gpio->irq_revert_type(irq);
}
int irq_get_gpio_level(int irq)
@ -186,30 +182,30 @@ int irq_get_gpio_level(int irq)
if (bad_irq(irq))
return -EINVAL;
if (irq < PLATFORM_GIC_IRQS_NR)
if (irq < PLATFORM_GIC_MAX_IRQ)
return 0;
else
return gpio_irq_chip->irq_get_gpio_level(irq);
return irqchip.gpio->irq_get_gpio_level(irq);
}
void irq_install_handler(int irq, interrupt_handler_t *handler, void *data)
{
if (irq >= PLATFORM_MAX_IRQS_NR) {
IRQ_W("IRQ %d is out of max supported IRQ(%d)\n",
irq, PLATFORM_MAX_IRQS_NR);
if (!intr_setup) {
IRQ_W("Interrupt framework is not intr_setup\n");
return;
}
if (!handler || irqs_desc[irq].handle_irq)
return;
if (!initialized) {
IRQ_W("Interrupt framework is not initialized\n");
if (irq >= PLATFORM_MAX_IRQ) {
IRQ_W("IRQ %d: Out of max supported IRQ(%d)\n",
irq, PLATFORM_MAX_IRQ);
return;
}
irqs_desc[irq].handle_irq = handler;
irqs_desc[irq].data = data;
if (!handler || irq_desc[irq].handle_irq)
return;
irq_desc[irq].handle_irq = handler;
irq_desc[irq].data = data;
}
void irq_free_handler(int irq)
@ -217,34 +213,18 @@ void irq_free_handler(int irq)
if (irq_handler_disable(irq))
return;
irqs_desc[irq].handle_irq = NULL;
irqs_desc[irq].data = NULL;
irq_desc[irq].handle_irq = NULL;
irq_desc[irq].data = NULL;
}
int irqs_suspend(void)
{
int err;
err = gic_irq_chip->irq_suspend();
if (err) {
IRQ_E("IRQs suspend failed, ret=%d\n", err);
return err;
}
return 0;
return irqchip.gic->irq_suspend();
}
int irqs_resume(void)
{
int err;
err = gic_irq_chip->irq_resume();
if (err) {
IRQ_E("IRQs resume failed, ret=%d\n", err);
return err;
}
return 0;
return irqchip.gic->irq_resume();
}
#ifdef CONFIG_ARM64

View File

@ -5,11 +5,9 @@
*/
#include <common.h>
#include <asm/io.h>
#include <asm/gic.h>
#include <config.h>
#include <irq-generic.h>
#include "irq-gic.h"
#include "irq-internal.h"
#define gicd_readl(offset) readl((void *)GICD_BASE + (offset))
#define gicc_readl(offset) readl((void *)GICC_BASE + (offset))
@ -139,7 +137,7 @@ static int gic_irq_enable(int irq)
u32 val, cpu_mask;
u32 shift = (irq % 4) * 8;
if (irq >= PLATFORM_GIC_IRQS_NR)
if (irq >= PLATFORM_GIC_MAX_IRQ)
return -EINVAL;
/* set enable */
@ -333,7 +331,7 @@ static int gic_irq_init(void)
u32 val;
/* end of interrupt */
gicc_writel(PLATFORM_GIC_IRQS_NR, GICC_EOIR);
gicc_writel(PLATFORM_GIC_MAX_IRQ, GICC_EOIR);
/* disable gicc and gicd */
gicc_writel(0, GICC_CTLR);
@ -371,7 +369,7 @@ static struct irq_chip gic_irq_chip = {
.irq_set_type = gic_irq_set_type,
};
struct irq_chip *arch_gic_irq_init(void)
struct irq_chip *arch_gic_get_irqchip(void)
{
return &gic_irq_chip;
}

View File

@ -1,18 +0,0 @@
/*
* (C) Copyright 2017 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _IRQ_GIC_H_
#define _IRQ_GIC_H_
#include <irq-platform.h>
#define PLATFORM_GIC_IRQS_NR GIC_IRQS_NR
#define PLATFORM_GPIO_IRQS_NR GPIO_IRQS_NR
#define PLATFORM_MAX_IRQS_NR (GIC_IRQS_NR + GPIO_IRQS_NR)
struct irq_chip *arch_gic_irq_init(void);
#endif /* _IRQ_GIC_H_ */

View File

@ -5,8 +5,7 @@
*/
#include <dm.h>
#include <irq-generic.h>
#include "irq-gpio-switch.h"
#include "irq-internal.h"
DECLARE_GLOBAL_DATA_PTR;

View File

@ -4,10 +4,7 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#include <asm/io.h>
#include <irq-generic.h>
#include "irq-gpio.h"
#include "irq-gpio-switch.h"
#include "irq-internal.h"
typedef enum GPIOIntType {
GPIOLevelLow = 0,
@ -337,7 +334,7 @@ static struct irq_chip gpio_irq_chip = {
.irq_get_gpio_level = gpio_irq_get_gpio_level,
};
struct irq_chip *arch_gpio_irq_init(void)
struct irq_chip *arch_gpio_get_irqchip(void)
{
return &gpio_irq_chip;
}

View File

@ -1,12 +0,0 @@
/*
* (C) Copyright 2017 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _IRQ_GPIO_H_
#define _IRQ_GPIO_H_
struct irq_chip *arch_gpio_irq_init(void);
#endif /* _IRQ_GPIO_H_ */

View File

@ -4,19 +4,39 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _IRQ_GPIO_SWITCH_H_
#define _IRQ_GPIO_SWITCH_H_
#ifndef _IRQ_GIC_H_
#define _IRQ_GIC_H_
#include <asm/io.h>
#include <common.h>
#include <irq-generic.h>
#include <irq-platform.h>
#include "irq-internal.h"
/* bank and pin bit mask */
/*
* IRQ-NUMBERS
*/
#define PLATFORM_GIC_MAX_IRQ (GIC_IRQS_NR)
#define PLATFORM_GPIO_MAX_IRQ (GIC_IRQS_NR + GPIO_IRQS_NR)
#define PLATFORM_MAX_IRQ (GIC_IRQS_NR + GPIO_IRQS_NR)
/*
* IRQ-CHIP
*/
struct irq_chip *arch_gic_get_irqchip(void);
struct irq_chip *arch_gpio_get_irqchip(void);
/*
* Other
*/
int bad_irq(int irq);
/*
* IRQ-GPIO-SWITCH
*/
#define GPIO_BANK_MASK 0xFFFFFF00
#define GPIO_BANK_OFFSET 8
#define GPIO_PIN_MASK 0x000000FF
#define GPIO_PIN_OFFSET 0
#define EINVAL_GPIO -1
#define PIN_BASE GIC_IRQS_NR
@ -29,15 +49,15 @@ struct gpio_bank {
int use_count;
};
#define GPIO_BANK_REGISTER(ID, GPIO_BANK_NUM) \
{ \
.name = __stringify(gpio##ID), \
.regbase = (unsigned char __iomem *)GPIO##ID##_PHYS, \
.id = ID, \
.irq_base = PIN_BASE + (ID) * (GPIO_BANK_NUM), \
.ngpio = GPIO_BANK_NUM, \
.use_count = 0 \
}
#define GPIO_BANK_REGISTER(ID, GPIO_BANK_NUM) \
{ \
.name = __stringify(gpio##ID), \
.regbase = (unsigned char __iomem *)GPIO##ID##_PHYS, \
.id = ID, \
.irq_base = PIN_BASE + (ID) * (GPIO_BANK_NUM), \
.ngpio = GPIO_BANK_NUM, \
.use_count = 0 \
}
/* gpio bank[31:8] and pin[7:0] */
#define GPIO_BANK(gpio) ((gpio & GPIO_BANK_MASK) >> GPIO_BANK_OFFSET)
@ -47,8 +67,9 @@ struct gpio_bank {
int hard_gpio_to_irq(u32 gpio);
int irq_to_gpio(int irq);
struct gpio_bank *gpio_id_to_bank(unsigned int id);
struct gpio_bank *gpio_to_bank(unsigned gpio);
#endif /* _IRQ_GPIO_SWITCH_H_ */
void __generic_gpio_handle_irq(int irq);
#endif /* _IRQ_GIC_H_ */

View File

@ -93,7 +93,4 @@ int gpio_to_irq(struct gpio_desc *gpio);
int hard_gpio_to_irq(unsigned gpio);
int phandle_gpio_to_irq(u32 gpio_phandle, u32 pin);
/* Only irq-gpio.c can call it */
void __generic_gpio_handle_irq(int irq);
#endif /* _IRQ_GENERIC_H */