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,
--- /dev/null
+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
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))
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);
#include <linux/pci.h>
#include <linux/reset.h>
#include <linux/types.h>
+#include <linux/version.h>
#include <linux/vmalloc.h>
#include "../pci.h"
.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
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();
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
#include <linux/pci.h>
#include <linux/reset.h>
#include <linux/types.h>
+#include <linux/version.h>
#include <linux/vmalloc.h>
#include "../pci.h"
if (PCI_SLOT(devfn) == 0)
return __raw_readl(priv->base + PCIE_DLSTATUS_REG)
& DLSTATUS_PHYLINKUP;
- /* else, fall through */
+ fallthrough;
default:
return false;
}
.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)
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();
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);
#include <linux/reset.h>
#include <linux/regmap.h>
#include <linux/types.h>
+#include <linux/version.h>
#include <linux/vmalloc.h>
#include "../pci.h"
if (PCI_SLOT(devfn) == 0)
return __raw_readl(priv->base + PCIE_DLSTATUS_REG)
& DLSTATUS_PHYLINKUP;
- /* else, fall through */
+ fallthrough;
default:
return false;
}
.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)
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);
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);
comtrend,ar-5315u |\
comtrend,ar-5387un |\
comtrend,vr-3025u)
+ ucidef_set_bridge_device switch
ucidef_set_interface_lan "lan1 lan2 lan3 lan4"
;;
esac
case "$(board_name)" in
comtrend,vr-3032u)
+ ucidef_set_bridge_device switch
ucidef_set_interface_lan "lan1 lan2 lan3 lan4"
;;
netgear,dgnd3700-v2)
--- /dev/null
+From cf908990d4a8ccdb73ee4484aa8cadad379ca314 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jogo@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@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@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@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@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 */
--- /dev/null
+From 5a079515cb3066aeb658634301a98871b47c2af4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@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@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 */
--- /dev/null
+From 3327df17635dd9d24a855ac6b7247fac381514cf Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@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@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 */
--- /dev/null
+From c17702bad18a085ae913752b45bcc20c2cea879e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@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@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@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@100000ac {
++ compatible = "brcm,bcm63268-timer-clocks";
++ reg = <0x100000ac 0x4>;
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ };
--- /dev/null
+From 3c8dd9d0937a19f3f20f28ba0b0b64f448d50dd4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@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@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@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);
--- /dev/null
+From 0377ad93031d3e51c2afe44231241185f684b6af Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@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@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;
+ }
--- /dev/null
+From f9ee3f28ecb979c77423be965ef9dd313bdb9e9b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@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@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)) {
--- /dev/null
+From 84c06b4a1dfa3e021fdbcafaff8cebfdec462402 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@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@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)
+ {
--- /dev/null
+From 590b60fb08cb1e70fe02d3f407c6b3dbe9ad06ff Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@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@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
--- /dev/null
+--- 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", ®))
+ continue;
+
+- if (reg < B53_CPU_PORT)
++ if (reg <= B53_CPU_PORT)
+ pdata->enabled_ports |= BIT(reg);
+ }
+
--- /dev/null
+From 32cf73d8c6485b7b97aca7e377a68436d09b7022 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@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@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;
+
--- /dev/null
+--- 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
--- /dev/null
+--- 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
--- /dev/null
+--- 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
--- /dev/null
+--- 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/
--- /dev/null
+--- 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
--- /dev/null
+From ff3409ab17d56450943364ba49a16960e3cdda9b Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jogo@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@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)))));
+ };
+
+ /*
# 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