[openwrt/openwrt] bmips: add linux v5.15 support

LEDE Commits lede-commits at lists.infradead.org
Fri May 20 04:17:21 PDT 2022


noltari pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/6a1e7c767f197b80385f4be9ac7a4b5af27cb4ec

commit 6a1e7c767f197b80385f4be9ac7a4b5af27cb4ec
Author: Álvaro Fernández Rojas <noltari at gmail.com>
AuthorDate: Wed May 18 22:52:06 2022 +0200

    bmips: add linux v5.15 support
    
    Build system: x86_64
    Build-tested: generic, nand
    Run-tested: generic/AR-5387un, nand/VR-3032u
    
    Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
---
 target/linux/bmips/Makefile                        |   1 +
 target/linux/bmips/config-5.15                     | 301 ++++++++++++++++
 .../bmips/files/arch/mips/bmips/ath9k-fixup.c      |   8 +-
 .../files/drivers/pci/controller/pci-bcm6348.c     |   9 +
 .../files/drivers/pci/controller/pcie-bcm6318.c    |  11 +-
 .../files/drivers/pci/controller/pcie-bcm6328.c    |  11 +-
 .../generic/base-files/etc/board.d/02_network      |   1 +
 .../bmips/nand/base-files/etc/board.d/02_network   |   1 +
 ...-support-for-bcm6345-style-external-inter.patch | 392 +++++++++++++++++++++
 ...mips-add-BCM63268-timer-clock-definitions.patch |  35 ++
 ...mips-add-BCM63268-timer-reset-definitions.patch |  26 ++
 ...bindings-clock-Add-BCM63268-timer-binding.patch |  59 ++++
 ...Add-BCM63268-timer-clock-and-reset-driver.patch | 281 +++++++++++++++
 ...-bmips-automatically-detect-CPU-frequency.patch | 238 +++++++++++++
 ...-mips-bmips-automatically-detect-RAM-size.patch | 196 +++++++++++
 ...ips-disable-ARCH_HAS_SYNC_DMA_FOR_CPU_ALL.patch |  80 +++++
 ...dcom-add-BCM6368-enetsw-controller-driver.patch |  46 +++
 .../501-net-dsa-b53-mmap-fix-enabled_ports.patch   |  11 +
 ...et-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch |  72 ++++
 .../600-mips-bmips-add-pci-support.patch           |  20 ++
 ...-pci-controllers-add-bcm6328-pcie-support.patch |  22 ++
 ...-pci-controllers-add-bcm6318-pcie-support.patch |  22 ++
 ...3-pci-controllers-add-bcm6348-pci-support.patch |  22 ++
 .../610-mips-bmips-add-pci-fixups.patch            |   6 +
 ...around-unaligned-accesses-failing-on-bcm6.patch |  26 ++
 target/linux/generic/config-5.15                   |   1 +
 26 files changed, 1894 insertions(+), 4 deletions(-)

diff --git a/target/linux/bmips/Makefile b/target/linux/bmips/Makefile
index 14eff38bb6..1fb89b11f3 100644
--- a/target/linux/bmips/Makefile
+++ b/target/linux/bmips/Makefile
@@ -10,6 +10,7 @@ SUBTARGETS:=generic nand
 FEATURES:=gpio source-only squashfs usb
 
 KERNEL_PATCHVER:=5.10
+KERNEL_TESTING_PATCHVER:=5.15
 
 define Target/Description
 	Build firmware images for BCM33xx cable modem chips,
diff --git a/target/linux/bmips/config-5.15 b/target/linux/bmips/config-5.15
new file mode 100644
index 0000000000..e8687cf5ab
--- /dev/null
+++ b/target/linux/bmips/config-5.15
@@ -0,0 +1,301 @@
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MMAP_RND_BITS_MAX=15
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_B53=y
+CONFIG_B53_MDIO_DRIVER=y
+CONFIG_B53_MMAP_DRIVER=y
+CONFIG_B53_SPI_DRIVER=y
+CONFIG_BCM6345_EXT_IRQ=y
+CONFIG_BCM6345_L1_IRQ=y
+CONFIG_BCM6368_ENETSW=y
+CONFIG_BCM63XX_POWER=y
+CONFIG_BCM7038_L1_IRQ=y
+CONFIG_BCM7038_WDT=y
+CONFIG_BCM7120_L2_IRQ=y
+CONFIG_BCMA=y
+CONFIG_BCMA_BLOCKIO=y
+# CONFIG_BCMA_DEBUG is not set
+# CONFIG_BCMA_DRIVER_GMAC_CMN is not set
+# CONFIG_BCMA_DRIVER_MIPS is not set
+CONFIG_BCMA_DRIVER_PCI=y
+# CONFIG_BCMA_DRIVER_PCI_HOSTMODE is not set
+CONFIG_BCMA_HOST_PCI=y
+CONFIG_BCMA_HOST_PCI_POSSIBLE=y
+# CONFIG_BCMA_HOST_SOC is not set
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_PM=y
+CONFIG_BMIPS_GENERIC=y
+CONFIG_BOARD_SCACHE=y
+CONFIG_BRCMSTB_L2_IRQ=y
+CONFIG_CEVT_R4K=y
+CONFIG_CLK_BCM63268_TIMER=y
+CONFIG_CLK_BCM_63XX_GATE=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CPU_BIG_ENDIAN=y
+CONFIG_CPU_BMIPS=y
+CONFIG_CPU_BMIPS32_3300=y
+CONFIG_CPU_BMIPS4350=y
+CONFIG_CPU_BMIPS4380=y
+CONFIG_CPU_BMIPS5000=y
+CONFIG_CPU_GENERIC_DUMP_TLB=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_RIXI=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
+CONFIG_CPU_NO_EFFICIENT_FFS=y
+CONFIG_CPU_R4K_CACHE_TLB=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_CPUFREQ=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_CRASH_DUMP=y
+CONFIG_CRC16=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_ZSTD=y
+CONFIG_CSRC_R4K=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DTC=y
+# CONFIG_DT_BCM93384WVG is not set
+# CONFIG_DT_BCM93384WVG_VIPER is not set
+# CONFIG_DT_BCM96368MVWG is not set
+# CONFIG_DT_BCM97125CBMB is not set
+# CONFIG_DT_BCM97346DBSMB is not set
+# CONFIG_DT_BCM97358SVMB is not set
+# CONFIG_DT_BCM97360SVMB is not set
+# CONFIG_DT_BCM97362SVMB is not set
+# CONFIG_DT_BCM97420C is not set
+# CONFIG_DT_BCM97425SVMB is not set
+# CONFIG_DT_BCM97435SVMB is not set
+# CONFIG_DT_BCM9EJTAGPRB is not set
+# CONFIG_DT_COMTREND_VR3032U is not set
+# CONFIG_DT_NETGEAR_CVG834G is not set
+CONFIG_DT_NONE=y
+# CONFIG_DT_SFR_NEUFBOX4_SERCOMM is not set
+# CONFIG_DT_SFR_NEUFBOX6_SERCOMM is not set
+CONFIG_FIXED_PHY=y
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_FIND_FIRST_BIT=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_LIB_ASHLDI3=y
+CONFIG_GENERIC_LIB_ASHRDI3=y
+CONFIG_GENERIC_LIB_CMPDI2=y
+CONFIG_GENERIC_LIB_LSHRDI3=y
+CONFIG_GENERIC_LIB_UCMPDI2=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_PINCTRL_GROUPS=y
+CONFIG_GENERIC_PINMUX_FUNCTIONS=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GPIOLIB=y
+# CONFIG_GPIO_BRCMSTB is not set
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_GPIO_REGMAP=y
+CONFIG_GRO_CELLS=y
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_BCM2835=y
+CONFIG_HZ_PERIODIC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_MIPS_CPU=y
+CONFIG_IRQ_WORK=y
+CONFIG_LEDS_BCM6328=y
+CONFIG_LEDS_BCM6358=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_BUS_MUX=y
+CONFIG_MDIO_BUS_MUX_BCM6368=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MEMFD_CREATE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MIGRATION=y
+CONFIG_MIPS=y
+CONFIG_MIPS_ASID_BITS=8
+CONFIG_MIPS_ASID_SHIFT=0
+CONFIG_MIPS_CLOCK_VSYSCALL=y
+# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
+CONFIG_MIPS_CMDLINE_FROM_DTB=y
+CONFIG_MIPS_CPU_SCACHE=y
+CONFIG_MIPS_EBPF_JIT=y
+CONFIG_MIPS_EXTERNAL_TIMER=y
+CONFIG_MIPS_L1_CACHE_SHIFT=7
+CONFIG_MIPS_L1_CACHE_SHIFT_6=y
+CONFIG_MIPS_L1_CACHE_SHIFT_7=y
+CONFIG_MIPS_LD_CAN_LINK_VDSO=y
+# CONFIG_MIPS_NO_APPENDED_DTB is not set
+CONFIG_MIPS_NR_CPU_NR_MAP=2
+CONFIG_MIPS_O32_FP64_SUPPORT=y
+CONFIG_MIPS_RAW_APPENDED_DTB=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MTD_BCM63XX_PARTS is not set
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_BE_BYTE_SWAP=y
+# CONFIG_MTD_CFI_GEOMETRY is not set
+# CONFIG_MTD_CFI_NOSWAP is not set
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_JEDECPROBE=y
+# CONFIG_MTD_PARSER_IMAGETAG is not set
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_TAG_BRCM=y
+CONFIG_NET_DSA_TAG_BRCM_COMMON=y
+CONFIG_NET_DSA_TAG_BRCM_LEGACY=y
+CONFIG_NET_DSA_TAG_BRCM_PREPEND=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_SWITCHDEV=y
+CONFIG_NO_EXCEPT_FILL=y
+CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
+CONFIG_NR_CPUS=2
+CONFIG_NVMEM=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_PADATA=y
+CONFIG_PCI=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIE_BCM6318=y
+CONFIG_PCIE_BCM6328=y
+CONFIG_PCIE_PME=y
+CONFIG_PCI_BCM6348=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DRIVERS_LEGACY=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYLINK=y
+CONFIG_PHYSICAL_START=0x80010000
+CONFIG_PHY_BCM63XX_USBH=y
+# CONFIG_PHY_BRCM_SATA is not set
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_BCM6318=y
+CONFIG_PINCTRL_BCM63268=y
+CONFIG_PINCTRL_BCM6328=y
+CONFIG_PINCTRL_BCM6358=y
+CONFIG_PINCTRL_BCM6362=y
+CONFIG_PINCTRL_BCM6368=y
+CONFIG_PINCTRL_BCM63XX=y
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+CONFIG_PM_GENERIC_DOMAINS=y
+CONFIG_PM_GENERIC_DOMAINS_OF=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_PROC_VMCORE=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_QUEUED_SPINLOCKS=y
+CONFIG_RATIONAL=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_RELAY=y
+CONFIG_RESET_BCM6345=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+# CONFIG_SERIAL_8250 is not set
+CONFIG_SERIAL_BCM63XX=y
+CONFIG_SERIAL_BCM63XX_CONSOLE=y
+CONFIG_SGL_ALLOC=y
+CONFIG_SMP=y
+CONFIG_SMP_UP=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SOC_BCM63XX=y
+CONFIG_SPI=y
+CONFIG_SPI_BCM63XX=y
+CONFIG_SPI_BCM63XX_HSSPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SRCU=y
+CONFIG_SSB=y
+CONFIG_SSB_B43_PCI_BRIDGE=y
+CONFIG_SSB_BLOCKIO=y
+# CONFIG_SSB_DRIVER_MIPS is not set
+CONFIG_SSB_DRIVER_PCICORE=y
+CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
+CONFIG_SSB_PCIHOST=y
+CONFIG_SSB_PCIHOST_POSSIBLE=y
+CONFIG_SSB_SPROM=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_SWPHY=y
+CONFIG_SYNC_R4K=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_SYS_HAS_CPU_BMIPS=y
+CONFIG_SYS_HAS_CPU_BMIPS32_3300=y
+CONFIG_SYS_HAS_CPU_BMIPS4350=y
+CONFIG_SYS_HAS_CPU_BMIPS4380=y
+CONFIG_SYS_HAS_CPU_BMIPS5000=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_HOTPLUG_CPU=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_SMP=y
+CONFIG_TARGET_ISA_REV=0
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_USB_EHCI_BIG_ENDIAN_DESC=y
+CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
+CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USE_OF=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_WEAK_ORDERING=y
+CONFIG_XPS=y
+CONFIG_XXHASH=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZSTD_COMPRESS=y
+CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/bmips/files/arch/mips/bmips/ath9k-fixup.c b/target/linux/bmips/files/arch/mips/bmips/ath9k-fixup.c
index fc03416507..03ebd20fa7 100644
--- a/target/linux/bmips/files/arch/mips/bmips/ath9k-fixup.c
+++ b/target/linux/bmips/files/arch/mips/bmips/ath9k-fixup.c
@@ -46,6 +46,7 @@ static void ath9k_pci_fixup(struct pci_dev *dev)
 	u32 bar0;
 	u32 val;
 	unsigned i;
