Re: [PATCH v2 06/10] irqchip: Add driver for WPCM450 interrupt controller

2021-04-07 Thread Jonathan Neuschäfer
On Wed, Apr 07, 2021 at 12:11:21PM +0100, Marc Zyngier wrote:
> On Tue, 06 Apr 2021 13:09:17 +0100,
> Jonathan Neuschäfer  wrote:
...
> > diff --git a/arch/arm/mach-npcm/Kconfig b/arch/arm/mach-npcm/Kconfig
> > index 658c8efb4ca14..a71cf1d189ae5 100644
> > --- a/arch/arm/mach-npcm/Kconfig
> > +++ b/arch/arm/mach-npcm/Kconfig
> > @@ -10,6 +10,7 @@ config ARCH_WPCM450
> > bool "Support for WPCM450 BMC (Hermon)"
> > depends on ARCH_MULTI_V5
> > select CPU_ARM926T
> > +   select WPCM450_AIC
> > select NPCM7XX_TIMER
> > help
> >   General support for WPCM450 BMC (Hermon).
> 
> I can't take this patch with this particular hunk, as I don't have
> this file in my tree. I can either drop this line, or delay the
> merging of this patch to a later point in time.

Hmm, indeed. Please apply the patch without this hunk. I'll reintroduce
it in another patch.

> 
> The driver otherwise looks ready.

Good.

Thanks,
Jonathan


signature.asc
Description: PGP signature


Re: [PATCH v2 06/10] irqchip: Add driver for WPCM450 interrupt controller

2021-04-07 Thread Marc Zyngier
On Tue, 06 Apr 2021 13:09:17 +0100,
Jonathan Neuschäfer  wrote:
> 
> The WPCM450 AIC ("Advanced Interrupt Controller") is the interrupt
> controller found in the Nuvoton WPCM450 SoC and other Winbond/Nuvoton
> SoCs.
> 
> The list of registers if based on the AMI vendor kernel and the
> Nuvoton W90N745 datasheet.
> 
> Although the hardware supports other interrupt modes, the driver only
> supports high-level interrupts at the moment, because other modes could
> not be tested so far.
> 
> Signed-off-by: Jonathan Neuschäfer 
> ---
> 
> v2:
> - Rename IRQS macro to AIC_NUM_IRQS
> - Fix IRQ range check
> - Use linux/printk.h header instead of linux/console.h
> - Add AIC_SCR_PRIORITY_MASK constant
> - Add missing register descriptions
> - Remove superfluous printk about IRQ flow type mismatch
> - Use BIT() macro
> - Rename _ack function to _eoi for accuracy, and use handle_fasteoi_irq
> ---
>  arch/arm/mach-npcm/Kconfig|   1 +
>  drivers/irqchip/Kconfig   |   6 ++
>  drivers/irqchip/Makefile  |   1 +
>  drivers/irqchip/irq-wpcm450-aic.c | 161 ++
>  4 files changed, 169 insertions(+)
>  create mode 100644 drivers/irqchip/irq-wpcm450-aic.c
> 
> diff --git a/arch/arm/mach-npcm/Kconfig b/arch/arm/mach-npcm/Kconfig
> index 658c8efb4ca14..a71cf1d189ae5 100644
> --- a/arch/arm/mach-npcm/Kconfig
> +++ b/arch/arm/mach-npcm/Kconfig
> @@ -10,6 +10,7 @@ config ARCH_WPCM450
>   bool "Support for WPCM450 BMC (Hermon)"
>   depends on ARCH_MULTI_V5
>   select CPU_ARM926T
> + select WPCM450_AIC
>   select NPCM7XX_TIMER
>   help
> General support for WPCM450 BMC (Hermon).

I can't take this patch with this particular hunk, as I don't have
this file in my tree. I can either drop this line, or delay the
merging of this patch to a later point in time.

The driver otherwise looks ready.

Thanks,

M.

-- 
Without deviation from the norm, progress is not possible.


[PATCH v2 06/10] irqchip: Add driver for WPCM450 interrupt controller

2021-04-06 Thread Jonathan Neuschäfer
The WPCM450 AIC ("Advanced Interrupt Controller") is the interrupt
controller found in the Nuvoton WPCM450 SoC and other Winbond/Nuvoton
SoCs.

The list of registers if based on the AMI vendor kernel and the
Nuvoton W90N745 datasheet.

Although the hardware supports other interrupt modes, the driver only
supports high-level interrupts at the moment, because other modes could
not be tested so far.

Signed-off-by: Jonathan Neuschäfer 
---

