};
/* Uart divisor latch read */
-@@ -2782,6 +2790,11 @@ serial8250_do_set_termios(struct uart_po
+@@ -2785,6 +2793,11 @@ serial8250_do_set_termios(struct uart_po
serial8250_set_ier(port, termios);
serial8250_set_efr(port, termios);
serial8250_set_divisor(port, baud, quot, frac);
-From f3fa5911b1f094e164c497f7b10d94d92852e285 Mon Sep 17 00:00:00 2001
+From 35af99f7482673bf5f5391fd33caf266f4f62aeb Mon Sep 17 00:00:00 2001
From: Caleb James DeLisle <cjd@cjdns.fr>
-Date: Wed, 14 Jan 2026 17:54:05 +0000
-Subject: [PATCH] dt-bindings: clock, reset: Add econet EN751221 bindings
+Date: Thu, 12 Mar 2026 16:24:48 +0000
+Subject: [PATCH] dt-bindings: clock, reset: Add econet EN751221
-Add clock and reset bindings for EN751221 based on the Airoha EN7523 SCU
-driver.
+Add clock and reset bindings for EN751221 as well as a "chip-scu" which is
+an additional regmap that is used by the clock driver as well as others.
+This split of the SCU across two register areas is the same as the Airoha
+AN758x family.
Signed-off-by: Caleb James DeLisle <cjd@cjdns.fr>
+Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
-The EN751221 has the same bifurcation of SCU as EN7581 so we use
-the same chip-scu as airoha,en7581-chip-scu.
----
- .../bindings/clock/airoha,en7523-scu.yaml | 17 +++++++-
- .../mips/econet,en751221-chip-scu.yaml | 42 +++++++++++++++++++
- .../dt-bindings/clock/econet,en751221-scu.h | 14 +++++++
- .../dt-bindings/reset/econet,en751221-scu.h | 41 ++++++++++++++++++
- 4 files changed, 113 insertions(+), 1 deletion(-)
- create mode 100644 Documentation/devicetree/bindings/mips/econet,en751221-chip-scu.yaml
+ .../bindings/clock/airoha,en7523-scu.yaml | 6 ++-
+ .../devicetree/bindings/mfd/syscon.yaml | 2 +
+ MAINTAINERS | 2 +
+ .../dt-bindings/clock/econet,en751221-scu.h | 12 +++++
+ .../dt-bindings/reset/econet,en751221-scu.h | 49 +++++++++++++++++++
+ 5 files changed, 70 insertions(+), 1 deletion(-)
create mode 100644 include/dt-bindings/clock/econet,en751221-scu.h
create mode 100644 include/dt-bindings/reset/econet,en751221-scu.h
reg:
items:
-@@ -67,7 +68,10 @@ allOf:
+@@ -67,7 +68,9 @@ allOf:
- if:
properties:
compatible:
- const: airoha,en7581-scu
-+ items:
-+ - enum:
-+ - airoha,en7581-scu
-+ - econet,en751221-scu
++ enum:
++ - airoha,en7581-scu
++ - econet,en751221-scu
then:
properties:
reg:
-@@ -98,3 +102,14 @@ examples:
+@@ -98,3 +101,4 @@ examples:
#reset-cells = <1>;
};
};
+
-+ - |
-+ soc {
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ scuclk: clock-controller@1fb00000 {
-+ compatible = "econet,en751221-scu";
-+ reg = <0x1fb00000 0x970>;
-+ };
-+ };
-\ No newline at end of file
---- /dev/null
-+++ b/Documentation/devicetree/bindings/mips/econet,en751221-chip-scu.yaml
-@@ -0,0 +1,42 @@
-+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/arm/airoha,en7581-chip-scu.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: EcoNet Chip SCU Controller for EN751221 SoC
-+
-+maintainers:
-+ - Caleb James DeLisle <cjd@cjdns.fr>
-+
-+description:
-+ The EcoNet chip-scu block provides a configuration interface for clock,
-+ io-muxing and other functionalities used by multiple controllers (e.g. clock,
-+ pinctrl, ecc) on EN751221 SoC.
-+
-+properties:
-+ compatible:
-+ items:
-+ - enum:
+--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
++++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
+@@ -61,6 +61,7 @@ select:
+ - cirrus,ep7209-syscon2
+ - cirrus,ep7209-syscon3
+ - cnxt,cx92755-uc
+ - econet,en751221-chip-scu
-+ - const: syscon
-+
-+ reg:
-+ maxItems: 1
-+
-+required:
-+ - compatible
-+ - reg
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ soc {
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ syscon@1fa20000 {
-+ compatible = "econet,en751221-chip-scu", "syscon";
-+ reg = <0x1fa20000 0x388>;
-+ };
-+ };
+ - freecom,fsg-cs2-system-controller
+ - fsl,imx93-aonmix-ns-syscfg
+ - fsl,imx93-wakeupmix-syscfg
+@@ -169,6 +170,7 @@ properties:
+ - cirrus,ep7209-syscon2
+ - cirrus,ep7209-syscon3
+ - cnxt,cx92755-uc
++ - econet,en751221-chip-scu
+ - freecom,fsg-cs2-system-controller
+ - fsl,imx93-aonmix-ns-syscfg
+ - fsl,imx93-wakeupmix-syscfg
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -8839,6 +8839,8 @@ F: arch/mips/boot/dts/econet/
+ F: arch/mips/econet/
+ F: drivers/clocksource/timer-econet-en751221.c
+ F: drivers/irqchip/irq-econet-en751221.c
++F: include/dt-bindings/clock/econet,en751221-scu.h
++F: include/dt-bindings/reset/econet,en751221-scu.h
+
+ ECRYPT FILE SYSTEM
+ M: Tyler Hicks <code@tyhicks.com>
--- /dev/null
+++ b/include/dt-bindings/clock/econet,en751221-scu.h
-@@ -0,0 +1,15 @@
+@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+
+#ifndef _DT_BINDINGS_CLOCK_ECONET_EN751221_SCU_H_
+#define EN751221_CLK_SPI 1
+#define EN751221_CLK_BUS 2
+#define EN751221_CLK_CPU 3
-+#define EN751221_CLK_HPT 4
-+#define EN751221_CLK_GSW 5
-+
-+#define EN751221_MAX_CLKS 6
++#define EN751221_CLK_GSW 4
+
+#endif /* _DT_BINDINGS_CLOCK_ECONET_EN751221_SCU_H_ */
-\ No newline at end of file
--- /dev/null
+++ b/include/dt-bindings/reset/econet,en751221-scu.h
@@ -0,0 +1,49 @@
-From 1dfb29374a040ba80d378b3465f4e0bcb67f4ba3 Mon Sep 17 00:00:00 2001
+From d8b034525fd9541f23c5a3c54cd1dbe716570e97 Mon Sep 17 00:00:00 2001
From: Caleb James DeLisle <cjd@cjdns.fr>
-Date: Wed, 14 Jan 2026 18:06:13 +0000
+Date: Thu, 12 Mar 2026 16:24:49 +0000
Subject: [PATCH] clk: airoha: Add econet EN751221 clock/reset support to
en7523-scu
correctly on EN751627, EN7528, and EN7580.
Signed-off-by: Caleb James DeLisle <cjd@cjdns.fr>
+Reviewed-by: Brian Masney <bmasney@redhat.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
drivers/clk/Kconfig | 6 +-
- drivers/clk/clk-en7523.c | 182 +++++++++++++++++++++++++++++++++++++++
- 2 files changed, 185 insertions(+), 3 deletions(-)
+ drivers/clk/clk-en7523.c | 223 ++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 221 insertions(+), 8 deletions(-)
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
#define RST_NR_PER_BANK 32
-@@ -33,15 +36,47 @@
+@@ -33,15 +36,50 @@
#define REG_RESET_CONTROL_PCIEHB BIT(29)
#define REG_RESET_CONTROL_PCIE1 BIT(27)
#define REG_RESET_CONTROL_PCIE2 BIT(26)
#define REG_CRYPTO_CLKSRC2 0x20c
+/* EN751221 */
+#define EN751221_REG_SPI_DIV 0x0cc
-+#define EN751221_REG_SPI_DIV_MASK GENMASK(31,8)
++#define EN751221_REG_SPI_DIV_MASK GENMASK(31, 8)
+#define EN751221_SPI_BASE 500000000
+#define EN751221_SPI_BASE_EN7526C 400000000
++#define EN751221_SPI_DIV_DEFAULT 40
+#define EN751221_REG_BUS 0x284
-+#define EN751221_REG_BUS_MASK GENMASK(21,12)
++#define EN751221_REG_BUS_MASK GENMASK(21, 12)
+#define EN751221_REG_SSR3 0x094
-+#define EN751221_REG_SSR3_GSW_MASK GENMASK(9,8)
++#define EN751221_REG_SSR3_GSW_MASK GENMASK(9, 8)
#define REG_RST_CTRL2 0x830
#define REG_RST_CTRL1 0x834
+#define EN751221_REG_RST_DMT 0x84
+#define EN751221_REG_RST_USB 0xec
+
++#define EN751221_MAX_CLKS 5
++
+enum en_hir {
+ HIR_UNKNOWN = -1,
+ HIR_TC3169 = 0,
struct en_clk_desc {
int id;
-@@ -93,6 +128,8 @@ static const u32 bus7581_base[] = { 6000
+@@ -93,6 +131,8 @@ static const u32 bus7581_base[] = { 6000
static const u32 npu7581_base[] = { 800000000, 750000000, 720000000, 600000000 };
static const u32 crypto_base[] = { 540000000, 480000000 };
static const u32 emmc7581_base[] = { 200000000, 150000000 };
static const struct en_clk_desc en7523_base_clks[] = {
{
-@@ -300,6 +337,13 @@ static const u16 en7581_rst_ofs[] = {
+@@ -300,6 +340,13 @@ static const u16 en7581_rst_ofs[] = {
REG_RST_CTRL1,
};
static const u16 en7523_rst_map[] = {
/* RST_CTRL2 */
[EN7523_XPON_PHY_RST] = 0,
-@@ -405,8 +449,61 @@ static const u16 en7581_rst_map[] = {
+@@ -405,8 +452,61 @@ static const u16 en7581_rst_map[] = {
[EN7581_XPON_MAC_RST] = RST_NR_PER_BANK + 31,
};
static u32 en7523_get_base_rate(const struct en_clk_desc *desc, u32 val)
{
-@@ -604,7 +701,8 @@ static int en7523_clk_hw_init(struct pla
+@@ -604,7 +704,8 @@ static int en7523_clk_hw_init(struct pla
en7523_register_clocks(&pdev->dev, clk_data, base, np_base);
return en7581_reset_register(&pdev->dev, np_base, en7523_rst_map,
}
static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
-@@ -705,7 +803,8 @@ static const struct reset_control_ops en
+@@ -705,7 +806,8 @@ static const struct reset_control_ops en
};
static int en7581_reset_register(struct device *dev, void __iomem *base,
{
struct en_rst_data *rst_data;
-@@ -713,7 +812,7 @@ static int en7581_reset_register(struct
+@@ -713,7 +815,7 @@ static int en7581_reset_register(struct
if (!rst_data)
return -ENOMEM;
rst_data->idx_map = rst_map;
rst_data->base = base;
-@@ -752,7 +851,123 @@ static int en7581_clk_hw_init(struct pla
+@@ -752,7 +854,107 @@ static int en7581_clk_hw_init(struct pla
writel(val | 3, base + REG_NP_SCU_PCIC);
return en7581_reset_register(&pdev->dev, base, en7581_rst_map,
+ u32 val = FIELD_GET(REG_HIR_MASK, readl(np_base + REG_HIR));
+
+ if (val < HIR_MAX)
-+ return (enum en_hir) val;
++ return (enum en_hir)val;
++
++ pr_warn("Unable to determine EcoNet SoC\n");
+
+ return HIR_UNKNOWN;
+}
+{
+ struct clk_hw *hw;
+
++ if (WARN_ON_ONCE(key >= EN751221_MAX_CLKS))
++ return;
++
+ hw = clk_hw_register_fixed_rate(dev, name, NULL, 0, rate);
+ if (IS_ERR(hw))
+ pr_err("Failed to register clk %s: %pe\n", name, hw);
+ } else {
+ div = FIELD_GET(EN751221_REG_SPI_DIV_MASK, div) * 2;
+ if (!div)
-+ div = 40;
++ div = EN751221_SPI_DIV_DEFAULT;
+
+ en751221_try_register_clk(dev, EN751221_CLK_SPI, clk_data,
+ "spi", rate / div);
+ en751221_try_register_clk(dev, EN751221_CLK_CPU, clk_data, "cpu",
+ rate * 4);
+
-+ /* HPT */
-+ switch (hid) {
-+ case HIR_EN751221:
-+ case HIR_EN751627:
-+ case HIR_EN7526C:
-+ case HIR_EN7580:
-+ case HIR_EN7528:
-+ rate = 200000000;
-+ break;
-+ case HIR_MT7505:
-+ rate = 100000000;
-+ break;
-+ case HIR_MT751020:
-+ rate = 800000000 / 3;
-+ break;
-+ default:
-+ rate = 250000000;
-+ }
-+ en751221_try_register_clk(dev, EN751221_CLK_HPT, clk_data, "hpt",
-+ rate);
-+
+ /* GSW */
+ rate = FIELD_GET(EN751221_REG_SSR3_GSW_MASK,
+ readl(np_base + EN751221_REG_SSR3));
}
static int en7523_clk_probe(struct platform_device *pdev)
-@@ -799,9 +1014,20 @@ static const struct en_clk_soc_data en75
+@@ -799,9 +1001,20 @@ static const struct en_clk_soc_data en75
.hw_init = en7581_clk_hw_init,
};
+++ /dev/null
-Subject: [PATCH] PCI: Skip bridge window reads when window is not supported
-
-pci_read_bridge_io() and pci_read_bridge_mmio_pref() read bridge window
-registers unconditionally. If the registers are hardwired to zero
-(not implemented), both base and limit will be 0. Since (0 <= 0) is
-true, a bogus window [mem 0x00000000-0x000fffff] or [io 0x0000-0x0fff]
-gets created.
-
-pci_read_bridge_windows() already detects unsupported windows by
-testing register writability and sets io_window/pref_window flags
-accordingly. Check these flags at the start of pci_read_bridge_io()
-and pci_read_bridge_mmio_pref() to skip reading registers when the
-window is not supported.
-
-Suggested-by: Bjorn Helgaas <helgaas@kernel.org>
-Signed-off-by: Ahmed Naseef <naseefkm@gmail.com>
---- a/drivers/pci/probe.c
-+++ b/drivers/pci/probe.c
-@@ -396,6 +396,9 @@ static void pci_read_bridge_io(struct pc
- unsigned long io_mask, io_granularity, base, limit;
- struct pci_bus_region region;
-
-+ if (!dev->io_window)
-+ return;
-+
- io_mask = PCI_IO_RANGE_MASK;
- io_granularity = 0x1000;
- if (dev->io_window_1k) {
-@@ -466,6 +469,9 @@ static void pci_read_bridge_mmio_pref(st
- pci_bus_addr_t base, limit;
- struct pci_bus_region region;
-
-+ if (!dev->pref_window)
-+ return;
-+
- pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo);
- pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo);
- base64 = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16;
--- /dev/null
+From 92427ab4378faa168d6953d0f8574b8fc1edcc14 Mon Sep 17 00:00:00 2001
+From: Ahmed Naseef <naseefkm@gmail.com>
+Date: Thu, 12 Mar 2026 16:53:32 +0000
+Subject: [PATCH] PCI: Prevent assignment to unsupported bridge windows
+
+Previously, pci_read_bridge_io() and pci_read_bridge_mmio_pref()
+unconditionally set resource type flags (IORESOURCE_IO or IORESOURCE_MEM |
+IORESOURCE_PREFETCH) when reading bridge window registers. For windows that
+are not implemented in hardware, this may cause the allocator to assign
+space for a window that doesn't exist.
+
+For example, the EcoNET EN7528 SoC Root Port doesn't support the
+prefetchable window, but since a downstream device had a prefetchable BAR,
+the allocator mistakenly assigned a prefetchable window:
+
+ pci 0001:00:01.0: [14c3:0811] type 01 class 0x060400 PCIe Root Port
+ pci 0001:00:01.0: PCI bridge to [bus 01-ff]
+ pci 0001:00:01.0: bridge window [mem 0x28000000-0x280fffff]: assigned
+ pci 0001:00:01.0: bridge window [mem 0x28100000-0x282fffff pref]: assigned
+ pci 0001:01:00.0: BAR 0 [mem 0x28100000-0x281fffff 64bit pref]: assigned
+
+pci_read_bridge_windows() already detects unsupported windows by testing
+register writability and sets dev->io_window/pref_window accordingly.
+
+Check dev->io_window/pref_window so we don't set the resource flags for
+unsupported windows, which prevents the allocator from assigning space to
+them.
+
+After this commit, the prefetchable BAR is correctly allocated from the
+non-prefetchable window:
+
+ pci 0001:00:01.0: bridge window [mem 0x28000000-0x281fffff]: assigned
+ pci 0001:01:00.0: BAR 0 [mem 0x28000000-0x280fffff 64bit pref]: assigned
+
+Suggested-by: Bjorn Helgaas <helgaas@kernel.org>
+Link: https://lore.kernel.org/all/20260113210259.GA715789@bhelgaas/
+Signed-off-by: Ahmed Naseef <naseefkm@gmail.com>
+Signed-off-by: Caleb James DeLisle <cjd@cjdns.fr>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Link: https://patch.msgid.link/20260312165332.569772-4-cjd@cjdns.fr
+---
+ drivers/pci/probe.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -396,6 +396,9 @@ static void pci_read_bridge_io(struct pc
+ unsigned long io_mask, io_granularity, base, limit;
+ struct pci_bus_region region;
+
++ if (!dev->io_window)
++ return;
++
+ io_mask = PCI_IO_RANGE_MASK;
+ io_granularity = 0x1000;
+ if (dev->io_window_1k) {
+@@ -466,6 +469,9 @@ static void pci_read_bridge_mmio_pref(st
+ pci_bus_addr_t base, limit;
+ struct pci_bus_region region;
+
++ if (!dev->pref_window)
++ return;
++
+ pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo);
+ pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo);
+ base64 = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16;