+	int rc;
 
 	for (i = 0; i < ath9k_num_fixups; i++) {
 		if (ath9k_fixups[i]->pci_dev != PCI_SLOT(dev->devfn))
@@ -74,8 +75,11 @@ static void ath9k_pci_fixup(struct pci_dev *dev)
 		return;
 	}
 
-	if (bridge)
-		pci_enable_device(bridge);
+	if (bridge) {
+		rc = pci_enable_device(bridge);
+		if (rc < 0)
+			pr_err("pci %s: bridge enable error\n", pci_name(dev));
+	}
 
 	pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0);
 	pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0);
diff --git a/target/linux/bmips/files/drivers/pci/controller/pci-bcm6348.c b/target/linux/bmips/files/drivers/pci/controller/pci-bcm6348.c
index c1d3bde5df..085cc30eba 100644
--- a/target/linux/bmips/files/drivers/pci/controller/pci-bcm6348.c
+++ b/target/linux/bmips/files/drivers/pci/controller/pci-bcm6348.c
@@ -21,6 +21,7 @@
 #include <linux/pci.h>
 #include <linux/reset.h>
 #include <linux/types.h>
+#include <linux/version.h>
 #include <linux/vmalloc.h>
 
 #include "../pci.h"
@@ -346,7 +347,9 @@ static struct pci_controller bcm6348_pci_controller = {
 	.pci_ops = &bcm6348_pci_ops,
 	.io_resource = &bcm6348_pci_io_resource,
 	.mem_resource = &bcm6348_pci_mem_resource,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5,13,0)
 	.busn_resource = &bcm6348_pci_busn_resource,
+#endif
 };
 
 #ifdef CONFIG_CARDBUS
@@ -729,6 +732,9 @@ static int bcm6348_pci_probe(struct platform_device *pdev)
 	struct device_node *np = dev->of_node;
 	struct bcm6348_pci *priv = &bcm6348_pci;
 	struct resource *res;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,13,0)
+	LIST_HEAD(resources);
+#endif
 
 	of_pci_check_probe_only();
 
@@ -771,6 +777,9 @@ static int bcm6348_pci_probe(struct platform_device *pdev)
 		return -EINVAL;
 
 	of_pci_parse_bus_range(np, &bcm6348_pci_busn_resource);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,13,0)
+	pci_add_resource(&resources, &bcm6348_pci_busn_resource);
+#endif
 
 	/*
 	 * Configuration accesses are done through IO space, remap 4
diff --git a/target/linux/bmips/files/drivers/pci/controller/pcie-bcm6318.c b/target/linux/bmips/files/drivers/pci/controller/pcie-bcm6318.c
index 1df67b8389..21d8e50063 100644
--- a/target/linux/bmips/files/drivers/pci/controller/pcie-bcm6318.c
+++ b/target/linux/bmips/files/drivers/pci/controller/pcie-bcm6318.c
@@ -19,6 +19,7 @@
 #include <linux/pci.h>
 #include <linux/reset.h>
 #include <linux/types.h>
+#include <linux/version.h>
 #include <linux/vmalloc.h>
 
 #include "../pci.h"
@@ -168,7 +169,7 @@ static int bcm6318_pcie_can_access(struct pci_bus *bus, int devfn)
 		if (PCI_SLOT(devfn) == 0)
 			return __raw_readl(priv->base + PCIE_DLSTATUS_REG)
 					& DLSTATUS_PHYLINKUP;
-		/* else, fall through */
+		fallthrough;
 	default:
 		return false;
 	}
@@ -226,7 +227,9 @@ static struct pci_controller bcm6318_pcie_controller = {
 	.pci_ops = &bcm6318_pcie_ops,
 	.io_resource = &bcm6318_pcie_io_resource,
 	.mem_resource = &bcm6318_pcie_mem_resource,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5,13,0)
 	.busn_resource = &bcm6318_pcie_busn_resource,
+#endif
 };
 
 static void bcm6318_pcie_reset(struct bcm6318_pcie *priv)
@@ -305,6 +308,9 @@ static int bcm6318_pcie_probe(struct platform_device *pdev)
 	struct bcm6318_pcie *priv = &bcm6318_pcie;
 	struct resource *res;
 	int ret;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,13,0)
+	LIST_HEAD(resources);
+#endif
 
 	of_pci_check_probe_only();
 
@@ -370,6 +376,9 @@ static int bcm6318_pcie_probe(struct platform_device *pdev)
 		return -EINVAL;
 
 	of_pci_parse_bus_range(np, &bcm6318_pcie_busn_resource);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,13,0)
+	pci_add_resource(&resources, &bcm6318_pcie_busn_resource);
+#endif
 
 	bcm6318_pcie_reset(priv);
 	bcm6318_pcie_setup(priv);
diff --git a/target/linux/bmips/files/drivers/pci/controller/pcie-bcm6328.c b/target/linux/bmips/files/drivers/pci/controller/pcie-bcm6328.c
index 4c0d3723b8..4c032cf3d9 100644
--- a/target/linux/bmips/files/drivers/pci/controller/pcie-bcm6328.c
+++ b/target/linux/bmips/files/drivers/pci/controller/pcie-bcm6328.c
@@ -23,6 +23,7 @@
 #include <linux/reset.h>
 #include <linux/regmap.h>
 #include <linux/types.h>
+#include <linux/version.h>
 #include <linux/vmalloc.h>
 
 #include "../pci.h"
@@ -151,7 +152,7 @@ static int bcm6328_pcie_can_access(struct pci_bus *bus, int devfn)
 		if (PCI_SLOT(devfn) == 0)
 			return __raw_readl(priv->base + PCIE_DLSTATUS_REG)
 			       & DLSTATUS_PHYLINKUP;
-		/* else, fall through */
+		fallthrough;
 	default:
 		return false;
 	}
@@ -209,7 +210,9 @@ static struct pci_controller bcm6328_pcie_controller = {
 	.pci_ops = &bcm6328_pcie_ops,
 	.io_resource = &bcm6328_pcie_io_resource,
 	.mem_resource = &bcm6328_pcie_mem_resource,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5,13,0)
 	.busn_resource = &bcm6328_pcie_busn_resource,
+#endif
 };
 
 static void bcm6328_pcie_reset(struct bcm6328_pcie *priv)
@@ -294,6 +297,9 @@ static int bcm6328_pcie_probe(struct platform_device *pdev)
 	struct resource *res;
 	unsigned int i;
 	int ret;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,13,0)
+	LIST_HEAD(resources);
+#endif
 
 	pm_runtime_enable(dev);
 	pm_runtime_no_callbacks(dev);
@@ -380,6 +386,9 @@ static int bcm6328_pcie_probe(struct platform_device *pdev)
 		return -EINVAL;
 
 	of_pci_parse_bus_range(np, &bcm6328_pcie_busn_resource);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,13,0)
+	pci_add_resource(&resources, &bcm6328_pcie_busn_resource);
+#endif
 
 	bcm6328_pcie_reset(priv);
 	bcm6328_pcie_setup(priv);
diff --git a/target/linux/bmips/generic/base-files/etc/board.d/02_network b/target/linux/bmips/generic/base-files/etc/board.d/02_network
index 3e60660331..238dd27939 100644
--- a/target/linux/bmips/generic/base-files/etc/board.d/02_network
+++ b/target/linux/bmips/generic/base-files/etc/board.d/02_network
@@ -8,6 +8,7 @@ case "$(board_name)" in
 comtrend,ar-5315u |\
 comtrend,ar-5387un |\
 comtrend,vr-3025u)
+	ucidef_set_bridge_device switch
 	ucidef_set_interface_lan "lan1 lan2 lan3 lan4"
 	;;
 esac
diff --git a/target/linux/bmips/nand/base-files/etc/board.d/02_network b/target/linux/bmips/nand/base-files/etc/board.d/02_network
index b5ee52a682..e8862e8e60 100644
--- a/target/linux/bmips/nand/base-files/etc/board.d/02_network
+++ b/target/linux/bmips/nand/base-files/etc/board.d/02_network
@@ -6,6 +6,7 @@ board_config_update
 
 case "$(board_name)" in
 comtrend,vr-3032u)
+	ucidef_set_bridge_device switch
 	ucidef_set_interface_lan "lan1 lan2 lan3 lan4"
 	;;
 netgear,dgnd3700-v2)
