2021-03-20 18:18:25

by J. Neuschäfer

[permalink] [raw]
Subject: [PATCH 00/14] Initial support for Nuvoton WPCM450 BMC SoC

This series adds basic support for the Nuvoton WPCM450 BMC SoC. It's an older
SoC but still commonly found on eBay, mostly in Supermicro X9 server boards.

Patches 1-6 add devicetree bindings for the WPCM450 SoC and its various parts.
Patches 7-11 add arch and driver support. Patches 12 and 13 add a devicetree
for the SoC and a board based on it. Patch 14 finally updates the MAINTAINERS
file.

Patch 2 requires "dt-bindings: arm: Convert nuvoton,npcm750 binding to YAML"
(https://lore.kernel.org/lkml/[email protected]/)

This series is based on 5.12-rc2, and doesn't cleanly apply to OpenBMC's dev-5.10
branch (there are some trivial merge conflicts).

Jonathan Neuschäfer (14):
dt-bindings: vendor-prefixes: Add Supermicro
dt-bindings: arm: npcm: Add nuvoton,wpcm450 compatible string
dt-bindings: interrupt-controller: Add nuvoton,wpcm450-aic
dt-bindings: serial: 8250: Add nuvoton,wpcm450-uart
dt-bindings: timer: nuvoton,npcm7xx: Add wpcm450-timer
dt-bindings: watchdog: npcm: Add nuvoton,wpcm450-wdt
ARM: npcm: Introduce Nuvoton WPCM450 SoC
irqchip: Add driver for WPCM450 interrupt controller
serial: 8250_of: Add nuvoton,wpcm450-uart
clocksource/drivers/npcm: Add support for WPCM450
watchdog: npcm: Add support for WPCM450
ARM: dts: Add devicetree for Nuvoton WPCM450 BMC chip
ARM: dts: Add devicetree for Supermicro X9SCi-LN4F based on WPCM450
MAINTAINERS: Nuvoton NPCM: Add wpcm patterns

.../devicetree/bindings/arm/npcm/npcm.yaml | 6 +
.../nuvoton,wpcm450-aic.yaml | 39 +++++
.../devicetree/bindings/serial/8250.yaml | 1 +
.../bindings/timer/nuvoton,npcm7xx-timer.txt | 3 +-
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
.../bindings/watchdog/nuvoton,npcm-wdt.txt | 3 +-
MAINTAINERS | 11 +-
arch/arm/boot/dts/Makefile | 2 +
.../nuvoton-wpcm450-supermicro-x9sci-ln4f.dts | 40 +++++
arch/arm/boot/dts/nuvoton-wpcm450.dtsi | 76 ++++++++
arch/arm/mach-npcm/Kconfig | 13 +-
arch/arm/mach-npcm/Makefile | 1 +
arch/arm/mach-npcm/wpcm450.c | 13 ++
drivers/clocksource/timer-npcm7xx.c | 1 +
drivers/irqchip/Kconfig | 6 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-wpcm450-aic.c | 162 ++++++++++++++++++
drivers/tty/serial/8250/8250_of.c | 1 +
drivers/watchdog/npcm_wdt.c | 1 +
19 files changed, 374 insertions(+), 8 deletions(-)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/nuvoton,wpcm450-aic.yaml
create mode 100644 arch/arm/boot/dts/nuvoton-wpcm450-supermicro-x9sci-ln4f.dts
create mode 100644 arch/arm/boot/dts/nuvoton-wpcm450.dtsi
create mode 100644 arch/arm/mach-npcm/wpcm450.c
create mode 100644 drivers/irqchip/irq-wpcm450-aic.c

--
2.30.2


2021-03-20 18:21:27

by J. Neuschäfer

[permalink] [raw]
Subject: [PATCH 02/14] dt-bindings: arm: npcm: Add nuvoton,wpcm450 compatible string

The WPCM450 is an older BMC SoC in the Nuvoton NPCM family, originally
marketed as Winbond WPCM450.

Signed-off-by: Jonathan Neuschäfer <[email protected]>
---

This patch requires "dt-bindings: arm: Convert nuvoton,npcm750 binding to YAML"
(https://lore.kernel.org/lkml/[email protected]/)
---
Documentation/devicetree/bindings/arm/npcm/npcm.yaml | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/npcm/npcm.yaml b/Documentation/devicetree/bindings/arm/npcm/npcm.yaml
index 894aefb70652a..95e51378089c9 100644
--- a/Documentation/devicetree/bindings/arm/npcm/npcm.yaml
+++ b/Documentation/devicetree/bindings/arm/npcm/npcm.yaml
@@ -14,6 +14,12 @@ properties:
const: '/'
compatible:
oneOf:
+ - description: WPCM450 based boards
+ items:
+ - enum:
+ - supermicro,x9sci-ln4f-bmc # Supermicro X9SCI-LN4F server's BMC
+ - const: nuvoton,wpcm450
+
- description: NPCM750 based boards
items:
- enum:
--
2.30.2

2021-03-20 18:21:32

by J. Neuschäfer

[permalink] [raw]
Subject: [PATCH 04/14] dt-bindings: serial: 8250: Add nuvoton,wpcm450-uart

Add a compatible string for the UART inside the Nuvoton WPCM450 SoC.

Signed-off-by: Jonathan Neuschäfer <[email protected]>
---
Documentation/devicetree/bindings/serial/8250.yaml | 1 +
1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/serial/8250.yaml b/Documentation/devicetree/bindings/serial/8250.yaml
index f54cae9ff7b28..c0e292cdaa6bc 100644
--- a/Documentation/devicetree/bindings/serial/8250.yaml
+++ b/Documentation/devicetree/bindings/serial/8250.yaml
@@ -55,6 +55,7 @@ properties:
- const: aspeed,ast2500-vuart
- const: intel,xscale-uart
- const: mrvl,pxa-uart
+ - const: nuvoton,wpcm450-uart
- const: nuvoton,npcm750-uart
- const: nvidia,tegra20-uart
- const: nxp,lpc3220-uart
--
2.30.2

2021-03-20 18:21:32

by J. Neuschäfer

[permalink] [raw]
Subject: [PATCH 03/14] dt-bindings: interrupt-controller: Add nuvoton,wpcm450-aic

The WPCM450 AIC ("Advanced Interrupt Controller") is the interrupt
controller found in the Nuvoton WPCM450 SoC and other Winbond/Nuvoton
SoCs.

Signed-off-by: Jonathan Neuschäfer <[email protected]>
---
.../nuvoton,wpcm450-aic.yaml | 39 +++++++++++++++++++
1 file changed, 39 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/nuvoton,wpcm450-aic.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/nuvoton,wpcm450-aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/nuvoton,wpcm450-aic.yaml
new file mode 100644
index 0000000000000..9ce6804bdb999
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/nuvoton,wpcm450-aic.yaml
@@ -0,0 +1,39 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/nuvoton,wpcm450-aic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Nuvoton WPCM450 Advanced Interrupt Controller bindings
+
+maintainers:
+ - Jonathan Neuschäfer <[email protected]>
+
+properties:
+ '#interrupt-cells':
+ const: 2
+
+ compatible:
+ const: nuvoton,wpcm450-aic
+
+ interrupt-controller: true
+
+ reg:
+ maxItems: 1
+
+additionalProperties: false
+
+required:
+ - '#interrupt-cells'
+ - compatible
+ - reg
+ - interrupt-controller
+
+examples:
+ - |
+ aic: interrupt-controller@b8002000 {
+ compatible = "nuvoton,wpcm450-aic";
+ reg = <0xb8002000 0x1000>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
--
2.30.2

2021-03-20 18:22:18

by J. Neuschäfer

[permalink] [raw]
Subject: [PATCH 01/14] dt-bindings: vendor-prefixes: Add Supermicro

Super Micro Computer, Inc. (https://www.supermicro.com/en/), commonly
known as Supermicro, is a manufacturer of server hardware.

Signed-off-by: Jonathan Neuschäfer <[email protected]>
---
Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index f6064d84a424d..ec6d6ccfbbb3b 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1085,6 +1085,8 @@ patternProperties:
description: Shenzhen Sunchip Technology Co., Ltd
"^SUNW,.*":
description: Sun Microsystems, Inc
+ "^supermicro,.*":
+ description: Super Micro Computer, Inc.
"^silvaco,.*":
description: Silvaco, Inc.
"^swir,.*":
--
2.30.2

2021-03-20 18:22:43

by J. Neuschäfer

[permalink] [raw]
Subject: [PATCH 06/14] dt-bindings: watchdog: npcm: Add nuvoton,wpcm450-wdt

Add a compatible string for the WPCM450 SoC, which has the same watchdog
timer.

Signed-off-by: Jonathan Neuschäfer <[email protected]>
---
.../devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt b/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt
index 6d593003c933b..9059f54dc023d 100644
--- a/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt
@@ -5,7 +5,8 @@ The watchdog supports a pre-timeout interrupt that fires 10ms before the
expiry.

Required properties:
-- compatible : "nuvoton,npcm750-wdt" for NPCM750 (Poleg).
+- compatible : "nuvoton,npcm750-wdt" for NPCM750 (Poleg), or
+ "nuvoton,wpcm450-wdt" for WPCM450 (Hermon).
- reg : Offset and length of the register set for the device.
- interrupts : Contain the timer interrupt with flags for
falling edge.
--
2.30.2

2021-03-20 18:23:36

by J. Neuschäfer

[permalink] [raw]
Subject: [PATCH 05/14] dt-bindings: timer: nuvoton,npcm7xx: Add wpcm450-timer

Add a compatible string for WPCM450, which has essentially the same
timer controller.

Signed-off-by: Jonathan Neuschäfer <[email protected]>
---
.../devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt b/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt
index 97258f1a1505b..ac3a5e887455d 100644
--- a/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt
+++ b/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt
@@ -4,7 +4,8 @@ Nuvoton NPCM7xx have three timer modules, each timer module provides five 24-bit
timer counters.

Required properties:
-- compatible : "nuvoton,npcm750-timer" for Poleg NPCM750.
+- compatible : "nuvoton,npcm750-timer" for Poleg NPCM750, or
+ "nuvoton,wpcm450-timer" for Hermon WPCM450.
- reg : Offset and length of the register set for the device.
- interrupts : Contain the timer interrupt of timer 0.
- clocks : phandle of timer reference clock (usually a 25 MHz clock).
--
2.30.2

2021-03-20 18:25:19

by J. Neuschäfer

[permalink] [raw]
Subject: [PATCH 07/14] ARM: npcm: Introduce Nuvoton WPCM450 SoC

The WPCM450 is an older BMC SoC in the Nuvoton NPCM family, originally
marketed as Winbond WPCM450.

Signed-off-by: Jonathan Neuschäfer <[email protected]>
---
arch/arm/mach-npcm/Kconfig | 12 +++++++++++-
arch/arm/mach-npcm/Makefile | 1 +
arch/arm/mach-npcm/wpcm450.c | 13 +++++++++++++
3 files changed, 25 insertions(+), 1 deletion(-)
create mode 100644 arch/arm/mach-npcm/wpcm450.c

diff --git a/arch/arm/mach-npcm/Kconfig b/arch/arm/mach-npcm/Kconfig
index 7f7002dc2b21f..658c8efb4ca14 100644
--- a/arch/arm/mach-npcm/Kconfig
+++ b/arch/arm/mach-npcm/Kconfig
@@ -1,11 +1,21 @@
# SPDX-License-Identifier: GPL-2.0-only
menuconfig ARCH_NPCM
bool "Nuvoton NPCM Architecture"
- depends on ARCH_MULTI_V7
+ depends on ARCH_MULTI_V5 || ARCH_MULTI_V7
select PINCTRL

if ARCH_NPCM

+config ARCH_WPCM450
+ bool "Support for WPCM450 BMC (Hermon)"
+ depends on ARCH_MULTI_V5
+ select CPU_ARM926T
+ select NPCM7XX_TIMER
+ help
+ General support for WPCM450 BMC (Hermon).
+
+ Winbond/Nuvoton WPCM450 BMC based on the ARM926EJ-S.
+
config ARCH_NPCM7XX
bool "Support for NPCM7xx BMC (Poleg)"
depends on ARCH_MULTI_V7
diff --git a/arch/arm/mach-npcm/Makefile b/arch/arm/mach-npcm/Makefile
index 1bc3a70bfab8b..0a915084c8ff3 100644
--- a/arch/arm/mach-npcm/Makefile
+++ b/arch/arm/mach-npcm/Makefile
@@ -2,4 +2,5 @@
AFLAGS_headsmp.o += -march=armv7-a

obj-$(CONFIG_ARCH_NPCM7XX) += npcm7xx.o
+obj-$(CONFIG_ARCH_WPCM450) += wpcm450.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
diff --git a/arch/arm/mach-npcm/wpcm450.c b/arch/arm/mach-npcm/wpcm450.c
new file mode 100644
index 0000000000000..f17b3dab45af3
--- /dev/null
+++ b/arch/arm/mach-npcm/wpcm450.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright 2021 Jonathan Neuschäfer
+
+#include <asm/mach/arch.h>
+
+static const char *const wpcm450_dt_match[] = {
+ "nuvoton,wpcm450",
+ NULL
+};
+
+DT_MACHINE_START(WPCM450_DT, "WPCM450 chip")
+ .dt_compat = wpcm450_dt_match,
+MACHINE_END
--
2.30.2

2021-03-20 18:25:23

by J. Neuschäfer

[permalink] [raw]
Subject: [PATCH 08/14] irqchip: Add driver for WPCM450 interrupt controller

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 <[email protected]>
---
arch/arm/mach-npcm/Kconfig | 1 +
drivers/irqchip/Kconfig | 6 ++
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-wpcm450-aic.c | 162 ++++++++++++++++++++++++++++++
4 files changed, 170 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 0000000000000..0d6dd8b1fc824
--- /dev/null
+++ b/drivers/irqchip/irq-wpcm450-aic.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright 2021 Jonathan Neuschäfer
+
+#include <linux/console.h>
+#include <linux/irqchip.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#include <asm/exception.h>
+
+#define AIC_SCR(x) ((x)*4) /* Source control registers */
+#define AIC_GEN 0x84
+#define AIC_GRSR 0x88
+#define AIC_IRSR 0x100 /* Interrupt raw status register */
+#define AIC_IASR 0x104 /* Interrupt active status register */
+#define AIC_ISR 0x108 /* Interrupt status register */
+#define AIC_IPER 0x10c /* Interrupt priority encoding register */
+#define AIC_ISNR 0x110 /* Interrupt source number register */
+#define AIC_IMR 0x114 /* 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 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(0xffffffff, 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 < IRQS; i++)
+ writel(AIC_SCR_SRCTYPE_HIGH_LEVEL | AIC_SCR_PRIORITY(7),
+ aic->regs + AIC_SCR(i));
+}
+
+static void __exception_irq_entry wpcm450_aic_handle_irq(struct pt_regs *regs)
+{
+ int hwirq;
+
+ /* Determine the interrupt source */
+ /* Read IPER to signal that nIRQ can be de-asserted */
+ hwirq = readl(aic->regs + AIC_IPER) / 4;
+
+ handle_domain_irq(aic->domain, hwirq, regs);
+}
+
+static void wpcm450_aic_ack(struct irq_data *d)
+{
+ /* Signal end-of-service */
+ writel(0, aic->regs + AIC_EOSCR);
+}
+
+static void wpcm450_aic_mask(struct irq_data *d)
+{
+ unsigned int mask = 1U << d->hwirq;
+
+ /* Disable (mask) the interrupt */
+ writel(mask, aic->regs + AIC_MDCR);
+}
+
+static void wpcm450_aic_unmask(struct irq_data *d)
+{
+ unsigned int mask = 1U << d->hwirq;
+
+ /* Enable (unmask) the interrupt */
+ writel(mask, aic->regs + AIC_MECR);
+}
+
+static int wpcm450_aic_set_type(struct irq_data *d, unsigned int flow_type)
+{
+ /*
+ * The hardware supports high/low level, as well as rising/falling edge
+ * modes, and the DT binding accommodates for that, but as long as
+ * other modes than high level mode are not used and can't be tested,
+ * they are rejected in this driver.
+ */
+ if ((flow_type & IRQ_TYPE_SENSE_MASK) != IRQ_TYPE_LEVEL_HIGH) {
+ pr_err("IRQ mode %#x is not supported\n", flow_type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct irq_chip wpcm450_aic_chip = {
+ .name = "wpcm450-aic",
+ .irq_ack = wpcm450_aic_ack,
+ .irq_mask = wpcm450_aic_mask,
+ .irq_unmask = wpcm450_aic_unmask,
+ .irq_set_type = wpcm450_aic_set_type,
+};
+
+static int wpcm450_aic_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq)
+{
+ if (hwirq > IRQS)
+ return -EPERM;
+
+ irq_set_chip_and_handler(irq, &wpcm450_aic_chip, handle_level_irq);
+ irq_set_chip_data(irq, aic);
+ irq_set_probe(irq);
+
+ return 0;
+}
+
+static const struct irq_domain_ops wpcm450_aic_ops = {
+ .map = wpcm450_aic_map,
+ .xlate = irq_domain_xlate_twocell,
+};
+
+static int __init wpcm450_aic_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ if (parent)
+ return -EINVAL;
+
+ aic = kzalloc(sizeof(*aic), GFP_KERNEL);
+ if (!aic)
+ return -ENOMEM;
+
+ aic->regs = of_iomap(node, 0);
+ if (!aic->regs) {
+ pr_err("Failed to map WPCM450 AIC registers\n");
+ return -ENOMEM;
+ }
+
+ wpcm450_aic_init_hw();
+
+ set_handle_irq(wpcm450_aic_handle_irq);
+
+ aic->domain = irq_domain_add_linear(node, IRQS, &wpcm450_aic_ops, aic);
+
+ return 0;
+}
+
+IRQCHIP_DECLARE(wpcm450_aic, "nuvoton,wpcm450-aic", wpcm450_aic_of_init);
--
2.30.2

2021-03-20 18:25:29

by J. Neuschäfer

[permalink] [raw]
Subject: [PATCH 09/14] serial: 8250_of: Add nuvoton,wpcm450-uart

Add a compatible string for the UART inside the Nuvoton WPCM450 SoC.
It works the same as the UART in NPCM750.

Signed-off-by: Jonathan Neuschäfer <[email protected]>
---
drivers/tty/serial/8250/8250_of.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c
index 65e9045dafe6d..0b077b45d6a94 100644
--- a/drivers/tty/serial/8250/8250_of.c
+++ b/drivers/tty/serial/8250/8250_of.c
@@ -318,6 +318,7 @@ static const struct of_device_id of_platform_serial_table[] = {
{ .compatible = "mrvl,mmp-uart",
.data = (void *)PORT_XSCALE, },
{ .compatible = "ti,da830-uart", .data = (void *)PORT_DA830, },
+ { .compatible = "nuvoton,wpcm450-uart", .data = (void *)PORT_NPCM, },
{ .compatible = "nuvoton,npcm750-uart", .data = (void *)PORT_NPCM, },
{ /* end of list */ },
};
--
2.30.2

2021-03-20 18:26:12

by J. Neuschäfer

[permalink] [raw]
Subject: [PATCH 10/14] clocksource/drivers/npcm: Add support for WPCM450

Add a compatible string for WPCM450, which has essentially the same
timer controller.

Signed-off-by: Jonathan Neuschäfer <[email protected]>
---
drivers/clocksource/timer-npcm7xx.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/clocksource/timer-npcm7xx.c b/drivers/clocksource/timer-npcm7xx.c
index 9780ffd8010e6..a00520cbb660a 100644
--- a/drivers/clocksource/timer-npcm7xx.c
+++ b/drivers/clocksource/timer-npcm7xx.c
@@ -208,5 +208,6 @@ static int __init npcm7xx_timer_init(struct device_node *np)
return 0;
}

+TIMER_OF_DECLARE(wpcm450, "nuvoton,wpcm450-timer", npcm7xx_timer_init);
TIMER_OF_DECLARE(npcm7xx, "nuvoton,npcm750-timer", npcm7xx_timer_init);

--
2.30.2

2021-03-20 18:26:25

by J. Neuschäfer

[permalink] [raw]
Subject: [PATCH 12/14] ARM: dts: Add devicetree for Nuvoton WPCM450 BMC chip

The WPCM450 is an older BMC SoC in the Nuvoton NPCM family, originally
marketed as Winbond WPCM450.

This patch adds a devicetree with basic functionality.

Signed-off-by: Jonathan Neuschäfer <[email protected]>
---
arch/arm/boot/dts/nuvoton-wpcm450.dtsi | 76 ++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
create mode 100644 arch/arm/boot/dts/nuvoton-wpcm450.dtsi

diff --git a/arch/arm/boot/dts/nuvoton-wpcm450.dtsi b/arch/arm/boot/dts/nuvoton-wpcm450.dtsi
new file mode 100644
index 0000000000000..d7cbeb1874840
--- /dev/null
+++ b/arch/arm/boot/dts/nuvoton-wpcm450.dtsi
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+// Copyright 2021 Jonathan Neuschäfer
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ compatible = "nuvoton,wpcm450";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,arm926ej-s";
+ device_type = "cpu";
+ reg = <0>;
+ };
+ };
+
+ clk24m: clock-24mhz {
+ /* 24 MHz dummy clock */
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ #clock-cells = <0>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&aic>;
+ ranges;
+
+ serial0: serial@b8000000 {
+ compatible = "nuvoton,wpcm450-uart";
+ reg = <0xb8000000 0x20>;
+ reg-shift = <2>;
+ interrupts = <7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk24m>;
+ status = "disabled";
+ };
+
+ serial1: serial@b8000100 {
+ compatible = "nuvoton,wpcm450-uart";
+ reg = <0xb8000100 0x20>;
+ reg-shift = <2>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk24m>;
+ status = "disabled";
+ };
+
+ timer0: timer@b8001000 {
+ compatible = "nuvoton,wpcm450-timer";
+ interrupts = <12 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xb8001000 0x1c>;
+ clocks = <&clk24m>;
+ };
+
+ watchdog0: watchdog@b800101c {
+ compatible = "nuvoton,wpcm450-wdt";
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xb800101c 0x4>;
+ clocks = <&clk24m>;
+ status = "disabled";
+ };
+
+ aic: interrupt-controller@b8002000 {
+ compatible = "nuvoton,wpcm450-aic";
+ reg = <0xb8002000 0x1000>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+};
--
2.30.2

2021-03-20 18:26:53

by J. Neuschäfer

[permalink] [raw]
Subject: [PATCH 11/14] watchdog: npcm: Add support for WPCM450

Signed-off-by: Jonathan Neuschäfer <[email protected]>
---
drivers/watchdog/npcm_wdt.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/watchdog/npcm_wdt.c b/drivers/watchdog/npcm_wdt.c
index 765577f11c8db..28a24caa2627c 100644
--- a/drivers/watchdog/npcm_wdt.c
+++ b/drivers/watchdog/npcm_wdt.c
@@ -229,6 +229,7 @@ static int npcm_wdt_probe(struct platform_device *pdev)

#ifdef CONFIG_OF
static const struct of_device_id npcm_wdt_match[] = {
+ {.compatible = "nuvoton,wpcm450-wdt"},
{.compatible = "nuvoton,npcm750-wdt"},
{},
};
--
2.30.2

2021-03-20 18:27:00

by J. Neuschäfer

[permalink] [raw]
Subject: [PATCH 14/14] MAINTAINERS: Nuvoton NPCM: Add wpcm patterns

Make sure that patches related to the Nuvoton WPCM450 (part of the NPCM
family) find the Nuvoton NPCM maintainers and reviewers.

I am adding myself as a reviewer, so that I don't miss these patches.

Signed-off-by: Jonathan Neuschäfer <[email protected]>
---
---
MAINTAINERS | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index d92f85ca831d3..97923952679a8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2184,14 +2184,15 @@ M: Tali Perry <[email protected]>
R: Patrick Venture <[email protected]>
R: Nancy Yuen <[email protected]>
R: Benjamin Fair <[email protected]>
+R: Jonathan Neuschäfer <[email protected]>
L: [email protected] (moderated for non-subscribers)
S: Supported
-F: Documentation/devicetree/bindings/*/*/*npcm*
-F: Documentation/devicetree/bindings/*/*npcm*
-F: arch/arm/boot/dts/nuvoton-npcm*
+F: Documentation/devicetree/bindings/*/*/*[nw]pcm*
+F: Documentation/devicetree/bindings/*/*[nw]pcm*
+F: arch/arm/boot/dts/nuvoton-[nw]pcm*
F: arch/arm/mach-npcm/
-F: drivers/*/*npcm*
-F: drivers/*/*/*npcm*
+F: drivers/*/*[nw]pcm*
+F: drivers/*/*/*[nw]pcm*
F: include/dt-bindings/clock/nuvoton,npcm7xx-clock.h

ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT
--
2.30.2

2021-03-20 18:28:27

by J. Neuschäfer

[permalink] [raw]
Subject: [PATCH 13/14] ARM: dts: Add devicetree for Supermicro X9SCi-LN4F based on WPCM450

The Supermicro X9SCi-LN4F is a server mainboard featuring the WPCM450
BMC. This patch adds a minimal devicetree for Linux running on the BMC.

Signed-off-by: Jonathan Neuschäfer <[email protected]>
---
arch/arm/boot/dts/Makefile | 2 +
.../nuvoton-wpcm450-supermicro-x9sci-ln4f.dts | 40 +++++++++++++++++++
2 files changed, 42 insertions(+)
create mode 100644 arch/arm/boot/dts/nuvoton-wpcm450-supermicro-x9sci-ln4f.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 8e5d4ab4e75e6..cab5b3c906f83 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -1305,6 +1305,8 @@ dtb-$(CONFIG_ARCH_VT8500) += \
wm8650-mid.dtb \
wm8750-apc8750.dtb \
wm8850-w70v2.dtb
+dtb-$(CONFIG_ARCH_WPCM450) += \
+ nuvoton-wpcm450-supermicro-x9sci-ln4f.dtb
dtb-$(CONFIG_ARCH_ZYNQ) += \
zynq-cc108.dtb \
zynq-ebaz4205.dtb \
diff --git a/arch/arm/boot/dts/nuvoton-wpcm450-supermicro-x9sci-ln4f.dts b/arch/arm/boot/dts/nuvoton-wpcm450-supermicro-x9sci-ln4f.dts
new file mode 100644
index 0000000000000..83f27fbf4e939
--- /dev/null
+++ b/arch/arm/boot/dts/nuvoton-wpcm450-supermicro-x9sci-ln4f.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+// Copyright 2021 Jonathan Neuschäfer
+
+/dts-v1/;
+
+/* The last 16 MiB are dedicated to the GPU */
+/memreserve/ 0x07000000 0x01000000;
+
+#include "nuvoton-wpcm450.dtsi"
+
+/ {
+ model = "Supermicro X9SCi-LN4F BMC";
+ compatible = "supermicro,x9sci-ln4f-bmc", "nuvoton,wpcm450";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0 0x08000000>; /* 128 MiB */
+ };
+};
+
+&serial0 {
+ /*
+ * Debug serial port. TX is exposed on the right pad of unpopulated
+ * resistor R1247, RX on the right pad of R1162.
+ */
+ status = "okay";
+};
+
+&serial1 {
+ /* "Serial over LAN" port. Connected to ttyS2 of the host system. */
+ status = "okay";
+};
+
+&watchdog0 {
+ status = "okay";
+};
--
2.30.2

2021-03-20 18:48:25

by J. Neuschäfer

[permalink] [raw]
Subject: Re: [PATCH 13/14] ARM: dts: Add devicetree for Supermicro X9SCi-LN4F based on WPCM450

On Sat, Mar 20, 2021 at 07:16:09PM +0100, Jonathan Neuschäfer wrote:
> The Supermicro X9SCi-LN4F is a server mainboard featuring the WPCM450
> BMC. This patch adds a minimal devicetree for Linux running on the BMC.
>
> Signed-off-by: Jonathan Neuschäfer <[email protected]>
> ---
[...]
> +&serial1 {
> + /* "Serial over LAN" port. Connected to ttyS2 of the host system. */
> + status = "okay";
> +};

One thing to note here: The SOL functionality doesn't work with this
patchset alone, because it requires a special register setting in the
SoC's System Global Control Register block (SPSWC.SPMOD = 2).

So it might make sense to drop the serial1 enablement for now.


Jonathan Neuschäfer


Attachments:
(No filename) (716.00 B)
signature.asc (849.00 B)
Download all attachments

2021-03-20 18:50:58

by J. Neuschäfer

[permalink] [raw]
Subject: Re: [PATCH 00/14] Initial support for Nuvoton WPCM450 BMC SoC

On Sat, Mar 20, 2021 at 07:15:56PM +0100, Jonathan Neuschäfer wrote:
> This series adds basic support for the Nuvoton WPCM450 BMC SoC. It's an older
> SoC but still commonly found on eBay, mostly in Supermicro X9 server boards.

Something I forgot to mention: I wrote a bit of third-party
documentation based on the various vendor kernel trees and it's
available at:

https://github.com/neuschaefer/wpcm450/wiki



Best regards,
Jonathan Neuschäfer


Attachments:
(No filename) (467.00 B)
signature.asc (849.00 B)
Download all attachments

2021-03-20 20:29:02

by Guenter Roeck

[permalink] [raw]
Subject: Re: [PATCH 11/14] watchdog: npcm: Add support for WPCM450

On 3/20/21 11:16 AM, Jonathan Neuschäfer wrote:

Patch description goes here.

Guenter

> Signed-off-by: Jonathan Neuschäfer <[email protected]>

> ---
> drivers/watchdog/npcm_wdt.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/watchdog/npcm_wdt.c b/drivers/watchdog/npcm_wdt.c
> index 765577f11c8db..28a24caa2627c 100644
> --- a/drivers/watchdog/npcm_wdt.c
> +++ b/drivers/watchdog/npcm_wdt.c
> @@ -229,6 +229,7 @@ static int npcm_wdt_probe(struct platform_device *pdev)
>
> #ifdef CONFIG_OF
> static const struct of_device_id npcm_wdt_match[] = {
> + {.compatible = "nuvoton,wpcm450-wdt"},
> {.compatible = "nuvoton,npcm750-wdt"},
> {},
> };
> --
> 2.30.2
>

2021-03-20 20:49:23

by J. Neuschäfer

[permalink] [raw]
Subject: Re: [PATCH 11/14] watchdog: npcm: Add support for WPCM450

On Sat, Mar 20, 2021 at 01:24:31PM -0700, Guenter Roeck wrote:
> On 3/20/21 11:16 AM, Jonathan Neuschäfer wrote:
>
> Patch description goes here.

Ah right, I forgot to add one. I'll fix it in the next iteration.


Jonathan


Attachments:
(No filename) (235.00 B)
signature.asc (849.00 B)
Download all attachments

2021-03-21 12:35:57

by J. Neuschäfer

[permalink] [raw]
Subject: Re: [PATCH 00/14] Initial support for Nuvoton WPCM450 BMC SoC

On Sun, Mar 21, 2021 at 01:07:53PM +0200, Tomer Maimon wrote:
> Hi Jonathan,
>
> Thanks a lot for trying to add WPCM450.
>
> Hoever WPCM450 is in EOL for several years and we are not supporting this
> product anymore.
> As you said it is only available in the secondary market.
>
> Due to it is better not to add the WPCM450 under Nuvoton maintenance.

I understand. I will instead add a new, separate section for WPCM450 to
the MAINTAINERS file.

> Again we highly appreciate your support and time on NPCM750 patches.

I expect there will be some more cooperation, because the SoCs share
some architectural similarity, for example the 100Mbit Ethernet
controller.


Best regards,
Jonathan


Attachments:
(No filename) (716.00 B)
signature.asc (849.00 B)
Download all attachments

2021-03-22 10:50:41

by Daniel Lezcano

[permalink] [raw]
Subject: Re: [PATCH 10/14] clocksource/drivers/npcm: Add support for WPCM450

On 20/03/2021 19:16, Jonathan Neuschäfer wrote:
> Add a compatible string for WPCM450, which has essentially the same
> timer controller.
>
> Signed-off-by: Jonathan Neuschäfer <[email protected]>
> ---

Applied, thanks


--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

2021-03-24 17:19:27

by Marc Zyngier

[permalink] [raw]
Subject: Re: [PATCH 08/14] irqchip: Add driver for WPCM450 interrupt controller

On Sat, 20 Mar 2021 18:16:04 +0000,
Jonathan Neuschäfer <[email protected]> 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 <[email protected]>
> ---
> arch/arm/mach-npcm/Kconfig | 1 +
> drivers/irqchip/Kconfig | 6 ++
> drivers/irqchip/Makefile | 1 +
> drivers/irqchip/irq-wpcm450-aic.c | 162 ++++++++++++++++++++++++++++++
> 4 files changed, 170 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 0000000000000..0d6dd8b1fc824
> --- /dev/null
> +++ b/drivers/irqchip/irq-wpcm450-aic.c
> @@ -0,0 +1,162 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +// Copyright 2021 Jonathan Neuschäfer
> +
> +#include <linux/console.h>

That's unexpected. Why do you need this?

> +#include <linux/irqchip.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +
> +#include <asm/exception.h>
> +
> +#define AIC_SCR(x) ((x)*4) /* Source control registers */
> +#define AIC_GEN 0x84
> +#define AIC_GRSR 0x88
> +#define AIC_IRSR 0x100 /* Interrupt raw status register */
> +#define AIC_IASR 0x104 /* Interrupt active status register */
> +#define AIC_ISR 0x108 /* Interrupt status register */
> +#define AIC_IPER 0x10c /* Interrupt priority encoding register */
> +#define AIC_ISNR 0x110 /* Interrupt source number register */
> +#define AIC_IMR 0x114 /* 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)

A mask would be welcomed for this field.

> +
> +#define IRQS 32

Please use something a bit less generic.

> +
> +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(0xffffffff, aic->regs + AIC_MDCR);

Consider using relaxed accessors throughout this driver.

> +
> + /*
> + * 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 < IRQS; i++)
> + writel(AIC_SCR_SRCTYPE_HIGH_LEVEL | AIC_SCR_PRIORITY(7),
> + aic->regs + AIC_SCR(i));
> +}
> +
> +static void __exception_irq_entry wpcm450_aic_handle_irq(struct pt_regs *regs)
> +{
> + int hwirq;
> +
> + /* Determine the interrupt source */
> + /* Read IPER to signal that nIRQ can be de-asserted */
> + hwirq = readl(aic->regs + AIC_IPER) / 4;
> +
> + handle_domain_irq(aic->domain, hwirq, regs);
> +}
> +
> +static void wpcm450_aic_ack(struct irq_data *d)
> +{
> + /* Signal end-of-service */
> + writel(0, aic->regs + AIC_EOSCR);

Is that an Ack or an EOI? My gut feeling is that the above read is the
Ack, and that this write should actually be an EOI callback.

> +}
> +
> +static void wpcm450_aic_mask(struct irq_data *d)
> +{
> + unsigned int mask = 1U << d->hwirq;

Consider using BIT().

> +
> + /* Disable (mask) the interrupt */
> + writel(mask, aic->regs + AIC_MDCR);
> +}
> +
> +static void wpcm450_aic_unmask(struct irq_data *d)
> +{
> + unsigned int mask = 1U << d->hwirq;
> +
> + /* Enable (unmask) the interrupt */
> + writel(mask, aic->regs + AIC_MECR);
> +}
> +
> +static int wpcm450_aic_set_type(struct irq_data *d, unsigned int flow_type)
> +{
> + /*
> + * The hardware supports high/low level, as well as rising/falling edge
> + * modes, and the DT binding accommodates for that, but as long as
> + * other modes than high level mode are not used and can't be tested,
> + * they are rejected in this driver.
> + */
> + if ((flow_type & IRQ_TYPE_SENSE_MASK) != IRQ_TYPE_LEVEL_HIGH) {
> + pr_err("IRQ mode %#x is not supported\n", flow_type);

The core kernel shouts loudly enough, no need for extra messages.

> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static struct irq_chip wpcm450_aic_chip = {
> + .name = "wpcm450-aic",
> + .irq_ack = wpcm450_aic_ack,
> + .irq_mask = wpcm450_aic_mask,
> + .irq_unmask = wpcm450_aic_unmask,
> + .irq_set_type = wpcm450_aic_set_type,
> +};
> +
> +static int wpcm450_aic_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq)
> +{
> + if (hwirq > IRQS)
> + return -EPERM;
> +
> + irq_set_chip_and_handler(irq, &wpcm450_aic_chip, handle_level_irq);
> + irq_set_chip_data(irq, aic);
> + irq_set_probe(irq);
> +
> + return 0;
> +}
> +
> +static const struct irq_domain_ops wpcm450_aic_ops = {
> + .map = wpcm450_aic_map,
> + .xlate = irq_domain_xlate_twocell,
> +};
> +
> +static int __init wpcm450_aic_of_init(struct device_node *node,
> + struct device_node *parent)
> +{
> + if (parent)
> + return -EINVAL;
> +
> + aic = kzalloc(sizeof(*aic), GFP_KERNEL);
> + if (!aic)
> + return -ENOMEM;
> +
> + aic->regs = of_iomap(node, 0);
> + if (!aic->regs) {
> + pr_err("Failed to map WPCM450 AIC registers\n");
> + return -ENOMEM;
> + }
> +
> + wpcm450_aic_init_hw();
> +
> + set_handle_irq(wpcm450_aic_handle_irq);
> +
> + aic->domain = irq_domain_add_linear(node, IRQS, &wpcm450_aic_ops, aic);
> +
> + return 0;
> +}
> +
> +IRQCHIP_DECLARE(wpcm450_aic, "nuvoton,wpcm450-aic", wpcm450_aic_of_init);

Otherwise, looks good.

M.

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

2021-03-26 18:54:15

by J. Neuschäfer

[permalink] [raw]
Subject: Re: [PATCH 08/14] irqchip: Add driver for WPCM450 interrupt controller

On Wed, Mar 24, 2021 at 05:16:35PM +0000, Marc Zyngier wrote:
> On Sat, 20 Mar 2021 18:16:04 +0000,
> Jonathan Neuschäfer <[email protected]> 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 <[email protected]>
> > ---
[...]
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +// Copyright 2021 Jonathan Neuschäfer
> > +
> > +#include <linux/console.h>
>
> That's unexpected. Why do you need this?

I forgot about linux/printk.h.

> > +#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)
>
> A mask would be welcomed for this field.

Ok, I'll add

+#define AIC_SCR_PRIORITY_MASK 0x7

Should I apply it in AIC_SCR_PRIORITY(x), too?

> > +
> > +#define IRQS 32
>
> Please use something a bit less generic.

Ok, I'll rename it to AIC_NUM_IRQS.

> > +static void wpcm450_aic_init_hw(void)
> > +{
> > + int i;
> > +
> > + /* Disable (mask) all interrupts */
> > + writel(0xffffffff, aic->regs + AIC_MDCR);
>
> Consider using relaxed accessors throughout this driver.

I'll read up on how to use them correctly.

> > +static void __exception_irq_entry wpcm450_aic_handle_irq(struct pt_regs *regs)
> > +{
> > + int hwirq;
> > +
> > + /* Determine the interrupt source */
> > + /* Read IPER to signal that nIRQ can be de-asserted */
> > + hwirq = readl(aic->regs + AIC_IPER) / 4;
> > +
> > + handle_domain_irq(aic->domain, hwirq, regs);
> > +}
> > +
> > +static void wpcm450_aic_ack(struct irq_data *d)
> > +{
> > + /* Signal end-of-service */
> > + writel(0, aic->regs + AIC_EOSCR);
>
> Is that an Ack or an EOI? My gut feeling is that the above read is the
> Ack, and that this write should actually be an EOI callback.

I agree that EOSCR (End of Service Command Register) matches the
description of EOI.

The reading IPER serves a dual purpose, as indicated above. I could
move the IPER read to a separate irq_ack function and use ISNR
(Interrupt source number register) in the IRQ handler instead. This
should work (haven't tested it yet), but I'm not sure it's strictly
better.

> > +static void wpcm450_aic_mask(struct irq_data *d)
> > +{
> > + unsigned int mask = 1U << d->hwirq;
>
> Consider using BIT().

Will do.

> > +static int wpcm450_aic_set_type(struct irq_data *d, unsigned int flow_type)
> > +{
> > + /*
> > + * The hardware supports high/low level, as well as rising/falling edge
> > + * modes, and the DT binding accommodates for that, but as long as
> > + * other modes than high level mode are not used and can't be tested,
> > + * they are rejected in this driver.
> > + */
> > + if ((flow_type & IRQ_TYPE_SENSE_MASK) != IRQ_TYPE_LEVEL_HIGH) {
> > + pr_err("IRQ mode %#x is not supported\n", flow_type);
>
> The core kernel shouts loudly enough, no need for extra messages.

Ok.

> Otherwise, looks good.
>
> M.


Thanks for your review!
Jonathan Neuschäfer


Attachments:
(No filename) (3.46 kB)
signature.asc (849.00 B)
Download all attachments

2021-03-27 16:42:04

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH 01/14] dt-bindings: vendor-prefixes: Add Supermicro

On Sat, 20 Mar 2021 19:15:57 +0100, Jonathan Neusch?fer wrote:
> Super Micro Computer, Inc. (https://www.supermicro.com/en/), commonly
> known as Supermicro, is a manufacturer of server hardware.
>
> Signed-off-by: Jonathan Neusch?fer <[email protected]>
> ---
> Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
> 1 file changed, 2 insertions(+)
>

Acked-by: Rob Herring <[email protected]>

2021-03-27 16:42:34

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH 02/14] dt-bindings: arm: npcm: Add nuvoton, wpcm450 compatible string

On Sat, 20 Mar 2021 19:15:58 +0100, Jonathan Neusch?fer wrote:
> The WPCM450 is an older BMC SoC in the Nuvoton NPCM family, originally
> marketed as Winbond WPCM450.
>
> Signed-off-by: Jonathan Neusch?fer <[email protected]>
> ---
>
> This patch requires "dt-bindings: arm: Convert nuvoton,npcm750 binding to YAML"
> (https://lore.kernel.org/lkml/[email protected]/)
> ---
> Documentation/devicetree/bindings/arm/npcm/npcm.yaml | 6 ++++++
> 1 file changed, 6 insertions(+)
>

Acked-by: Rob Herring <[email protected]>

2021-03-27 16:43:18

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH 03/14] dt-bindings: interrupt-controller: Add nuvoton, wpcm450-aic

On Sat, 20 Mar 2021 19:15:59 +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.
>
> Signed-off-by: Jonathan Neusch?fer <[email protected]>
> ---
> .../nuvoton,wpcm450-aic.yaml | 39 +++++++++++++++++++
> 1 file changed, 39 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/interrupt-controller/nuvoton,wpcm450-aic.yaml
>

Reviewed-by: Rob Herring <[email protected]>

2021-03-27 16:44:18

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH 06/14] dt-bindings: watchdog: npcm: Add nuvoton,wpcm450-wdt

On Sat, 20 Mar 2021 19:16:02 +0100, Jonathan Neusch?fer wrote:
> Add a compatible string for the WPCM450 SoC, which has the same watchdog
> timer.
>
> Signed-off-by: Jonathan Neusch?fer <[email protected]>
> ---
> .../devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>

Acked-by: Rob Herring <[email protected]>

2021-03-27 16:45:37

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH 04/14] dt-bindings: serial: 8250: Add nuvoton,wpcm450-uart

On Sat, 20 Mar 2021 19:16:00 +0100, Jonathan Neusch?fer wrote:
> Add a compatible string for the UART inside the Nuvoton WPCM450 SoC.
>
> Signed-off-by: Jonathan Neusch?fer <[email protected]>
> ---
> Documentation/devicetree/bindings/serial/8250.yaml | 1 +
> 1 file changed, 1 insertion(+)
>

Acked-by: Rob Herring <[email protected]>

2021-03-27 16:45:56

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH 05/14] dt-bindings: timer: nuvoton,npcm7xx: Add wpcm450-timer

On Sat, 20 Mar 2021 19:16:01 +0100, Jonathan Neusch?fer wrote:
> Add a compatible string for WPCM450, which has essentially the same
> timer controller.
>
> Signed-off-by: Jonathan Neusch?fer <[email protected]>
> ---
> .../devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>

Acked-by: Rob Herring <[email protected]>

2021-04-04 20:31:25

by Daniel Lezcano

[permalink] [raw]
Subject: Re: [PATCH 05/14] dt-bindings: timer: nuvoton,npcm7xx: Add wpcm450-timer

On 20/03/2021 19:16, Jonathan Neuschäfer wrote:
> Add a compatible string for WPCM450, which has essentially the same
> timer controller.
>
> Signed-off-by: Jonathan Neuschäfer <[email protected]>
> ---

Applied, thanks


--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

2021-04-06 06:53:54

by J. Neuschäfer

[permalink] [raw]
Subject: Re: [PATCH 08/14] irqchip: Add driver for WPCM450 interrupt controller

On Fri, Mar 26, 2021 at 07:52:07PM +0100, Jonathan Neuschäfer wrote:
> On Wed, Mar 24, 2021 at 05:16:35PM +0000, Marc Zyngier wrote:
> > On Sat, 20 Mar 2021 18:16:04 +0000, Jonathan Neuschäfer <[email protected]> wrote:
[...]
> > > + /* Disable (mask) all interrupts */
> > > + writel(0xffffffff, aic->regs + AIC_MDCR);
> >
> > Consider using relaxed accessors throughout this driver.
>
> I'll read up on how to use them correctly.

Upon further consideration, I decided not to bother with relaxed MMIO
access, because it doesn't make a difference on the target platform —
Nuvoton WPCM450 with ARM926 (ARMv5).


Best regards,
Jonathan Neuschäfer


Attachments:
(No filename) (675.00 B)
signature.asc (849.00 B)
Download all attachments
Subject: [tip: timers/core] dt-bindings: timer: nuvoton,npcm7xx: Add wpcm450-timer

The following commit has been merged into the timers/core branch of tip:

Commit-ID: 8120891105ba32b45bc35f7dc07e6d87a8314556
Gitweb: https://git.kernel.org/tip/8120891105ba32b45bc35f7dc07e6d87a8314556
Author: Jonathan Neuschäfer <[email protected]>
AuthorDate: Sat, 20 Mar 2021 19:16:01 +01:00
Committer: Daniel Lezcano <[email protected]>
CommitterDate: Thu, 08 Apr 2021 16:41:20 +02:00

dt-bindings: timer: nuvoton,npcm7xx: Add wpcm450-timer

Add a compatible string for WPCM450, which has essentially the same
timer controller.

Signed-off-by: Jonathan Neuschäfer <[email protected]>
Acked-by: Rob Herring <[email protected]>
Signed-off-by: Daniel Lezcano <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt b/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt
index 97258f1..ac3a5e8 100644
--- a/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt
+++ b/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt
@@ -4,7 +4,8 @@ Nuvoton NPCM7xx have three timer modules, each timer module provides five 24-bit
timer counters.

Required properties:
-- compatible : "nuvoton,npcm750-timer" for Poleg NPCM750.
+- compatible : "nuvoton,npcm750-timer" for Poleg NPCM750, or
+ "nuvoton,wpcm450-timer" for Hermon WPCM450.
- reg : Offset and length of the register set for the device.
- interrupts : Contain the timer interrupt of timer 0.
- clocks : phandle of timer reference clock (usually a 25 MHz clock).

Subject: [tip: timers/core] clocksource/drivers/npcm: Add support for WPCM450

The following commit has been merged into the timers/core branch of tip:

Commit-ID: 690daddcb60246d8a510aaad7b954bcc53eba17e
Gitweb: https://git.kernel.org/tip/690daddcb60246d8a510aaad7b954bcc53eba17e
Author: Jonathan Neuschäfer <[email protected]>
AuthorDate: Sat, 20 Mar 2021 19:16:06 +01:00
Committer: Daniel Lezcano <[email protected]>
CommitterDate: Thu, 08 Apr 2021 13:24:16 +02:00

clocksource/drivers/npcm: Add support for WPCM450

Add a compatible string for WPCM450, which has essentially the same
timer controller.

Signed-off-by: Jonathan Neuschäfer <[email protected]>
Signed-off-by: Daniel Lezcano <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
drivers/clocksource/timer-npcm7xx.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/clocksource/timer-npcm7xx.c b/drivers/clocksource/timer-npcm7xx.c
index 9780ffd..a00520c 100644
--- a/drivers/clocksource/timer-npcm7xx.c
+++ b/drivers/clocksource/timer-npcm7xx.c
@@ -208,5 +208,6 @@ static int __init npcm7xx_timer_init(struct device_node *np)
return 0;
}

+TIMER_OF_DECLARE(wpcm450, "nuvoton,wpcm450-timer", npcm7xx_timer_init);
TIMER_OF_DECLARE(npcm7xx, "nuvoton,npcm750-timer", npcm7xx_timer_init);