v2:
- Rename IRQS macro to AIC_NUM_IRQS
- Fix IRQ range check
- Use linux/printk.h header instead of linux/console.h
- Add AIC_SCR_PRIORITY_MASK constant
- Add missing register descriptions
- Remove superfluous printk about IRQ flow type mismatch
- Use BIT() macro
- Rename _ack function to _eoi for accuracy, and use handle_fasteoi_irq
---
 arch/arm/mach-npcm/Kconfig|   1 +
 drivers/irqchip/Kconfig   |   6 ++
 drivers/irqchip/Makefile  |   1 +
 drivers/irqchip/irq-wpcm450-aic.c | 161 ++
 4 files changed, 169 insertions(+)
 create mode 100644 drivers/irqchip/irq-wpcm450-aic.c

diff --git a/arch/arm/mach-npcm/Kconfig b/arch/arm/mach-npcm/Kconfig
index 658c8efb4ca14..a71cf1d189ae5 100644
--- a/arch/arm/mach-npcm/Kconfig
+++ b/arch/arm/mach-npcm/Kconfig
@@ -10,6 +10,7 @@ config ARCH_WPCM450
bool "Support for WPCM450 BMC (Hermon)"
depends on ARCH_MULTI_V5
select CPU_ARM926T
+   select WPCM450_AIC
select NPCM7XX_TIMER
help
  General support for WPCM450 BMC (Hermon).
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index e74fa206240a1..baf4efec31c67 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -586,4 +586,10 @@ config MST_IRQ
help
  Support MStar Interrupt Controller.

+config WPCM450_AIC
+   bool "Nuvoton WPCM450 Advanced Interrupt Controller"
+   depends on ARCH_WPCM450 || COMPILE_TEST
+   help
+ Support for the interrupt controller in the Nuvoton WPCM450 BMC SoC.
+
 endmenu
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index c59b95a0532c9..bef57937e7296 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -113,3 +113,4 @@ obj-$(CONFIG_LOONGSON_PCH_MSI)  += 
irq-loongson-pch-msi.o
 obj-$(CONFIG_MST_IRQ)  += irq-mst-intc.o
 obj-$(CONFIG_SL28CPLD_INTC)+= irq-sl28cpld.o
 obj-$(CONFIG_MACH_REALTEK_RTL) += irq-realtek-rtl.o
+obj-$(CONFIG_WPCM450_AIC)  += irq-wpcm450-aic.o
diff --git a/drivers/irqchip/irq-wpcm450-aic.c 
b/drivers/irqchip/irq-wpcm450-aic.c
new file mode 100644
index 0..f3ac392d5bc87
--- /dev/null
+++ b/drivers/irqchip/irq-wpcm450-aic.c
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright 2021 Jonathan Neuschäfer
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#define AIC_SCR(x) ((x)*4) /* Source control registers */
+#define AIC_GEN0x84/* Interrupt group enable control 
register */
+#define AIC_GRSR   0x88/* Interrupt group raw status register */
+#define AIC_IRSR   0x100   /* Interrupt raw status register */
+#define AIC_IASR   0x104   /* Interrupt active status register */
+#define AIC_ISR0x108   /* Interrupt status register */
+#define AIC_IPER   0x10c   /* Interrupt priority encoding register */
+#define AIC_ISNR   0x110   /* Interrupt source number register */
+#define AIC_IMR0x114   /* Interrupt mask register */
+#define AIC_OISR   0x118   /* Output interrupt status register */
+#define AIC_MECR   0x120   /* Mask enable command register */
+#define AIC_MDCR   0x124   /* Mask disable command register */
+#define AIC_SSCR   0x128   /* Source set command register */
+#define AIC_SCCR   0x12c   /* Source clear command register */
+#define AIC_EOSCR  0x130   /* End of service command register */
+
+#define AIC_SCR_SRCTYPE_LOW_LEVEL  (0 << 6)
+#define AIC_SCR_SRCTYPE_HIGH_LEVEL (1 << 6)
+#define AIC_SCR_SRCTYPE_NEG_EDGE   (2 << 6)
+#define AIC_SCR_SRCTYPE_POS_EDGE   (3 << 6)
+#define AIC_SCR_PRIORITY(x)(x)
+#define AIC_SCR_PRIORITY_MASK  0x7
+
+#define AIC_NUM_IRQS   32
+
+struct wpcm450_aic {
+   void __iomem *regs;
+   struct irq_domain *domain;
+};
+
+static struct wpcm450_aic *aic;
+
+static void wpcm450_aic_init_hw(void)
+{
+   int i;
+
+   /* Disable (mask) all interrupts */
+   writel(0x, aic->regs + AIC_MDCR);
+
+   /*
+* Make sure the interrupt controller is ready to serve new interrupts.
+* Reading from IPER indicates that the nIRQ signal may be deasserted,
+* and writing to EOSCR indicates that interrupt handling has finished.
+*/
+   readl(aic->regs + AIC_IPER);
+   writel(0, aic->regs + AIC_EOSCR);
+
+   /* Initialize trigger mode and priority of each interrupt source */
+   for (i = 0; i < AIC_NUM_IRQS; i++)
+