RE: [PATCH 4/6] irqchip/aspeed: Add Aspeed eSPI interrupt controller
Hi Marc, I will revise the patch as suggested. Thanks for the feedback. Chiawei > -Original Message- > From: Marc Zyngier > Sent: Thursday, January 7, 2021 6:18 PM > To: ChiaWei Wang > > Subject: Re: [PATCH 4/6] irqchip/aspeed: Add Aspeed eSPI interrupt controller > > On 2021-01-07 02:59, ChiaWei Wang wrote: > > Hi Marc, > > > >> -Original Message- > >> From: Marc Zyngier > >> Sent: Wednesday, January 6, 2021 6:59 PM > >> To: ChiaWei Wang > >> Subject: Re: [PATCH 4/6] irqchip/aspeed: Add Aspeed eSPI interrupt > >> controller > >> > >> On 2021-01-06 05:59, Chia-Wei, Wang wrote: > >> > The eSPI interrupt controller acts as a SW IRQ number decoder to > >> > correctly control/dispatch interrupts of the eSPI peripheral, > >> > virtual wire, out-of-band, and flash channels. > >> > > >> > Signed-off-by: Chia-Wei, Wang > >> > --- > >> > drivers/irqchip/Makefile | 2 +- > >> > drivers/irqchip/irq-aspeed-espi-ic.c | 251 > >> > include/soc/aspeed/espi.h| 279 > >> +++ > >> > 3 files changed, 531 insertions(+), 1 deletion(-) create mode > >> > 100644 drivers/irqchip/irq-aspeed-espi-ic.c > >> > create mode 100644 include/soc/aspeed/espi.h > >> > > >> > diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile > >> > index > >> > 0ac93bfaec61..56da4a3123f8 100644 > >> > --- a/drivers/irqchip/Makefile > >> > +++ b/drivers/irqchip/Makefile > >> > @@ -86,7 +86,7 @@ obj-$(CONFIG_MVEBU_PIC)+= > >> irq-mvebu-pic.o > >> > obj-$(CONFIG_MVEBU_SEI) += irq-mvebu-sei.o > >> > obj-$(CONFIG_LS_EXTIRQ) += irq-ls-extirq.o > >> > obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o > >> > -obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o > irq-aspeed-i2c-ic.o > >> > irq-aspeed-scu-ic.o > >> > +obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o > irq-aspeed-i2c-ic.o > >> > irq-aspeed-scu-ic.o irq-aspeed-espi-ic.o > >> > obj-$(CONFIG_STM32_EXTI)+= irq-stm32-exti.o > >> > obj-$(CONFIG_QCOM_IRQ_COMBINER) += qcom-irq-combiner.o > >> > obj-$(CONFIG_IRQ_UNIPHIER_AIDET)+= irq-uniphier-aidet.o > >> > diff --git a/drivers/irqchip/irq-aspeed-espi-ic.c > >> > b/drivers/irqchip/irq-aspeed-espi-ic.c > >> > new file mode 100644 > >> > index ..8a5cc8fe3f0c > >> > --- /dev/null > >> > +++ b/drivers/irqchip/irq-aspeed-espi-ic.c > >> > @@ -0,0 +1,251 @@ > >> > +// SPDX-License-Identifier: GPL-2.0-or-later > >> > +/* > >> > + * Copyright (c) 2020 Aspeed Technology Inc. > >> > + */ > >> > +#include > >> > +#include > >> > +#include > >> > +#include > >> > +#include #include > >> > + #include #include > >> > + #include #include > >> > + #include > >> > + > >> > +#include > >> > +#include > >> > + > >> > +#define DEVICE_NAME "aspeed-espi-ic" > >> > +#define IRQCHIP_NAME"eSPI-IC" > >> > + > >> > +#define ESPI_IC_IRQ_NUM 7 > >> > + > >> > +struct aspeed_espi_ic { > >> > +struct regmap *map; > >> > +int irq; > >> > +int gpio_irq; > >> > +struct irq_domain *irq_domain; > >> > +}; > >> > + > >> > +static void aspeed_espi_ic_gpio_isr(struct irq_desc *desc) { > >> > +unsigned int irq; > >> > +struct aspeed_espi_ic *espi_ic = > >> > irq_desc_get_handler_data(desc); > >> > +struct irq_chip *chip = irq_desc_get_chip(desc); > >> > + > >> > +chained_irq_enter(chip, desc); > >> > + > >> > +irq = irq_find_mapping(espi_ic->irq_domain, > >> > + ASPEED_ESPI_IC_CTRL_RESET); > >> > +generic_handle_irq(irq); > >> > + > >> > +irq = irq_find_mapping(espi_ic->irq_domain, > >> > + ASPEED_ESPI_IC_CHAN_RESET); > >> > +generic_handle_irq(irq); > >> > >> So for
Re: [PATCH 4/6] irqchip/aspeed: Add Aspeed eSPI interrupt controller
On 2021-01-07 02:59, ChiaWei Wang wrote: Hi Marc, -Original Message- From: Marc Zyngier Sent: Wednesday, January 6, 2021 6:59 PM To: ChiaWei Wang Subject: Re: [PATCH 4/6] irqchip/aspeed: Add Aspeed eSPI interrupt controller On 2021-01-06 05:59, Chia-Wei, Wang wrote: > The eSPI interrupt controller acts as a SW IRQ number decoder to > correctly control/dispatch interrupts of the eSPI peripheral, virtual > wire, out-of-band, and flash channels. > > Signed-off-by: Chia-Wei, Wang > --- > drivers/irqchip/Makefile | 2 +- > drivers/irqchip/irq-aspeed-espi-ic.c | 251 > include/soc/aspeed/espi.h| 279 +++ > 3 files changed, 531 insertions(+), 1 deletion(-) create mode 100644 > drivers/irqchip/irq-aspeed-espi-ic.c > create mode 100644 include/soc/aspeed/espi.h > > diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index > 0ac93bfaec61..56da4a3123f8 100644 > --- a/drivers/irqchip/Makefile > +++ b/drivers/irqchip/Makefile > @@ -86,7 +86,7 @@ obj-$(CONFIG_MVEBU_PIC) += irq-mvebu-pic.o > obj-$(CONFIG_MVEBU_SEI) += irq-mvebu-sei.o > obj-$(CONFIG_LS_EXTIRQ) += irq-ls-extirq.o > obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o > -obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o irq-aspeed-i2c-ic.o > irq-aspeed-scu-ic.o > +obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o irq-aspeed-i2c-ic.o > irq-aspeed-scu-ic.o irq-aspeed-espi-ic.o > obj-$(CONFIG_STM32_EXTI) += irq-stm32-exti.o > obj-$(CONFIG_QCOM_IRQ_COMBINER) += qcom-irq-combiner.o > obj-$(CONFIG_IRQ_UNIPHIER_AIDET) += irq-uniphier-aidet.o > diff --git a/drivers/irqchip/irq-aspeed-espi-ic.c > b/drivers/irqchip/irq-aspeed-espi-ic.c > new file mode 100644 > index ..8a5cc8fe3f0c > --- /dev/null > +++ b/drivers/irqchip/irq-aspeed-espi-ic.c > @@ -0,0 +1,251 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * Copyright (c) 2020 Aspeed Technology Inc. > + */ > +#include > +#include > +#include > +#include > +#include #include > +#include #include #include > + #include #include > + > +#include > +#include > + > +#define DEVICE_NAME "aspeed-espi-ic" > +#define IRQCHIP_NAME "eSPI-IC" > + > +#define ESPI_IC_IRQ_NUM 7 > + > +struct aspeed_espi_ic { > + struct regmap *map; > + int irq; > + int gpio_irq; > + struct irq_domain *irq_domain; > +}; > + > +static void aspeed_espi_ic_gpio_isr(struct irq_desc *desc) { > + unsigned int irq; > + struct aspeed_espi_ic *espi_ic = irq_desc_get_handler_data(desc); > + struct irq_chip *chip = irq_desc_get_chip(desc); > + > + chained_irq_enter(chip, desc); > + > + irq = irq_find_mapping(espi_ic->irq_domain, > + ASPEED_ESPI_IC_CTRL_RESET); > + generic_handle_irq(irq); > + > + irq = irq_find_mapping(espi_ic->irq_domain, > + ASPEED_ESPI_IC_CHAN_RESET); > + generic_handle_irq(irq); So for each mux interrupt, you generate two endpoints interrupt, without even checking whether they are pending? That's no good. As the eSPI IC driver is chained to Aspeed GPIO IC, the pending is checked in the gpio-aspeed.c That's not the place to do that. > + > + chained_irq_exit(chip, desc); > +} > + > +static void aspeed_espi_ic_isr(struct irq_desc *desc) { > + unsigned int sts; > + unsigned int irq; > + struct aspeed_espi_ic *espi_ic = irq_desc_get_handler_data(desc); > + struct irq_chip *chip = irq_desc_get_chip(desc); > + > + chained_irq_enter(chip, desc); > + > + regmap_read(espi_ic->map, ESPI_INT_STS, ); > + > + if (sts & ESPI_INT_STS_PERIF_BITS) { > + irq = irq_find_mapping(espi_ic->irq_domain, > + ASPEED_ESPI_IC_PERIF_EVENT); > + generic_handle_irq(irq); > + } > + > + if (sts & ESPI_INT_STS_VW_BITS) { > + irq = irq_find_mapping(espi_ic->irq_domain, > + ASPEED_ESPI_IC_VW_EVENT); > + generic_handle_irq(irq); > + } > + > + if (sts & ESPI_INT_STS_OOB_BITS) { > + irq = irq_find_mapping(espi_ic->irq_domain, > + ASPEED_ESPI_IC_OOB_EVENT); > + generic_handle_irq(irq); > + } > + > + if (sts & ESPI_INT_STS_FLASH_BITS) { > + irq = irq_find_mapping(espi_ic->irq_domain, > + ASPEED_ESPI_IC_FLASH_EVENT); > + generic_handle_irq(irq); > + } > + > + if (sts & ESPI_INT_STS_HW_RST_DEASSERT) { > + irq = irq_find_mapping(espi_ic->irq
RE: [PATCH 4/6] irqchip/aspeed: Add Aspeed eSPI interrupt controller
Hi Marc, > -Original Message- > From: Marc Zyngier > Sent: Wednesday, January 6, 2021 6:59 PM > To: ChiaWei Wang > Subject: Re: [PATCH 4/6] irqchip/aspeed: Add Aspeed eSPI interrupt controller > > On 2021-01-06 05:59, Chia-Wei, Wang wrote: > > The eSPI interrupt controller acts as a SW IRQ number decoder to > > correctly control/dispatch interrupts of the eSPI peripheral, virtual > > wire, out-of-band, and flash channels. > > > > Signed-off-by: Chia-Wei, Wang > > --- > > drivers/irqchip/Makefile | 2 +- > > drivers/irqchip/irq-aspeed-espi-ic.c | 251 > > include/soc/aspeed/espi.h| 279 > +++ > > 3 files changed, 531 insertions(+), 1 deletion(-) create mode 100644 > > drivers/irqchip/irq-aspeed-espi-ic.c > > create mode 100644 include/soc/aspeed/espi.h > > > > diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index > > 0ac93bfaec61..56da4a3123f8 100644 > > --- a/drivers/irqchip/Makefile > > +++ b/drivers/irqchip/Makefile > > @@ -86,7 +86,7 @@ obj-$(CONFIG_MVEBU_PIC) += > irq-mvebu-pic.o > > obj-$(CONFIG_MVEBU_SEI)+= irq-mvebu-sei.o > > obj-$(CONFIG_LS_EXTIRQ)+= irq-ls-extirq.o > > obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o > > -obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o irq-aspeed-i2c-ic.o > > irq-aspeed-scu-ic.o > > +obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o irq-aspeed-i2c-ic.o > > irq-aspeed-scu-ic.o irq-aspeed-espi-ic.o > > obj-$(CONFIG_STM32_EXTI) += irq-stm32-exti.o > > obj-$(CONFIG_QCOM_IRQ_COMBINER)+= qcom-irq-combiner.o > > obj-$(CONFIG_IRQ_UNIPHIER_AIDET) += irq-uniphier-aidet.o > > diff --git a/drivers/irqchip/irq-aspeed-espi-ic.c > > b/drivers/irqchip/irq-aspeed-espi-ic.c > > new file mode 100644 > > index ..8a5cc8fe3f0c > > --- /dev/null > > +++ b/drivers/irqchip/irq-aspeed-espi-ic.c > > @@ -0,0 +1,251 @@ > > +// SPDX-License-Identifier: GPL-2.0-or-later > > +/* > > + * Copyright (c) 2020 Aspeed Technology Inc. > > + */ > > +#include > > +#include > > +#include > > +#include > > +#include #include > > +#include #include #include > > + #include #include > > + > > +#include > > +#include > > + > > +#define DEVICE_NAME"aspeed-espi-ic" > > +#define IRQCHIP_NAME "eSPI-IC" > > + > > +#define ESPI_IC_IRQ_NUM7 > > + > > +struct aspeed_espi_ic { > > + struct regmap *map; > > + int irq; > > + int gpio_irq; > > + struct irq_domain *irq_domain; > > +}; > > + > > +static void aspeed_espi_ic_gpio_isr(struct irq_desc *desc) { > > + unsigned int irq; > > + struct aspeed_espi_ic *espi_ic = irq_desc_get_handler_data(desc); > > + struct irq_chip *chip = irq_desc_get_chip(desc); > > + > > + chained_irq_enter(chip, desc); > > + > > + irq = irq_find_mapping(espi_ic->irq_domain, > > + ASPEED_ESPI_IC_CTRL_RESET); > > + generic_handle_irq(irq); > > + > > + irq = irq_find_mapping(espi_ic->irq_domain, > > + ASPEED_ESPI_IC_CHAN_RESET); > > + generic_handle_irq(irq); > > So for each mux interrupt, you generate two endpoints interrupt, without even > checking whether they are pending? That's no good. As the eSPI IC driver is chained to Aspeed GPIO IC, the pending is checked in the gpio-aspeed.c > > + > > + chained_irq_exit(chip, desc); > > +} > > + > > +static void aspeed_espi_ic_isr(struct irq_desc *desc) { > > + unsigned int sts; > > + unsigned int irq; > > + struct aspeed_espi_ic *espi_ic = irq_desc_get_handler_data(desc); > > + struct irq_chip *chip = irq_desc_get_chip(desc); > > + > > + chained_irq_enter(chip, desc); > > + > > + regmap_read(espi_ic->map, ESPI_INT_STS, ); > > + > > + if (sts & ESPI_INT_STS_PERIF_BITS) { > > + irq = irq_find_mapping(espi_ic->irq_domain, > > + ASPEED_ESPI_IC_PERIF_EVENT); > > + generic_handle_irq(irq); > > + } > > + > > + if (sts & ESPI_INT_STS_VW_BITS) { > > + irq = irq_find_mapping(espi_ic->irq_domain, > > + ASPEED_ESPI_IC_VW_EVENT); > > + generic_handle_irq(irq); > > + } > > + > > + if (sts & ESPI_INT_STS_O
Re: [PATCH 4/6] irqchip/aspeed: Add Aspeed eSPI interrupt controller
On 2021-01-06 05:59, Chia-Wei, Wang wrote: The eSPI interrupt controller acts as a SW IRQ number decoder to correctly control/dispatch interrupts of the eSPI peripheral, virtual wire, out-of-band, and flash channels. Signed-off-by: Chia-Wei, Wang --- drivers/irqchip/Makefile | 2 +- drivers/irqchip/irq-aspeed-espi-ic.c | 251 include/soc/aspeed/espi.h| 279 +++ 3 files changed, 531 insertions(+), 1 deletion(-) create mode 100644 drivers/irqchip/irq-aspeed-espi-ic.c create mode 100644 include/soc/aspeed/espi.h diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 0ac93bfaec61..56da4a3123f8 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -86,7 +86,7 @@ obj-$(CONFIG_MVEBU_PIC) += irq-mvebu-pic.o obj-$(CONFIG_MVEBU_SEI)+= irq-mvebu-sei.o obj-$(CONFIG_LS_EXTIRQ)+= irq-ls-extirq.o obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o -obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o irq-aspeed-i2c-ic.o irq-aspeed-scu-ic.o +obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o irq-aspeed-i2c-ic.o irq-aspeed-scu-ic.o irq-aspeed-espi-ic.o obj-$(CONFIG_STM32_EXTI) += irq-stm32-exti.o obj-$(CONFIG_QCOM_IRQ_COMBINER)+= qcom-irq-combiner.o obj-$(CONFIG_IRQ_UNIPHIER_AIDET) += irq-uniphier-aidet.o diff --git a/drivers/irqchip/irq-aspeed-espi-ic.c b/drivers/irqchip/irq-aspeed-espi-ic.c new file mode 100644 index ..8a5cc8fe3f0c --- /dev/null +++ b/drivers/irqchip/irq-aspeed-espi-ic.c @@ -0,0 +1,251 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020 Aspeed Technology Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DEVICE_NAME"aspeed-espi-ic" +#define IRQCHIP_NAME "eSPI-IC" + +#define ESPI_IC_IRQ_NUM7 + +struct aspeed_espi_ic { + struct regmap *map; + int irq; + int gpio_irq; + struct irq_domain *irq_domain; +}; + +static void aspeed_espi_ic_gpio_isr(struct irq_desc *desc) +{ + unsigned int irq; + struct aspeed_espi_ic *espi_ic = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); + + chained_irq_enter(chip, desc); + + irq = irq_find_mapping(espi_ic->irq_domain, + ASPEED_ESPI_IC_CTRL_RESET); + generic_handle_irq(irq); + + irq = irq_find_mapping(espi_ic->irq_domain, + ASPEED_ESPI_IC_CHAN_RESET); + generic_handle_irq(irq); So for each mux interrupt, you generate two endpoints interrupt, without even checking whether they are pending? That's no good. + + chained_irq_exit(chip, desc); +} + +static void aspeed_espi_ic_isr(struct irq_desc *desc) +{ + unsigned int sts; + unsigned int irq; + struct aspeed_espi_ic *espi_ic = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); + + chained_irq_enter(chip, desc); + + regmap_read(espi_ic->map, ESPI_INT_STS, ); + + if (sts & ESPI_INT_STS_PERIF_BITS) { + irq = irq_find_mapping(espi_ic->irq_domain, + ASPEED_ESPI_IC_PERIF_EVENT); + generic_handle_irq(irq); + } + + if (sts & ESPI_INT_STS_VW_BITS) { + irq = irq_find_mapping(espi_ic->irq_domain, + ASPEED_ESPI_IC_VW_EVENT); + generic_handle_irq(irq); + } + + if (sts & ESPI_INT_STS_OOB_BITS) { + irq = irq_find_mapping(espi_ic->irq_domain, + ASPEED_ESPI_IC_OOB_EVENT); + generic_handle_irq(irq); + } + + if (sts & ESPI_INT_STS_FLASH_BITS) { + irq = irq_find_mapping(espi_ic->irq_domain, + ASPEED_ESPI_IC_FLASH_EVENT); + generic_handle_irq(irq); + } + + if (sts & ESPI_INT_STS_HW_RST_DEASSERT) { + irq = irq_find_mapping(espi_ic->irq_domain, + ASPEED_ESPI_IC_CTRL_EVENT); + generic_handle_irq(irq); + } This is horrible. Why can't you just use fls() in a loop? + + chained_irq_exit(chip, desc); +} + +static void aspeed_espi_ic_irq_disable(struct irq_data *data) +{ + struct aspeed_espi_ic *espi_ic = irq_data_get_irq_chip_data(data); + + switch (data->hwirq) { + case ASPEED_ESPI_IC_CTRL_EVENT: + regmap_update_bits(espi_ic->map, ESPI_INT_EN, + ESPI_INT_EN_HW_RST_DEASSERT, + 0); + break; + case ASPEED_ESPI_IC_PERIF_EVENT: + regmap_update_bits(espi_ic->map, ESPI_INT_EN, +
[PATCH 4/6] irqchip/aspeed: Add Aspeed eSPI interrupt controller
The eSPI interrupt controller acts as a SW IRQ number decoder to correctly control/dispatch interrupts of the eSPI peripheral, virtual wire, out-of-band, and flash channels. Signed-off-by: Chia-Wei, Wang --- drivers/irqchip/Makefile | 2 +- drivers/irqchip/irq-aspeed-espi-ic.c | 251 include/soc/aspeed/espi.h| 279 +++ 3 files changed, 531 insertions(+), 1 deletion(-) create mode 100644 drivers/irqchip/irq-aspeed-espi-ic.c create mode 100644 include/soc/aspeed/espi.h diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 0ac93bfaec61..56da4a3123f8 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -86,7 +86,7 @@ obj-$(CONFIG_MVEBU_PIC) += irq-mvebu-pic.o obj-$(CONFIG_MVEBU_SEI)+= irq-mvebu-sei.o obj-$(CONFIG_LS_EXTIRQ)+= irq-ls-extirq.o obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o -obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o irq-aspeed-i2c-ic.o irq-aspeed-scu-ic.o +obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o irq-aspeed-i2c-ic.o irq-aspeed-scu-ic.o irq-aspeed-espi-ic.o obj-$(CONFIG_STM32_EXTI) += irq-stm32-exti.o obj-$(CONFIG_QCOM_IRQ_COMBINER)+= qcom-irq-combiner.o obj-$(CONFIG_IRQ_UNIPHIER_AIDET) += irq-uniphier-aidet.o diff --git a/drivers/irqchip/irq-aspeed-espi-ic.c b/drivers/irqchip/irq-aspeed-espi-ic.c new file mode 100644 index ..8a5cc8fe3f0c --- /dev/null +++ b/drivers/irqchip/irq-aspeed-espi-ic.c @@ -0,0 +1,251 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020 Aspeed Technology Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DEVICE_NAME"aspeed-espi-ic" +#define IRQCHIP_NAME "eSPI-IC" + +#define ESPI_IC_IRQ_NUM7 + +struct aspeed_espi_ic { + struct regmap *map; + int irq; + int gpio_irq; + struct irq_domain *irq_domain; +}; + +static void aspeed_espi_ic_gpio_isr(struct irq_desc *desc) +{ + unsigned int irq; + struct aspeed_espi_ic *espi_ic = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); + + chained_irq_enter(chip, desc); + + irq = irq_find_mapping(espi_ic->irq_domain, + ASPEED_ESPI_IC_CTRL_RESET); + generic_handle_irq(irq); + + irq = irq_find_mapping(espi_ic->irq_domain, + ASPEED_ESPI_IC_CHAN_RESET); + generic_handle_irq(irq); + + chained_irq_exit(chip, desc); +} + +static void aspeed_espi_ic_isr(struct irq_desc *desc) +{ + unsigned int sts; + unsigned int irq; + struct aspeed_espi_ic *espi_ic = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); + + chained_irq_enter(chip, desc); + + regmap_read(espi_ic->map, ESPI_INT_STS, ); + + if (sts & ESPI_INT_STS_PERIF_BITS) { + irq = irq_find_mapping(espi_ic->irq_domain, + ASPEED_ESPI_IC_PERIF_EVENT); + generic_handle_irq(irq); + } + + if (sts & ESPI_INT_STS_VW_BITS) { + irq = irq_find_mapping(espi_ic->irq_domain, + ASPEED_ESPI_IC_VW_EVENT); + generic_handle_irq(irq); + } + + if (sts & ESPI_INT_STS_OOB_BITS) { + irq = irq_find_mapping(espi_ic->irq_domain, + ASPEED_ESPI_IC_OOB_EVENT); + generic_handle_irq(irq); + } + + if (sts & ESPI_INT_STS_FLASH_BITS) { + irq = irq_find_mapping(espi_ic->irq_domain, + ASPEED_ESPI_IC_FLASH_EVENT); + generic_handle_irq(irq); + } + + if (sts & ESPI_INT_STS_HW_RST_DEASSERT) { + irq = irq_find_mapping(espi_ic->irq_domain, + ASPEED_ESPI_IC_CTRL_EVENT); + generic_handle_irq(irq); + } + + chained_irq_exit(chip, desc); +} + +static void aspeed_espi_ic_irq_disable(struct irq_data *data) +{ + struct aspeed_espi_ic *espi_ic = irq_data_get_irq_chip_data(data); + + switch (data->hwirq) { + case ASPEED_ESPI_IC_CTRL_EVENT: + regmap_update_bits(espi_ic->map, ESPI_INT_EN, + ESPI_INT_EN_HW_RST_DEASSERT, + 0); + break; + case ASPEED_ESPI_IC_PERIF_EVENT: + regmap_update_bits(espi_ic->map, ESPI_INT_EN, + ESPI_INT_EN_PERIF_BITS, 0); + break; + case ASPEED_ESPI_IC_VW_EVENT: + regmap_update_bits(espi_ic->map, ESPI_INT_EN, + ESPI_INT_EN_VW_BITS, 0); +