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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
>
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
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
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
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.
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
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]>
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]>
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]>
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]>
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]>
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]>
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
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
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).
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);