diff --git a/target/linux/bmips/patches-5.15/100-irqchip-add-support-for-bcm6345-style-external-inter.patch b/target/linux/bmips/patches-5.15/100-irqchip-add-support-for-bcm6345-style-external-inter.patch
new file mode 100644
index 0000000000..ba55107bb1
--- /dev/null
+++ b/target/linux/bmips/patches-5.15/100-irqchip-add-support-for-bcm6345-style-external-inter.patch
@@ -0,0 +1,392 @@
+From cf908990d4a8ccdb73ee4484aa8cadad379ca314 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jogo at openwrt.org>
+Date: Sun, 30 Nov 2014 14:54:27 +0100
+Subject: [PATCH 2/5] irqchip: add support for bcm6345-style external
+ interrupt controller
+
+Signed-off-by: Jonas Gorski <jogo at openwrt.org>
+---
+ .../interrupt-controller/brcm,bcm6345-ext-intc.txt |   29 ++
+ drivers/irqchip/Kconfig                            |    4 +
+ drivers/irqchip/Makefile                           |    1 +
+ drivers/irqchip/irq-bcm6345-ext.c                  |  287 ++++++++++++++++++++
+ include/linux/irqchip/irq-bcm6345-ext.h            |   14 +
+ 5 files changed, 335 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-ext-intc.txt
+ create mode 100644 drivers/irqchip/irq-bcm6345-ext.c
+ create mode 100644 include/linux/irqchip/irq-bcm6345-ext.h
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-ext-intc.txt
+@@ -0,0 +1,29 @@
++Broadcom BCM6345-style external interrupt controller
++
++Required properties:
++
++- compatible: Should be "brcm,bcm6345-ext-intc" or "brcm,bcm6318-ext-intc".
++- reg: Specifies the base physical addresses and size of the registers.
++- interrupt-controller: identifies the node as an interrupt controller.
++- #interrupt-cells: Specifies the number of cells needed to encode an interrupt
++  source, Should be 2.
++- interrupt-parent: Specifies the phandle to the parent interrupt controller
++  this one is cascaded from.
++- interrupts: Specifies the interrupt line(s) in the interrupt-parent controller
++  node, valid values depend on the type of parent interrupt controller.
++
++Optional properties:
++
++- brcm,field-width: Size of each field (mask, clear, sense, ...) in bits in the
++  register. Defaults to 4.
++
++Example:
++
++ext_intc: interrupt-controller at 10000018 {
++	compatible = "brcm,bcm6345-ext-intc";
++	interrupt-parent = <&periph_intc>;
++	#interrupt-cells = <2>;
++	reg = <0x10000018 0x4>;
++	interrupt-controller;
++	interrupts = <24>, <25>, <26>, <27>;
++};
+--- a/drivers/irqchip/Kconfig
++++ b/drivers/irqchip/Kconfig
+@@ -108,6 +108,10 @@ config I8259
+ 	bool
+ 	select IRQ_DOMAIN
+ 
++config BCM6345_EXT_IRQ
++	bool "BCM6345 External IRQ Controller"
++	select IRQ_DOMAIN
++
+ config BCM6345_L1_IRQ
+ 	bool
+ 	select GENERIC_IRQ_CHIP
+--- a/drivers/irqchip/Makefile
++++ b/drivers/irqchip/Makefile
+@@ -62,6 +62,7 @@ obj-$(CONFIG_XTENSA_MX)			+= irq-xtensa-
+ obj-$(CONFIG_XILINX_INTC)		+= irq-xilinx-intc.o
+ obj-$(CONFIG_IRQ_CROSSBAR)		+= irq-crossbar.o
+ obj-$(CONFIG_SOC_VF610)			+= irq-vf610-mscm-ir.o
++obj-$(CONFIG_BCM6345_EXT_IRQ)		+= irq-bcm6345-ext.o
+ obj-$(CONFIG_BCM6345_L1_IRQ)		+= irq-bcm6345-l1.o
+ obj-$(CONFIG_BCM7038_L1_IRQ)		+= irq-bcm7038-l1.o
+ obj-$(CONFIG_BCM7120_L2_IRQ)		+= irq-bcm7120-l2.o
+--- /dev/null
++++ b/drivers/irqchip/irq-bcm6345-ext.c
+@@ -0,0 +1,299 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2014 Jonas Gorski <jogo at openwrt.org>
++ */
++
++#include <linux/ioport.h>
++#include <linux/irq.h>
++#include <linux/irqchip.h>
++#include <linux/irqchip/chained_irq.h>
++#include <linux/irqchip/irq-bcm6345-ext.h>
++#include <linux/kernel.h>
++#include <linux/of.h>
++#include <linux/of_irq.h>
++#include <linux/of_address.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++
++#ifdef CONFIG_BCM63XX
++#include <asm/mach-bcm63xx/bcm63xx_irq.h>
++
++#define VIRQ_BASE		IRQ_EXTERNAL_BASE
++#else
++#define VIRQ_BASE		0
++#endif
++
++#define MAX_IRQS		4
++
++#define EXTIRQ_CFG_SENSE	0
++#define EXTIRQ_CFG_STAT		1
++#define EXTIRQ_CFG_CLEAR	2
++#define EXTIRQ_CFG_MASK		3
++#define EXTIRQ_CFG_BOTHEDGE	4
++#define EXTIRQ_CFG_LEVELSENSE	5
++
++struct intc_data {
++	struct irq_chip chip;
++	struct irq_domain *domain;
++	raw_spinlock_t lock;
++
++	int parent_irq[MAX_IRQS];
++	void __iomem *reg;
++	int shift;
++	unsigned int toggle_clear_on_ack:1;
++};
++
++static void bcm6345_ext_intc_irq_handle(struct irq_desc *desc)
++{
++	struct intc_data *data = irq_desc_get_handler_data(desc);
++	struct irq_chip *chip = irq_desc_get_chip(desc);
++	unsigned int irq = irq_desc_get_irq(desc);
++	unsigned int idx;
++
++	chained_irq_enter(chip, desc);
++
++	for (idx = 0; idx < MAX_IRQS; idx++) {
++		if (data->parent_irq[idx] != irq)
++			continue;
++
++		generic_handle_irq(irq_find_mapping(data->domain, idx));
++	}
++
++	chained_irq_exit(chip, desc);
++}
++
++static void bcm6345_ext_intc_irq_ack(struct irq_data *data)
++{
++	struct intc_data *priv = data->domain->host_data;
++	irq_hw_number_t hwirq = irqd_to_hwirq(data);
++	u32 reg;
++
++	raw_spin_lock(&priv->lock);
++	reg = __raw_readl(priv->reg);
++	__raw_writel(reg | (1 << (hwirq + EXTIRQ_CFG_CLEAR * priv->shift)),
++		     priv->reg);
++	if (priv->toggle_clear_on_ack)
++		__raw_writel(reg, priv->reg);
++	raw_spin_unlock(&priv->lock);
++}
++
++static void bcm6345_ext_intc_irq_mask(struct irq_data *data)
++{
++	struct intc_data *priv = data->domain->host_data;
++	irq_hw_number_t hwirq = irqd_to_hwirq(data);
++	u32 reg;
++
++	raw_spin_lock(&priv->lock);
++	reg = __raw_readl(priv->reg);
++	reg &= ~(1 << (hwirq + EXTIRQ_CFG_MASK * priv->shift));
++	__raw_writel(reg, priv->reg);
++	raw_spin_unlock(&priv->lock);
++}
++
++static void bcm6345_ext_intc_irq_unmask(struct irq_data *data)
++{
++	struct intc_data *priv = data->domain->host_data;
++	irq_hw_number_t hwirq = irqd_to_hwirq(data);
++	u32 reg;
++
++	raw_spin_lock(&priv->lock);
++	reg = __raw_readl(priv->reg);
++	reg |= 1 << (hwirq + EXTIRQ_CFG_MASK * priv->shift);
++	__raw_writel(reg, priv->reg);
++	raw_spin_unlock(&priv->lock);
++}
++
++static int bcm6345_ext_intc_set_type(struct irq_data *data,
++				     unsigned int flow_type)
++{
++	struct intc_data *priv = data->domain->host_data;
++	irq_hw_number_t hwirq = irqd_to_hwirq(data);
++	bool levelsense = 0, sense = 0, bothedge = 0;
++	u32 reg;
++
++	flow_type &= IRQ_TYPE_SENSE_MASK;
++
++	if (flow_type == IRQ_TYPE_NONE)
++		flow_type = IRQ_TYPE_LEVEL_LOW;
++
++	switch (flow_type) {
++	case IRQ_TYPE_EDGE_BOTH:
++		bothedge = 1;
++		break;
++
++	case IRQ_TYPE_EDGE_RISING:
++		sense = 1;
++		break;
++
++	case IRQ_TYPE_EDGE_FALLING:
++		break;
++
++	case IRQ_TYPE_LEVEL_HIGH:
++		levelsense = 1;
++		sense = 1;
++		break;
++
++	case IRQ_TYPE_LEVEL_LOW:
++		levelsense = 1;
++		break;
++
++	default:
++		pr_err("bogus flow type combination given!\n");
++		return -EINVAL;
++	}
++
++	raw_spin_lock(&priv->lock);
++	reg = __raw_readl(priv->reg);
++
++	if (levelsense)
++		reg |= 1 << (hwirq + EXTIRQ_CFG_LEVELSENSE * priv->shift);
++	else
++		reg &= ~(1 << (hwirq + EXTIRQ_CFG_LEVELSENSE * priv->shift));
++	if (sense)
++		reg |= 1 << (hwirq + EXTIRQ_CFG_SENSE * priv->shift);
++	else
++		reg &= ~(1 << (hwirq + EXTIRQ_CFG_SENSE * priv->shift));
++	if (bothedge)
++		reg |= 1 << (hwirq + EXTIRQ_CFG_BOTHEDGE * priv->shift);
++	else
++		reg &= ~(1 << (hwirq + EXTIRQ_CFG_BOTHEDGE * priv->shift));
++
++	__raw_writel(reg, priv->reg);
++	raw_spin_unlock(&priv->lock);
++
++	irqd_set_trigger_type(data, flow_type);
++	if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
++		irq_set_handler_locked(data, handle_level_irq);
++	else
++		irq_set_handler_locked(data, handle_edge_irq);
++
++	return 0;
++}
++
++static int bcm6345_ext_intc_map(struct irq_domain *d, unsigned int irq,
++				irq_hw_number_t hw)
++{
++	struct intc_data *priv = d->host_data;
++
++	irq_set_chip_and_handler(irq, &priv->chip, handle_level_irq);
++
++	return 0;
++}
++
++static const struct irq_domain_ops bcm6345_ext_domain_ops = {
++	.xlate = irq_domain_xlate_twocell,
++	.map = bcm6345_ext_intc_map,
++};
++
++static int __init __bcm6345_ext_intc_init(struct device_node *node,
++					  int num_irqs, int *irqs,
++					  void __iomem *reg, int shift,
++					  bool toggle_clear_on_ack)
++{
++	struct intc_data *data;
++	unsigned int i;
++	int start = VIRQ_BASE;
++
++	data = kzalloc(sizeof(*data), GFP_KERNEL);
++	if (!data)
++		return -ENOMEM;
++
++	raw_spin_lock_init(&data->lock);
++
++	for (i = 0; i < num_irqs; i++) {
++		data->parent_irq[i] = irqs[i];
++
++		irq_set_handler_data(irqs[i], data);
++		irq_set_chained_handler(irqs[i], bcm6345_ext_intc_irq_handle);
++	}
++
++	data->reg = reg;
++	data->shift = shift;
++	data->toggle_clear_on_ack = toggle_clear_on_ack;
++
++	data->chip.name = "bcm6345-ext-intc";
++	data->chip.irq_ack = bcm6345_ext_intc_irq_ack;
++	data->chip.irq_mask = bcm6345_ext_intc_irq_mask;
++	data->chip.irq_unmask = bcm6345_ext_intc_irq_unmask;
++	data->chip.irq_set_type = bcm6345_ext_intc_set_type;
++
++	/*
++	 * If we have less than 4 irqs, this is the second controller on
++	 * bcm63xx. So increase the VIRQ start to not overlap with the first
++	 * one, but only do so if we actually use a non-zero start.
++	 *
++	 * This can be removed when bcm63xx has no legacy users anymore.
++	 */
++	if (start && num_irqs < 4)
++		start += 4;
++
++	data->domain = irq_domain_add_simple(node, num_irqs, start,
++					     &bcm6345_ext_domain_ops, data);
++	if (!data->domain) {
++		kfree(data);
++		return -ENOMEM;
++	}
++
++	return 0;
++}
++
++void __init bcm6345_ext_intc_init(int num_irqs, int *irqs, void __iomem *reg,
++				  int shift)
++{
++	__bcm6345_ext_intc_init(NULL, num_irqs, irqs, reg, shift, false);
++}
++
++#ifdef CONFIG_OF
++static int __init bcm6345_ext_intc_of_init(struct device_node *node,
++					   struct device_node *parent)
++{
++	int num_irqs, ret = -EINVAL;
++	unsigned i;
++	void __iomem *base;
++	int irqs[MAX_IRQS] = { 0 };
++	u32 shift;
++	bool toggle_clear_on_ack = false;
++
++	num_irqs = of_irq_count(node);
++
++	if (!num_irqs || num_irqs > MAX_IRQS)
++		return -EINVAL;
++
++	if (of_property_read_u32(node, "brcm,field-width", &shift))
++		shift = 4;
++
++	/* on BCM6318 setting CLEAR seems to continuously mask interrupts */
++	if (of_device_is_compatible(node, "brcm,bcm6318-ext-intc"))
++		toggle_clear_on_ack = true;
++
++	for (i = 0; i < num_irqs; i++) {
++		irqs[i] = irq_of_parse_and_map(node, i);
++		if (!irqs[i])
++			return -ENOMEM;
++	}
++
++	base = of_iomap(node, 0);
++	if (!base)
++		return -ENXIO;
++
++	ret = __bcm6345_ext_intc_init(node, num_irqs, irqs, base, shift,
++				      toggle_clear_on_ack);
++	if (!ret)
++		return 0;
++
++	iounmap(base);
++
++	for (i = 0; i < num_irqs; i++)
++		irq_dispose_mapping(irqs[i]);
++
++	return ret;
++}
++
++IRQCHIP_DECLARE(bcm6318_ext_intc, "brcm,bcm6318-ext-intc",
++		bcm6345_ext_intc_of_init);
++IRQCHIP_DECLARE(bcm6345_ext_intc, "brcm,bcm6345-ext-intc",
++		bcm6345_ext_intc_of_init);
++#endif
+--- /dev/null
++++ b/include/linux/irqchip/irq-bcm6345-ext.h
+@@ -0,0 +1,14 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2014 Jonas Gorski <jogo at openwrt.org>
++ */
++
++#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_H
++#define __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_H
++
++void bcm6345_ext_intc_init(int n_irqs, int *irqs, void __iomem *reg, int shift);
++
++#endif /* __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_H */
diff --git a/target/linux/bmips/patches-5.15/110-mips-bmips-add-BCM63268-timer-clock-definitions.patch b/target/linux/bmips/patches-5.15/110-mips-bmips-add-BCM63268-timer-clock-definitions.patch
new file mode 100644
index 0000000000..0df7db9717
--- /dev/null
+++ b/target/linux/bmips/patches-5.15/110-mips-bmips-add-BCM63268-timer-clock-definitions.patch
@@ -0,0 +1,35 @@
+From 5a079515cb3066aeb658634301a98871b47c2af4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Thu, 25 Feb 2021 19:44:22 +0100
+Subject: [PATCH 1/4] mips: bmips: add BCM63268 timer clock definitions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add missing timer clock definitions for BCM63268.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ include/dt-bindings/clock/bcm63268-clock.h | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/include/dt-bindings/clock/bcm63268-clock.h
++++ b/include/dt-bindings/clock/bcm63268-clock.h
+@@ -27,4 +27,17 @@
+ #define BCM63268_CLK_TBUS	27
+ #define BCM63268_CLK_ROBOSW250	31
+ 
++#define BCM63268_TCLK_EPHY1		0
++#define BCM63268_TCLK_EPHY2		1
++#define BCM63268_TCLK_EPHY3		2
++#define BCM63268_TCLK_GPHY1		3
++#define BCM63268_TCLK_DSL		4
++#define BCM63268_TCLK_WAKEON_EPHY	6
++#define BCM63268_TCLK_WAKEON_DSL	7
++#define BCM63268_TCLK_FAP1		11
++#define BCM63268_TCLK_FAP2		15
++#define BCM63268_TCLK_UTO_50		16
++#define BCM63268_TCLK_UTO_EXTIN		17
++#define BCM63268_TCLK_USB_REF		18
++
+ #endif /* __DT_BINDINGS_CLOCK_BCM63268_H */
diff --git a/target/linux/bmips/patches-5.15/111-mips-bmips-add-BCM63268-timer-reset-definitions.patch b/target/linux/bmips/patches-5.15/111-mips-bmips-add-BCM63268-timer-reset-definitions.patch
new file mode 100644
index 0000000000..7b694d3289
--- /dev/null
+++ b/target/linux/bmips/patches-5.15/111-mips-bmips-add-BCM63268-timer-reset-definitions.patch
@@ -0,0 +1,26 @@
+From 3327df17635dd9d24a855ac6b7247fac381514cf Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Thu, 25 Feb 2021 19:45:04 +0100
+Subject: [PATCH 2/4] mips: bmips: add BCM63268 timer reset definitions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add missing timer reset definitions for BCM63268.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ include/dt-bindings/reset/bcm63268-reset.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/include/dt-bindings/reset/bcm63268-reset.h
++++ b/include/dt-bindings/reset/bcm63268-reset.h
+@@ -23,4 +23,8 @@
+ #define BCM63268_RST_PCIE_HARD	17
+ #define BCM63268_RST_GPHY	18
+ 
++#define BCM63268_TRST_SW	29
++#define BCM63268_TRST_HW	30
++#define BCM63268_TRST_POR	31
++
+ #endif /* __DT_BINDINGS_RESET_BCM63268_H */
diff --git a/target/linux/bmips/patches-5.15/112-dt-bindings-clock-Add-BCM63268-timer-binding.patch b/target/linux/bmips/patches-5.15/112-dt-bindings-clock-Add-BCM63268-timer-binding.patch
new file mode 100644
index 0000000000..945bdfc3d0
--- /dev/null
+++ b/target/linux/bmips/patches-5.15/112-dt-bindings-clock-Add-BCM63268-timer-binding.patch
@@ -0,0 +1,59 @@
+From c17702bad18a085ae913752b45bcc20c2cea879e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Thu, 25 Feb 2021 19:53:08 +0100
+Subject: [PATCH 3/4] dt-bindings: clock: Add BCM63268 timer binding
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Document the Broadcom BCM63268 Clock and Reset controller.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ .../clock/brcm,bcm63268-timer-clocks.yaml     | 40 +++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/clock/brcm,bcm63268-timer-clocks.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/clock/brcm,bcm63268-timer-clocks.yaml
+@@ -0,0 +1,40 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/clock/brcm,bcm63268-timer-clocks.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Broadcom BCM63268 Timer Clock and Reset Device Tree Bindings
++
++maintainers:
++  - Álvaro Fernández Rojas <noltari at gmail.com>
++
++properties:
++  compatible:
++    const: brcm,bcm63268-timer-clocks
++
++  reg:
++    maxItems: 1
++
++  "#clock-cells":
++    const: 1
++
++  "#reset-cells":
++    const: 1
++
++required:
++  - compatible
++  - reg
++  - "#clock-cells"
++  - "#reset-cells"
++
++additionalProperties: false
++
++examples:
++  - |
++    timer_clk: clock-controller at 100000ac {
++      compatible = "brcm,bcm63268-timer-clocks";
++      reg = <0x100000ac 0x4>;
++      #clock-cells = <1>;
++      #reset-cells = <1>;
++    };
diff --git a/target/linux/bmips/patches-5.15/113-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch b/target/linux/bmips/patches-5.15/113-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch
new file mode 100644
index 0000000000..484647a6e1
--- /dev/null
+++ b/target/linux/bmips/patches-5.15/113-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch
@@ -0,0 +1,281 @@
+From 3c8dd9d0937a19f3f20f28ba0b0b64f448d50dd4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Thu, 25 Feb 2021 19:54:04 +0100
+Subject: [PATCH 4/4] clk: bcm: Add BCM63268 timer clock and reset driver
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add driver for BCM63268 timer clock and reset controller.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ drivers/clk/bcm/Kconfig              |   9 ++
+ drivers/clk/bcm/Makefile             |   1 +
+ drivers/clk/bcm/clk-bcm63268-timer.c | 232 +++++++++++++++++++++++++++
+ 3 files changed, 242 insertions(+)
+ create mode 100644 drivers/clk/bcm/clk-bcm63268-timer.c
+
+--- a/drivers/clk/bcm/Kconfig
++++ b/drivers/clk/bcm/Kconfig
+@@ -37,6 +37,15 @@ config CLK_BCM_63XX_GATE
+ 	  Enable common clock framework support for Broadcom BCM63xx DSL SoCs
+ 	  based on the MIPS architecture
+ 
++config CLK_BCM63268_TIMER
++	bool "Broadcom BCM63268 timer clock and reset support"
++	depends on BMIPS_GENERIC || COMPILE_TEST
++	default BMIPS_GENERIC
++	select RESET_CONTROLLER
++	help
++	  Enable timer clock and reset support for Broadcom BCM63268 DSL SoCs
++	  based on the MIPS architecture.
++
+ config CLK_BCM_KONA
+ 	bool "Broadcom Kona CCU clock support"
+ 	depends on ARCH_BCM_MOBILE || COMPILE_TEST
+--- a/drivers/clk/bcm/Makefile
++++ b/drivers/clk/bcm/Makefile
+@@ -1,6 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ obj-$(CONFIG_CLK_BCM_63XX)	+= clk-bcm63xx.o
+ obj-$(CONFIG_CLK_BCM_63XX_GATE)	+= clk-bcm63xx-gate.o
++obj-$(CONFIG_CLK_BCM63268_TIMER) += clk-bcm63268-timer.o
+ obj-$(CONFIG_CLK_BCM_KONA)	+= clk-kona.o
+ obj-$(CONFIG_CLK_BCM_KONA)	+= clk-kona-setup.o
+ obj-$(CONFIG_CLK_BCM_KONA)	+= clk-bcm281xx.o
+--- /dev/null
++++ b/drivers/clk/bcm/clk-bcm63268-timer.c
+@@ -0,0 +1,232 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * BCM63268 Timer Clock and Reset Controller Driver
++ *
++ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari at gmail.com>
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/reset-controller.h>
++
++#include <dt-bindings/clock/bcm63268-clock.h>
++
++#define BCM63268_TIMER_RESET_SLEEP_MIN_US	10000
++#define BCM63268_TIMER_RESET_SLEEP_MAX_US	20000
++
++struct bcm63268_tclkrst_hw {
++	void __iomem *regs;
++	spinlock_t lock;
++
++	struct reset_controller_dev rcdev;
++	struct clk_hw_onecell_data data;
++};
++
++struct bcm63268_tclk_table_entry {
++	const char * const name;
++	u8 bit;
++	unsigned long flags;
++};
++
++static const struct bcm63268_tclk_table_entry bcm63268_timer_clocks[] = {
++	{
++		.name = "ephy1",
++		.bit = BCM63268_TCLK_EPHY1,
++	}, {
++		.name = "ephy2",
++		.bit = BCM63268_TCLK_EPHY2,
++	}, {
++		.name = "ephy3",
++		.bit = BCM63268_TCLK_EPHY3,
++	}, {
++		.name = "gphy1",
++		.bit = BCM63268_TCLK_GPHY1,
++	}, {
++		.name = "dsl",
++		.bit = BCM63268_TCLK_DSL,
++	}, {
++		.name = "wakeon_ephy",
++		.bit = BCM63268_TCLK_WAKEON_EPHY,
++	}, {
++		.name = "wakeon_dsl",
++		.bit = BCM63268_TCLK_WAKEON_DSL,
++	}, {
++		.name = "fap1_pll",
++		.bit = BCM63268_TCLK_FAP1,
++	}, {
++		.name = "fap2_pll",
++		.bit = BCM63268_TCLK_FAP2,
++	}, {
++		.name = "uto_50",
++		.bit = BCM63268_TCLK_UTO_50,
++	}, {
++		.name = "uto_extin",
++		.bit = BCM63268_TCLK_UTO_EXTIN,
++	}, {
++		.name = "usb_ref",
++		.bit = BCM63268_TCLK_USB_REF,
++	}, {
++		/* sentinel */
++	}
++};
++
++static inline struct bcm63268_tclkrst_hw *
++to_bcm63268_timer_reset(struct reset_controller_dev *rcdev)
++{
++	return container_of(rcdev, struct bcm63268_tclkrst_hw, rcdev);
++}
++
++static int bcm63268_timer_reset_update(struct reset_controller_dev *rcdev,
++				unsigned long id, bool assert)
++{
++	struct bcm63268_tclkrst_hw *reset = to_bcm63268_timer_reset(rcdev);
++	unsigned long flags;
++	uint32_t val;
++
++	spin_lock_irqsave(&reset->lock, flags);
++	val = __raw_readl(reset->regs);
++	if (assert)
++		val &= ~BIT(id);
++	else
++		val |= BIT(id);
++	__raw_writel(val, reset->regs);
++	spin_unlock_irqrestore(&reset->lock, flags);
++
++	return 0;
++}
++
++static int bcm63268_timer_reset_assert(struct reset_controller_dev *rcdev,
++				unsigned long id)
++{
++	return bcm63268_timer_reset_update(rcdev, id, true);
++}
++
++static int bcm63268_timer_reset_deassert(struct reset_controller_dev *rcdev,
++				  unsigned long id)
++{
++	return bcm63268_timer_reset_update(rcdev, id, false);
++}
++
++static int bcm63268_timer_reset_reset(struct reset_controller_dev *rcdev,
++			       unsigned long id)
++{
++	bcm63268_timer_reset_update(rcdev, id, true);
++	usleep_range(BCM63268_TIMER_RESET_SLEEP_MIN_US,
++		     BCM63268_TIMER_RESET_SLEEP_MAX_US);
++
++	bcm63268_timer_reset_update(rcdev, id, false);
++	/*
++	 * Ensure component is taken out reset state by sleeping also after
++	 * deasserting the reset. Otherwise, the component may not be ready
++	 * for operation.
++	 */
++	usleep_range(BCM63268_TIMER_RESET_SLEEP_MIN_US,
++		     BCM63268_TIMER_RESET_SLEEP_MAX_US);
++
++	return 0;
++}
++
++static int bcm63268_timer_reset_status(struct reset_controller_dev *rcdev,
++				unsigned long id)
++{
++	struct bcm63268_tclkrst_hw *reset = to_bcm63268_timer_reset(rcdev);
++
++	return !(__raw_readl(reset->regs) & BIT(id));
++}
++
++static struct reset_control_ops bcm63268_timer_reset_ops = {
++	.assert = bcm63268_timer_reset_assert,
++	.deassert = bcm63268_timer_reset_deassert,
++	.reset = bcm63268_timer_reset_reset,
++	.status = bcm63268_timer_reset_status,
++};
++
++static int bcm63268_tclk_probe(struct platform_device *pdev)
++{
++	struct device *dev = &pdev->dev;
++	const struct bcm63268_tclk_table_entry *entry, *table;
++	struct bcm63268_tclkrst_hw *hw;
++	u8 maxbit = 0;
++	int i, ret;
++
++	table = of_device_get_match_data(dev);
++	if (!table)
++		return -EINVAL;
++
++	for (entry = table; entry->name; entry++)
++		maxbit = max_t(u8, maxbit, entry->bit);
++	maxbit++;
++
++	hw = devm_kzalloc(&pdev->dev, struct_size(hw, data.hws, maxbit),
++			  GFP_KERNEL);
++	if (!hw)
++		return -ENOMEM;
++
++	platform_set_drvdata(pdev, hw);
++
++	spin_lock_init(&hw->lock);
++
++	hw->data.num = maxbit;
++	for (i = 0; i < maxbit; i++)
++		hw->data.hws[i] = ERR_PTR(-ENODEV);
++
++	hw->regs = devm_platform_ioremap_resource(pdev, 0);
++	if (IS_ERR(hw->regs))
++		return PTR_ERR(hw->regs);
++
++	for (entry = table; entry->name; entry++) {
++		struct clk_hw *clk;
++
++		clk = clk_hw_register_gate(dev, entry->name, NULL,
++					   entry->flags, hw->regs, entry->bit,
++					   CLK_GATE_BIG_ENDIAN, &hw->lock);
++		if (IS_ERR(clk)) {
++			ret = PTR_ERR(clk);
++			goto out_err;
++		}
++
++		hw->data.hws[entry->bit] = clk;
++	}
++
++	ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
++				     &hw->data);
++	if (!ret)
++		return 0;
++
++	hw->rcdev.of_node = dev->of_node;
++	hw->rcdev.ops = &bcm63268_timer_reset_ops;
++
++	ret = devm_reset_controller_register(dev, &hw->rcdev);
++	if (ret)
++		dev_err(dev, "Failed to register reset controller\n");
++
++out_err:
++	for (i = 0; i < hw->data.num; i++) {
++		if (!IS_ERR(hw->data.hws[i]))
++			clk_hw_unregister_gate(hw->data.hws[i]);
++	}
++
++	return ret;
++}
++
++static const struct of_device_id bcm63268_tclk_dt_ids[] = {
++	{
++		.compatible = "brcm,bcm63268-timer-clocks",
++		.data = &bcm63268_timer_clocks,
++	}, {
++		/* sentinel */
++	}
++};
++
++static struct platform_driver bcm63268_tclk = {
++	.probe = bcm63268_tclk_probe,
++	.driver = {
++		.name = "bcm63268-timer-clock",
++		.of_match_table = bcm63268_tclk_dt_ids,
++	},
++};
++builtin_platform_driver(bcm63268_tclk);
diff --git a/target/linux/bmips/patches-5.15/200-mips-bmips-automatically-detect-CPU-frequency.patch b/target/linux/bmips/patches-5.15/200-mips-bmips-automatically-detect-CPU-frequency.patch
new file mode 100644
index 0000000000..40c977baf8
--- /dev/null
+++ b/target/linux/bmips/patches-5.15/200-mips-bmips-automatically-detect-CPU-frequency.patch
@@ -0,0 +1,238 @@
+From 0377ad93031d3e51c2afe44231241185f684b6af Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Fri, 5 Mar 2021 15:14:32 +0100
+Subject: [PATCH 1/2] mips: bmips: automatically detect CPU frequency
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Some BCM63xx SoCs support multiple CPU frequencies depending on HW config.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ arch/mips/bmips/setup.c | 198 ++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 191 insertions(+), 7 deletions(-)
+
+--- a/arch/mips/bmips/setup.c
++++ b/arch/mips/bmips/setup.c
+@@ -31,11 +31,51 @@
+ 
+ #define RELO_NORMAL_VEC		BIT(18)
+ 
++#define REG_BCM6318_SOB		((void __iomem *)CKSEG1ADDR(0x10000900))
++#define BCM6318_FREQ_SHIFT	23
++#define BCM6318_FREQ_MASK	(0x3 << BCM6318_FREQ_SHIFT)
++
+ #define REG_BCM6328_OTP		((void __iomem *)CKSEG1ADDR(0x1000062c))
+ #define BCM6328_TP1_DISABLED	BIT(9)
++#define REG_BCM6328_MISC_SB	((void __iomem *)CKSEG1ADDR(0x10001a40))
++#define BCM6328_FCVO_SHIFT	7
++#define BCM6328_FCVO_MASK	(0x1f << BCM6328_FCVO_SHIFT)
++
++#define REG_BCM6358_DDR_PLLC	((void __iomem *)0xfffe12b8)
++#define BCM6358_PLLC_M1_SHIFT	0
++#define BCM6358_PLLC_M1_MASK	(0xff << BCM6358_PLLC_M1_SHIFT)
++#define BCM6358_PLLC_N1_SHIFT	23
++#define BCM6358_PLLC_N1_MASK	(0x3f << BCM6358_PLLC_N1_SHIFT)
++#define BCM6358_PLLC_N2_SHIFT	29
++#define BCM6358_PLLC_N2_MASK	(0x7 << BCM6358_PLLC_N2_SHIFT)
++
++#define REG_BCM6362_MISC_SB	((void __iomem *)CKSEG1ADDR(0x10001814))
++#define BCM6362_FCVO_SHIFT	1
++#define BCM6362_FCVO_MASK	(0x1f << BCM6362_FCVO_SHIFT)
++
++#define REG_BCM6368_DDR_PLLC	((void __iomem *)CKSEG1ADDR(0x100012a0))
++#define BCM6368_PLLC_P1_SHIFT	0
++#define BCM6368_PLLC_P1_MASK	(0xf << BCM6368_PLLC_P1_SHIFT)
++#define BCM6368_PLLC_P2_SHIFT	4
++#define BCM6368_PLLC_P2_MASK	(0xf << BCM6368_PLLC_P2_SHIFT)
++#define BCM6368_PLLC_NDIV_SHIFT	16
++#define BCM6368_PLLC_NDIV_MASK	(0x1ff << BCM6368_PLLC_NDIV_SHIFT)
++#define REG_BCM6368_DDR_PLLD	((void __iomem *)CKSEG1ADDR(0x100012a4))
++#define BCM6368_PLLD_MDIV_SHIFT	0
++#define BCM6368_PLLD_MDIV_MASK	(0xff << BCM6368_PLLD_MDIV_SHIFT)
++
++#define REG_BCM63268_MISC_SB	((void __iomem *)CKSEG1ADDR(0x10001814))
++#define BCM63268_FCVO_SHIFT	21
++#define BCM63268_FCVO_MASK	(0xf << BCM63268_FCVO_SHIFT)
++
+ 
+ static const unsigned long kbase = VMLINUX_LOAD_ADDRESS & 0xfff00000;
+ 
++struct bmips_cpufreq {
++	const char		*compatible;
++	u32			(*cpu_freq)(void);
++};
++
+ struct bmips_quirk {
+ 	const char		*compatible;
+ 	void			(*quirk_fn)(void);
+@@ -134,17 +174,161 @@ const char *get_system_type(void)
+ 	return "Generic BMIPS kernel";
+ }
+ 
++static u32 bcm6318_cpufreq(void)
++{
++	u32 val = __raw_readl(REG_BCM6318_SOB);
++
++	switch ((val & BCM6318_FREQ_MASK) >> BCM6318_FREQ_SHIFT) {
++	case 0:
++		return 166000000;
++	case 2:
++		return 250000000;
++	case 3:
++		return 333000000;
++	case 1:
++		return 400000000;
++	default:
++		return 0;
++	}
++}
++
++static u32 bcm6328_cpufreq(void)
++{
++	u32 val = __raw_readl(REG_BCM6328_MISC_SB);
++
++	switch ((val & BCM6328_FCVO_MASK) >> BCM6328_FCVO_SHIFT) {
++	case 0x12:
++	case 0x14:
++	case 0x19:
++		return 160000000;
++	case 0x1c:
++		return 192000000;
++	case 0x13:
++	case 0x15:
++		return 200000000;
++	case 0x1a:
++		return 384000000;
++	case 0x16:
++		return 400000000;
++	default:
++		return 320000000;
++	}
++}
++
++static u32 bcm6358_cpufreq(void)
++{
++	u32 val, n1, n2, m1;
++
++	val = __raw_readl(REG_BCM6358_DDR_PLLC);
++	n1 = (val & BCM6358_PLLC_N1_MASK) >> BCM6358_PLLC_N1_SHIFT;
++	n2 = (val & BCM6358_PLLC_N2_MASK) >> BCM6358_PLLC_N2_SHIFT;
++	m1 = (val & BCM6358_PLLC_M1_MASK) >> BCM6358_PLLC_M1_SHIFT;
++
++	return (16 * 1000000 * n1 * n2) / m1;
++}
++
++static u32 bcm6362_cpufreq(void)
++{
++	u32 val = __raw_readl(REG_BCM6362_MISC_SB);
++
++	switch ((val & BCM6362_FCVO_MASK) >> BCM6362_FCVO_SHIFT) {
++	case 0x04:
++	case 0x0c:
++	case 0x14:
++	case 0x1c:
++		return 160000000;
++	case 0x15:
++	case 0x1d:
++		return 200000000;
++	case 0x03:
++	case 0x0b:
++	case 0x13:
++	case 0x1b:
++		return 240000000;
++	case 0x07:
++	case 0x17:
++		return 384000000;
++	case 0x05:
++	case 0x0e:
++	case 0x16:
++	case 0x1e:
++	case 0x1f:
++		return 400000000;
++	case 0x06:
++		return 440000000;
++	default:
++		return 320000000;
++	}
++}
++
++static u32 bcm6368_cpufreq(void)
++{
++	u32 val, p1, p2, ndiv, m1;
++
++	val = __raw_readl(REG_BCM6368_DDR_PLLC);
++	p1 = (val & BCM6368_PLLC_P1_MASK) >> BCM6368_PLLC_P1_SHIFT;
++	p2 = (val & BCM6368_PLLC_P2_MASK) >> BCM6368_PLLC_P2_SHIFT;
++	ndiv = (val & BCM6368_PLLC_NDIV_MASK) >>
++	       BCM6368_PLLC_NDIV_SHIFT;
++
++	val = __raw_readl(REG_BCM6368_DDR_PLLD);
++	m1 = (val & BCM6368_PLLD_MDIV_MASK) >> BCM6368_PLLD_MDIV_SHIFT;
++
++	return (((64 * 1000000) / p1) * p2 * ndiv) / m1;
++}
++
++static u32 bcm63268_cpufreq(void)
++{
++	u32 val = __raw_readl(REG_BCM63268_MISC_SB);
++
++	switch ((val & BCM63268_FCVO_MASK) >> BCM63268_FCVO_SHIFT) {
++	case 0x3:
++	case 0xe:
++		return 320000000;
++	case 0xa:
++		return 333000000;
++	case 0x2:
++	case 0xb:
++	case 0xf:
++		return 400000000;
++	default:
++		return 0;
++	}
++}
++
++static const struct bmips_cpufreq bmips_cpufreq_list[] = {
++	{ "brcm,bcm6318", &bcm6318_cpufreq },
++	{ "brcm,bcm6328", &bcm6328_cpufreq },
++	{ "brcm,bcm6358", &bcm6358_cpufreq },
++	{ "brcm,bcm6362", &bcm6362_cpufreq },
++	{ "brcm,bcm6368", &bcm6368_cpufreq },
++	{ "brcm,bcm63268", &bcm63268_cpufreq },
++	{ /* sentinel */ }
++};
++
+ void __init plat_time_init(void)
+ {
++	const struct bmips_cpufreq *cf;
+ 	struct device_node *np;
+-	u32 freq;
++	u32 freq = 0;
+ 
+-	np = of_find_node_by_name(NULL, "cpus");
+-	if (!np)
+-		panic("missing 'cpus' DT node");
+-	if (of_property_read_u32(np, "mips-hpt-frequency", &freq) < 0)
+-		panic("missing 'mips-hpt-frequency' property");
+-	of_node_put(np);
++	for (cf = bmips_cpufreq_list; cf->cpu_freq; cf++) {
++		if (of_flat_dt_is_compatible(of_get_flat_dt_root(),
++					     cf->compatible)) {
++			freq = cf->cpu_freq() / 2;
++			printk("%s detected @ %u MHz\n", cf->compatible, freq / 500000);
++			break;
++		}
++	}
++
++	if (!freq) {
++		np = of_find_node_by_name(NULL, "cpus");
++		if (!np)
++			panic("missing 'cpus' DT node");
++		if (of_property_read_u32(np, "mips-hpt-frequency", &freq) < 0)
++			panic("missing 'mips-hpt-frequency' property");
++		of_node_put(np);
++	}
+ 
+ 	mips_hpt_frequency = freq;
+ }
diff --git a/target/linux/bmips/patches-5.15/201-mips-bmips-automatically-detect-RAM-size.patch b/target/linux/bmips/patches-5.15/201-mips-bmips-automatically-detect-RAM-size.patch
new file mode 100644
index 0000000000..b06795a44e
--- /dev/null
+++ b/target/linux/bmips/patches-5.15/201-mips-bmips-automatically-detect-RAM-size.patch
@@ -0,0 +1,196 @@
+From f9ee3f28ecb979c77423be965ef9dd313bdb9e9b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Mon, 8 Mar 2021 16:58:34 +0100
+Subject: [PATCH 2/2] mips: bmips: automatically detect RAM size
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Some devices have different amounts of RAM installed depending on HW revision.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ arch/mips/bmips/setup.c | 118 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 118 insertions(+)
+
+--- a/arch/mips/bmips/setup.c
++++ b/arch/mips/bmips/setup.c
+@@ -19,6 +19,7 @@
+ #include <linux/of_platform.h>
+ #include <linux/libfdt.h>
+ #include <linux/smp.h>
++#include <linux/types.h>
+ #include <asm/addrspace.h>
+ #include <asm/bmips.h>
+ #include <asm/bootinfo.h>
+@@ -34,13 +35,16 @@
+ #define REG_BCM6318_SOB		((void __iomem *)CKSEG1ADDR(0x10000900))
+ #define BCM6318_FREQ_SHIFT	23
+ #define BCM6318_FREQ_MASK	(0x3 << BCM6318_FREQ_SHIFT)
++#define BCM6318_SDRAM_ADDR	((void __iomem *)CKSEG1ADDR(0x10004000))
+ 
+ #define REG_BCM6328_OTP		((void __iomem *)CKSEG1ADDR(0x1000062c))
+ #define BCM6328_TP1_DISABLED	BIT(9)
+ #define REG_BCM6328_MISC_SB	((void __iomem *)CKSEG1ADDR(0x10001a40))
+ #define BCM6328_FCVO_SHIFT	7
+ #define BCM6328_FCVO_MASK	(0x1f << BCM6328_FCVO_SHIFT)
++#define BCM6328_MEMC_ADDR	((void __iomem *)CKSEG1ADDR(0x10003000))
+ 
++#define BCM6358_MEMC_ADDR	((void __iomem *)0xfffe1200)
+ #define REG_BCM6358_DDR_PLLC	((void __iomem *)0xfffe12b8)
+ #define BCM6358_PLLC_M1_SHIFT	0
+ #define BCM6358_PLLC_M1_MASK	(0xff << BCM6358_PLLC_M1_SHIFT)
+@@ -52,7 +56,9 @@
+ #define REG_BCM6362_MISC_SB	((void __iomem *)CKSEG1ADDR(0x10001814))
+ #define BCM6362_FCVO_SHIFT	1
+ #define BCM6362_FCVO_MASK	(0x1f << BCM6362_FCVO_SHIFT)
++#define BCM6362_MEMC_ADDR	((void __iomem *)CKSEG1ADDR(0x10003000))
+ 
++#define BCM6368_MEMC_ADDR	((void __iomem *)CKSEG1ADDR(0x10001200))
+ #define REG_BCM6368_DDR_PLLC	((void __iomem *)CKSEG1ADDR(0x100012a0))
+ #define BCM6368_PLLC_P1_SHIFT	0
+ #define BCM6368_PLLC_P1_MASK	(0xf << BCM6368_PLLC_P1_SHIFT)
+@@ -67,7 +73,21 @@
+ #define REG_BCM63268_MISC_SB	((void __iomem *)CKSEG1ADDR(0x10001814))
+ #define BCM63268_FCVO_SHIFT	21
+ #define BCM63268_FCVO_MASK	(0xf << BCM63268_FCVO_SHIFT)
++#define BCM63268_MEMC_ADDR	((void __iomem *)CKSEG1ADDR(0x10003000))
+ 
++#define SDRAM_CFG_REG		0x0
++#define SDRAM_SPACE_SHIFT	4
++#define SDRAM_SPACE_MASK	(0xf << SDRAM_SPACE_SHIFT)
++
++#define MEMC_CFG_REG		0x4
++#define MEMC_CFG_32B_SHIFT	1
++#define MEMC_CFG_32B_MASK	(1 << MEMC_CFG_32B_SHIFT)
++#define MEMC_CFG_COL_SHIFT	3
++#define MEMC_CFG_COL_MASK	(0x3 << MEMC_CFG_COL_SHIFT)
++#define MEMC_CFG_ROW_SHIFT	6
++#define MEMC_CFG_ROW_MASK	(0x3 << MEMC_CFG_ROW_SHIFT)
++
++#define DDR_CSEND_REG		0x8
+ 
+ static const unsigned long kbase = VMLINUX_LOAD_ADDRESS & 0xfff00000;
+ 
+@@ -76,6 +96,11 @@ struct bmips_cpufreq {
+ 	u32			(*cpu_freq)(void);
+ };
+ 
++struct bmips_memsize {
++	const char		*compatible;
++	phys_addr_t		(*mem_size)(void);
++};
++
+ struct bmips_quirk {
+ 	const char		*compatible;
+ 	void			(*quirk_fn)(void);
+@@ -333,9 +358,90 @@ void __init plat_time_init(void)
+ 	mips_hpt_frequency = freq;
+ }
+ 
++static inline phys_addr_t bmips_dram_size(unsigned int cols,
++					  unsigned int rows,
++					  unsigned int is_32b,
++					  unsigned int banks)
++{
++	rows += 11; /* 0 => 11 address bits ... 2 => 13 address bits */
++	cols += 8; /* 0 => 8 address bits ... 2 => 10 address bits */
++	is_32b += 1;
++
++	return 1 << (cols + rows + is_32b + banks);
++}
++
++static phys_addr_t _bcm6318_memsize(void __iomem *addr)
++{
++	u32 val;
++
++	val = __raw_readl(addr + SDRAM_CFG_REG);
++	val = (val & SDRAM_SPACE_MASK) >> SDRAM_SPACE_SHIFT;
++
++	return (1 << (val + 20));
++}
++
++static phys_addr_t _bcm6328_memsize(void __iomem *addr)
++{
++	return __raw_readl(addr + DDR_CSEND_REG) << 24;
++}
++
++static phys_addr_t _bcm6358_memsize(void __iomem *addr)
++{
++	unsigned int cols, rows, is_32b;
++	u32 val;
++
++	val = __raw_readl(addr + MEMC_CFG_REG);
++	rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT;
++	cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT;
++	is_32b = (val & MEMC_CFG_32B_MASK) ? 0 : 1;
++
++	return bmips_dram_size(cols, rows, is_32b, 2);
++}
++
++static phys_addr_t bcm6318_memsize(void)
++{
++	return _bcm6318_memsize(BCM6318_SDRAM_ADDR);
++}
++
++static phys_addr_t bcm6328_memsize(void)
++{
++	return _bcm6328_memsize(BCM6328_MEMC_ADDR);
++}
++
++static phys_addr_t bcm6358_memsize(void)
++{
++	return _bcm6358_memsize(BCM6358_MEMC_ADDR);
++}
++
++static phys_addr_t bcm6362_memsize(void)
++{
++	return _bcm6328_memsize(BCM6362_MEMC_ADDR);
++}
++
++static phys_addr_t bcm6368_memsize(void)
++{
++	return _bcm6358_memsize(BCM6368_MEMC_ADDR);
++}
++
++static phys_addr_t bcm63268_memsize(void)
++{
++	return _bcm6328_memsize(BCM63268_MEMC_ADDR);
++}
++
++static const struct bmips_memsize bmips_memsize_list[] = {
++	{ "brcm,bcm6318", &bcm6318_memsize },
++	{ "brcm,bcm6328", &bcm6328_memsize },
++	{ "brcm,bcm6358", &bcm6358_memsize },
++	{ "brcm,bcm6362", &bcm6362_memsize },
++	{ "brcm,bcm6368", &bcm6368_memsize },
++	{ "brcm,bcm63268", &bcm63268_memsize },
++	{ /* sentinel */ }
++};
++
+ void __init plat_mem_setup(void)
+ {
+ 	void *dtb;
++	const struct bmips_memsize *ms;
+ 	const struct bmips_quirk *q;
+ 
+ 	set_io_port_base(0);
+@@ -353,6 +459,18 @@ void __init plat_mem_setup(void)
+ 
+ 	__dt_setup_arch(dtb);
+ 
++	for (ms = bmips_memsize_list; ms->mem_size; ms++) {
++		if (of_flat_dt_is_compatible(of_get_flat_dt_root(),
++					     ms->compatible)) {
++			phys_addr_t mem = ms->mem_size();
++			if (mem) {
++				memblock_add(0, mem);
++				printk("%uMB of RAM installed\n", mem >> 20);
++				break;
++			}
++		}
++	}
++
+ 	for (q = bmips_quirk_list; q->quirk_fn; q++) {
+ 		if (of_flat_dt_is_compatible(of_get_flat_dt_root(),
+ 					     q->compatible)) {
diff --git a/target/linux/bmips/patches-5.15/202-mips-bmips-disable-ARCH_HAS_SYNC_DMA_FOR_CPU_ALL.patch b/target/linux/bmips/patches-5.15/202-mips-bmips-disable-ARCH_HAS_SYNC_DMA_FOR_CPU_ALL.patch
new file mode 100644
index 0000000000..af232e8758
--- /dev/null
+++ b/target/linux/bmips/patches-5.15/202-mips-bmips-disable-ARCH_HAS_SYNC_DMA_FOR_CPU_ALL.patch
@@ -0,0 +1,80 @@
+From 84c06b4a1dfa3e021fdbcafaff8cebfdec462402 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Tue, 23 Feb 2021 10:39:48 +0100
+Subject: [PATCH] mips: bmips: disable ARCH_HAS_SYNC_DMA_FOR_CPU_ALL
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Enabling this option causes kernel panics on BCM6358 with EHCI/OHCI:
+[    3.881739] usb 1-1: new high-speed USB device number 2 using ehci-platform
+[    3.895011] Reserved instruction in kernel code[#1]:
+[    3.900113] CPU: 0 PID: 1 Comm: init Not tainted 5.10.16 #0
+[    3.905829] $ 0   : 00000000 10008700 00000000 77d94060
+[    3.911238] $ 4   : 7fd1f088 00000000 81431cac 81431ca0
+[    3.916641] $ 8   : 00000000 ffffefff 8075cd34 00000000
+[    3.922043] $12   : 806f8d40 f3e812b7 00000000 000d9aaa
+[    3.927446] $16   : 7fd1f068 7fd1f080 7ff559b8 81428470
+[    3.932848] $20   : 00000000 00000000 55590000 77d70000
+[    3.938251] $24   : 00000018 00000010
+[    3.943655] $28   : 81430000 81431e60 81431f28 800157fc
+[    3.949058] Hi    : 00000000
+[    3.952013] Lo    : 00000000
+[    3.955019] epc   : 80015808 setup_sigcontext+0x54/0x24c
+[    3.960464] ra    : 800157fc setup_sigcontext+0x48/0x24c
+[    3.965913] Status: 10008703	KERNEL EXL IE
+[    3.970216] Cause : 00800028 (ExcCode 0a)
+[    3.974340] PrId  : 0002a010 (Broadcom BMIPS4350)
+[    3.979170] Modules linked in: ohci_platform ohci_hcd fsl_mph_dr_of ehci_platform ehci_fsl ehci_hcd gpio_button_hotplug usbcore nls_base usb_common
+[    3.992907] Process init (pid: 1, threadinfo=(ptrval), task=(ptrval), tls=77e22ec8)
+[    4.000776] Stack : 81431ef4 7fd1f080 81431f28 81428470 7fd1f068 81431edc 7ff559b8 81428470
+[    4.009467]         81431f28 7fd1f080 55590000 77d70000 77d5498c 80015c70 806f0000 8063ae74
+[    4.018149]         08100002 81431f28 0000000a 08100002 81431f28 0000000a 77d6b418 00000003
+[    4.026831]         ffffffff 80016414 80080734 81431ecc 81431ecc 00000001 00000000 04000000
+[    4.035512]         77d54874 00000000 00000000 00000000 00000000 00000012 00000002 00000000
+[    4.044196]         ...
+[    4.046706] Call Trace:
+[    4.049238] [<80015808>] setup_sigcontext+0x54/0x24c
+[    4.054356] [<80015c70>] setup_frame+0xdc/0x124
+[    4.059015] [<80016414>] do_notify_resume+0x1dc/0x288
+[    4.064207] [<80011b50>] work_notifysig+0x10/0x18
+[    4.069036]
+[    4.070538] Code: 8fc300b4  00001025  26240008 <ac820000> ac830004  3c048063  0c0228aa  24846a00  26240010
+[    4.080686]
+[    4.082517] ---[ end trace 22a8edb41f5f983b ]---
+[    4.087374] Kernel panic - not syncing: Fatal exception
+[    4.092753] Rebooting in 1 seconds..
+
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ arch/mips/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -264,7 +264,6 @@ config ATH79
+ config BMIPS_GENERIC
+ 	bool "Broadcom Generic BMIPS kernel"
+ 	select ARCH_HAS_RESET_CONTROLLER
+-	select ARCH_HAS_SYNC_DMA_FOR_CPU_ALL
+ 	select ARCH_HAS_PHYS_TO_DMA
+ 	select BOOT_RAW
+ 	select NO_EXCEPT_FILL
+--- a/arch/mips/bmips/dma.c
++++ b/arch/mips/bmips/dma.c
+@@ -64,6 +64,7 @@ phys_addr_t dma_to_phys(struct device *d
+ 	return dma_addr;
+ }
+ 
++#ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL
+ void arch_sync_dma_for_cpu_all(void)
+ {
+ 	void __iomem *cbr = BMIPS_GET_CBR();
+@@ -79,6 +80,7 @@ void arch_sync_dma_for_cpu_all(void)
+ 	__raw_writel(cfg | 0x100, cbr + BMIPS_RAC_CONFIG);
+ 	__raw_readl(cbr + BMIPS_RAC_CONFIG);
+ }
++#endif /* CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL */
+ 
+ static int __init bmips_init_dma_ranges(void)
+ {
diff --git a/target/linux/bmips/patches-5.15/500-net-broadcom-add-BCM6368-enetsw-controller-driver.patch b/target/linux/bmips/patches-5.15/500-net-broadcom-add-BCM6368-enetsw-controller-driver.patch
new file mode 100644
index 0000000000..35a1ccd60d
--- /dev/null
+++ b/target/linux/bmips/patches-5.15/500-net-broadcom-add-BCM6368-enetsw-controller-driver.patch
@@ -0,0 +1,46 @@
+From 590b60fb08cb1e70fe02d3f407c6b3dbe9ad06ff Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Mon, 1 Mar 2021 07:34:39 +0100
+Subject: [PATCH 3/4] net: broadcom: add BCM6368 enetsw controller driver
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This controller is present on BCM6318, BCM6328, BCM6362, BCM6368 and BCM63268
+SoCs.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ drivers/net/ethernet/broadcom/Kconfig         |    8 +
+ drivers/net/ethernet/broadcom/Makefile        |    1 +
+ .../net/ethernet/broadcom/bcm6368-enetsw.c    | 1111 +++++++++++++++++
+ 3 files changed, 1120 insertions(+)
+ create mode 100644 drivers/net/ethernet/broadcom/bcm6368-enetsw.c
+
+--- a/drivers/net/ethernet/broadcom/Kconfig
++++ b/drivers/net/ethernet/broadcom/Kconfig
+@@ -68,6 +68,14 @@ config BCM63XX_ENET
+ 	  This driver supports the ethernet MACs in the Broadcom 63xx
+ 	  MIPS chipset family (BCM63XX).
+ 
++config BCM6368_ENETSW
++	tristate "Broadcom BCM6368 internal mac support"
++	depends on BMIPS_GENERIC || COMPILE_TEST
++	default y
++	help
++	  This driver supports Ethernet controller integrated into Broadcom
++	  BCM6368 family SoCs.
++
+ config BCMGENET
+ 	tristate "Broadcom GENET internal MAC support"
+ 	depends on HAS_IOMEM
+--- a/drivers/net/ethernet/broadcom/Makefile
++++ b/drivers/net/ethernet/broadcom/Makefile
+@@ -6,6 +6,7 @@
+ obj-$(CONFIG_B44) += b44.o
+ obj-$(CONFIG_BCM4908_ENET) += bcm4908_enet.o
+ obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o
++obj-$(CONFIG_BCM6368_ENETSW) += bcm6368-enetsw.o
+ obj-$(CONFIG_BCMGENET) += genet/
+ obj-$(CONFIG_BNX2) += bnx2.o
+ obj-$(CONFIG_CNIC) += cnic.o
diff --git a/target/linux/bmips/patches-5.15/501-net-dsa-b53-mmap-fix-enabled_ports.patch b/target/linux/bmips/patches-5.15/501-net-dsa-b53-mmap-fix-enabled_ports.patch
new file mode 100644
index 0000000000..7d1fb7105d
--- /dev/null
+++ b/target/linux/bmips/patches-5.15/501-net-dsa-b53-mmap-fix-enabled_ports.patch
@@ -0,0 +1,11 @@
+--- a/drivers/net/dsa/b53/b53_mmap.c
++++ b/drivers/net/dsa/b53/b53_mmap.c
+@@ -263,7 +263,7 @@ static int b53_mmap_probe_of(struct plat
+ 		if (of_property_read_u32(of_port, "reg", &reg))
+ 			continue;
+ 
+-		if (reg < B53_CPU_PORT)
++		if (reg <= B53_CPU_PORT)
+ 			pdata->enabled_ports |= BIT(reg);
+ 	}
+ 
diff --git a/target/linux/bmips/patches-5.15/510-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch b/target/linux/bmips/patches-5.15/510-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch
new file mode 100644
index 0000000000..3921477224
--- /dev/null
+++ b/target/linux/bmips/patches-5.15/510-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch
@@ -0,0 +1,72 @@
+From 32cf73d8c6485b7b97aca7e377a68436d09b7022 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Sun, 14 Mar 2021 20:03:44 +0100
+Subject: [PATCH] net: dsa: b53: add support for BCM63xx RGMIIs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ drivers/net/dsa/b53/b53_common.c | 37 ++++++++++++++++++++++++++++++++
+ 1 file changed, 37 insertions(+)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1209,6 +1209,36 @@ static void b53_force_port_config(struct
+ 	b53_write8(dev, B53_CTRL_PAGE, off, reg);
+ }
+ 
++static void b53_adjust_63xx_rgmii(struct dsa_switch *ds, int port,
++				  phy_interface_t interface)
++{
++	struct b53_device *dev = ds->priv;
++	u8 rgmii_ctrl = 0, off;
++
++	if (port == 8)
++		off = B53_RGMII_CTRL_IMP;
++	else
++		off = B53_RGMII_CTRL_P(port);
++
++	b53_read8(dev, B53_CTRL_PAGE, off, &rgmii_ctrl);
++
++	rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC);
++	if (interface == PHY_INTERFACE_MODE_RGMII_ID)
++		rgmii_ctrl |= (RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC);
++	else if (interface == PHY_INTERFACE_MODE_RGMII_RXID)
++		rgmii_ctrl |= RGMII_CTRL_DLL_RXC;
++	else if (interface == PHY_INTERFACE_MODE_RGMII_TXID)
++		rgmii_ctrl |= RGMII_CTRL_DLL_TXC;
++
++	if (port != B53_CPU_PORT)
++		rgmii_ctrl |= RGMII_CTRL_ENABLE_GMII;
++
++	b53_write8(dev, B53_CTRL_PAGE, off, rgmii_ctrl);
++
++	dev_info(ds->dev, "Configured port %d for %s\n", port,
++		 phy_modes(interface));
++}
++
+ static void b53_adjust_link(struct dsa_switch *ds, int port,
+ 			    struct phy_device *phydev)
+ {
+@@ -1235,6 +1265,9 @@ static void b53_adjust_link(struct dsa_s
+ 			      tx_pause, rx_pause);
+ 	b53_force_link(dev, port, phydev->link);
+ 
++	if (is63xx(dev))
++		b53_adjust_63xx_rgmii(ds, port, phydev->interface);
++
+ 	if (is531x5(dev) && phy_interface_is_rgmii(phydev)) {
+ 		if (port == dev->imp_port)
+ 			off = B53_RGMII_CTRL_IMP;
+@@ -1421,6 +1454,9 @@ void b53_phylink_mac_link_up(struct dsa_
+ {
+ 	struct b53_device *dev = ds->priv;
+ 
++	if (is63xx(dev) && port >= 4)
++		b53_adjust_63xx_rgmii(ds, port, interface);
++
+ 	if (mode == MLO_AN_PHY)
+ 		return;
+ 
diff --git a/target/linux/bmips/patches-5.15/600-mips-bmips-add-pci-support.patch b/target/linux/bmips/patches-5.15/600-mips-bmips-add-pci-support.patch
new file mode 100644
index 0000000000..b219868442
--- /dev/null
+++ b/target/linux/bmips/patches-5.15/600-mips-bmips-add-pci-support.patch
@@ -0,0 +1,20 @@
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -276,6 +276,7 @@ config BMIPS_GENERIC
+ 	select BCM7038_L1_IRQ
+ 	select BCM7120_L2_IRQ
+ 	select BRCMSTB_L2_IRQ
++	select HAVE_PCI
+ 	select IRQ_MIPS_CPU
+ 	select DMA_NONCOHERENT
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+--- a/arch/mips/pci/Makefile
++++ b/arch/mips/pci/Makefile
+@@ -28,6 +28,7 @@ obj-$(CONFIG_PCI_XTALK_BRIDGE)	+= pci-xt
+ # These are still pretty much in the old state, watch, go blind.
+ #
+ obj-$(CONFIG_ATH79)		+= fixup-ath79.o
++obj-$(CONFIG_BMIPS_GENERIC)	+= fixup-bmips.o
+ obj-$(CONFIG_MIPS_COBALT)	+= fixup-cobalt.o
+ obj-$(CONFIG_LEMOTE_FULOONG2E)	+= fixup-fuloong2e.o ops-loongson2.o
+ obj-$(CONFIG_LEMOTE_MACH2F)	+= fixup-lemote2f.o ops-loongson2.o
diff --git a/target/linux/bmips/patches-5.15/601-pci-controllers-add-bcm6328-pcie-support.patch b/target/linux/bmips/patches-5.15/601-pci-controllers-add-bcm6328-pcie-support.patch
new file mode 100644
index 0000000000..4ebc806e1e
--- /dev/null
+++ b/target/linux/bmips/patches-5.15/601-pci-controllers-add-bcm6328-pcie-support.patch
@@ -0,0 +1,22 @@
+--- a/drivers/pci/controller/Kconfig
++++ b/drivers/pci/controller/Kconfig
+@@ -3,6 +3,11 @@
+ menu "PCI controller drivers"
+ 	depends on PCI
+ 
++config PCIE_BCM6328
++	bool "BCM6328 PCIe controller"
++	depends on BMIPS_GENERIC || COMPILE_TEST
++	depends on OF
++
+ config PCI_MVEBU
+ 	bool "Marvell EBU PCIe controller"
+ 	depends on ARCH_MVEBU || ARCH_DOVE || COMPILE_TEST
+--- a/drivers/pci/controller/Makefile
++++ b/drivers/pci/controller/Makefile
+@@ -1,4 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0
++obj-$(CONFIG_PCIE_BCM6328) += pcie-bcm6328.o
+ obj-$(CONFIG_PCIE_CADENCE) += cadence/
+ obj-$(CONFIG_PCI_FTPCI100) += pci-ftpci100.o
+ obj-$(CONFIG_PCI_IXP4XX) += pci-ixp4xx.o
diff --git a/target/linux/bmips/patches-5.15/602-pci-controllers-add-bcm6318-pcie-support.patch b/target/linux/bmips/patches-5.15/602-pci-controllers-add-bcm6318-pcie-support.patch
new file mode 100644
index 0000000000..3674028aec
--- /dev/null
+++ b/target/linux/bmips/patches-5.15/602-pci-controllers-add-bcm6318-pcie-support.patch
@@ -0,0 +1,22 @@
+--- a/drivers/pci/controller/Kconfig
++++ b/drivers/pci/controller/Kconfig
+@@ -3,6 +3,11 @@
+ menu "PCI controller drivers"
+ 	depends on PCI
+ 
++config PCIE_BCM6318
++	bool "BCM6318 PCIe controller"
++	depends on BMIPS_GENERIC || COMPILE_TEST
++	depends on OF
++
+ config PCIE_BCM6328
+ 	bool "BCM6328 PCIe controller"
+ 	depends on BMIPS_GENERIC || COMPILE_TEST
+--- a/drivers/pci/controller/Makefile
++++ b/drivers/pci/controller/Makefile
+@@ -1,4 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0
++obj-$(CONFIG_PCIE_BCM6318) += pcie-bcm6318.o
+ obj-$(CONFIG_PCIE_BCM6328) += pcie-bcm6328.o
+ obj-$(CONFIG_PCIE_CADENCE) += cadence/
+ obj-$(CONFIG_PCI_FTPCI100) += pci-ftpci100.o
diff --git a/target/linux/bmips/patches-5.15/603-pci-controllers-add-bcm6348-pci-support.patch b/target/linux/bmips/patches-5.15/603-pci-controllers-add-bcm6348-pci-support.patch
new file mode 100644
index 0000000000..c0572604ee
--- /dev/null
+++ b/target/linux/bmips/patches-5.15/603-pci-controllers-add-bcm6348-pci-support.patch
@@ -0,0 +1,22 @@
+--- a/drivers/pci/controller/Kconfig
++++ b/drivers/pci/controller/Kconfig
+@@ -3,6 +3,11 @@
+ menu "PCI controller drivers"
+ 	depends on PCI
+ 
++config PCI_BCM6348
++	bool "BCM6348 PCI controller"
++	depends on BMIPS_GENERIC || COMPILE_TEST
++	depends on OF
++
+ config PCIE_BCM6318
+ 	bool "BCM6318 PCIe controller"
+ 	depends on BMIPS_GENERIC || COMPILE_TEST
+--- a/drivers/pci/controller/Makefile
++++ b/drivers/pci/controller/Makefile
+@@ -1,4 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0
++obj-$(CONFIG_PCI_BCM6348) += pci-bcm6348.o
+ obj-$(CONFIG_PCIE_BCM6318) += pcie-bcm6318.o
+ obj-$(CONFIG_PCIE_BCM6328) += pcie-bcm6328.o
+ obj-$(CONFIG_PCIE_CADENCE) += cadence/
diff --git a/target/linux/bmips/patches-5.15/610-mips-bmips-add-pci-fixups.patch b/target/linux/bmips/patches-5.15/610-mips-bmips-add-pci-fixups.patch
new file mode 100644
index 0000000000..5f68308986
--- /dev/null
+++ b/target/linux/bmips/patches-5.15/610-mips-bmips-add-pci-fixups.patch
@@ -0,0 +1,6 @@
+--- a/arch/mips/bmips/Makefile
++++ b/arch/mips/bmips/Makefile
+@@ -1,2 +1,3 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ obj-y		+= setup.o irq.o dma.o
++obj-y		+= ath9k-fixup.o b43-sprom.o
diff --git a/target/linux/bmips/patches-5.15/800-jffs2-work-around-unaligned-accesses-failing-on-bcm6.patch b/target/linux/bmips/patches-5.15/800-jffs2-work-around-unaligned-accesses-failing-on-bcm6.patch
new file mode 100644
index 0000000000..d98d27c6b4
--- /dev/null
+++ b/target/linux/bmips/patches-5.15/800-jffs2-work-around-unaligned-accesses-failing-on-bcm6.patch
@@ -0,0 +1,26 @@
+From ff3409ab17d56450943364ba49a16960e3cdda9b Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jogo at openwrt.org>
+Date: Sun, 6 Apr 2014 22:33:16 +0200
+Subject: [RFC] jffs2: work around unaligned accesses failing on bcm63xx/smp
+
+Unligned memcpy_fromio randomly fails with an unaligned dst. Work around
+it by ensuring we are always doing aligned copies.
+
+Should fix filename corruption in jffs2 with SMP.
+
+Signed-off-by: Jonas Gorski <jogo at openwrt.org>
+---
+ fs/jffs2/nodelist.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/jffs2/nodelist.h
++++ b/fs/jffs2/nodelist.h
+@@ -259,7 +259,7 @@ struct jffs2_full_dirent
+ 	uint32_t ino; /* == zero for unlink */
+ 	unsigned int nhash;
+ 	unsigned char type;
+-	unsigned char name[];
++	unsigned char name[] __attribute__((aligned((sizeof(long)))));
+ };
+ 
+ /*
diff --git a/target/linux/generic/config-5.15 b/target/linux/generic/config-5.15
index d53e4cc55b..a8a7dfc6ff 100644
--- a/target/linux/generic/config-5.15
+++ b/target/linux/generic/config-5.15
@@ -4675,6 +4675,7 @@ CONFIG_PINCONF=y
 # CONFIG_PINCTRL_MT8365 is not set
 # CONFIG_PINCTRL_MTK_V2 is not set
 # CONFIG_PINCTRL_OCELOT is not set
+# CONFIG_PINCTRL_PISTACHIO is not set
 # CONFIG_PINCTRL_SC7280 is not set
 # CONFIG_PINCTRL_SC8180X is not set
 # CONFIG_PINCTRL_SDX55 is not set




More information about the lede-commits mailing list