bcm53xx: add support for kernel 4.1
authorHauke Mehrtens <hauke@hauke-m.de>
Thu, 25 Jun 2015 21:33:53 +0000 (21:33 +0000)
committerHauke Mehrtens <hauke@hauke-m.de>
Thu, 25 Jun 2015 21:33:53 +0000 (21:33 +0000)
This only removes the patches already applied upstream and makes the
rest apply cleanly.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
SVN-Revision: 46128

44 files changed:
target/linux/bcm53xx/config-4.1 [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/058-ARM-BCM5301X-Add-USB-LED-for-Buffalo-WZR-1750DHP.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/059-ARM-BCM5301X-Add-DT-for-Buffalo-WXR-1900DHP.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/060-ARM-BCM5301X-Add-DT-for-SmartRG-SR400ac.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/061-ARM-BCM5301X-Add-DT-for-Asus-RT-AC68U.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/062-ARM-BCM5301X-Add-DT-for-Asus-RT-AC56U.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/063-ARM-BCM5301X-Ignore-another-BCM4709-specific-fault-c.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/064-ARM-BCM5301X-add-NAND-flash-chip-description.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/065-ARM-BCM5301X-add-IRQ-numbers-for-PCIe-controller.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/066-ARM-BCM5301X-Add-DT-for-Asus-RT-AC87U.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/110-firmware-backport-NVRAM-driver.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/112-bcm53xx-sprom-add-sprom-driver.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/131-ARM-BCM5301X-Implement-SMP-support.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/180-USB-bcma-remove-chip-id-check.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/181-USB-bcma-replace-numbers-with-constants.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/182-USB-bcma-use-devm_kzalloc.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/183-USB-bcma-fix-error-handling-in-bcma_hcd_create_pdev.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/184-USB-bcma-add-bcm53xx-support.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/185-USB-bcma-add-support-for-controlling-bus-power-throu.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/300-ARM-BCM5301X-Disable-MMU-and-Dcache-for-decompression.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/301-ARM-BCM5301X-Add-SPROM.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/303-ARM-BCM5310X-Enable-earlyprintk-on-tested-devices.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/305-ARM-BCM53XX-set-customized-AUXCTL.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/306-ARM-BCM5301X-Specify-RAM-on-devices-by-including-HIG.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/320-ARM-BCM5301X-Add-Buffalo-WXR-1900DHP-clock-and-USB-p.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/321-ARM-BCM5301X-Set-vcc-gpio-for-USB-controllers.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/332-ARM-BCM5301X-Add-power-button-for-Buffalo-WZR-1750DHP.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/340-ARM-BCM5301X-Add-profiling-support.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/351-ARM-BCM5301X-Enable-ChipCommon-UART-serial-console.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/352-ARM-BCM5301X-Add-back-Luxul-XWC-1000-NAND-flash-layo.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/400-mtd-bcm47xxpart-scan-whole-flash-on-ARCH_BCM_5301X.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/404-mtd-bcm53xxspiflash-new-driver-for-SPI-flahes-on-Bro.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/420-mtd-bcm5301x_nand.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/700-bgmac-add-support-for-the-3rd-bus-core-device.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/710-b53-add-hacky-CPU-port-fixes-for-devices-not-using-p.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/800-bcma-use-two-different-initcalls-if-built-in.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/810-USB-bcma-make-helper-creating-platform-dev-more-gene.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/811-USB-bcma-use-separated-function-for-USB-2.0-initiali.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/812-USB-bcma-add-USB-3.0-support.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/813-USB-bcma-fix-setting-VCC-GPIO-value.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/820-xhci-add-Broadcom-specific-fake-doorbell.patch [new file with mode: 0644]
target/linux/bcm53xx/patches-4.1/901-mtd-bcm47xxpart-workaround-for-Asus-RT-AC87U-asus-pa.patch [new file with mode: 0644]

diff --git a/target/linux/bcm53xx/config-4.1 b/target/linux/bcm53xx/config-4.1
new file mode 100644 (file)
index 0000000..8daa3aa
--- /dev/null
@@ -0,0 +1,312 @@
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_ARCH_ALPINE is not set
+CONFIG_ARCH_BCM=y
+# CONFIG_ARCH_BCM_21664 is not set
+# CONFIG_ARCH_BCM_281XX is not set
+CONFIG_ARCH_BCM_5301X=y
+# CONFIG_ARCH_BCM_63XX is not set
+# CONFIG_ARCH_BCM_CYGNUS is not set
+CONFIG_ARCH_BCM_IPROC=y
+# CONFIG_ARCH_BRCMSTB is not set
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
+CONFIG_ARCH_HAS_SG_CHAIN=y
+CONFIG_ARCH_HAS_TICK_BROADCAST=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MULTIPLATFORM=y
+# CONFIG_ARCH_MULTI_CPU_AUTO is not set
+CONFIG_ARCH_MULTI_V6_V7=y
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARCH_NR_GPIO=0
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
+CONFIG_ARCH_SUPPORTS_UPROBES=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_USE_BUILTIN_BSWAP=y
+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_ARM=y
+CONFIG_ARM_AMBA=y
+CONFIG_ARM_APPENDED_DTB=y
+# CONFIG_ARM_ATAG_DTB_COMPAT is not set
+# CONFIG_ARM_CPU_SUSPEND is not set
+# CONFIG_ARM_CRYPTO is not set
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_ERRATA_764369=y
+CONFIG_ARM_ERRATA_775420=y
+CONFIG_ARM_ERRATA_798181=y
+CONFIG_ARM_GIC=y
+CONFIG_ARM_GLOBAL_TIMER=y
+CONFIG_ARM_HAS_SG_CHAIN=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+# CONFIG_ARM_LPAE is not set
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+# CONFIG_ARM_SP805_WATCHDOG is not set
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_ATAGS=y
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_B53=y
+# CONFIG_B53_MMAP_DRIVER is not set
+# CONFIG_B53_PHY_DRIVER is not set
+CONFIG_B53_SRAB_DRIVER=y
+CONFIG_BCM47XX_NVRAM=y
+CONFIG_BCM47XX_SPROM=y
+CONFIG_BCM47XX_WDT=y
+CONFIG_BCMA=y
+CONFIG_BCMA_BLOCKIO=y
+CONFIG_BCMA_DEBUG=y
+CONFIG_BCMA_DRIVER_GMAC_CMN=y
+CONFIG_BCMA_DRIVER_GPIO=y
+CONFIG_BCMA_DRIVER_PCI=y
+CONFIG_BCMA_HOST_PCI=y
+CONFIG_BCMA_HOST_PCI_POSSIBLE=y
+CONFIG_BCMA_HOST_SOC=y
+CONFIG_BGMAC=y
+CONFIG_BOUNCE=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLKSRC_OF=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_COMMON_CLK=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_CPU_HAS_ASID=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_V7=y
+CONFIG_CRC16=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_XZ=y
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_DEBUG_BCM_5301X=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_INCLUDE="debug/8250.S"
+CONFIG_DEBUG_UART_8250=y
+# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set
+CONFIG_DEBUG_UART_8250_SHIFT=0
+CONFIG_DEBUG_UART_PHYS=0x18000300
+CONFIG_DEBUG_UART_VIRT=0xf1000300
+CONFIG_DEBUG_UNCOMPRESS=y
+CONFIG_DEBUG_USER=y
+CONFIG_DTC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_FIXED_PHY=y
+CONFIG_FRAME_POINTER=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IO=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_74X164=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIO_SYSFS=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_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_ARCH_AUDITSYSCALL=y
+CONFIG_HAVE_ARCH_BITREVERSE=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_ARM_SCU=y
+CONFIG_HAVE_ARM_TWD=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_HAVE_BPF_JIT=y
+CONFIG_HAVE_CC_STACKPROTECTOR=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_CLK_PREPARE=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_HAVE_IDE=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZ4=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_HAVE_NET_DSA=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_OPTPROBES=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_HAVE_PERF_REGS=y
+CONFIG_HAVE_PERF_USER_STACK_DUMP=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_SMP=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_UID16=y
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
+CONFIG_HIGHMEM=y
+# CONFIG_HIGHPTE is not set
+CONFIG_HZ_FIXED=0
+CONFIG_HZ_PERIODIC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IOMMU_HELPER=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+# CONFIG_LZ4_COMPRESS is not set
+# CONFIG_LZ4_DECOMPRESS is not set
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MDIO_BOARDINFO=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_MIGHT_HAVE_PCI=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MTD_BCM47XX_PARTS=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_BCM=y
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_PHYSMAP_OF is not set
+CONFIG_MTD_SPI_BCM53XXSPIFLASH=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+CONFIG_MTD_UBI_BLOCK=y
+# CONFIG_MTD_UBI_FASTMAP is not set
+# CONFIG_MTD_UBI_GLUEBI is not set
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+# CONFIG_MULTIUSER is not set
+CONFIG_MULTI_IRQ_HANDLER=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NO_BOOTMEM=y
+CONFIG_NR_CPUS=4
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_ADDRESS_PCI=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_MTD=y
+CONFIG_OF_NET=y
+CONFIG_OF_PCI=y
+CONFIG_OF_PCI_IRQ=y
+CONFIG_OF_RESERVED_MEM=y
+CONFIG_OLD_SIGACTION=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PCI=y
+# CONFIG_PCIE_IPROC is not set
+# CONFIG_PCIE_IPROC_PLATFORM is not set
+CONFIG_PCI_BCM5301X=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PINCTRL=y
+# CONFIG_PINCTRL_AMD is not set
+# CONFIG_PL310_ERRATA_588369 is not set
+CONFIG_PL310_ERRATA_727915=y
+CONFIG_PL310_ERRATA_753970=y
+CONFIG_PL310_ERRATA_769419=y
+# CONFIG_RCU_EXPEDITE_BOOT is not set
+CONFIG_RCU_STALL_COMMON=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_SCHED_HRTICK=y
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_BCM53XX=y
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_GPIO=y
+CONFIG_SPI_MASTER=y
+CONFIG_SRCU=y
+CONFIG_STOP_MACHINE=y
+CONFIG_SWCONFIG=y
+CONFIG_SWIOTLB=y
+CONFIG_SWP_EMULATE=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TREE_RCU=y
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_XZ=y
+CONFIG_UBIFS_FS_ZLIB=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_USB_SUPPORT=y
+CONFIG_USE_OF=y
+# CONFIG_VDSO is not set
+CONFIG_VECTORS_BASE=0xffff0000
+# CONFIG_VFP is not set
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_XEN is not set
+CONFIG_XPS=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_BCJ=y
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZONE_DMA_FLAG=0
diff --git a/target/linux/bcm53xx/patches-4.1/058-ARM-BCM5301X-Add-USB-LED-for-Buffalo-WZR-1750DHP.patch b/target/linux/bcm53xx/patches-4.1/058-ARM-BCM5301X-Add-USB-LED-for-Buffalo-WZR-1750DHP.patch
new file mode 100644 (file)
index 0000000..290ea0a
--- /dev/null
@@ -0,0 +1,26 @@
+From 35ad0e50bd6683c6699586e3bd5045f0695586d9 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Wed, 13 May 2015 09:10:51 +0200
+Subject: [PATCH] ARM: BCM5301X: Add USB LED for Buffalo WZR-1750DHP
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+---
+ arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
++++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
+@@ -47,6 +47,12 @@
+       leds {
+               compatible = "gpio-leds";
++              usb {
++                      label = "bcm53xx:blue:usb";
++                      gpios = <&hc595 0 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-off";
++              };
++
+               power0 {
+                       label = "bcm53xx:red:power";
+                       gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
diff --git a/target/linux/bcm53xx/patches-4.1/059-ARM-BCM5301X-Add-DT-for-Buffalo-WXR-1900DHP.patch b/target/linux/bcm53xx/patches-4.1/059-ARM-BCM5301X-Add-DT-for-Buffalo-WXR-1900DHP.patch
new file mode 100644 (file)
index 0000000..e16d39b
--- /dev/null
@@ -0,0 +1,157 @@
+From 35eecd10ee57b9d4f31e12598296b235ed2b34ae Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Wed, 13 May 2015 09:10:52 +0200
+Subject: [PATCH] ARM: BCM5301X: Add DT for Buffalo WXR-1900DHP
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+---
+ arch/arm/boot/dts/Makefile                        |   1 +
+ arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts | 127 ++++++++++++++++++++++
+ 2 files changed, 128 insertions(+)
+ create mode 100644 arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
+
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -63,6 +63,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
+       bcm47081-asus-rt-n18u.dtb \
+       bcm47081-buffalo-wzr-600dhp2.dtb \
+       bcm47081-buffalo-wzr-900dhp.dtb \
++      bcm4709-buffalo-wxr-1900dhp.dtb \
+       bcm4709-netgear-r8000.dtb
+ dtb-$(CONFIG_ARCH_BCM_63XX) += \
+       bcm963138dvt.dtb
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
+@@ -0,0 +1,127 @@
++/*
++ * Broadcom BCM470X / BCM5301X ARM platform code.
++ * DTS for Buffalo WXR-1900DHP
++ *
++ * Copyright (C) 2015 Felix Fietkau <nbd@openwrt.org>
++ *
++ * Licensed under the GNU/GPL. See COPYING for details.
++ */
++
++/dts-v1/;
++
++#include "bcm4708.dtsi"
++
++/ {
++      compatible = "buffalo,wxr-1900dhp", "brcm,bcm4709", "brcm,bcm4708";
++      model = "Buffalo WXR-1900DHP";
++
++      chosen {
++              bootargs = "console=ttyS0,115200";
++      };
++
++      memory {
++              reg = <0x00000000 0x08000000>;
++      };
++
++      leds {
++              compatible = "gpio-leds";
++
++              usb {
++                      label = "bcm53xx:green:usb";
++                      gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-off";
++              };
++
++              power-amber {
++                      label = "bcm53xx:amber:power";
++                      gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-off";
++              };
++
++              power-white {
++                      label = "bcm53xx:white:power";
++                      gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-on";
++              };
++
++              router-amber {
++                      label = "bcm53xx:amber:router";
++                      gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-off";
++              };
++
++              router-white {
++                      label = "bcm53xx:white:router";
++                      gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-off";
++              };
++
++              wan-amber {
++                      label = "bcm53xx:amber:wan";
++                      gpios = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-off";
++              };
++
++              wan-white {
++                      label = "bcm53xx:white:wan";
++                      gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-off";
++              };
++
++              wireless-amber {
++                      label = "bcm53xx:amber:wireless";
++                      gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-off";
++              };
++
++              wireless-white {
++                      label = "bcm53xx:white:wireless";
++                      gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-off";
++              };
++      };
++
++      gpio-keys {
++              compatible = "gpio-keys";
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              power {
++                      label = "Power";
++                      linux,code = <KEY_POWER>;
++                      gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
++              };
++
++              restart {
++                      label = "Reset";
++                      linux,code = <KEY_RESTART>;
++                      gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
++              };
++
++              aoss {
++                      label = "AOSS";
++                      linux,code = <KEY_WPS_BUTTON>;
++                      gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
++              };
++
++              /* Commit mode set by switch? */
++              mode {
++                      label = "Mode";
++                      linux,code = <KEY_SETUP>;
++                      gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
++              };
++
++              /* Switch: AP mode */
++              sw_ap {
++                      label = "AP";
++                      linux,code = <BTN_0>;
++                      gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
++              };
++
++              eject {
++                      label = "USB eject";
++                      linux,code = <KEY_EJECTCD>;
++                      gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
++              };
++      };
++};
diff --git a/target/linux/bcm53xx/patches-4.1/060-ARM-BCM5301X-Add-DT-for-SmartRG-SR400ac.patch b/target/linux/bcm53xx/patches-4.1/060-ARM-BCM5301X-Add-DT-for-SmartRG-SR400ac.patch
new file mode 100644 (file)
index 0000000..dafae7b
--- /dev/null
@@ -0,0 +1,148 @@
+From 691917f20cae813d242f7123a4dc97e7d48e6ff1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Wed, 13 May 2015 09:10:53 +0200
+Subject: [PATCH] ARM: BCM5301X: Add DT for SmartRG SR400ac
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+---
+ arch/arm/boot/dts/Makefile                    |   1 +
+ arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts | 119 ++++++++++++++++++++++++++
+ 2 files changed, 120 insertions(+)
+ create mode 100644 arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
+
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -60,6 +60,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
+       bcm4708-luxul-xwc-1000.dtb \
+       bcm4708-netgear-r6250.dtb \
+       bcm4708-netgear-r6300-v2.dtb \
++      bcm4708-smartrg-sr400ac.dtb \
+       bcm47081-asus-rt-n18u.dtb \
+       bcm47081-buffalo-wzr-600dhp2.dtb \
+       bcm47081-buffalo-wzr-900dhp.dtb \
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
+@@ -0,0 +1,119 @@
++/*
++ * Broadcom BCM470X / BCM5301X arm platform code.
++ * DTS for SmartRG SR400ac
++ *
++ * Copyright (C) 2015 Rafał Miłecki <zajec5@gmail.com>
++ *
++ * Licensed under the GNU/GPL. See COPYING for details.
++ */
++
++/dts-v1/;
++
++#include "bcm4708.dtsi"
++
++/ {
++      compatible = "smartrg,sr400ac", "brcm,bcm4708";
++      model = "SmartRG SR400ac";
++
++      chosen {
++              bootargs = "console=ttyS0,115200";
++      };
++
++      memory {
++              reg = <0x00000000 0x08000000>;
++      };
++
++      leds {
++              compatible = "gpio-leds";
++
++              power-white {
++                      label = "bcm53xx:white:power";
++                      gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-on";
++              };
++
++              power-amber {
++                      label = "bcm53xx:amber:power";
++                      gpios = <&chipcommon 2 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-off";
++              };
++
++              usb2 {
++                      label = "bcm53xx:white:usb2";
++                      gpios = <&chipcommon 3 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-off";
++              };
++
++              usb3-white {
++                      label = "bcm53xx:white:usb3";
++                      gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-off";
++              };
++
++              usb3-green {
++                      label = "bcm53xx:green:usb3";
++                      gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-off";
++              };
++
++              wps {
++                      label = "bcm53xx:white:wps";
++                      gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-off";
++              };
++
++              status-red {
++                      label = "bcm53xx:red:status";
++                      gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-off";
++              };
++
++              status-green {
++                      label = "bcm53xx:green:status";
++                      gpios = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-off";
++              };
++
++              status-blue {
++                      label = "bcm53xx:blue:status";
++                      gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-off";
++              };
++
++              wan-white {
++                      label = "bcm53xx:white:wan";
++                      gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-off";
++              };
++
++              wan-red {
++                      label = "bcm53xx:red:wan";
++                      gpios = <&chipcommon 13 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "default-off";
++              };
++      };
++
++      gpio-keys {
++              compatible = "gpio-keys";
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              rfkill {
++                      label = "WiFi";
++                      linux,code = <KEY_RFKILL>;
++                      gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
++              };
++
++              wps {
++                      label = "WPS";
++                      linux,code = <KEY_WPS_BUTTON>;
++                      gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
++              };
++
++              restart {
++                      label = "Reset";
++                      linux,code = <KEY_RESTART>;
++                      gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
++              };
++      };
++};
diff --git a/target/linux/bcm53xx/patches-4.1/061-ARM-BCM5301X-Add-DT-for-Asus-RT-AC68U.patch b/target/linux/bcm53xx/patches-4.1/061-ARM-BCM5301X-Add-DT-for-Asus-RT-AC68U.patch
new file mode 100644 (file)
index 0000000..02e644e
--- /dev/null
@@ -0,0 +1,112 @@
+From b5f350c790ae6aaf3dda5a825d7e3fdeed731164 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Sat, 28 Mar 2015 15:01:38 +0100
+Subject: [PATCH] ARM: BCM5301X: Add DT for Asus RT-AC68U
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+---
+ arch/arm/boot/dts/Makefile                  |  1 +
+ arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts | 83 +++++++++++++++++++++++++++++
+ 2 files changed, 84 insertions(+)
+ create mode 100644 arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
+
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -56,6 +56,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
+       bcm2835-rpi-b.dtb \
+       bcm2835-rpi-b-plus.dtb
+ dtb-$(CONFIG_ARCH_BCM_5301X) += \
++      bcm4708-asus-rt-ac68u.dtb \
+       bcm4708-buffalo-wzr-1750dhp.dtb \
+       bcm4708-luxul-xwc-1000.dtb \
+       bcm4708-netgear-r6250.dtb \
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
+@@ -0,0 +1,83 @@
++/*
++ * Broadcom BCM470X / BCM5301X ARM platform code.
++ * DTS for Asus RT-AC68U
++ *
++ * Copyright (C) 2015 Rafał Miłecki <zajec5@gmail.com>
++ *
++ * Licensed under the GNU/GPL. See COPYING for details.
++ */
++
++/dts-v1/;
++
++#include "bcm4708.dtsi"
++
++/ {
++      compatible = "asus,rt-ac68u", "brcm,bcm4708";
++      model = "Asus RT-AC68U (BCM4708)";
++
++      chosen {
++              bootargs = "console=ttyS0,115200";
++      };
++
++      memory {
++              reg = <0x00000000 0x08000000>;
++      };
++
++      leds {
++              compatible = "gpio-leds";
++
++              usb2 {
++                      label = "bcm53xx:blue:usb2";
++                      gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
++                      linux,default-trigger = "default-off";
++              };
++
++              power {
++                      label = "bcm53xx:blue:power";
++                      gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
++                      linux,default-trigger = "default-on";
++              };
++
++              logo {
++                      label = "bcm53xx:white:logo";
++                      gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
++                      linux,default-trigger = "default-on";
++              };
++
++              usb3 {
++                      label = "bcm53xx:blue:usb3";
++                      gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
++                      linux,default-trigger = "default-off";
++              };
++      };
++
++      gpio-keys {
++              compatible = "gpio-keys";
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              brightness {
++                      label = "Backlight";
++                      linux,code = <KEY_BRIGHTNESS_ZERO>;
++                      gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
++              };
++
++              wps {
++                      label = "WPS";
++                      linux,code = <KEY_WPS_BUTTON>;
++                      gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
++              };
++
++              restart {
++                      label = "Reset";
++                      linux,code = <KEY_RESTART>;
++                      gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
++              };
++
++              rfkill {
++                      label = "WiFi";
++                      linux,code = <KEY_RFKILL>;
++                      gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
++              };
++      };
++};
diff --git a/target/linux/bcm53xx/patches-4.1/062-ARM-BCM5301X-Add-DT-for-Asus-RT-AC56U.patch b/target/linux/bcm53xx/patches-4.1/062-ARM-BCM5301X-Add-DT-for-Asus-RT-AC56U.patch
new file mode 100644 (file)
index 0000000..e72835b
--- /dev/null
@@ -0,0 +1,125 @@
+From 16dc3bac722252a10e396546f44135ae1b6a7ff3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Tue, 31 Mar 2015 17:29:18 +0200
+Subject: [PATCH] ARM: BCM5301X: Add DT for Asus RT-AC56U
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+---
+ arch/arm/boot/dts/Makefile                  |  1 +
+ arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts | 96 +++++++++++++++++++++++++++++
+ 2 files changed, 97 insertions(+)
+ create mode 100644 arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
+
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -56,6 +56,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
+       bcm2835-rpi-b.dtb \
+       bcm2835-rpi-b-plus.dtb
+ dtb-$(CONFIG_ARCH_BCM_5301X) += \
++      bcm4708-asus-rt-ac56u.dtb \
+       bcm4708-asus-rt-ac68u.dtb \
+       bcm4708-buffalo-wzr-1750dhp.dtb \
+       bcm4708-luxul-xwc-1000.dtb \
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
+@@ -0,0 +1,96 @@
++/*
++ * Broadcom BCM470X / BCM5301X ARM platform code.
++ * DTS for Asus RT-AC56U
++ *
++ * Copyright (C) 2015 Rafał Miłecki <zajec5@gmail.com>
++ *
++ * Licensed under the GNU/GPL. See COPYING for details.
++ */
++
++/dts-v1/;
++
++#include "bcm4708.dtsi"
++
++/ {
++      compatible = "asus,rt-ac56u", "brcm,bcm4708";
++      model = "Asus RT-AC56U (BCM4708)";
++
++      chosen {
++              bootargs = "console=ttyS0,115200";
++      };
++
++      memory {
++              reg = <0x00000000 0x08000000>;
++      };
++
++      leds {
++              compatible = "gpio-leds";
++
++              usb3 {
++                      label = "bcm53xx:blue:usb3";
++                      gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
++                      linux,default-trigger = "default-off";
++              };
++
++              wan {
++                      label = "bcm53xx:blue:wan";
++                      gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
++                      linux,default-trigger = "default-off";
++              };
++
++              lan {
++                      label = "bcm53xx:blue:lan";
++                      gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
++                      linux,default-trigger = "default-off";
++              };
++
++              power {
++                      label = "bcm53xx:blue:power";
++                      gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
++                      linux,default-trigger = "default-on";
++              };
++
++              all {
++                      label = "bcm53xx:blue:all";
++                      gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
++                      linux,default-trigger = "default-on";
++              };
++
++              2ghz {
++                      label = "bcm53xx:blue:2ghz";
++                      gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
++                      linux,default-trigger = "default-off";
++              };
++
++
++              usb2 {
++                      label = "bcm53xx:blue:usb2";
++                      gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
++                      linux,default-trigger = "default-off";
++              };
++      };
++
++      gpio-keys {
++              compatible = "gpio-keys";
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              rfkill {
++                      label = "WiFi";
++                      linux,code = <KEY_RFKILL>;
++                      gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
++              };
++
++              restart {
++                      label = "Reset";
++                      linux,code = <KEY_RESTART>;
++                      gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
++              };
++
++              wps {
++                      label = "WPS";
++                      linux,code = <KEY_WPS_BUTTON>;
++                      gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
++              };
++      };
++};
diff --git a/target/linux/bcm53xx/patches-4.1/063-ARM-BCM5301X-Ignore-another-BCM4709-specific-fault-c.patch b/target/linux/bcm53xx/patches-4.1/063-ARM-BCM5301X-Ignore-another-BCM4709-specific-fault-c.patch
new file mode 100644 (file)
index 0000000..8716a0d
--- /dev/null
@@ -0,0 +1,41 @@
+From 7eb68a2a0519a77b93184c695d4d293c92dc2286 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Wed, 11 Feb 2015 16:40:58 +0100
+Subject: [PATCH] ARM: BCM5301X: Ignore another (BCM4709 specific) fault code
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Broadcom ARM devices seem to generate some fault once per boot. We
+already have an ignoring handler for BCM4707/BCM4708, but BCM4709
+generates different code.
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+---
+ arch/arm/mach-bcm/bcm_5301x.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/arch/arm/mach-bcm/bcm_5301x.c
++++ b/arch/arm/mach-bcm/bcm_5301x.c
+@@ -18,15 +18,16 @@ static bool first_fault = true;
+ static int bcm5301x_abort_handler(unsigned long addr, unsigned int fsr,
+                                struct pt_regs *regs)
+ {
+-      if (fsr == 0x1c06 && first_fault) {
++      if ((fsr == 0x1406 || fsr == 0x1c06) && first_fault) {
+               first_fault = false;
+               /*
+-               * These faults with code 0x1c06 happens for no good reason,
+-               * possibly left over from the CFE boot loader.
++               * These faults with codes 0x1406 (BCM4709) or 0x1c06 happens
++               * for no good reason, possibly left over from the CFE boot
++               * loader.
+                */
+               pr_warn("External imprecise Data abort at addr=%#lx, fsr=%#x ignored.\n",
+-              addr, fsr);
++                      addr, fsr);
+               /* Returning non-zero causes fault display and panic */
+               return 0;
diff --git a/target/linux/bcm53xx/patches-4.1/064-ARM-BCM5301X-add-NAND-flash-chip-description.patch b/target/linux/bcm53xx/patches-4.1/064-ARM-BCM5301X-add-NAND-flash-chip-description.patch
new file mode 100644 (file)
index 0000000..aa99f37
--- /dev/null
@@ -0,0 +1,210 @@
+From 9faa5960eef3204cae6637b530f5e23e53b5a9ef Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Fri, 29 May 2015 23:39:47 +0200
+Subject: [PATCH] ARM: BCM5301X: add NAND flash chip description
+
+This adds the NAND flash chip description for a standard chip found
+connected to this SoC. This makes use of generic Broadcom NAND driver
+with the iProc interface.
+
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+---
+ arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts        |  1 +
+ arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts        |  1 +
+ arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts  |  1 +
+ arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts       |  9 +++-----
+ arch/arm/boot/dts/bcm4708-netgear-r6250.dts        |  1 +
+ arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts     |  1 +
+ arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts      |  1 +
+ arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts        |  1 +
+ arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts |  1 +
+ arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts  |  1 +
+ arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts  |  1 +
+ arch/arm/boot/dts/bcm4709-netgear-r8000.dts        |  1 +
+ arch/arm/boot/dts/bcm5301x-nand-cs0-bch8.dtsi      | 24 ++++++++++++++++++++++
+ arch/arm/boot/dts/bcm5301x.dtsi                    | 12 +++++++++++
+ 14 files changed, 50 insertions(+), 6 deletions(-)
+ create mode 100644 arch/arm/boot/dts/bcm5301x-nand-cs0-bch8.dtsi
+
+--- a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
++++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
+@@ -10,6 +10,7 @@
+ /dts-v1/;
+ #include "bcm4708.dtsi"
++#include "bcm5301x-nand-cs0-bch8.dtsi"
+ / {
+       compatible = "asus,rt-ac56u", "brcm,bcm4708";
+--- a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
++++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
+@@ -10,6 +10,7 @@
+ /dts-v1/;
+ #include "bcm4708.dtsi"
++#include "bcm5301x-nand-cs0-bch8.dtsi"
+ / {
+       compatible = "asus,rt-ac68u", "brcm,bcm4708";
+--- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
++++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
+@@ -10,6 +10,7 @@
+ /dts-v1/;
+ #include "bcm4708.dtsi"
++#include "bcm5301x-nand-cs0-bch8.dtsi"
+ / {
+       compatible = "buffalo,wzr-1750dhp", "brcm,bcm4708";
+--- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
++++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
+@@ -10,6 +10,7 @@
+ /dts-v1/;
+ #include "bcm4708.dtsi"
++#include "bcm5301x-nand-cs0-bch8.dtsi"
+ / {
+       compatible = "luxul,xwc-1000", "brcm,bcm4708";
+@@ -23,12 +24,8 @@
+               reg = <0x00000000 0x08000000>;
+       };
+-      axi@18000000 {
+-              nand@28000 {
+-                      reg = <0x00028000 0x1000>;
+-                      #address-cells = <1>;
+-                      #size-cells = <1>;
+-
++      nand: nand@18028000 {
++              nandcs@0 {
+                       partition@0 {
+                               label = "ubi";
+                               reg = <0x00000000 0x08000000>;
+--- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
++++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
+@@ -10,6 +10,7 @@
+ /dts-v1/;
+ #include "bcm4708.dtsi"
++#include "bcm5301x-nand-cs0-bch8.dtsi"
+ / {
+       compatible = "netgear,r6250v1", "brcm,bcm4708";
+--- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
++++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
+@@ -10,6 +10,7 @@
+ /dts-v1/;
+ #include "bcm4708.dtsi"
++#include "bcm5301x-nand-cs0-bch8.dtsi"
+ / {
+       compatible = "netgear,r6300v2", "brcm,bcm4708";
+--- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
++++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
+@@ -10,6 +10,7 @@
+ /dts-v1/;
+ #include "bcm4708.dtsi"
++#include "bcm5301x-nand-cs0-bch8.dtsi"
+ / {
+       compatible = "smartrg,sr400ac", "brcm,bcm4708";
+--- a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
++++ b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
+@@ -10,6 +10,7 @@
+ /dts-v1/;
+ #include "bcm47081.dtsi"
++#include "bcm5301x-nand-cs0-bch8.dtsi"
+ / {
+       compatible = "asus,rt-n18u", "brcm,bcm47081", "brcm,bcm4708";
+--- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
++++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
+@@ -10,6 +10,7 @@
+ /dts-v1/;
+ #include "bcm47081.dtsi"
++#include "bcm5301x-nand-cs0-bch8.dtsi"
+ / {
+       compatible = "buffalo,wzr-600dhp2", "brcm,bcm47081", "brcm,bcm4708";
+--- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
++++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
+@@ -10,6 +10,7 @@
+ /dts-v1/;
+ #include "bcm47081.dtsi"
++#include "bcm5301x-nand-cs0-bch8.dtsi"
+ / {
+       compatible = "buffalo,wzr-900dhp", "brcm,bcm47081", "brcm,bcm4708";
+--- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
++++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
+@@ -10,6 +10,7 @@
+ /dts-v1/;
+ #include "bcm4708.dtsi"
++#include "bcm5301x-nand-cs0-bch8.dtsi"
+ / {
+       compatible = "buffalo,wxr-1900dhp", "brcm,bcm4709", "brcm,bcm4708";
+--- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
++++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
+@@ -10,6 +10,7 @@
+ /dts-v1/;
+ #include "bcm4708.dtsi"
++#include "bcm5301x-nand-cs0-bch8.dtsi"
+ / {
+       compatible = "netgear,r8000", "brcm,bcm4709", "brcm,bcm4708";
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm5301x-nand-cs0-bch8.dtsi
+@@ -0,0 +1,24 @@
++/*
++ * Broadcom BCM470X / BCM5301X Nand chip defaults.
++ *
++ * This should be included if the NAND controller is on chip select 0
++ * and uses 8 bit ECC.
++ *
++ * Copyright (C) 2015 Hauke Mehrtens <hauke@hauke-m.de>
++ *
++ * Licensed under the GNU/GPL. See COPYING for details.
++ */
++
++/ {
++      nand@18028000 {
++              nandcs@0 {
++                      compatible = "brcm,nandcs";
++                      reg = <0>;
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      nand-ecc-strength = <8>;
++                      nand-ecc-step-size = <512>;
++              };
++      };
++};
+--- a/arch/arm/boot/dts/bcm5301x.dtsi
++++ b/arch/arm/boot/dts/bcm5301x.dtsi
+@@ -143,4 +143,16 @@
+                       #gpio-cells = <2>;
+               };
+       };
++
++      nand: nand@18028000 {
++              compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1", "brcm,brcmnand";
++              reg = <0x18028000 0x600>, <0x1811a408 0x600>, <0x18028f00 0x20>;
++              reg-names = "nand", "iproc-idm", "iproc-ext";
++              interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
++
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              brcm,nand-has-wp;
++      };
+ };
diff --git a/target/linux/bcm53xx/patches-4.1/065-ARM-BCM5301X-add-IRQ-numbers-for-PCIe-controller.patch b/target/linux/bcm53xx/patches-4.1/065-ARM-BCM5301X-add-IRQ-numbers-for-PCIe-controller.patch
new file mode 100644 (file)
index 0000000..1422115
--- /dev/null
@@ -0,0 +1,48 @@
+From 1f80de6863ca0e36cabc622e858168fe5beb1e92 Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Sun, 24 May 2015 21:08:14 +0200
+Subject: [PATCH] ARM: BCM5301X: add IRQ numbers for PCIe controller
+
+The driver for the PCIe controller was just added, this adds the
+missing definition of the IRQ numbers to device tree. The driver itself
+will be automatically detected by bcma.
+
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+---
+ arch/arm/boot/dts/bcm5301x.dtsi | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+--- a/arch/arm/boot/dts/bcm5301x.dtsi
++++ b/arch/arm/boot/dts/bcm5301x.dtsi
+@@ -108,6 +108,30 @@
+                       /* ChipCommon */
+                       <0x00000000 0 &gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
++                      /* PCIe Controller 0 */
++                      <0x00012000 0 &gic GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
++                      <0x00012000 1 &gic GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
++                      <0x00012000 2 &gic GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
++                      <0x00012000 3 &gic GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
++                      <0x00012000 4 &gic GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
++                      <0x00012000 5 &gic GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
++
++                      /* PCIe Controller 1 */
++                      <0x00013000 0 &gic GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
++                      <0x00013000 1 &gic GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
++                      <0x00013000 2 &gic GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
++                      <0x00013000 3 &gic GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
++                      <0x00013000 4 &gic GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
++                      <0x00013000 5 &gic GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
++
++                      /* PCIe Controller 2 */
++                      <0x00014000 0 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
++                      <0x00014000 1 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
++                      <0x00014000 2 &gic GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
++                      <0x00014000 3 &gic GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
++                      <0x00014000 4 &gic GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
++                      <0x00014000 5 &gic GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
++
+                       /* USB 2.0 Controller */
+                       <0x00021000 0 &gic GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/target/linux/bcm53xx/patches-4.1/066-ARM-BCM5301X-Add-DT-for-Asus-RT-AC87U.patch b/target/linux/bcm53xx/patches-4.1/066-ARM-BCM5301X-Add-DT-for-Asus-RT-AC87U.patch
new file mode 100644 (file)
index 0000000..5790c9a
--- /dev/null
@@ -0,0 +1,95 @@
+From 26343bdacfcdbf6ee3303d6078a015b908f90193 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Sat, 16 May 2015 16:55:39 +0200
+Subject: [PATCH] ARM: BCM5301X: Add DT for Asus RT-AC87U
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+---
+ arch/arm/boot/dts/Makefile                  |  1 +
+ arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts | 65 +++++++++++++++++++++++++++++
+ 2 files changed, 66 insertions(+)
+ create mode 100644 arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
+
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -66,6 +66,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
+       bcm47081-asus-rt-n18u.dtb \
+       bcm47081-buffalo-wzr-600dhp2.dtb \
+       bcm47081-buffalo-wzr-900dhp.dtb \
++      bcm4709-asus-rt-ac87u.dtb \
+       bcm4709-buffalo-wxr-1900dhp.dtb \
+       bcm4709-netgear-r8000.dtb
+ dtb-$(CONFIG_ARCH_BCM_63XX) += \
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
+@@ -0,0 +1,65 @@
++/*
++ * Broadcom BCM470X / BCM5301X ARM platform code.
++ * DTS for Asus RT-AC87U
++ *
++ * Copyright (C) 2015 Rafał Miłecki <zajec5@gmail.com>
++ *
++ * Licensed under the GNU/GPL. See COPYING for details.
++ */
++
++/dts-v1/;
++
++#include "bcm4708.dtsi"
++
++/ {
++      compatible = "asus,rt-ac87u", "brcm,bcm4709", "brcm,bcm4708";
++      model = "Asus RT-AC87U";
++
++      chosen {
++              bootargs = "console=ttyS0,115200";
++      };
++
++      memory {
++              reg = <0x00000000 0x08000000>;
++      };
++
++      leds {
++              compatible = "gpio-leds";
++
++              wps {
++                      label = "bcm53xx:blue:wps";
++                      gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
++                      linux,default-trigger = "default-off";
++              };
++
++              power {
++                      label = "bcm53xx:blue:power";
++                      gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
++                      linux,default-trigger = "default-on";
++              };
++
++              wan {
++                      label = "bcm53xx:red:wan";
++                      gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
++                      linux,default-trigger = "default-off";
++              };
++      };
++
++      gpio-keys {
++              compatible = "gpio-keys";
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              wps {
++                      label = "WPS";
++                      linux,code = <KEY_WPS_BUTTON>;
++                      gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
++              };
++
++              restart {
++                      label = "Reset";
++                      linux,code = <KEY_RESTART>;
++                      gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
++              };
++      };
++};
diff --git a/target/linux/bcm53xx/patches-4.1/110-firmware-backport-NVRAM-driver.patch b/target/linux/bcm53xx/patches-4.1/110-firmware-backport-NVRAM-driver.patch
new file mode 100644 (file)
index 0000000..5e944b0
--- /dev/null
@@ -0,0 +1,49 @@
+From 0509f6dcc46d10ea4bb8c70494dc7ae11bcb3f01 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Wed, 10 Dec 2014 21:14:10 +0100
+Subject: [PATCH] firmware: backport NVRAM driver
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+ arch/arm/Kconfig                      | 2 ++
+ drivers/firmware/Kconfig              | 1 +
+ drivers/firmware/Makefile             | 1 +
+ drivers/net/ethernet/broadcom/b44.c   | 2 +-
+ drivers/net/ethernet/broadcom/bgmac.c | 2 +-
+ drivers/ssb/driver_chipcommon_pmu.c   | 2 +-
+ 6 files changed, 7 insertions(+), 3 deletions(-)
+
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -2105,6 +2105,8 @@ source "drivers/Kconfig"
+ source "drivers/firmware/Kconfig"
++source "drivers/firmware/Kconfig"
++
+ source "fs/Kconfig"
+ source "arch/arm/Kconfig.debug"
+--- a/drivers/firmware/Kconfig
++++ b/drivers/firmware/Kconfig
+@@ -136,6 +136,7 @@ config QCOM_SCM
+       bool
+       depends on ARM || ARM64
++source "drivers/firmware/broadcom/Kconfig"
+ source "drivers/firmware/google/Kconfig"
+ source "drivers/firmware/efi/Kconfig"
+--- a/drivers/firmware/Makefile
++++ b/drivers/firmware/Makefile
+@@ -14,6 +14,7 @@ obj-$(CONFIG_FIRMWARE_MEMMAP)        += memmap.
+ obj-$(CONFIG_QCOM_SCM)                += qcom_scm.o
+ CFLAGS_qcom_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
++obj-y                         += broadcom/
+ obj-$(CONFIG_GOOGLE_FIRMWARE) += google/
+ obj-$(CONFIG_EFI)             += efi/
+ obj-$(CONFIG_UEFI_CPER)               += efi/
diff --git a/target/linux/bcm53xx/patches-4.1/112-bcm53xx-sprom-add-sprom-driver.patch b/target/linux/bcm53xx/patches-4.1/112-bcm53xx-sprom-add-sprom-driver.patch
new file mode 100644 (file)
index 0000000..b914fd9
--- /dev/null
@@ -0,0 +1,69 @@
+From 4e0ab3269a6d260a41a3673157753147f5f71341 Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Sun, 4 May 2014 13:19:20 +0200
+Subject: [PATCH 03/17] bcm47xx-sprom: add Broadcom sprom parser driver
+
+This driver needs an nvram driver and fetches the sprom values from the
+nvram and provides it to any other driver. The calibration data for the
+wifi chip the mac address and some more board description data is
+stores in the sprom.
+
+This is based on a copy of arch/mips/bcm47xx/sprom.c and my plan is to
+make the bcm47xx MIPS SoCs also use this driver some time later.
+
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+---
+ .../devicetree/bindings/misc/bcm47xx-sprom.txt     |  16 +
+ drivers/misc/Kconfig                               |  11 +
+ drivers/misc/Makefile                              |   1 +
+ drivers/misc/bcm47xx-sprom.c                       | 690 +++++++++++++++++++++
+ 4 files changed, 718 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/misc/bcm47xx-sprom.txt
+ create mode 100644 drivers/misc/bcm47xx-sprom.c
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/misc/bcm47xx-sprom.txt
+@@ -0,0 +1,16 @@
++Broadcom bcm47xx/bcm53xx sprom converter
++
++This driver provbides an sprom based on a given nvram.
++
++Required properties:
++
++- compatible : brcm,bcm47xx-sprom
++
++- nvram : reference to a nvram driver, e.g. bcm47xx-nvram
++
++Example:
++
++sprom0: sprom@0 {
++      compatible = "brcm,bcm47xx-sprom";
++      nvram = <&nvram0>;
++};
+--- a/drivers/misc/Kconfig
++++ b/drivers/misc/Kconfig
+@@ -515,6 +515,17 @@ config VEXPRESS_SYSCFG
+         bus. System Configuration interface is one of the possible means
+         of generating transactions on this bus.
++config BCM47XX_SPROM
++      tristate "BCM47XX sprom driver"
++      help
++        This driver parses the sprom from a given nvram which is found on
++        Broadcom bcm47xx and bcm53xx SoCs.
++
++        The sprom contains board configuration data like the
++        calibration data fro the wifi chips, the mac addresses used
++        by the board and many other board configuration data. This
++        driver will provide the sprom to bcma.
++
+ source "drivers/misc/c2port/Kconfig"
+ source "drivers/misc/eeprom/Kconfig"
+ source "drivers/misc/cb710/Kconfig"
+--- a/drivers/misc/Makefile
++++ b/drivers/misc/Makefile
+@@ -56,3 +56,4 @@ obj-$(CONFIG_GENWQE)         += genwqe/
+ obj-$(CONFIG_ECHO)            += echo/
+ obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o
+ obj-$(CONFIG_CXL_BASE)                += cxl/
++obj-$(CONFIG_BCM47XX_SPROM)   += bcm47xx-sprom.o
diff --git a/target/linux/bcm53xx/patches-4.1/131-ARM-BCM5301X-Implement-SMP-support.patch b/target/linux/bcm53xx/patches-4.1/131-ARM-BCM5301X-Implement-SMP-support.patch
new file mode 100644 (file)
index 0000000..bdc7dea
--- /dev/null
@@ -0,0 +1,314 @@
+From 707ab07695ea8953a5bb56512e7bb38ca79c5c38 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Thu, 19 Feb 2015 23:27:59 +0100
+Subject: [PATCH V2] ARM: BCM5301X: Implement SMP support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+V2: Change code after receiving Florian's comments:
+    1) Use "mmio-sram"
+    2) Remove commented out ASM call
+    3) Fix coding style in ASM
+    4) Simplify finding OF node
+---
+ Documentation/devicetree/bindings/arm/bcm4708.txt |  24 ++++
+ Documentation/devicetree/bindings/arm/cpus.txt    |   1 +
+ arch/arm/boot/dts/bcm4708.dtsi                    |  13 ++
+ arch/arm/mach-bcm/Makefile                        |   3 +
+ arch/arm/mach-bcm/bcm5301x_headsmp.S              |  45 ++++++
+ arch/arm/mach-bcm/bcm5301x_smp.c                  | 158 ++++++++++++++++++++++
+ 6 files changed, 244 insertions(+)
+ create mode 100644 arch/arm/mach-bcm/bcm5301x_headsmp.S
+ create mode 100644 arch/arm/mach-bcm/bcm5301x_smp.c
+
+--- a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm4708.txt
++++ b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm4708.txt
+@@ -6,3 +6,27 @@ Boards with the BCM4708 SoC shall have t
+ Required root node property:
+ compatible = "brcm,bcm4708";
++
++Optional sub-node properties:
++
++compatible = "mmio-sram" for SRAM access with IO memory region
++              This is needed for SMP-capable SoCs which use part of
++              SRAM for storing location of code to be executed by the
++              extra cores.
++              SMP support requires another sub-node with compatible
++              property "brcm,bcm4708-sysram".
++
++Example:
++
++      sysram@ffff0000 {
++              compatible = "mmio-sram";
++              reg = <0xffff0000 0x10000>;
++              #address-cells = <1>;
++              #size-cells = <1>;
++              ranges = <0 0xffff0000 0x10000>;
++
++              smp-sysram@0 {
++                      compatible = "brcm,bcm4708-sysram";
++                      reg = <0x0 0x1000>;
++              };
++      };
+--- a/Documentation/devicetree/bindings/arm/cpus.txt
++++ b/Documentation/devicetree/bindings/arm/cpus.txt
+@@ -189,6 +189,7 @@ nodes to be present and contain the prop
+                         can be one of:
+                           "allwinner,sun6i-a31"
+                           "arm,psci"
++                          "brcm,bcm4708-smp"
+                           "brcm,brahma-b15"
+                           "marvell,armada-375-smp"
+                           "marvell,armada-380-smp"
+--- a/arch/arm/boot/dts/bcm4708.dtsi
++++ b/arch/arm/boot/dts/bcm4708.dtsi
+@@ -15,6 +15,7 @@
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
++              enable-method = "brcm,bcm4708-smp";
+               cpu@0 {
+                       device_type = "cpu";
+@@ -31,4 +32,16 @@
+               };
+       };
++      sysram@ffff0000 {
++              compatible = "mmio-sram";
++              reg = <0xffff0000 0x10000>;
++              #address-cells = <1>;
++              #size-cells = <1>;
++              ranges = <0 0xffff0000 0x10000>;
++
++              smp-sysram@0 {
++                      compatible = "brcm,bcm4708-sysram";
++                      reg = <0x0 0x1000>;
++              };
++      };
+ };
+--- a/arch/arm/mach-bcm/Makefile
++++ b/arch/arm/mach-bcm/Makefile
+@@ -36,6 +36,9 @@ obj-$(CONFIG_ARCH_BCM2835)   += board_bcm2
+ # BCM5301X
+ obj-$(CONFIG_ARCH_BCM_5301X)  += bcm_5301x.o
++ifeq ($(CONFIG_SMP),y)
++obj-$(CONFIG_ARCH_BCM_5301X)  += bcm5301x_smp.o bcm5301x_headsmp.o
++endif
+ # BCM63XXx
+ obj-$(CONFIG_ARCH_BCM_63XX)   := bcm63xx.o
+--- /dev/null
++++ b/arch/arm/mach-bcm/bcm5301x_headsmp.S
+@@ -0,0 +1,45 @@
++/*
++ * Broadcom BCM470X / BCM5301X ARM platform code.
++ *
++ * Copyright (c) 2003 ARM Limited
++ * All Rights Reserved
++ *
++ * Licensed under the GNU/GPL. See COPYING for details.
++ */
++#include <linux/linkage.h>
++
++/*
++ * BCM5301X specific entry point for secondary CPUs.
++ */
++ENTRY(bcm5301x_secondary_startup)
++      mrc     p15, 0, r0, c0, c0, 5
++      and     r0, r0, #15
++      adr     r4, 1f
++      ldmia   r4, {r5, r6}
++      sub     r4, r4, r5
++      add     r6, r6, r4
++pen:  ldr     r7, [r6]
++      cmp     r7, r0
++      bne     pen
++
++      /*
++       * In case L1 cache has unpredictable contents at power-up
++       * clean its contents without flushing.
++       */
++      bl      v7_invalidate_l1
++
++      mov     r0, #0
++      mcr     p15, 0, r0, c7, c5, 0   /* Invalidate icache */
++      dsb
++      isb
++
++      /*
++       * we've been released from the holding pen: secondary_stack
++       * should now contain the SVC stack for this core
++       */
++      b       secondary_startup
++ENDPROC(bcm5301x_secondary_startup)
++
++      .align 2
++1:    .long   .
++      .long   pen_release
+--- /dev/null
++++ b/arch/arm/mach-bcm/bcm5301x_smp.c
+@@ -0,0 +1,158 @@
++/*
++ * Broadcom BCM470X / BCM5301X ARM platform code.
++ *
++ * Copyright (C) 2002 ARM Ltd.
++ * Copyright (C) 2015 Rafał Miłecki <zajec5@gmail.com>
++ *
++ * Licensed under the GNU/GPL. See COPYING for details.
++ */
++
++#include <asm/cacheflush.h>
++#include <asm/delay.h>
++#include <asm/smp_plat.h>
++#include <asm/smp_scu.h>
++
++#include <linux/clockchips.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++
++#define SOC_ROM_LUT_OFF               0x400
++
++extern void bcm5301x_secondary_startup(void);
++
++static void __cpuinit write_pen_release(int val)
++{
++      pen_release = val;
++      smp_wmb();
++      sync_cache_w(&pen_release);
++}
++
++static DEFINE_SPINLOCK(boot_lock);
++
++static void __init bcm5301x_smp_secondary_set_entry(void (*entry_point)(void))
++{
++      void __iomem *sysram_base_addr = NULL;
++      struct device_node *node;
++
++      node = of_find_compatible_node(NULL, NULL, "brcm,bcm4708-sysram");
++      if (!of_device_is_available(node))
++              return;
++
++      sysram_base_addr = of_iomap(node, 0);
++      if (!sysram_base_addr) {
++              pr_warn("Failed to map sysram\n");
++              return;
++      }
++
++      writel(virt_to_phys(entry_point), sysram_base_addr + SOC_ROM_LUT_OFF);
++
++      dsb_sev();      /* Exit WFI */
++      mb();           /* make sure write buffer is drained */
++
++      iounmap(sysram_base_addr);
++}
++
++static void __init bcm5301x_smp_prepare_cpus(unsigned int max_cpus)
++{
++      void __iomem *scu_base;
++
++      if (!scu_a9_has_base()) {
++              pr_warn("Unknown SCU base\n");
++              return;
++      }
++
++      scu_base = ioremap((phys_addr_t)scu_a9_get_base(), SZ_256);
++      if (!scu_base) {
++              pr_err("Failed to remap SCU\n");
++              return;
++      }
++
++      /* Initialise the SCU */
++      scu_enable(scu_base);
++
++      /* Let CPUs know where to start */
++      bcm5301x_smp_secondary_set_entry(bcm5301x_secondary_startup);
++
++      iounmap(scu_base);
++}
++
++static void __cpuinit bcm5301x_smp_secondary_init(unsigned int cpu)
++{
++      trace_hardirqs_off();
++
++      /*
++       * let the primary processor know we're out of the
++       * pen, then head off into the C entry point
++       */
++      write_pen_release(-1);
++
++      /*
++       * Synchronise with the boot thread.
++       */
++      spin_lock(&boot_lock);
++      spin_unlock(&boot_lock);
++}
++
++static int __cpuinit bcm5301x_smp_boot_secondary(unsigned int cpu,
++                                               struct task_struct *idle)
++{
++      unsigned long timeout;
++
++      /*
++       * set synchronisation state between this boot processor
++       * and the secondary one
++       */
++      spin_lock(&boot_lock);
++
++      /*
++       * The secondary processor is waiting to be released from
++       * the holding pen - release it, then wait for it to flag
++       * that it has been released by resetting pen_release.
++       *
++       * Note that "pen_release" is the hardware CPU ID, whereas
++       * "cpu" is Linux's internal ID.
++       */
++      write_pen_release(cpu_logical_map(cpu));
++
++       /* Send the secondary CPU SEV */
++      dsb_sev();
++
++      udelay(100);
++
++      /*
++       * Send the secondary CPU a soft interrupt, thereby causing
++       * the boot monitor to read the system wide flags register,
++       * and branch to the address found there.
++       */
++      arch_send_wakeup_ipi_mask(cpumask_of(cpu));
++
++      /*
++       * Timeout set on purpose in jiffies so that on slow processors
++       * that must also have low HZ it will wait longer.
++       */
++      timeout = jiffies + (HZ * 10);
++      while (time_before(jiffies, timeout)) {
++              smp_rmb();
++              if (pen_release == -1)
++                      break;
++
++              udelay(10);
++      }
++
++      /*
++       * now the secondary core is starting up let it run its
++       * calibrations, then wait for it to finish
++       */
++      spin_unlock(&boot_lock);
++
++      return pen_release != -1 ? -ENOSYS : 0;
++}
++
++static struct smp_operations bcm5301x_smp_ops __initdata = {
++      .smp_prepare_cpus       = bcm5301x_smp_prepare_cpus,
++      .smp_secondary_init     = bcm5301x_smp_secondary_init,
++      .smp_boot_secondary     = bcm5301x_smp_boot_secondary,
++};
++
++CPU_METHOD_OF_DECLARE(bcm5301x_smp, "brcm,bcm4708-smp",
++                    &bcm5301x_smp_ops);
diff --git a/target/linux/bcm53xx/patches-4.1/170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch b/target/linux/bcm53xx/patches-4.1/170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch
new file mode 100644 (file)
index 0000000..d4dedc0
--- /dev/null
@@ -0,0 +1,534 @@
+From cf067bf8bb993d6cfdc42d750ae241c43f88403f Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Mon, 12 May 2014 11:55:20 +0200
+Subject: [PATCH 1/2] PCI: BCM5301X: add PCIe2 driver for BCM5301X SoCs
+
+This driver supports the PCIe controller found on the BCM4708 and
+similar SoCs. The controller itself is automatically detected by bcma.
+
+This controller is found on SoCs usually used in SOHO routers to
+connect the wifi cards to the SoC. All the of the BCM5301X SoCs I know
+of have 2 or 3 of these controllers in the SoC.
+
+I had to use PCI domains otherwise the pci_create_root_bus() function
+in drivers/pci/probe.c would fail for the second controller being
+registered because pci_find_bus() would find the same PCIe bus again
+and assume it is already registered, which ends up in a kernel panic in
+pcibios_init_hw() in arch/arm/kernel/bios32.c
+
+The ARM PCI code assumes that every controller has an I/O space and
+adds a dummy area if the driver does not specify one. This will work
+for the first controller, but when we register the second one this will
+result in an error. To prevent this problem we add an empty I/O space.
+
+Currently I have problems with probing the devices on the bus, because
+pci_bus_add_devices() is called too early in pci_scan_root_bus() in
+drivers/pci/probe.c, before pci_bus_assign_resources() was called in
+pci_common_init_dev() in arch/arm/kernel/bios32.c. When the devices are
+added too early they do not have any resources and adding fails. I have
+to remove the call to pci_bus_add_devices() in pci_scan_root_bus() to
+make registration work, calling pci_bus_add_devices() later again does
+not fix this problem.
+
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+---
+ arch/arm/mach-bcm/Kconfig            |   1 +
+ drivers/pci/host/Kconfig             |   7 +
+ drivers/pci/host/Makefile            |   1 +
+ drivers/pci/host/pci-host-bcm5301x.c | 428 +++++++++++++++++++++++++++++++++++
+ 4 files changed, 437 insertions(+)
+ create mode 100644 drivers/pci/host/pci-host-bcm5301x.c
+
+--- a/arch/arm/mach-bcm/Kconfig
++++ b/arch/arm/mach-bcm/Kconfig
+@@ -38,6 +38,7 @@ config ARCH_BCM_CYGNUS
+ config ARCH_BCM_5301X
+       bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7
+       select ARCH_BCM_IPROC
++      select PCI_DOMAINS if PCI
+       help
+         Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores.
+--- a/drivers/pci/host/Kconfig
++++ b/drivers/pci/host/Kconfig
+@@ -125,4 +125,11 @@ config PCIE_IPROC_PLATFORM
+         Say Y here if you want to use the Broadcom iProc PCIe controller
+         through the generic platform bus interface
++config PCI_BCM5301X
++      bool "BCM5301X PCIe2 host controller"
++      depends on BCMA && OF && ARM && PCI_DOMAINS
++      help
++        Say Y here if you want to support the PCIe host controller found
++        on Broadcom BCM5301X and BCM470X (Northstar) SoCs.
++
+ endmenu
+--- a/drivers/pci/host/Makefile
++++ b/drivers/pci/host/Makefile
+@@ -15,3 +15,4 @@ obj-$(CONFIG_PCI_LAYERSCAPE) += pci-laye
+ obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
+ obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
+ obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
++obj-$(CONFIG_PCI_BCM5301X) += pci-host-bcm5301x.o
+--- /dev/null
++++ b/drivers/pci/host/pci-host-bcm5301x.c
+@@ -0,0 +1,459 @@
++/*
++ * Northstar PCI-Express driver
++ * Only supports Root-Complex (RC) mode
++ *
++ * Notes:
++ * PCI Domains are being used to identify the PCIe port 1:1.
++ *
++ * Only MEM access is supported, PAX does not support IO.
++ *
++ * Copyright 2012-2014, Broadcom Corporation
++ * Copyright 2014, Hauke Mehrtens <hauke@hauke-m.de>
++ *
++ * Licensed under the GNU/GPL. See COPYING for details.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/delay.h>
++#include <linux/pci.h>
++#include <linux/io.h>
++#include <linux/ioport.h>
++#include <linux/bcma/bcma.h>
++#include <linux/bcma/bcma_driver_pcie2.h>
++
++#define       SOC_PCIE_HDR_OFF        0x400   /* 256 bytes per function */
++
++#define PCI_LINK_STATUS_CTRL_2_OFFSET 0xDC
++#define PCI_TARGET_LINK_SPEED_MASK    0xF
++#define PCI_TARGET_LINK_SPEED_GEN2    0x2
++#define PCI_TARGET_LINK_SPEED_GEN1    0x1
++
++static int bcma_pcie2_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
++{
++      struct pci_sys_data *sys = pdev->sysdata;
++      struct bcma_device *bdev = sys->private_data;
++
++      return bcma_core_irq(bdev, 5);
++}
++
++static u32 bcma_pcie2_cfg_base(struct bcma_device *bdev, int busno,
++                             unsigned int devfn, int where)
++{
++      int slot = PCI_SLOT(devfn);
++      int fn = PCI_FUNC(devfn);
++      u32 addr_reg;
++
++      if (busno == 0) {
++              if (slot >= 1)
++                      return 0;
++              bcma_write32(bdev, BCMA_CORE_PCIE2_CONFIGINDADDR,
++                           where & 0xffc);
++              return BCMA_CORE_PCIE2_CONFIGINDDATA;
++      }
++      if (fn > 1)
++              return 0;
++      addr_reg = (busno & 0xff) << 20 | (slot << 15) | (fn << 12) |
++                 (where & 0xffc) | (1 & 0x3);
++
++      bcma_write32(bdev, BCMA_CORE_PCIE2_CFG_ADDR, addr_reg);
++      return BCMA_CORE_PCIE2_CFG_DATA;
++}
++
++static u32 bcma_pcie2_read_config(struct bcma_device *bdev, int busno,
++                                unsigned int devfn, int where, int size)
++{
++      u32 base;
++      u32 data_reg;
++      u32 mask;
++      int shift;
++
++      base = bcma_pcie2_cfg_base(bdev, busno, devfn, where);
++
++      if (!base)
++              return ~0UL;
++
++      data_reg = bcma_read32(bdev, base);
++
++      if (size == 4)
++              return data_reg;
++
++      mask = (1 << (size * 8)) - 1;
++      shift = (where % 4) * 8;
++      return (data_reg >> shift) & mask;
++}
++
++static void bcma_pcie2_write_config(struct bcma_device *bdev, int busno,
++                                  unsigned int devfn, int where, int size,
++                                  u32 val)
++{
++      u32 base;
++      u32 data_reg;
++
++      base = bcma_pcie2_cfg_base(bdev, busno, devfn, where);
++
++      if (!base)
++              return;
++
++      if (size < 4) {
++              u32 mask = (1 << (size * 8)) - 1;
++              int shift = (where % 4) * 8;
++
++              data_reg = bcma_read32(bdev, base);
++              data_reg &= ~(mask << shift);
++              data_reg |= (val & mask) << shift;
++      } else {
++              data_reg = val;
++      }
++
++      bcma_write32(bdev, base, data_reg);
++}
++
++static int bcma_pcie2_read_config_pci(struct pci_bus *bus, unsigned int devfn,
++                                 int where, int size, u32 *val)
++{
++      struct pci_sys_data *sys = bus->sysdata;
++      struct bcma_device *bdev = sys->private_data;
++
++      *val = bcma_pcie2_read_config(bdev, bus->number, devfn, where, size);
++
++      return PCIBIOS_SUCCESSFUL;
++}
++
++static int bcma_pcie2_write_config_pci(struct pci_bus *bus, unsigned int devfn,
++                                  int where, int size, u32 val)
++{
++      struct pci_sys_data *sys = bus->sysdata;
++      struct bcma_device *bdev = sys->private_data;
++
++      bcma_pcie2_write_config(bdev, bus->number, devfn, where, size, val);
++
++      return PCIBIOS_SUCCESSFUL;
++}
++
++/*
++ * Methods for accessing configuration registers
++ */
++static struct pci_ops bcma_pcie2_ops = {
++      .read = bcma_pcie2_read_config_pci,
++      .write = bcma_pcie2_write_config_pci,
++};
++
++/* NS: CLASS field is R/O, and set to wrong 0x200 value */
++static void bcma_pcie2_fixup_class(struct pci_dev *dev)
++{
++      dev->class = PCI_CLASS_BRIDGE_PCI << 8;
++}
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x8011, bcma_pcie2_fixup_class);
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x8012, bcma_pcie2_fixup_class);
++
++/*
++ * Check link status, return 0 if link is up in RC mode,
++ * otherwise return non-zero
++ */
++static int bcma_pcie2_check_link(struct bcma_device *bdev, struct pci_sys_data *sys)
++{
++      u32 tmp32;
++      u16 tmp16;
++      u16 pos;
++      u8 nlw;
++      /*
++       * Setup callback (bcma_pcie2_setup) is called in pcibios_init_hw before
++       * creating bus root, so we don't have it here yet. On the other hand
++       * we really want to use pci_bus_find_capability helper to check NLW.
++       * Let's fake simple pci_bus just to query for capabilities.
++       */
++      struct pci_bus bus = {
++              .number = 0,
++              .ops = &bcma_pcie2_ops,
++              .sysdata = sys,
++      };
++
++      tmp32 = bcma_read32(bdev, BCMA_CORE_PCIE2_LINK_STATUS);
++      dev_dbg(&bdev->dev, "link status: 0x%08x\n", tmp32);
++
++      tmp32 = bcma_read32(bdev, BCMA_CORE_PCIE2_STRAP_STATUS);
++      dev_dbg(&bdev->dev, "strap status: 0x%08x\n", tmp32);
++
++      /* check link status to see if link is active */
++      pos = pci_bus_find_capability(&bus, 0, PCI_CAP_ID_EXP);
++      pci_bus_read_config_word(&bus, 0, pos + PCI_EXP_LNKSTA, &tmp16);
++      nlw = (tmp16 & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT;
++
++      if (nlw == 0) {
++              /* try GEN 1 link speed */
++              tmp32 = bcma_pcie2_read_config(bdev, 0, 0,
++                                      PCI_LINK_STATUS_CTRL_2_OFFSET, 4);
++              if ((tmp32 & PCI_TARGET_LINK_SPEED_MASK) ==
++                              PCI_TARGET_LINK_SPEED_GEN2) {
++                      tmp32 &= ~PCI_TARGET_LINK_SPEED_MASK;
++                      tmp32 |= PCI_TARGET_LINK_SPEED_GEN1;
++                      bcma_pcie2_write_config(bdev, 0, 0,
++                                      PCI_LINK_STATUS_CTRL_2_OFFSET, 4, tmp32);
++                      tmp32 = bcma_pcie2_read_config(bdev, 0, 0,
++                                      PCI_LINK_STATUS_CTRL_2_OFFSET, 4);
++                      msleep(100);
++
++                      pos = pci_bus_find_capability(&bus, 0, PCI_CAP_ID_EXP);
++                      pci_bus_read_config_word(&bus, 0, pos + PCI_EXP_LNKSTA,
++                                      &tmp16);
++                      nlw = (tmp16 & PCI_EXP_LNKSTA_NLW) >>
++                              PCI_EXP_LNKSTA_NLW_SHIFT;
++              }
++      }
++
++      dev_info(&bdev->dev, "link: %s\n", nlw ? "UP" : "DOWN");
++      return nlw ? 0 : -ENODEV;
++}
++
++/*
++ * Initializte the PCIe controller
++ */
++static void bcma_pcie2_hw_init(struct bcma_device *bdev)
++{
++      u32 tmp32;
++      u16 tmp16;
++
++      /* Change MPS and MRRS to 512 */
++      tmp16 = bcma_pcie2_read_config(bdev, 0, 0, 0x4d4, 2);
++      tmp16 &= ~7;
++      tmp16 |= 2;
++      bcma_pcie2_write_config(bdev, 0, 0, 0x4d4, 2, tmp16);
++
++      tmp32 = bcma_pcie2_read_config(bdev, 0, 0, 0xb4, 4);
++      tmp32 &= ~((7 << 12) | (7 << 5));
++      tmp32 |= (2 << 12) | (2 << 5);
++      bcma_pcie2_write_config(bdev, 0, 0, 0xb4, 4, tmp32);
++
++      /*
++       * Turn-on Root-Complex (RC) mode, from reset default of EP
++       * The mode is set by straps, can be overwritten via DMU
++       * register <cru_straps_control> bit 5, "1" means RC
++       */
++
++      /* Send a downstream reset */
++      bcma_write32(bdev, BCMA_CORE_PCIE2_CLK_CONTROL,
++                   PCIE2_CLKC_RST_OE | PCIE2_CLKC_RST);
++      usleep_range(250, 400);
++      bcma_write32(bdev, BCMA_CORE_PCIE2_CLK_CONTROL, PCIE2_CLKC_RST_OE);
++      msleep(250);
++
++      /* TBD: take care of PM, check we're on */
++}
++
++/*
++ * Setup the address translation
++ *
++ * NOTE: All PCI-to-CPU address mapping are 1:1 for simplicity
++ */
++static int bcma_pcie2_map_init(struct bcma_device *bdev, u32 addr)
++{
++      /* 64MB alignment */
++      if (!addr || (addr & (SZ_64M - 1)))
++              return -EINVAL;
++
++      bcma_write32(bdev, BCMA_CORE_PCIE2_OMAP0_LOWER, addr);
++      bcma_write32(bdev, BCMA_CORE_PCIE2_OARR0, addr | 0x01);
++
++      bcma_write32(bdev, BCMA_CORE_PCIE2_OMAP1_LOWER, addr + SZ_64M);
++      bcma_write32(bdev, BCMA_CORE_PCIE2_OARR1, (addr + SZ_64M) | 0x01);
++
++      /*
++       * Inbound address translation setup
++       * Northstar only maps up to 128 MiB inbound, DRAM could be up to 1 GiB.
++       *
++       * For now allow access to entire DRAM, assuming it is less than 128MiB,
++       * otherwise DMA bouncing mechanism may be required.
++       * Also consider DMA mask to limit DMA physical address
++       */
++      /* 64-bit LE regs, write low word, high is 0 at reset */
++      bcma_write32(bdev, BCMA_CORE_PCIE2_FUNC0_IMAP1, PHYS_OFFSET | 0x1);
++      bcma_write32(bdev, BCMA_CORE_PCIE2_IARR1_LOWER,
++                         PHYS_OFFSET | ((SZ_128M >> 20) & 0xff));
++      return 0;
++}
++
++/*
++ * Setup PCIE Host bridge
++ */
++static int bcma_pcie2_bridge_init(struct bcma_device *bdev, u32 addr, u32 size)
++{
++      bcma_pcie2_write_config(bdev, 0, 0, PCI_PRIMARY_BUS, 1, 0);
++      bcma_pcie2_write_config(bdev, 0, 0, PCI_SECONDARY_BUS, 1, 1);
++      bcma_pcie2_write_config(bdev, 0, 0, PCI_SUBORDINATE_BUS, 1, 4);
++
++      bcma_pcie2_read_config(bdev, 0, 0, PCI_PRIMARY_BUS, 1);
++      bcma_pcie2_read_config(bdev, 0, 0, PCI_SECONDARY_BUS, 1);
++      bcma_pcie2_read_config(bdev, 0, 0, PCI_SUBORDINATE_BUS, 1);
++
++      /* MEM_BASE, MEM_LIM require 1MB alignment */
++      if (((addr >> 16) & 0xf) || (((addr + size) >> 16) & 0xf))
++              return -EINVAL;
++
++      bcma_pcie2_write_config(bdev, 0, 0, PCI_MEMORY_BASE, 2, addr >> 16);
++      bcma_pcie2_write_config(bdev, 0, 0, PCI_MEMORY_LIMIT, 2,
++                              (addr + size) >> 16);
++
++      /* These registers are not supported on the NS */
++      bcma_pcie2_write_config(bdev, 0, 0, PCI_IO_BASE_UPPER16, 2, 0);
++      bcma_pcie2_write_config(bdev, 0, 0, PCI_IO_LIMIT_UPPER16, 2, 0);
++
++      /* Force class to that of a Bridge */
++      bcma_pcie2_write_config(bdev, 0, 0, PCI_CLASS_DEVICE, 2,
++                              PCI_CLASS_BRIDGE_PCI);
++
++      bcma_pcie2_read_config(bdev, 0, 0, PCI_CLASS_DEVICE, 2);
++      bcma_pcie2_read_config(bdev, 0, 0, PCI_MEMORY_BASE, 2);
++      bcma_pcie2_read_config(bdev, 0, 0, PCI_MEMORY_LIMIT, 2);
++      return 0;
++}
++
++static void bcma_pcie2_3rd_init(struct bcma_bus *bus)
++{
++      /* PCIE PLL block register (base 0x8000) */
++      bcma_chipco_b_mii_write(&bus->drv_cc_b, 0x00000088, 0x57fe8000);
++      /* Check PCIE PLL lock status */
++      bcma_chipco_b_mii_write(&bus->drv_cc_b, 0x00000088, 0x67c60000);
++}
++
++/* To improve PCIE phy jitter */
++static void bcma_pcie2_improve_phy_jitter(struct bcma_bus *bus, int phyaddr)
++{
++      u32 val;
++
++      /* Change blkaddr */
++      val = (1 << 30) | (1 << 28) | (phyaddr << 23) | (0x1f << 18) |
++              (2 << 16) | (0x863 << 4);
++      bcma_chipco_b_mii_write(&bus->drv_cc_b, 0x0000009a, val);
++
++      /* Write 0x0190 to 0x13 regaddr */
++      val = (1 << 30) | (1 << 28) | (phyaddr << 23) | (0x13 << 18) |
++              (2 << 16) | 0x0190;
++      bcma_chipco_b_mii_write(&bus->drv_cc_b, 0x0000009a, val);
++
++      /* Write 0x0191 to 0x19 regaddr */
++      val = (1 << 30) | (1 << 28) | (phyaddr << 23) | (0x19 << 18) |
++              (2 << 16) | 0x0191;
++      bcma_chipco_b_mii_write(&bus->drv_cc_b, 0x0000009a, val);
++}
++
++static int bcma_pcie2_setup(int nr, struct pci_sys_data *sys)
++{
++      struct bcma_device *bdev = sys->private_data;
++      struct bcma_bus *bus = bdev->bus;
++      struct resource *res;
++      struct bcma_device *arm_core;
++      u32 cru_straps_ctrl;
++      int ret;
++      int phyaddr;
++
++      if (bdev->core_unit == 2) {
++              arm_core = bcma_find_core(bus, BCMA_CORE_ARMCA9);
++              cru_straps_ctrl = bcma_read32(arm_core, 0x2a0);
++
++              /* 3rd PCIE is not selected */
++              if (cru_straps_ctrl & 0x10)
++                      return -ENODEV;
++
++              bcma_pcie2_3rd_init(bus);
++              phyaddr = 0xf;
++      } else {
++              phyaddr = bdev->core_unit;
++      }
++      bcma_pcie2_improve_phy_jitter(bus, phyaddr);
++
++      /* create mem resource */
++      res = devm_kzalloc(&bdev->dev, sizeof(*res), GFP_KERNEL);
++      if (!res)
++              return -EINVAL;
++
++      res->start = bdev->addr_s[0];
++      res->end = bdev->addr_s[0] + SZ_128M -1;
++      res->name = "PCIe dummy IO space";
++      res->flags = IORESOURCE_MEM;
++
++      pci_add_resource(&sys->resources, res);
++
++      /* This PCIe controller does not support IO Mem, so use a dummy one. */
++      res = devm_kzalloc(&bdev->dev, sizeof(*res), GFP_KERNEL);
++      if (!res)
++              return -EINVAL;
++
++      res->start = 0;
++      res->end = 0;
++      res->name = "PCIe dummy IO space";
++      res->flags = IORESOURCE_IO;
++
++      pci_add_resource(&sys->resources, res);
++
++      bcma_pcie2_hw_init(bdev);
++      ret = bcma_pcie2_map_init(bdev, bdev->addr_s[0]);
++      if (ret)
++              return ret;
++
++      /*
++       * Skip inactive ports -
++       * will need to change this for hot-plugging
++       */
++      ret = bcma_pcie2_check_link(bdev, sys);
++      if (ret)
++              return ret;
++
++      ret = bcma_pcie2_bridge_init(bdev, bdev->addr_s[0], SZ_128M);
++      if (ret)
++              return ret;
++
++      return 1;
++}
++
++static int bcma_pcie2_probe(struct bcma_device *bdev)
++{
++      struct hw_pci hw = {
++              .nr_controllers = 1,
++              .private_data   = (void **)&bdev,
++              .setup          = bcma_pcie2_setup,
++              .map_irq        = bcma_pcie2_map_irq,
++              .ops            = &bcma_pcie2_ops,
++      };
++
++      dev_info(&bdev->dev, "initializing PCIe controller\n");
++
++      /* Announce this port to ARM/PCI common code */
++      pci_common_init_dev(&bdev->dev, &hw);
++
++      /* Setup virtual-wire interrupts */
++      bcma_write32(bdev, BCMA_CORE_PCIE2_SYS_RC_INTX_EN, 0xf);
++
++      /* Enable memory and bus master */
++      bcma_write32(bdev, SOC_PCIE_HDR_OFF + 4, 0x6);
++
++      return 0;
++}
++
++static const struct bcma_device_id bcma_pcie2_table[] = {
++      BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_PCIEG2, BCMA_ANY_REV, BCMA_ANY_CLASS),
++      {},
++};
++MODULE_DEVICE_TABLE(bcma, bcma_pcie2_table);
++
++static struct bcma_driver bcma_pcie2_driver = {
++      .name           = KBUILD_MODNAME,
++      .id_table       = bcma_pcie2_table,
++      .probe          = bcma_pcie2_probe,
++};
++
++static int __init bcma_pcie2_init(void)
++{
++      return bcma_driver_register(&bcma_pcie2_driver);
++}
++module_init(bcma_pcie2_init);
++
++static void __exit bcma_pcie2_exit(void)
++{
++      bcma_driver_unregister(&bcma_pcie2_driver);
++}
++module_exit(bcma_pcie2_exit);
++
++MODULE_AUTHOR("Hauke Mehrtens");
++MODULE_DESCRIPTION("BCM5301X PCIe host controller");
++MODULE_LICENSE("GPLv2");
diff --git a/target/linux/bcm53xx/patches-4.1/180-USB-bcma-remove-chip-id-check.patch b/target/linux/bcm53xx/patches-4.1/180-USB-bcma-remove-chip-id-check.patch
new file mode 100644 (file)
index 0000000..e5e3010
--- /dev/null
@@ -0,0 +1,34 @@
+From baf3d128e5bdf9d322539609133a15b493b0c2ef Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Thu, 11 Jun 2015 22:57:35 +0200
+Subject: [PATCH] USB: bcma: remove chip id check
+
+I have never seen any bcma device with an USB host core which was not a
+SoC, the bcma devices have an USB device core with a different core id.
+Some SoC have IDs with 47XX and 53XX in decimal form which would be
+rejected by this check. Instead of fixing this check just remove it.
+
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+---
+ drivers/usb/host/bcma-hcd.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+--- a/drivers/usb/host/bcma-hcd.c
++++ b/drivers/usb/host/bcma-hcd.c
+@@ -214,16 +214,11 @@ err_alloc:
+ static int bcma_hcd_probe(struct bcma_device *dev)
+ {
+       int err;
+-      u16 chipid_top;
+       u32 ohci_addr;
+       struct bcma_hcd_device *usb_dev;
+       struct bcma_chipinfo *chipinfo;
+       chipinfo = &dev->bus->chipinfo;
+-      /* USBcores are only connected on embedded devices. */
+-      chipid_top = (chipinfo->id & 0xFF00);
+-      if (chipid_top != 0x4700 && chipid_top != 0x5300)
+-              return -ENODEV;
+       /* TODO: Probably need checks here; is the core connected? */
diff --git a/target/linux/bcm53xx/patches-4.1/181-USB-bcma-replace-numbers-with-constants.patch b/target/linux/bcm53xx/patches-4.1/181-USB-bcma-replace-numbers-with-constants.patch
new file mode 100644 (file)
index 0000000..5ae4e0d
--- /dev/null
@@ -0,0 +1,24 @@
+From f5bc834917a8b1b9487749bdfe8eda52a01967b4 Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Thu, 11 Jun 2015 22:57:36 +0200
+Subject: [PATCH] USB: bcma: replace numbers with constants
+
+The constants for these numbers were added long time ago, use them.
+
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+---
+ drivers/usb/host/bcma-hcd.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/bcma-hcd.c
++++ b/drivers/usb/host/bcma-hcd.c
+@@ -233,7 +233,8 @@ static int bcma_hcd_probe(struct bcma_de
+       /* In AI chips EHCI is addrspace 0, OHCI is 1 */
+       ohci_addr = dev->addr_s[0];
+-      if ((chipinfo->id == 0x5357 || chipinfo->id == 0x4749)
++      if ((chipinfo->id == BCMA_CHIP_ID_BCM5357 ||
++           chipinfo->id == BCMA_CHIP_ID_BCM4749)
+           && chipinfo->rev == 0)
+               ohci_addr = 0x18009000;
diff --git a/target/linux/bcm53xx/patches-4.1/182-USB-bcma-use-devm_kzalloc.patch b/target/linux/bcm53xx/patches-4.1/182-USB-bcma-use-devm_kzalloc.patch
new file mode 100644 (file)
index 0000000..700d354
--- /dev/null
@@ -0,0 +1,47 @@
+From 93724affb195149df6f7630901d878f6e273fa02 Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Thu, 11 Jun 2015 22:57:37 +0200
+Subject: [PATCH] USB: bcma: use devm_kzalloc
+
+Instead of manually handling the frees use devm. There was also a free
+missing in the unregister call which is not needed with devm.
+
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+---
+ drivers/usb/host/bcma-hcd.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/host/bcma-hcd.c
++++ b/drivers/usb/host/bcma-hcd.c
+@@ -225,7 +225,8 @@ static int bcma_hcd_probe(struct bcma_de
+       if (dma_set_mask_and_coherent(dev->dma_dev, DMA_BIT_MASK(32)))
+               return -EOPNOTSUPP;
+-      usb_dev = kzalloc(sizeof(struct bcma_hcd_device), GFP_KERNEL);
++      usb_dev = devm_kzalloc(&dev->dev, sizeof(struct bcma_hcd_device),
++                             GFP_KERNEL);
+       if (!usb_dev)
+               return -ENOMEM;
+@@ -239,10 +240,8 @@ static int bcma_hcd_probe(struct bcma_de
+               ohci_addr = 0x18009000;
+       usb_dev->ohci_dev = bcma_hcd_create_pdev(dev, true, ohci_addr);
+-      if (IS_ERR(usb_dev->ohci_dev)) {
+-              err = PTR_ERR(usb_dev->ohci_dev);
+-              goto err_free_usb_dev;
+-      }
++      if (IS_ERR(usb_dev->ohci_dev))
++              return PTR_ERR(usb_dev->ohci_dev);
+       usb_dev->ehci_dev = bcma_hcd_create_pdev(dev, false, dev->addr);
+       if (IS_ERR(usb_dev->ehci_dev)) {
+@@ -255,8 +254,6 @@ static int bcma_hcd_probe(struct bcma_de
+ err_unregister_ohci_dev:
+       platform_device_unregister(usb_dev->ohci_dev);
+-err_free_usb_dev:
+-      kfree(usb_dev);
+       return err;
+ }
diff --git a/target/linux/bcm53xx/patches-4.1/183-USB-bcma-fix-error-handling-in-bcma_hcd_create_pdev.patch b/target/linux/bcm53xx/patches-4.1/183-USB-bcma-fix-error-handling-in-bcma_hcd_create_pdev.patch
new file mode 100644 (file)
index 0000000..91cd0fa
--- /dev/null
@@ -0,0 +1,33 @@
+From 232996d1ba3002e7e80b18075e2838fc86f21412 Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Thu, 11 Jun 2015 22:57:38 +0200
+Subject: [PATCH] USB: bcma: fix error handling in bcma_hcd_create_pdev()
+
+This patch makes bcma_hcd_create_pdev() not return NULL, but a prober
+error code in case of an error.
+
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+---
+ drivers/usb/host/bcma-hcd.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/bcma-hcd.c
++++ b/drivers/usb/host/bcma-hcd.c
+@@ -169,7 +169,7 @@ static struct platform_device *bcma_hcd_
+ {
+       struct platform_device *hci_dev;
+       struct resource hci_res[2];
+-      int ret = -ENOMEM;
++      int ret;
+       memset(hci_res, 0, sizeof(hci_res));
+@@ -183,7 +183,7 @@ static struct platform_device *bcma_hcd_
+       hci_dev = platform_device_alloc(ohci ? "ohci-platform" :
+                                       "ehci-platform" , 0);
+       if (!hci_dev)
+-              return NULL;
++              return ERR_PTR(-ENOMEM);
+       hci_dev->dev.parent = &dev->dev;
+       hci_dev->dev.dma_mask = &hci_dev->dev.coherent_dma_mask;
diff --git a/target/linux/bcm53xx/patches-4.1/184-USB-bcma-add-bcm53xx-support.patch b/target/linux/bcm53xx/patches-4.1/184-USB-bcma-add-bcm53xx-support.patch
new file mode 100644 (file)
index 0000000..bca555c
--- /dev/null
@@ -0,0 +1,133 @@
+From b65851f41c22b8c69b8fe9ca7782d19ed2155efc Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Thu, 11 Jun 2015 22:57:39 +0200
+Subject: [PATCH] USB: bcma: add bcm53xx support
+
+The Broadcom ARM SoCs with this usb core need a different
+initialization and they have a different core id. This patch adds
+support for these USB 2.0 core.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+---
+ drivers/usb/host/bcma-hcd.c | 81 +++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 78 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/host/bcma-hcd.c
++++ b/drivers/usb/host/bcma-hcd.c
+@@ -2,7 +2,8 @@
+  * Broadcom specific Advanced Microcontroller Bus
+  * Broadcom USB-core driver (BCMA bus glue)
+  *
+- * Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de>
++ * Copyright 2011-2015 Hauke Mehrtens <hauke@hauke-m.de>
++ * Copyright 2015 Felix Fietkau <nbd@openwrt.org>
+  *
+  * Based on ssb-ohci driver
+  * Copyright 2007 Michael Buesch <m@bues.ch>
+@@ -88,7 +89,7 @@ static void bcma_hcd_4716wa(struct bcma_
+ }
+ /* based on arch/mips/brcm-boards/bcm947xx/pcibios.c */
+-static void bcma_hcd_init_chip(struct bcma_device *dev)
++static void bcma_hcd_init_chip_mips(struct bcma_device *dev)
+ {
+       u32 tmp;
+@@ -159,6 +160,70 @@ static void bcma_hcd_init_chip(struct bc
+       }
+ }
++static void bcma_hcd_init_chip_arm_phy(struct bcma_device *dev)
++{
++      struct bcma_device *arm_core;
++      void __iomem *dmu;
++
++      arm_core = bcma_find_core(dev->bus, BCMA_CORE_ARMCA9);
++      if (!arm_core) {
++              dev_err(&dev->dev, "can not find ARM Cortex A9 ihost core\n");
++              return;
++      }
++
++      dmu = ioremap_nocache(arm_core->addr_s[0], 0x1000);
++      if (!dmu) {
++              dev_err(&dev->dev, "can not map ARM Cortex A9 ihost core\n");
++              return;
++      }
++
++      /* Unlock DMU PLL settings */
++      iowrite32(0x0000ea68, dmu + 0x180);
++
++      /* Write USB 2.0 PLL control setting */
++      iowrite32(0x00dd10c3, dmu + 0x164);
++
++      /* Lock DMU PLL settings */
++      iowrite32(0x00000000, dmu + 0x180);
++
++      iounmap(dmu);
++}
++
++static void bcma_hcd_init_chip_arm_hc(struct bcma_device *dev)
++{
++      u32 val;
++
++      /*
++       * Delay after PHY initialized to ensure HC is ready to be configured
++       */
++      usleep_range(1000, 2000);
++
++      /* Set packet buffer OUT threshold */
++      val = bcma_read32(dev, 0x94);
++      val &= 0xffff;
++      val |= 0x80 << 16;
++      bcma_write32(dev, 0x94, val);
++
++      /* Enable break memory transfer */
++      val = bcma_read32(dev, 0x9c);
++      val |= 1;
++      bcma_write32(dev, 0x9c, val);
++}
++
++static void bcma_hcd_init_chip_arm(struct bcma_device *dev)
++{
++      bcma_core_enable(dev, 0);
++
++      if (dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM4707 ||
++          dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM53018) {
++              if (dev->bus->chipinfo.pkg == BCMA_PKG_ID_BCM4707 ||
++                  dev->bus->chipinfo.pkg == BCMA_PKG_ID_BCM4708)
++                      bcma_hcd_init_chip_arm_phy(dev);
++
++              bcma_hcd_init_chip_arm_hc(dev);
++      }
++}
++
+ static const struct usb_ehci_pdata ehci_pdata = {
+ };
+@@ -230,7 +295,16 @@ static int bcma_hcd_probe(struct bcma_de
+       if (!usb_dev)
+               return -ENOMEM;
+-      bcma_hcd_init_chip(dev);
++      switch (dev->id.id) {
++      case BCMA_CORE_NS_USB20:
++              bcma_hcd_init_chip_arm(dev);
++              break;
++      case BCMA_CORE_USB20_HOST:
++              bcma_hcd_init_chip_mips(dev);
++              break;
++      default:
++              return -ENODEV;
++      }
+       /* In AI chips EHCI is addrspace 0, OHCI is 1 */
+       ohci_addr = dev->addr_s[0];
+@@ -299,6 +373,7 @@ static int bcma_hcd_resume(struct bcma_d
+ static const struct bcma_device_id bcma_hcd_table[] = {
+       BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS),
++      BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB20, BCMA_ANY_REV, BCMA_ANY_CLASS),
+       {},
+ };
+ MODULE_DEVICE_TABLE(bcma, bcma_hcd_table);
diff --git a/target/linux/bcm53xx/patches-4.1/185-USB-bcma-add-support-for-controlling-bus-power-throu.patch b/target/linux/bcm53xx/patches-4.1/185-USB-bcma-add-support-for-controlling-bus-power-throu.patch
new file mode 100644 (file)
index 0000000..d9a8a1e
--- /dev/null
@@ -0,0 +1,82 @@
+From f3cf44a313b3687efd55ba091558e20a4d218c31 Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Thu, 11 Jun 2015 22:57:40 +0200
+Subject: [PATCH] USB: bcma: add support for controlling bus power through GPIO
+
+On some boards a GPIO is needed to activate USB controller. Make it
+possible to specify such a GPIO in device tree.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+---
+ drivers/usb/host/bcma-hcd.c | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+--- a/drivers/usb/host/bcma-hcd.c
++++ b/drivers/usb/host/bcma-hcd.c
+@@ -24,6 +24,8 @@
+ #include <linux/platform_device.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
+ #include <linux/usb/ehci_pdriver.h>
+ #include <linux/usb/ohci_pdriver.h>
+@@ -224,6 +226,23 @@ static void bcma_hcd_init_chip_arm(struc
+       }
+ }
++static void bcma_hci_platform_power_gpio(struct bcma_device *dev, bool val)
++{
++      int gpio;
++
++      gpio = of_get_named_gpio(dev->dev.of_node, "vcc-gpio", 0);
++      if (!gpio_is_valid(gpio))
++              return;
++
++      if (val) {
++              gpio_request(gpio, "bcma-hcd-gpio");
++              gpio_set_value(gpio, 1);
++      } else {
++              gpio_set_value(gpio, 0);
++              gpio_free(gpio);
++      }
++}
++
+ static const struct usb_ehci_pdata ehci_pdata = {
+ };
+@@ -295,6 +314,8 @@ static int bcma_hcd_probe(struct bcma_de
+       if (!usb_dev)
+               return -ENOMEM;
++      bcma_hci_platform_power_gpio(dev, true);
++
+       switch (dev->id.id) {
+       case BCMA_CORE_NS_USB20:
+               bcma_hcd_init_chip_arm(dev);
+@@ -347,6 +368,7 @@ static void bcma_hcd_remove(struct bcma_
+ static void bcma_hcd_shutdown(struct bcma_device *dev)
+ {
++      bcma_hci_platform_power_gpio(dev, false);
+       bcma_core_disable(dev, 0);
+ }
+@@ -354,6 +376,7 @@ static void bcma_hcd_shutdown(struct bcm
+ static int bcma_hcd_suspend(struct bcma_device *dev)
+ {
++      bcma_hci_platform_power_gpio(dev, false);
+       bcma_core_disable(dev, 0);
+       return 0;
+@@ -361,6 +384,7 @@ static int bcma_hcd_suspend(struct bcma_
+ static int bcma_hcd_resume(struct bcma_device *dev)
+ {
++      bcma_hci_platform_power_gpio(dev, true);
+       bcma_core_enable(dev, 0);
+       return 0;
diff --git a/target/linux/bcm53xx/patches-4.1/300-ARM-BCM5301X-Disable-MMU-and-Dcache-for-decompression.patch b/target/linux/bcm53xx/patches-4.1/300-ARM-BCM5301X-Disable-MMU-and-Dcache-for-decompression.patch
new file mode 100644 (file)
index 0000000..bc5757f
--- /dev/null
@@ -0,0 +1,195 @@
+From 26023cdfacaf116545b1087b9d1fe50dc6fbda10 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Wed, 24 Sep 2014 22:14:07 +0200
+Subject: [PATCH] ARM: BCM5301X: Disable MMU and Dcache for decompression
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Without this fix kernel was randomly hanging in ~25% of tries during
+early init. Hangs used to happen at random places in the start_kernel.
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+ arch/arm/boot/compressed/Makefile                |   5 +
+ arch/arm/boot/compressed/head-bcm_5301x-mpcore.S |  37 +++++++
+ arch/arm/boot/compressed/mpcore_cache.S          | 118 +++++++++++++++++++++++
+ 3 files changed, 160 insertions(+)
+ create mode 100644 arch/arm/boot/compressed/head-bcm_5301x-mpcore.S
+ create mode 100644 arch/arm/boot/compressed/mpcore_cache.S
+
+--- a/arch/arm/boot/compressed/Makefile
++++ b/arch/arm/boot/compressed/Makefile
+@@ -31,6 +31,11 @@ ifeq ($(CONFIG_ARCH_ACORN),y)
+ OBJS          += ll_char_wr.o font.o
+ endif
++ifeq ($(CONFIG_ARCH_BCM_5301X),y)
++OBJS          += head-bcm_5301x-mpcore.o
++OBJS          += mpcore_cache.o
++endif
++
+ ifeq ($(CONFIG_ARCH_SA1100),y)
+ OBJS          += head-sa1100.o
+ endif
+--- /dev/null
++++ b/arch/arm/boot/compressed/head-bcm_5301x-mpcore.S
+@@ -0,0 +1,37 @@
++/*
++ *
++ * Platform specific tweaks.  This is merged into head.S by the linker.
++ *
++ */
++
++#include <linux/linkage.h>
++#include <asm/assembler.h>
++#include <asm/cp15.h>
++
++              .section        ".start", "ax"
++
++/*
++ * This code section is spliced into the head code by the linker
++ */
++
++__plat_uncompress_start:
++
++      @ Preserve r8/r7 i.e. kernel entry values
++      mov     r12, r8
++
++      @ Clear MMU enable and Dcache enable bits
++      mrc     p15, 0, r0, c1, c0, 0           @ Read SCTLR
++      bic     r0, #CR_C|CR_M
++      mcr     p15, 0, r0, c1, c0, 0           @ Write SCTLR
++      nop
++
++      @ Call the cache invalidation routine
++      bl      v7_all_dcache_invalidate
++      nop
++      mov     r0,#0
++      ldr     r3, =0x19022000                 @ L2 cache controller, control reg
++      str     r0, [r3, #0x100]                @ Disable L2 cache
++      nop
++
++      @ Restore
++      mov     r8, r12
+--- /dev/null
++++ b/arch/arm/boot/compressed/mpcore_cache.S
+@@ -0,0 +1,118 @@
++/*****************************************************************************
++* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
++*
++* Unless you and Broadcom execute a separate written software license
++* agreement governing use of this software, this software is licensed to you
++* under the terms of the GNU General Public License version 2, available at
++* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
++*
++* Notwithstanding the above, under no circumstances may you combine this
++* software in any way with any other Broadcom software provided under a
++* license other than the GPL, without Broadcom's express prior written
++* consent.
++*****************************************************************************/
++
++#include <linux/linkage.h>
++#include <linux/init.h>
++
++      __INIT
++
++/*
++ * v7_l1_cache_invalidate
++ *
++ * Invalidate contents of L1 cache without flushing its contents
++ * into outer cache and memory. This is needed when the contents
++ * of the cache are unpredictable after power-up.
++ *
++ * corrupts r0-r6
++ */
++
++ENTRY(v7_l1_cache_invalidate)
++      mov     r0, #0
++      mcr     p15, 2, r0, c0, c0, 0   @ set cache level to 1
++      mrc     p15, 1, r0, c0, c0, 0   @ read CLIDR
++
++      ldr     r1, =0x7fff
++      and     r2, r1, r0, lsr #13     @ get max # of index size
++
++      ldr     r1, =0x3ff
++      and     r3, r1, r0, lsr #3      @ NumWays - 1
++      add     r2, r2, #1              @ NumSets
++
++      and     r0, r0, #0x7
++      add     r0, r0, #4              @ SetShift
++
++      clz     r1, r3                  @ WayShift
++      add     r4, r3, #1              @ NumWays
++1:    sub     r2, r2, #1              @ NumSets--
++      mov     r3, r4                  @ Temp = NumWays
++2:    subs    r3, r3, #1              @ Temp--
++      mov     r5, r3, lsl r1
++      mov     r6, r2, lsl r0
++      orr     r5, r5, r6              @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
++      mcr     p15, 0, r5, c7, c6, 2   @ Invalidate line
++      bgt     2b
++      cmp     r2, #0
++      bgt     1b
++      dsb
++      mov     r0,#0
++      mcr     p15,0,r0,c7,c5,0        /* Invalidate icache */
++      isb
++      mov     pc, lr
++ENDPROC(v7_l1_cache_invalidate)
++
++/*
++ * v7_all_dcache_invalidate
++ *
++ * Invalidate without flushing the contents of all cache levels
++ * accesible by the current processor core.
++ * This is useful when the contents of cache memory are undetermined
++ * at power-up.
++ *    Corrupted registers: r0-r7, r9-r11
++ *
++ * Based on cache-v7.S: v7_flush_dcache_all()
++ */
++
++ENTRY(v7_all_dcache_invalidate)
++      mrc     p15, 1, r0, c0, c0, 1   @ read clidr
++      ands    r3, r0, #0x7000000      @ extract loc from clidr
++      mov     r3, r3, lsr #23         @ left align loc bit field
++      beq     finished                @ if loc is 0, then no need to clean
++      mov     r10, #0                 @ start clean at cache level 0
++loop1:
++      add     r2, r10, r10, lsr #1    @ work out 3x current cache level
++      mov     r1, r0, lsr r2          @ extract cache type bits from clidr
++      and     r1, r1, #7              @ mask of bits for current cache only
++      cmp     r1, #2                  @ see what cache we have at this level
++      blt     skip                    @ skip if no cache, or just i-cache
++      mcr     p15, 2, r10, c0, c0, 0  @ select current cache level in cssr
++      isb                             @ isb to sych the new cssr&csidr
++      mrc     p15, 1, r1, c0, c0, 0   @ read the new csidr
++      and     r2, r1, #7              @ extract the length of the cache lines
++      add     r2, r2, #4              @ add 4 (line length offset)
++      ldr     r4, =0x3ff
++      ands    r4, r4, r1, lsr #3      @ find maximum number on the way size
++      clz     r5, r4                  @ find bit pos of way size increment
++      ldr     r7, =0x7fff
++      ands    r7, r7, r1, lsr #13     @ extract max number of the index size
++loop2:
++      mov     r9, r4                  @ create working copy of max way size
++loop3:
++      orr     r11, r10, r9, lsl r5    @ factor way and cache number into r11
++      orr     r11, r11, r7, lsl r2    @ factor index number into r11
++      mcr     p15, 0, r11, c7, c6, 2  @ Invalidate line
++      subs    r9, r9, #1              @ decrement the way
++      bge     loop3
++      subs    r7, r7, #1              @ decrement the index
++      bge     loop2
++skip:
++      add     r10, r10, #2            @ increment cache number
++      cmp     r3, r10
++      bgt     loop1
++finished:
++      mov     r10, #0                 @ swith back to cache level 0
++      mcr     p15, 2, r10, c0, c0, 0  @ select current cache level in cssr
++      dsb
++      isb
++      mov     pc, lr
++ENDPROC(v7_all_dcache_invalidate)
diff --git a/target/linux/bcm53xx/patches-4.1/301-ARM-BCM5301X-Add-SPROM.patch b/target/linux/bcm53xx/patches-4.1/301-ARM-BCM5301X-Add-SPROM.patch
new file mode 100644 (file)
index 0000000..ca6462e
--- /dev/null
@@ -0,0 +1,26 @@
+From d404e0b22356078a51719fa911f6e09cb1a72d80 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Sun, 7 Jun 2015 16:18:18 +0200
+Subject: [PATCH] ARM: BCM5301X: Add SPROM
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+ arch/arm/boot/dts/bcm5301x.dtsi | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/arm/boot/dts/bcm5301x.dtsi
++++ b/arch/arm/boot/dts/bcm5301x.dtsi
+@@ -95,6 +95,10 @@
+               };
+       };
++      sprom0: sprom@0 {
++              compatible = "brcm,bcm47xx-sprom";
++      };
++
+       axi@18000000 {
+               compatible = "brcm,bus-axi";
+               reg = <0x18000000 0x1000>;
diff --git a/target/linux/bcm53xx/patches-4.1/303-ARM-BCM5310X-Enable-earlyprintk-on-tested-devices.patch b/target/linux/bcm53xx/patches-4.1/303-ARM-BCM5310X-Enable-earlyprintk-on-tested-devices.patch
new file mode 100644 (file)
index 0000000..9b562ce
--- /dev/null
@@ -0,0 +1,148 @@
+From eb1075cc48d3c315c7403822c33da9588ab76492 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Wed, 14 Jan 2015 08:33:25 +0100
+Subject: [PATCH] ARM: BCM5310X: Enable earlyprintk on tested devices
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+ arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts  | 2 +-
+ arch/arm/boot/dts/bcm4708-netgear-r6250.dts        | 2 +-
+ arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts        | 2 +-
+ arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 2 +-
+ 4 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
++++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
+@@ -17,7 +17,7 @@
+       model = "Buffalo WZR-1750DHP (BCM4708)";
+       chosen {
+-              bootargs = "console=ttyS0,115200";
++              bootargs = "console=ttyS0,115200 earlyprintk";
+       };
+       memory {
+--- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
++++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
+@@ -17,7 +17,7 @@
+       model = "Netgear R6250 V1 (BCM4708)";
+       chosen {
+-              bootargs = "console=ttyS0,115200";
++              bootargs = "console=ttyS0,115200 earlyprintk";
+       };
+       memory {
+--- a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
++++ b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
+@@ -17,7 +17,7 @@
+       model = "Asus RT-N18U (BCM47081)";
+       chosen {
+-              bootargs = "console=ttyS0,115200";
++              bootargs = "console=ttyS0,115200 earlyprintk";
+       };
+       memory {
+--- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
++++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
+@@ -17,7 +17,7 @@
+       model = "Buffalo WZR-600DHP2 (BCM47081)";
+       chosen {
+-              bootargs = "console=ttyS0,115200";
++              bootargs = "console=ttyS0,115200 earlyprintk";
+       };
+       memory {
+--- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
++++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
+@@ -17,7 +17,7 @@
+       model = "Buffalo WZR-900DHP (BCM47081)";
+       chosen {
+-              bootargs = "console=ttyS0,115200";
++              bootargs = "console=ttyS0,115200 earlyprintk";
+       };
+       memory {
+--- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
++++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
+@@ -17,7 +17,7 @@
+       model = "Netgear R8000 (BCM4709)";
+       chosen {
+-              bootargs = "console=ttyS0,115200";
++              bootargs = "console=ttyS0,115200 earlyprintk";
+       };
+       memory {
+--- a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
++++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
+@@ -17,7 +17,7 @@
+       model = "Asus RT-AC56U (BCM4708)";
+       chosen {
+-              bootargs = "console=ttyS0,115200";
++              bootargs = "console=ttyS0,115200 earlyprintk";
+       };
+       memory {
+--- a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
++++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
+@@ -17,7 +17,7 @@
+       model = "Asus RT-AC68U (BCM4708)";
+       chosen {
+-              bootargs = "console=ttyS0,115200";
++              bootargs = "console=ttyS0,115200 earlyprintk";
+       };
+       memory {
+--- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
++++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
+@@ -17,7 +17,7 @@
+       model = "Luxul XWC-1000 (BCM4708)";
+       chosen {
+-              bootargs = "console=ttyS0,115200";
++              bootargs = "console=ttyS0,115200 earlyprintk";
+       };
+       memory {
+--- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
++++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
+@@ -17,7 +17,7 @@
+       model = "Buffalo WXR-1900DHP";
+       chosen {
+-              bootargs = "console=ttyS0,115200";
++              bootargs = "console=ttyS0,115200 earlyprintk";
+       };
+       memory {
+--- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
++++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
+@@ -17,7 +17,7 @@
+       model = "SmartRG SR400ac";
+       chosen {
+-              bootargs = "console=ttyS0,115200";
++              bootargs = "console=ttyS0,115200 earlyprintk";
+       };
+       memory {
+--- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
++++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
+@@ -16,7 +16,7 @@
+       model = "Asus RT-AC87U";
+       chosen {
+-              bootargs = "console=ttyS0,115200";
++              bootargs = "console=ttyS0,115200 earlyprintk";
+       };
+       memory {
diff --git a/target/linux/bcm53xx/patches-4.1/305-ARM-BCM53XX-set-customized-AUXCTL.patch b/target/linux/bcm53xx/patches-4.1/305-ARM-BCM53XX-set-customized-AUXCTL.patch
new file mode 100644 (file)
index 0000000..a2bed2a
--- /dev/null
@@ -0,0 +1,30 @@
+From 4a658590f83c1e916ab63ed7fe6f0841924247db Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Fri, 3 Oct 2014 18:37:33 +0200
+Subject: [PATCH 2/2] ARM: BCM53XX: set customized AUXCTL
+
+This activated some more features in the l310 cache.
+
+This is based on some vendor code
+
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+---
+ arch/arm/mach-bcm/bcm_5301x.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/mach-bcm/bcm_5301x.c
++++ b/arch/arm/mach-bcm/bcm_5301x.c
+@@ -50,7 +50,12 @@ static const char __initconst *bcm5301x_
+ };
+ DT_MACHINE_START(BCM5301X, "BCM5301X")
+-      .l2c_aux_val    = 0,
++      .l2c_aux_val    = L310_AUX_CTRL_CACHE_REPLACE_RR |
++                        L310_AUX_CTRL_DATA_PREFETCH |
++                        L310_AUX_CTRL_INSTR_PREFETCH |
++                        L310_AUX_CTRL_EARLY_BRESP |
++                        L2C_AUX_CTRL_SHARED_OVERRIDE |
++                        L310_AUX_CTRL_FULL_LINE_ZERO,
+       .l2c_aux_mask   = ~0,
+       .init_early     = bcm5301x_init_early,
+       .dt_compat      = bcm5301x_dt_compat,
diff --git a/target/linux/bcm53xx/patches-4.1/306-ARM-BCM5301X-Specify-RAM-on-devices-by-including-HIG.patch b/target/linux/bcm53xx/patches-4.1/306-ARM-BCM5301X-Specify-RAM-on-devices-by-including-HIG.patch
new file mode 100644 (file)
index 0000000..6637a62
--- /dev/null
@@ -0,0 +1,161 @@
+From 36b2fbb3badf0e32b371e1f7579a95d4fe25c0e1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Wed, 14 Jan 2015 09:13:58 +0100
+Subject: [PATCH] ARM: BCM5301X: Specify RAM on devices by including HIGHMEM
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+ arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts  | 3 ++-
+ arch/arm/boot/dts/bcm4708-netgear-r6250.dts        | 3 ++-
+ arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts     | 3 ++-
+ arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts        | 3 ++-
+ arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 3 ++-
+ 5 files changed, 10 insertions(+), 5 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
++++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
+@@ -21,7 +21,8 @@
+       };
+       memory {
+-              reg = <0x00000000 0x08000000>;
++              reg = <0x00000000 0x08000000
++                     0x88000000 0x18000000>;
+       };
+       spi {
+--- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
++++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
+@@ -21,7 +21,8 @@
+       };
+       memory {
+-              reg = <0x00000000 0x08000000>;
++              reg = <0x00000000 0x08000000
++                     0x88000000 0x08000000>;
+       };
+       chipcommonA {
+--- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
++++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
+@@ -21,7 +21,8 @@
+       };
+       memory {
+-              reg = <0x00000000 0x08000000>;
++              reg = <0x00000000 0x08000000
++                     0x88000000 0x08000000>;
+       };
+       leds {
+--- a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
++++ b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
+@@ -21,7 +21,8 @@
+       };
+       memory {
+-              reg = <0x00000000 0x08000000>;
++              reg = <0x00000000 0x08000000
++                     0x88000000 0x08000000>;
+       };
+       leds {
+--- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
++++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
+@@ -21,7 +21,8 @@
+       };
+       memory {
+-              reg = <0x00000000 0x08000000>;
++              reg = <0x00000000 0x08000000
++                     0x88000000 0x08000000>;
+       };
+       spi {
+--- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
++++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
+@@ -21,7 +21,8 @@
+       };
+       memory {
+-              reg = <0x00000000 0x08000000>;
++              reg = <0x00000000 0x08000000
++                     0x88000000 0x08000000>;
+       };
+       gpio-keys {
+--- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
++++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
+@@ -21,7 +21,8 @@
+       };
+       memory {
+-              reg = <0x00000000 0x08000000>;
++              reg = <0x00000000 0x08000000
++                     0x88000000 0x08000000>;
+       };
+       leds {
+--- a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
++++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
+@@ -21,7 +21,8 @@
+       };
+       memory {
+-              reg = <0x00000000 0x08000000>;
++              reg = <0x00000000 0x08000000
++                     0x88000000 0x08000000>;
+       };
+       leds {
+--- a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
++++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
+@@ -21,7 +21,8 @@
+       };
+       memory {
+-              reg = <0x00000000 0x08000000>;
++              reg = <0x00000000 0x08000000
++                     0x88000000 0x08000000>;
+       };
+       leds {
+--- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
++++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
+@@ -21,7 +21,8 @@
+       };
+       memory {
+-              reg = <0x00000000 0x08000000>;
++              reg = <0x00000000 0x08000000
++                     0x88000000 0x18000000>;
+       };
+       leds {
+--- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
++++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
+@@ -21,7 +21,8 @@
+       };
+       memory {
+-              reg = <0x00000000 0x08000000>;
++              reg = <0x00000000 0x08000000
++                     0x88000000 0x08000000>;
+       };
+       leds {
+--- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
++++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
+@@ -20,7 +20,8 @@
+       };
+       memory {
+-              reg = <0x00000000 0x08000000>;
++              reg = <0x00000000 0x08000000
++                     0x88000000 0x08000000>;
+       };
+       leds {
diff --git a/target/linux/bcm53xx/patches-4.1/320-ARM-BCM5301X-Add-Buffalo-WXR-1900DHP-clock-and-USB-p.patch b/target/linux/bcm53xx/patches-4.1/320-ARM-BCM5301X-Add-Buffalo-WXR-1900DHP-clock-and-USB-p.patch
new file mode 100644 (file)
index 0000000..f99460a
--- /dev/null
@@ -0,0 +1,41 @@
+From 504dba5b073a9009ae1e3f2fc53ea9c3aa10c38a Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Wed, 13 May 2015 20:56:38 +0200
+Subject: [PATCH] ARM: BCM5301X: Add Buffalo WXR-1900DHP clock and USB power
+ control
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+ arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
++++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
+@@ -25,6 +25,23 @@
+                      0x88000000 0x18000000>;
+       };
++      clocks {
++              clk_periph: periph {
++                      clock-frequency = <500000000>;
++              };
++      };
++
++      axi@18000000 {
++              usb2@21000 {
++                      reg = <0x00021000 0x1000>;
++
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      vcc-gpio = <&chipcommon 13 GPIO_ACTIVE_HIGH>;
++              };
++      };
++
+       leds {
+               compatible = "gpio-leds";
diff --git a/target/linux/bcm53xx/patches-4.1/321-ARM-BCM5301X-Set-vcc-gpio-for-USB-controllers.patch b/target/linux/bcm53xx/patches-4.1/321-ARM-BCM5301X-Set-vcc-gpio-for-USB-controllers.patch
new file mode 100644 (file)
index 0000000..7e5f018
--- /dev/null
@@ -0,0 +1,63 @@
+From f1ee1275f65e87e035260f4d09a0f0ba98c6854d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Sun, 21 Jun 2015 12:56:32 +0200
+Subject: [PATCH] ARM: BCM5301X: Set vcc-gpio for USB controllers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+ arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts | 20 ++++++++++++++++++++
+ arch/arm/boot/dts/bcm4708-netgear-r6250.dts       | 11 +++++++++++
+ 2 files changed, 31 insertions(+)
+
+--- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
++++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
+@@ -25,6 +25,26 @@
+                      0x88000000 0x18000000>;
+       };
++      axi@18000000 {
++              usb2@21000 {
++                      reg = <0x00021000 0x1000>;
++
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
++              };
++
++              usb3@23000 {
++                      reg = <0x00023000 0x1000>;
++
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      vcc-gpio = <&chipcommon 10 GPIO_ACTIVE_LOW>;
++              };
++      };
++
+       spi {
+               compatible = "spi-gpio";
+               num-chipselects = <1>;
+--- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
++++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
+@@ -35,6 +35,17 @@
+               };
+       };
++      axi@18000000 {
++              usb3@23000 {
++                      reg = <0x00023000 0x1000>;
++
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      vcc-gpio = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
++              };
++      };
++
+       leds {
+               compatible = "gpio-leds";
diff --git a/target/linux/bcm53xx/patches-4.1/332-ARM-BCM5301X-Add-power-button-for-Buffalo-WZR-1750DHP.patch b/target/linux/bcm53xx/patches-4.1/332-ARM-BCM5301X-Add-power-button-for-Buffalo-WZR-1750DHP.patch
new file mode 100644 (file)
index 0000000..f9ca7eb
--- /dev/null
@@ -0,0 +1,20 @@
+From: Felix Fietkau <nbd@openwrt.org>
+Subject: [PATCH] ARM: BCM5301X: Add power button for Buffalo WZR-1750DHP
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+---
+--- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
++++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
+@@ -123,6 +123,12 @@
+               #address-cells = <1>;
+               #size-cells = <0>;
++              power {
++                      label = "Power";
++                      linux,code = <KEY_POWER>;
++                      gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
++              };
++
+               restart {
+                       label = "Reset";
+                       linux,code = <KEY_RESTART>;
diff --git a/target/linux/bcm53xx/patches-4.1/340-ARM-BCM5301X-Add-profiling-support.patch b/target/linux/bcm53xx/patches-4.1/340-ARM-BCM5301X-Add-profiling-support.patch
new file mode 100644 (file)
index 0000000..291ec72
--- /dev/null
@@ -0,0 +1,20 @@
+Subject: [PATCH] ARM: BCM5301X: Add profiling support
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+---
+--- a/arch/arm/boot/dts/bcm5301x.dtsi
++++ b/arch/arm/boot/dts/bcm5301x.dtsi
+@@ -82,6 +82,13 @@
+               };
+       };
++      pmu {
++              compatible = "arm,cortex-a9-pmu";
++              interrupts =
++                      <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
++                      <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
++      };
++
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <0>;
diff --git a/target/linux/bcm53xx/patches-4.1/351-ARM-BCM5301X-Enable-ChipCommon-UART-serial-console.patch b/target/linux/bcm53xx/patches-4.1/351-ARM-BCM5301X-Enable-ChipCommon-UART-serial-console.patch
new file mode 100644 (file)
index 0000000..87065de
--- /dev/null
@@ -0,0 +1,250 @@
+From 6c223da976a9225ba9fae8d6f891a8fffaae6092 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Fri, 5 Dec 2014 17:38:40 +0100
+Subject: [PATCH] ARM: BCM5301X: Enable ChipCommon UART (serial console)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+ arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts  | 10 ++++++++++
+ arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts     | 10 ++++++++++
+ arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts        | 10 ++++++++++
+ arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 10 ++++++++++
+ 4 files changed, 40 insertions(+)
+
+--- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
++++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
+@@ -25,6 +25,16 @@
+                      0x88000000 0x18000000>;
+       };
++      chipcommonA {
++              uart0: serial@0300 {
++                      status = "okay";
++              };
++
++              uart1: serial@0400 {
++                      status = "okay";
++              };
++      };
++
+       axi@18000000 {
+               usb2@21000 {
+                       reg = <0x00021000 0x1000>;
+--- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
++++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
+@@ -25,6 +25,16 @@
+                      0x88000000 0x08000000>;
+       };
++      chipcommonA {
++              uart0: serial@0300 {
++                      status = "okay";
++              };
++
++              uart1: serial@0400 {
++                      status = "okay";
++              };
++      };
++
+       leds {
+               compatible = "gpio-leds";
+--- a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
++++ b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
+@@ -25,6 +25,16 @@
+                      0x88000000 0x08000000>;
+       };
++      chipcommonA {
++              uart0: serial@0300 {
++                      status = "okay";
++              };
++
++              uart1: serial@0400 {
++                      status = "okay";
++              };
++      };
++
+       leds {
+               compatible = "gpio-leds";
+--- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
++++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
+@@ -25,6 +25,16 @@
+                      0x88000000 0x08000000>;
+       };
++      chipcommonA {
++              uart0: serial@0300 {
++                      status = "okay";
++              };
++
++              uart1: serial@0400 {
++                      status = "okay";
++              };
++      };
++
+       spi {
+               compatible = "spi-gpio";
+               num-chipselects = <1>;
+--- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
++++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
+@@ -23,6 +23,16 @@
+       memory {
+               reg = <0x00000000 0x08000000>;
+       };
++ 
++      chipcommonA {
++              uart0: serial@0300 {
++                      status = "okay";
++              };
++
++              uart1: serial@0400 {
++                      status = "okay";
++              };
++      };
+       nand: nand@18028000 {
+               nandcs@0 {
+--- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
++++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
+@@ -25,6 +25,16 @@
+                      0x88000000 0x08000000>;
+       };
++      chipcommonA {
++              uart0: serial@0300 {
++                      status = "okay";
++              };
++
++              uart1: serial@0400 {
++                      status = "okay";
++              };
++      };
++
+       gpio-keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+--- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
++++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
+@@ -46,6 +46,18 @@
+               };
+       };
++      chipcommonA {
++              uart0: serial@0300 {
++                      status = "okay";
++                      clock-frequency = <125000000>;
++              };
++
++              uart1: serial@0400 {
++                      status = "okay";
++                      clock-frequency = <125000000>;
++              };
++      };
++
+       gpio-keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+--- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
++++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
+@@ -25,6 +25,18 @@
+                      0x88000000 0x08000000>;
+       };
++      chipcommonA {
++              uart0: serial@0300 {
++                      status = "okay";
++                      clock-frequency = <125000000>;
++              };
++
++              uart1: serial@0400 {
++                      status = "okay";
++                      clock-frequency = <125000000>;
++              };
++      };
++
+       leds {
+               compatible = "gpio-leds";
+--- a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
++++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
+@@ -25,6 +25,16 @@
+                      0x88000000 0x08000000>;
+       };
++      chipcommonA {
++              uart0: serial@0300 {
++                      status = "okay";
++              };
++
++              uart1: serial@0400 {
++                      status = "okay";
++              };
++      };
++
+       leds {
+               compatible = "gpio-leds";
+--- a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
++++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
+@@ -25,6 +25,16 @@
+                      0x88000000 0x08000000>;
+       };
++      chipcommonA {
++              uart0: serial@0300 {
++                      status = "okay";
++              };
++
++              uart1: serial@0400 {
++                      status = "okay";
++              };
++      };
++
+       leds {
+               compatible = "gpio-leds";
+--- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
++++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
+@@ -25,6 +25,18 @@
+                      0x88000000 0x18000000>;
+       };
++      chipcommonA {
++              uart0: serial@0300 {
++                      status = "okay";
++                      clock-frequency = <125000000>;
++              };
++
++              uart1: serial@0400 {
++                      status = "okay";
++                      clock-frequency = <125000000>;
++              };
++      };
++
+       clocks {
+               clk_periph: periph {
+                       clock-frequency = <500000000>;
+--- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
++++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
+@@ -25,6 +25,16 @@
+                      0x88000000 0x08000000>;
+       };
++      chipcommonA {
++              uart0: serial@0300 {
++                      status = "okay";
++              };
++
++              uart1: serial@0400 {
++                      status = "okay";
++              };
++      };
++
+       leds {
+               compatible = "gpio-leds";
diff --git a/target/linux/bcm53xx/patches-4.1/352-ARM-BCM5301X-Add-back-Luxul-XWC-1000-NAND-flash-layo.patch b/target/linux/bcm53xx/patches-4.1/352-ARM-BCM5301X-Add-back-Luxul-XWC-1000-NAND-flash-layo.patch
new file mode 100644 (file)
index 0000000..df65e0d
--- /dev/null
@@ -0,0 +1,37 @@
+From b97e582cd05f6ba80bdb63d9f677a3395edc7ff1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Sun, 7 Jun 2015 15:37:43 +0200
+Subject: [PATCH] ARM: BCM5301X: Add back Luxul XWC-1000 NAND flash layout
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+In OpenWrt we still use old NAND driver instead of "brcm,nandcs", so
+we need to add this DT entry back.
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+ arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
++++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
+@@ -34,6 +34,18 @@
+               };
+       };
++      axi@18000000 {
++              nand@28000 {
++                      reg = <0x00028000 0x1000>;
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++                      partition@0 {
++                              label = "ubi";
++                              reg = <0x00000000 0x08000000>;
++                      };
++              };
++      };
++
+       nand: nand@18028000 {
+               nandcs@0 {
+                       partition@0 {
diff --git a/target/linux/bcm53xx/patches-4.1/400-mtd-bcm47xxpart-scan-whole-flash-on-ARCH_BCM_5301X.patch b/target/linux/bcm53xx/patches-4.1/400-mtd-bcm47xxpart-scan-whole-flash-on-ARCH_BCM_5301X.patch
new file mode 100644 (file)
index 0000000..ccdb28b
--- /dev/null
@@ -0,0 +1,31 @@
+From d658c21d6697293a928434fd6ac19264b5a8948d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Fri, 30 Jan 2015 08:25:54 +0100
+Subject: [PATCH] mtd: bcm47xxpart: scan whole flash on ARCH_BCM_5301X
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+ drivers/mtd/bcm47xxpart.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/mtd/bcm47xxpart.c
++++ b/drivers/mtd/bcm47xxpart.c
+@@ -120,9 +120,15 @@ static int bcm47xxpart_parse(struct mtd_
+       /* Parse block by block looking for magics */
+       for (offset = 0; offset <= master->size - blocksize;
+            offset += blocksize) {
++#ifndef CONFIG_ARCH_BCM_5301X
++              /*
++               * ARM routers may have partitions in higher memory. E.g.
++               * Netgear R8000 has board_data at 0x2600000.
++               */
+               /* Nothing more in higher memory */
+               if (offset >= 0x2000000)
+                       break;
++#endif
+               if (curr_part >= BCM47XXPART_MAX_PARTS) {
+                       pr_warn("Reached maximum number of partitions, scanning stopped!\n");
diff --git a/target/linux/bcm53xx/patches-4.1/404-mtd-bcm53xxspiflash-new-driver-for-SPI-flahes-on-Bro.patch b/target/linux/bcm53xx/patches-4.1/404-mtd-bcm53xxspiflash-new-driver-for-SPI-flahes-on-Bro.patch
new file mode 100644 (file)
index 0000000..41ef3b3
--- /dev/null
@@ -0,0 +1,19 @@
+--- a/drivers/mtd/spi-nor/Kconfig
++++ b/drivers/mtd/spi-nor/Kconfig
+@@ -28,4 +28,10 @@ config SPI_FSL_QUADSPI
+         This enables support for the Quad SPI controller in master mode.
+         We only connect the NOR to this controller now.
++config MTD_SPI_BCM53XXSPIFLASH
++      tristate "SPI-NOR flashes connected to the Broadcom ARM SoC"
++      depends on MTD_SPI_NOR
++      help
++        SPI driver for flashes used on Broadcom ARM SoCs.
++
+ endif # MTD_SPI_NOR
+--- a/drivers/mtd/spi-nor/Makefile
++++ b/drivers/mtd/spi-nor/Makefile
+@@ -1,2 +1,3 @@
+ obj-$(CONFIG_MTD_SPI_NOR)     += spi-nor.o
+ obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o
++obj-$(CONFIG_MTD_SPI_BCM53XXSPIFLASH) += bcm53xxspiflash.o
diff --git a/target/linux/bcm53xx/patches-4.1/420-mtd-bcm5301x_nand.patch b/target/linux/bcm53xx/patches-4.1/420-mtd-bcm5301x_nand.patch
new file mode 100644 (file)
index 0000000..07cde21
--- /dev/null
@@ -0,0 +1,1608 @@
+--- a/drivers/mtd/nand/Kconfig
++++ b/drivers/mtd/nand/Kconfig
+@@ -530,4 +530,10 @@ config MTD_NAND_HISI504
+       help
+         Enables support for NAND controller on Hisilicon SoC Hip04.
++config MTD_NAND_BCM
++      tristate "Support for NAND on some Broadcom SoC"
++      help
++        This driver is currently used for the NAND flash controller on the
++        Broadcom BCM5301X (NorthStar) SoCs.
++
+ endif # MTD_NAND
+--- a/drivers/mtd/nand/Makefile
++++ b/drivers/mtd/nand/Makefile
+@@ -52,5 +52,6 @@ obj-$(CONFIG_MTD_NAND_XWAY)          += xway_nan
+ obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)  += bcm47xxnflash/
+ obj-$(CONFIG_MTD_NAND_SUNXI)          += sunxi_nand.o
+ obj-$(CONFIG_MTD_NAND_HISI504)                += hisi504_nand.o
++obj-$(CONFIG_MTD_NAND_BCM)            += bcm_nand.o
+ nand-objs := nand_base.o nand_bbt.o nand_timings.o
+--- /dev/null
++++ b/drivers/mtd/nand/bcm_nand.c
+@@ -0,0 +1,1583 @@
++/*
++ * Nortstar NAND controller driver
++ *
++ * (c) Broadcom, Inc. 2012 All Rights Reserved.
++ * Copyright 2014 Hauke Mehrtens <hauke@hauke-m.de>
++ *
++ * Licensed under the GNU/GPL. See COPYING for details.
++ *
++ * This module interfaces the NAND controller and hardware ECC capabilities
++ * tp the generic NAND chip support in the NAND library.
++ *
++ * Notes:
++ *    This driver depends on generic NAND driver, but works at the
++ *    page level for operations.
++ *
++ *    When a page is written, the ECC calculated also protects the OOB
++ *    bytes not taken by ECC, and so the OOB must be combined with any
++ *    OOB data that preceded the page-write operation in order for the
++ *    ECC to be calculated correctly.
++ *    Also, when the page is erased, but OOB data is not, HW ECC will
++ *    indicate an error, because it checks OOB too, which calls for some
++ *    help from the software in this driver.
++ *
++ * TBD:
++ *    Block locking/unlocking support, OTP support
++ */
++
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/io.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++#include <linux/err.h>
++#include <linux/slab.h>
++#include <linux/bcma/bcma.h>
++#include <linux/of_irq.h>
++
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/nand.h>
++#include <linux/mtd/partitions.h>
++
++#define NANDC_MAX_CHIPS               2       /* Only 2 CSn supported in NorthStar */
++
++/*
++ * Driver private control structure
++ */
++struct bcmnand_ctrl {
++      struct mtd_info         mtd;
++      struct nand_chip        nand;
++      struct bcma_device      *core;
++
++      struct completion       op_completion;
++
++      struct nand_ecclayout   ecclayout;
++      int                     cmd_ret;        /* saved error code */
++      unsigned char           oob_index;
++      unsigned char           id_byte_index;
++      unsigned char           chip_num;
++      unsigned char           last_cmd;
++      unsigned char           ecc_level;
++      unsigned char           sector_size_shift;
++      unsigned char           sec_per_page_shift;
++};
++
++
++/*
++ * IRQ numbers - offset from first irq in nandc_irq resource
++ */
++#define NANDC_IRQ_RD_MISS             0
++#define NANDC_IRQ_ERASE_COMPLETE      1
++#define NANDC_IRQ_COPYBACK_COMPLETE   2
++#define NANDC_IRQ_PROGRAM_COMPLETE    3
++#define NANDC_IRQ_CONTROLLER_RDY      4
++#define NANDC_IRQ_RDBSY_RDY           5
++#define NANDC_IRQ_ECC_UNCORRECTABLE   6
++#define NANDC_IRQ_ECC_CORRECTABLE     7
++#define NANDC_IRQ_NUM                 8
++
++struct bcmnand_reg_field {
++      unsigned int reg;
++      unsigned int pos;
++      unsigned int width;
++};
++
++/*
++ * REGISTERS
++ *
++ * Individual bit-fields aof registers are specificed here
++ * for clarity, and the rest of the code will access each field
++ * as if it was its own register.
++ *
++ * Following registers are off <reg_base>:
++ */
++#define REG_BIT_FIELD(r, p, w)        ((struct bcmnand_reg_field){(r), (p), (w)})
++
++#define NANDC_8KB_PAGE_SUPPORT                REG_BIT_FIELD(0x0, 31, 1)
++#define NANDC_REV_MAJOR                       REG_BIT_FIELD(0x0, 8, 8)
++#define NANDC_REV_MINOR                       REG_BIT_FIELD(0x0, 0, 8)
++
++#define NANDC_CMD_START_OPCODE                REG_BIT_FIELD(0x4, 24, 5)
++
++#define NANDC_CMD_CS_SEL              REG_BIT_FIELD(0x8, 16, 3)
++#define NANDC_CMD_EXT_ADDR            REG_BIT_FIELD(0x8, 0, 16)
++
++#define NANDC_CMD_ADDRESS             REG_BIT_FIELD(0xc, 0, 32)
++#define NANDC_CMD_END_ADDRESS         REG_BIT_FIELD(0x10, 0, 32)
++
++#define NANDC_INT_STATUS              REG_BIT_FIELD(0x14, 0, 32)
++#define NANDC_INT_STAT_CTLR_RDY               REG_BIT_FIELD(0x14, 31, 1)
++#define NANDC_INT_STAT_FLASH_RDY      REG_BIT_FIELD(0x14, 30, 1)
++#define NANDC_INT_STAT_CACHE_VALID    REG_BIT_FIELD(0x14, 29, 1)
++#define NANDC_INT_STAT_SPARE_VALID    REG_BIT_FIELD(0x14, 28, 1)
++#define NANDC_INT_STAT_ERASED         REG_BIT_FIELD(0x14, 27, 1)
++#define NANDC_INT_STAT_PLANE_RDY      REG_BIT_FIELD(0x14, 26, 1)
++#define NANDC_INT_STAT_FLASH_STATUS   REG_BIT_FIELD(0x14, 0, 8)
++
++#define NANDC_CS_LOCK                 REG_BIT_FIELD(0x18, 31, 1)
++#define NANDC_CS_AUTO_CONFIG          REG_BIT_FIELD(0x18, 30, 1)
++#define NANDC_CS_NAND_WP              REG_BIT_FIELD(0x18, 29, 1)
++#define NANDC_CS_BLK0_WP              REG_BIT_FIELD(0x18, 28, 1)
++#define NANDC_CS_SW_USING_CS(n)               REG_BIT_FIELD(0x18, 8+(n), 1)
++#define NANDC_CS_MAP_SEL_CS(n)                REG_BIT_FIELD(0x18, 0+(n), 1)
++
++#define NANDC_XOR_ADDR_BLK0_ONLY      REG_BIT_FIELD(0x1c, 31, 1)
++#define NANDC_XOR_ADDR_CS(n)          REG_BIT_FIELD(0x1c, 0+(n), 1)
++
++#define NANDC_LL_OP_RET_IDLE          REG_BIT_FIELD(0x20, 31, 1)
++#define NANDC_LL_OP_CLE                       REG_BIT_FIELD(0x20, 19, 1)
++#define NANDC_LL_OP_ALE                       REG_BIT_FIELD(0x20, 18, 1)
++#define NANDC_LL_OP_WE                        REG_BIT_FIELD(0x20, 17, 1)
++#define NANDC_LL_OP_RE                        REG_BIT_FIELD(0x20, 16, 1)
++#define NANDC_LL_OP_DATA              REG_BIT_FIELD(0x20, 0, 16)
++
++#define NANDC_MPLANE_ADDR_EXT         REG_BIT_FIELD(0x24, 0, 16)
++#define NANDC_MPLANE_ADDR             REG_BIT_FIELD(0x28, 0, 32)
++
++#define NANDC_ACC_CTRL_CS(n)          REG_BIT_FIELD(0x50+((n)<<4), 0, 32)
++#define NANDC_ACC_CTRL_RD_ECC(n)      REG_BIT_FIELD(0x50+((n)<<4), 31, 1)
++#define NANDC_ACC_CTRL_WR_ECC(n)      REG_BIT_FIELD(0x50+((n)<<4), 30, 1)
++#define NANDC_ACC_CTRL_CE_CARE(n)     REG_BIT_FIELD(0x50+((n)<<4), 29, 1)
++#define NANDC_ACC_CTRL_PGM_RDIN(n)    REG_BIT_FIELD(0x50+((n)<<4), 28, 1)
++#define NANDC_ACC_CTRL_ERA_ECC_ERR(n) REG_BIT_FIELD(0x50+((n)<<4), 27, 1)
++#define NANDC_ACC_CTRL_PGM_PARTIAL(n) REG_BIT_FIELD(0x50+((n)<<4), 26, 1)
++#define NANDC_ACC_CTRL_WR_PREEMPT(n)  REG_BIT_FIELD(0x50+((n)<<4), 25, 1)
++#define NANDC_ACC_CTRL_PG_HIT(n)      REG_BIT_FIELD(0x50+((n)<<4), 24, 1)
++#define NANDC_ACC_CTRL_PREFETCH(n)    REG_BIT_FIELD(0x50+((n)<<4), 23, 1)
++#define NANDC_ACC_CTRL_CACHE_MODE(n)  REG_BIT_FIELD(0x50+((n)<<4), 22, 1)
++#define NANDC_ACC_CTRL_CACHE_LASTPG(n)        REG_BIT_FIELD(0x50+((n)<<4), 21, 1)
++#define NANDC_ACC_CTRL_ECC_LEVEL(n)   REG_BIT_FIELD(0x50+((n)<<4), 16, 5)
++#define NANDC_ACC_CTRL_SECTOR_1K(n)   REG_BIT_FIELD(0x50+((n)<<4), 7, 1)
++#define NANDC_ACC_CTRL_SPARE_SIZE(n)  REG_BIT_FIELD(0x50+((n)<<4), 0, 7)
++
++#define NANDC_CONFIG_CS(n)            REG_BIT_FIELD(0x54+((n)<<4), 0, 32)
++#define NANDC_CONFIG_LOCK(n)          REG_BIT_FIELD(0x54+((n)<<4), 31, 1)
++#define NANDC_CONFIG_BLK_SIZE(n)      REG_BIT_FIELD(0x54+((n)<<4), 28, 3)
++#define NANDC_CONFIG_CHIP_SIZE(n)     REG_BIT_FIELD(0x54+((n)<<4), 24, 4)
++#define NANDC_CONFIG_CHIP_WIDTH(n)    REG_BIT_FIELD(0x54+((n)<<4), 23, 1)
++#define NANDC_CONFIG_PAGE_SIZE(n)     REG_BIT_FIELD(0x54+((n)<<4), 20, 2)
++#define NANDC_CONFIG_FUL_ADDR_BYTES(n)        REG_BIT_FIELD(0x54+((n)<<4), 16, 3)
++#define NANDC_CONFIG_COL_ADDR_BYTES(n)        REG_BIT_FIELD(0x54+((n)<<4), 12, 3)
++#define NANDC_CONFIG_BLK_ADDR_BYTES(n)        REG_BIT_FIELD(0x54+((n)<<4), 8, 3)
++
++#define NANDC_TIMING_1_CS(n)          REG_BIT_FIELD(0x58+((n)<<4), 0, 32)
++#define NANDC_TIMING_2_CS(n)          REG_BIT_FIELD(0x5c+((n)<<4), 0, 32)
++      /* Individual bits for Timing registers - TBD */
++
++#define NANDC_CORR_STAT_THRESH_CS(n)  REG_BIT_FIELD(0xc0, 6*(n), 6)
++
++#define NANDC_BLK_WP_END_ADDR         REG_BIT_FIELD(0xc8, 0, 32)
++
++#define NANDC_MPLANE_ERASE_CYC2_OPCODE        REG_BIT_FIELD(0xcc, 24, 8)
++#define NANDC_MPLANE_READ_STAT_OPCODE REG_BIT_FIELD(0xcc, 16, 8)
++#define NANDC_MPLANE_PROG_ODD_OPCODE  REG_BIT_FIELD(0xcc, 8, 8)
++#define NANDC_MPLANE_PROG_TRL_OPCODE  REG_BIT_FIELD(0xcc, 0, 8)
++
++#define NANDC_MPLANE_PGCACHE_TRL_OPCODE       REG_BIT_FIELD(0xd0, 24, 8)
++#define NANDC_MPLANE_READ_STAT2_OPCODE        REG_BIT_FIELD(0xd0, 16, 8)
++#define NANDC_MPLANE_READ_EVEN_OPCODE REG_BIT_FIELD(0xd0, 8, 8)
++#define NANDC_MPLANE_READ_ODD__OPCODE REG_BIT_FIELD(0xd0, 0, 8)
++
++#define NANDC_MPLANE_CTRL_ERASE_CYC2_EN       REG_BIT_FIELD(0xd4, 31, 1)
++#define NANDC_MPLANE_CTRL_RD_ADDR_SIZE        REG_BIT_FIELD(0xd4, 30, 1)
++#define NANDC_MPLANE_CTRL_RD_CYC_ADDR REG_BIT_FIELD(0xd4, 29, 1)
++#define NANDC_MPLANE_CTRL_RD_COL_ADDR REG_BIT_FIELD(0xd4, 28, 1)
++
++#define NANDC_UNCORR_ERR_COUNT                REG_BIT_FIELD(0xfc, 0, 32)
++
++#define NANDC_CORR_ERR_COUNT          REG_BIT_FIELD(0x100, 0, 32)
++
++#define NANDC_READ_CORR_BIT_COUNT     REG_BIT_FIELD(0x104, 0, 32)
++
++#define NANDC_BLOCK_LOCK_STATUS               REG_BIT_FIELD(0x108, 0, 8)
++
++#define NANDC_ECC_CORR_ADDR_CS                REG_BIT_FIELD(0x10c, 16, 3)
++#define NANDC_ECC_CORR_ADDR_EXT               REG_BIT_FIELD(0x10c, 0, 16)
++
++#define NANDC_ECC_CORR_ADDR           REG_BIT_FIELD(0x110, 0, 32)
++
++#define NANDC_ECC_UNC_ADDR_CS         REG_BIT_FIELD(0x114, 16, 3)
++#define NANDC_ECC_UNC_ADDR_EXT                REG_BIT_FIELD(0x114, 0, 16)
++
++#define NANDC_ECC_UNC_ADDR            REG_BIT_FIELD(0x118, 0, 32)
++
++#define NANDC_READ_ADDR_CS            REG_BIT_FIELD(0x11c, 16, 3)
++#define NANDC_READ_ADDR_EXT           REG_BIT_FIELD(0x11c, 0, 16)
++#define NANDC_READ_ADDR                       REG_BIT_FIELD(0x120, 0, 32)
++
++#define NANDC_PROG_ADDR_CS            REG_BIT_FIELD(0x124, 16, 3)
++#define NANDC_PROG_ADDR_EXT           REG_BIT_FIELD(0x124, 0, 16)
++#define NANDC_PROG_ADDR                       REG_BIT_FIELD(0x128, 0, 32)
++
++#define NANDC_CPYBK_ADDR_CS           REG_BIT_FIELD(0x12c, 16, 3)
++#define NANDC_CPYBK_ADDR_EXT          REG_BIT_FIELD(0x12c, 0, 16)
++#define NANDC_CPYBK_ADDR              REG_BIT_FIELD(0x130, 0, 32)
++
++#define NANDC_ERASE_ADDR_CS           REG_BIT_FIELD(0x134, 16, 3)
++#define NANDC_ERASE_ADDR_EXT          REG_BIT_FIELD(0x134, 0, 16)
++#define NANDC_ERASE_ADDR              REG_BIT_FIELD(0x138, 0, 32)
++
++#define NANDC_INV_READ_ADDR_CS                REG_BIT_FIELD(0x13c, 16, 3)
++#define NANDC_INV_READ_ADDR_EXT               REG_BIT_FIELD(0x13c, 0, 16)
++#define NANDC_INV_READ_ADDR           REG_BIT_FIELD(0x140, 0, 32)
++
++#define NANDC_INIT_STAT                       REG_BIT_FIELD(0x144, 0, 32)
++#define NANDC_INIT_ONFI_DONE          REG_BIT_FIELD(0x144, 31, 1)
++#define NANDC_INIT_DEVID_DONE         REG_BIT_FIELD(0x144, 30, 1)
++#define NANDC_INIT_SUCCESS            REG_BIT_FIELD(0x144, 29, 1)
++#define NANDC_INIT_FAIL                       REG_BIT_FIELD(0x144, 28, 1)
++#define NANDC_INIT_BLANK              REG_BIT_FIELD(0x144, 27, 1)
++#define NANDC_INIT_TIMEOUT            REG_BIT_FIELD(0x144, 26, 1)
++#define NANDC_INIT_UNC_ERROR          REG_BIT_FIELD(0x144, 25, 1)
++#define NANDC_INIT_CORR_ERROR         REG_BIT_FIELD(0x144, 24, 1)
++#define NANDC_INIT_PARAM_RDY          REG_BIT_FIELD(0x144, 23, 1)
++#define NANDC_INIT_AUTH_FAIL          REG_BIT_FIELD(0x144, 22, 1)
++
++#define NANDC_ONFI_STAT                       REG_BIT_FIELD(0x148, 0, 32)
++#define NANDC_ONFI_DEBUG              REG_BIT_FIELD(0x148, 28, 4)
++#define NANDC_ONFI_PRESENT            REG_BIT_FIELD(0x148, 27, 1)
++#define NANDC_ONFI_BADID_PG2          REG_BIT_FIELD(0x148, 5, 1)
++#define NANDC_ONFI_BADID_PG1          REG_BIT_FIELD(0x148, 4, 1)
++#define NANDC_ONFI_BADID_PG0          REG_BIT_FIELD(0x148, 3, 1)
++#define NANDC_ONFI_BADCRC_PG2         REG_BIT_FIELD(0x148, 2, 1)
++#define NANDC_ONFI_BADCRC_PG1         REG_BIT_FIELD(0x148, 1, 1)
++#define NANDC_ONFI_BADCRC_PG0         REG_BIT_FIELD(0x148, 0, 1)
++
++#define NANDC_ONFI_DEBUG_DATA         REG_BIT_FIELD(0x14c, 0, 32)
++
++#define NANDC_SEMAPHORE                       REG_BIT_FIELD(0x150, 0, 8)
++
++#define NANDC_DEVID_BYTE(b)           REG_BIT_FIELD(0x194+((b)&0x4), \
++                                              24-(((b)&3)<<3), 8)
++
++#define NANDC_LL_RDDATA                       REG_BIT_FIELD(0x19c, 0, 16)
++
++#define NANDC_INT_N_REG(n)            REG_BIT_FIELD(0xf00|((n)<<2), 0, 1)
++#define NANDC_INT_DIREC_READ_MISS     REG_BIT_FIELD(0xf00, 0, 1)
++#define NANDC_INT_ERASE_DONE          REG_BIT_FIELD(0xf04, 0, 1)
++#define NANDC_INT_CPYBK_DONE          REG_BIT_FIELD(0xf08, 0, 1)
++#define NANDC_INT_PROGRAM_DONE                REG_BIT_FIELD(0xf0c, 0, 1)
++#define NANDC_INT_CONTROLLER_RDY      REG_BIT_FIELD(0xf10, 0, 1)
++#define NANDC_INT_RDBSY_RDY           REG_BIT_FIELD(0xf14, 0, 1)
++#define NANDC_INT_ECC_UNCORRECTABLE   REG_BIT_FIELD(0xf18, 0, 1)
++#define NANDC_INT_ECC_CORRECTABLE     REG_BIT_FIELD(0xf1c, 0, 1)
++
++/*
++ * Following  registers are treated as contigous IO memory, offset is from
++ * <reg_base>, and the data is in big-endian byte order
++ */
++#define NANDC_SPARE_AREA_READ_OFF     0x200
++#define NANDC_SPARE_AREA_WRITE_OFF    0x280
++#define NANDC_CACHE_OFF                       0x400
++#define NANDC_CACHE_SIZE              (128*4)
++
++struct bcmnand_areg_field {
++      unsigned int reg;
++      unsigned int pos;
++      unsigned int width;
++};
++
++/*
++ * Following are IDM (a.k.a. Slave Wrapper) registers are off <idm_base>:
++ */
++#define IDMREG_BIT_FIELD(r, p, w)     ((struct bcmnand_areg_field){(r), (p), (w)})
++
++#define NANDC_IDM_AXI_BIG_ENDIAN      IDMREG_BIT_FIELD(0x408, 28, 1)
++#define NANDC_IDM_APB_LITTLE_ENDIAN   IDMREG_BIT_FIELD(0x408, 24, 1)
++#define NANDC_IDM_TM                  IDMREG_BIT_FIELD(0x408, 16, 5)
++#define NANDC_IDM_IRQ_CORRECABLE_EN   IDMREG_BIT_FIELD(0x408, 9, 1)
++#define NANDC_IDM_IRQ_UNCORRECABLE_EN IDMREG_BIT_FIELD(0x408, 8, 1)
++#define NANDC_IDM_IRQ_RDYBSY_RDY_EN   IDMREG_BIT_FIELD(0x408, 7, 1)
++#define NANDC_IDM_IRQ_CONTROLLER_RDY_EN       IDMREG_BIT_FIELD(0x408, 6, 1)
++#define NANDC_IDM_IRQ_PRPOGRAM_COMP_EN        IDMREG_BIT_FIELD(0x408, 5, 1)
++#define NANDC_IDM_IRQ_COPYBK_COMP_EN  IDMREG_BIT_FIELD(0x408, 4, 1)
++#define NANDC_IDM_IRQ_ERASE_COMP_EN   IDMREG_BIT_FIELD(0x408, 3, 1)
++#define NANDC_IDM_IRQ_READ_MISS_EN    IDMREG_BIT_FIELD(0x408, 2, 1)
++#define NANDC_IDM_IRQ_N_EN(n)         IDMREG_BIT_FIELD(0x408, 2+(n), 1)
++
++#define NANDC_IDM_CLOCK_EN            IDMREG_BIT_FIELD(0x408, 0, 1)
++
++#define NANDC_IDM_IO_ECC_CORR         IDMREG_BIT_FIELD(0x500, 3, 1)
++#define NANDC_IDM_IO_ECC_UNCORR               IDMREG_BIT_FIELD(0x500, 2, 1)
++#define NANDC_IDM_IO_RDYBSY           IDMREG_BIT_FIELD(0x500, 1, 1)
++#define NANDC_IDM_IO_CTRL_RDY         IDMREG_BIT_FIELD(0x500, 0, 1)
++
++#define NANDC_IDM_RESET                       IDMREG_BIT_FIELD(0x800, 0, 1)
++      /* Remaining IDM registers do not seem to be useful, skipped */
++
++/*
++ * NAND Controller has its own command opcodes
++ * different from opcodes sent to the actual flash chip
++ */
++#define NANDC_CMD_OPCODE_NULL         0
++#define NANDC_CMD_OPCODE_PAGE_READ    1
++#define NANDC_CMD_OPCODE_SPARE_READ   2
++#define NANDC_CMD_OPCODE_STATUS_READ  3
++#define NANDC_CMD_OPCODE_PAGE_PROG    4
++#define NANDC_CMD_OPCODE_SPARE_PROG   5
++#define NANDC_CMD_OPCODE_DEVID_READ   7
++#define NANDC_CMD_OPCODE_BLOCK_ERASE  8
++#define NANDC_CMD_OPCODE_FLASH_RESET  9
++
++/*
++ * NAND Controller hardware ECC data size
++ *
++ * The following table contains the number of bytes needed for
++ * each of the ECC levels, per "sector", which is either 512 or 1024 bytes.
++ * The actual layout is as follows:
++ * The entire spare area is equally divided into as many sections as there
++ * are sectors per page, and the ECC data is located at the end of each
++ * of these sections.
++ * For example, given a 2K per page and 64 bytes spare device, configured for
++ * sector size 1k and ECC level of 4, the spare area will be divided into 2
++ * sections 32 bytes each, and the last 14 bytes of 32 in each section will
++ * be filled with ECC data.
++ * Note: the name of the algorythm and the number of error bits it can correct
++ * is of no consequence to this driver, therefore omitted.
++ */
++struct bcmnand_ecc_size_s {
++      unsigned char sector_size_shift;
++      unsigned char ecc_level;
++      unsigned char ecc_bytes_per_sec;
++      unsigned char reserved;
++};
++
++static const struct bcmnand_ecc_size_s bcmnand_ecc_sizes[] = {
++      { 9,    0,      0 },
++      { 10,   0,      0 },
++      { 9,    1,      2 },
++      { 10,   1,      4 },
++      { 9,    2,      4 },
++      { 10,   2,      7 },
++      { 9,    3,      6 },
++      { 10,   3,      11 },
++      { 9,    4,      7 },
++      { 10,   4,      14 },
++      { 9,    5,      9 },
++      { 10,   5,      18 },
++      { 9,    6,      11 },
++      { 10,   6,      21 },
++      { 9,    7,      13 },
++      { 10,   7,      25 },
++      { 9,    8,      14 },
++      { 10,   8,      28 },
++
++      { 9,    9,      16 },
++      { 9,    10,     18 },
++      { 9,    11,     20 },
++      { 9,    12,     21 },
++
++      { 10,   9,      32 },
++      { 10,   10,     35 },
++      { 10,   11,     39 },
++      { 10,   12,     42 },
++};
++
++/*
++ * Populate the various fields that depend on how
++ * the hardware ECC data is located in the spare area
++ *
++ * For this controiller, it is easier to fill-in these
++ * structures at run time.
++ *
++ * The bad-block marker is assumed to occupy one byte
++ * at chip->badblockpos, which must be in the first
++ * sector of the spare area, namely it is either
++ * at offset 0 or 5.
++ * Some chips use both for manufacturer's bad block
++ * markers, but we ingore that issue here, and assume only
++ * one byte is used as bad-block marker always.
++ */
++static int bcmnand_hw_ecc_layout(struct bcmnand_ctrl *ctrl)
++{
++      struct nand_ecclayout *layout;
++      struct device *dev = &ctrl->core->dev;
++      unsigned int i, j, k;
++      unsigned int ecc_per_sec, oob_per_sec;
++      unsigned int bbm_pos = ctrl->nand.badblockpos;
++
++      /* Caclculate spare area per sector size */
++      oob_per_sec = ctrl->mtd.oobsize >> ctrl->sec_per_page_shift;
++
++      /* Try to calculate the amount of ECC bytes per sector with a formula */
++      if (ctrl->sector_size_shift == 9)
++              ecc_per_sec = ((ctrl->ecc_level * 14) + 7) >> 3;
++      else if (ctrl->sector_size_shift == 10)
++              ecc_per_sec = ((ctrl->ecc_level * 14) + 3) >> 2;
++      else
++              ecc_per_sec = oob_per_sec + 1;  /* cause an error if not in table */
++
++      /* Now find out the answer according to the table */
++      for (i = 0; i < ARRAY_SIZE(bcmnand_ecc_sizes); i++) {
++              if (bcmnand_ecc_sizes[i].ecc_level == ctrl->ecc_level &&
++                  bcmnand_ecc_sizes[i].sector_size_shift ==
++                              ctrl->sector_size_shift) {
++                      break;
++              }
++      }
++
++      /* Table match overrides formula */
++      if (bcmnand_ecc_sizes[i].ecc_level == ctrl->ecc_level &&
++          bcmnand_ecc_sizes[i].sector_size_shift == ctrl->sector_size_shift)
++              ecc_per_sec = bcmnand_ecc_sizes[i].ecc_bytes_per_sec;
++
++      /* Return an error if calculated ECC leaves no room for OOB */
++      if ((ctrl->sec_per_page_shift != 0 && ecc_per_sec >= oob_per_sec) ||
++          (ctrl->sec_per_page_shift == 0 && ecc_per_sec >= (oob_per_sec - 1))) {
++              dev_err(dev, "ECC level %d too high, leaves no room for OOB data\n",
++                      ctrl->ecc_level);
++              return -EINVAL;
++      }
++
++      /* Fill in the needed fields */
++      ctrl->nand.ecc.size = ctrl->mtd.writesize >> ctrl->sec_per_page_shift;
++      ctrl->nand.ecc.bytes = ecc_per_sec;
++      ctrl->nand.ecc.steps = 1 << ctrl->sec_per_page_shift;
++      ctrl->nand.ecc.total = ecc_per_sec << ctrl->sec_per_page_shift;
++      ctrl->nand.ecc.strength = ctrl->ecc_level;
++
++      /* Build an ecc layout data structure */
++      layout = &ctrl->ecclayout;
++      memset(layout, 0, sizeof(*layout));
++
++      /* Total number of bytes used by HW ECC */
++      layout->eccbytes = ecc_per_sec << ctrl->sec_per_page_shift;
++
++      /* Location for each of the HW ECC bytes */
++      for (i = j = 0, k = 1;
++           i < ARRAY_SIZE(layout->eccpos) && i < layout->eccbytes;
++           i++, j++) {
++              /* switch sector # */
++              if (j == ecc_per_sec) {
++                      j = 0;
++                      k++;
++              }
++              /* save position of each HW-generated ECC byte */
++              layout->eccpos[i] = (oob_per_sec * k) - ecc_per_sec + j;
++
++              /* Check that HW ECC does not overlap bad-block marker */
++              if (bbm_pos == layout->eccpos[i]) {
++                      dev_err(dev, "ECC level %d too high, HW ECC collides with bad-block marker position\n",
++                              ctrl->ecc_level);
++                      return -EINVAL;
++              }
++      }
++
++      /* Location of all user-available OOB byte-ranges */
++      for (i = 0; i < ARRAY_SIZE(layout->oobfree); i++) {
++              struct nand_oobfree *oobfree = &layout->oobfree[i];
++
++              if (i >= (1 << ctrl->sec_per_page_shift))
++                      break;
++              oobfree->offset = oob_per_sec * i;
++              oobfree->length = oob_per_sec - ecc_per_sec;
++
++              /* Bad-block marker must be in the first sector spare area */
++              if (WARN_ON(bbm_pos >= (oobfree->offset + oobfree->length)))
++                      return -EINVAL;
++
++              if (i != 0)
++                      continue;
++
++              /* Remove bad-block marker from available byte range */
++              if (bbm_pos == oobfree->offset) {
++                      oobfree->offset += 1;
++                      oobfree->length -= 1;
++              } else if (bbm_pos == (oobfree->offset + oobfree->length - 1)) {
++                      oobfree->length -= 1;
++              } else {
++                      layout->oobfree[i + 1].offset = bbm_pos + 1;
++                      layout->oobfree[i + 1].length =
++                              oobfree->length - bbm_pos - 1;
++                      oobfree->length = bbm_pos;
++                      i++;
++              }
++      }
++
++      layout->oobavail = ((oob_per_sec - ecc_per_sec)
++              << ctrl->sec_per_page_shift) - 1;
++
++      ctrl->mtd.oobavail = layout->oobavail;
++      ctrl->nand.ecc.layout = layout;
++
++      /* Output layout for debugging */
++      dev_dbg(dev, "Spare area=%d eccbytes %d, ecc bytes located at:\n",
++              ctrl->mtd.oobsize, layout->eccbytes);
++      for (i = j = 0;
++           i < ARRAY_SIZE(layout->eccpos) && i < layout->eccbytes; i++)
++              pr_debug(" %d", layout->eccpos[i]);
++      pr_debug("\n");
++
++      dev_dbg(dev, "Available %d bytes at (off,len):\n", layout->oobavail);
++      for (i = 0; i < ARRAY_SIZE(layout->oobfree); i++)
++              pr_debug("(%d,%d) ", layout->oobfree[i].offset,
++                       layout->oobfree[i].length);
++      pr_debug("\n");
++
++      return 0;
++}
++
++/*
++ * Register bit-field manipulation routines
++ */
++
++static inline unsigned int bcmnand_reg_read(struct bcmnand_ctrl *ctrl,
++                                          struct bcmnand_reg_field rbf)
++{
++      u32 val;
++
++      val = bcma_read32(ctrl->core, rbf.reg);
++      val >>= rbf.pos;
++      val &= (1 << rbf.width) - 1;
++
++      return val;
++}
++
++static inline void bcmnand_reg_write(struct bcmnand_ctrl *ctrl,
++                                   struct bcmnand_reg_field rbf,
++                                   unsigned newval)
++{
++      u32 val, msk;
++
++      msk = (1 << rbf.width) - 1;
++      msk <<= rbf.pos;
++      newval <<= rbf.pos;
++      newval &= msk;
++
++      val = bcma_read32(ctrl->core, rbf.reg);
++      val &= ~msk;
++      val |= newval;
++      bcma_write32(ctrl->core, rbf.reg, val);
++}
++
++static inline unsigned int bcmnand_reg_aread(struct bcmnand_ctrl *ctrl,
++                                           struct bcmnand_areg_field rbf)
++{
++      u32 val;
++
++      val = bcma_aread32(ctrl->core, rbf.reg);
++      val >>= rbf.pos;
++      val &= (1 << rbf.width) - 1;
++
++      return val;
++}
++
++static inline void bcmnand_reg_awrite(struct bcmnand_ctrl *ctrl,
++                                    struct bcmnand_areg_field rbf,
++                                    unsigned int newval)
++{
++      u32 val, msk;
++
++      msk = (1 << rbf.width) - 1;
++      msk <<= rbf.pos;
++      newval <<= rbf.pos;
++      newval &= msk;
++
++      val = bcma_aread32(ctrl->core, rbf.reg);
++      val &= ~msk;
++      val |= newval;
++      bcma_awrite32(ctrl->core, rbf.reg, val);
++}
++
++/*
++ * NAND Interface - dev_ready
++ *
++ * Return 1 iff device is ready, 0 otherwise
++ */
++static int bcmnand_dev_ready(struct mtd_info *mtd)
++{
++      struct nand_chip *chip = mtd->priv;
++      struct bcmnand_ctrl *ctrl = chip->priv;
++
++      return bcmnand_reg_aread(ctrl, NANDC_IDM_IO_CTRL_RDY);
++}
++
++/*
++ * Interrupt service routines
++ */
++static irqreturn_t bcmnand_isr(int irq, void *dev_id)
++{
++      struct bcmnand_ctrl *ctrl = dev_id;
++      int irq_off;
++
++      irq_off = irq - ctrl->core->irq;
++      WARN_ON(irq_off < 0 || irq_off >= NANDC_IRQ_NUM);
++
++      if (!bcmnand_reg_read(ctrl, NANDC_INT_N_REG(irq_off)))
++              return IRQ_NONE;
++
++      /* Acknowledge interrupt */
++      bcmnand_reg_write(ctrl, NANDC_INT_N_REG(irq_off), 1);
++
++      /* Wake up task */
++      complete(&ctrl->op_completion);
++
++      return IRQ_HANDLED;
++}
++
++static int bcmnand_wait_interrupt(struct bcmnand_ctrl *ctrl,
++                                unsigned int irq_off,
++                                unsigned int timeout_usec)
++{
++      long timeout_jiffies;
++      int ret = 0;
++
++      reinit_completion(&ctrl->op_completion);
++
++      /* Acknowledge interrupt */
++      bcmnand_reg_write(ctrl, NANDC_INT_N_REG(irq_off), 1);
++
++      /* Enable IRQ to wait on */
++      bcmnand_reg_awrite(ctrl, NANDC_IDM_IRQ_N_EN(irq_off), 1);
++
++      timeout_jiffies = 1 + usecs_to_jiffies(timeout_usec);
++
++      if (irq_off != NANDC_IRQ_CONTROLLER_RDY ||
++              0 == bcmnand_reg_aread(ctrl, NANDC_IDM_IO_CTRL_RDY)) {
++
++              timeout_jiffies = wait_for_completion_timeout(
++                                      &ctrl->op_completion, timeout_jiffies);
++
++              if (timeout_jiffies < 0)
++                      ret =  timeout_jiffies;
++              if (timeout_jiffies == 0)
++                      ret = -ETIME;
++      }
++
++      /* Disable IRQ, we're done waiting */
++      bcmnand_reg_awrite(ctrl, NANDC_IDM_IRQ_N_EN(irq_off), 0);
++
++      if (bcmnand_reg_aread(ctrl, NANDC_IDM_IO_CTRL_RDY))
++              ret = 0;
++
++      return ret;
++}
++
++/*
++ * wait for command completion
++ */
++static int bcmnand_wait_cmd(struct bcmnand_ctrl *ctrl, unsigned int timeout_usec)
++{
++      unsigned int retries;
++
++      if (bcmnand_reg_read(ctrl, NANDC_INT_STAT_CTLR_RDY))
++              return 0;
++
++      /* If the timeout is long, wait for interrupt */
++      if (timeout_usec >= jiffies_to_usecs(1) >> 4)
++              return bcmnand_wait_interrupt(
++                      ctrl, NANDC_IRQ_CONTROLLER_RDY, timeout_usec);
++
++      /* Wait for completion of the prior command */
++      retries = (timeout_usec >> 3) + 1;
++
++      while (retries-- &&
++              0 == bcmnand_reg_read(ctrl, NANDC_INT_STAT_CTLR_RDY)) {
++              cpu_relax();
++              udelay(6);
++      }
++
++      if (retries == 0)
++              return -ETIME;
++
++      return 0;
++}
++
++
++/*
++ * NAND Interface - waitfunc
++ */
++static int bcmnand_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)
++{
++      struct bcmnand_ctrl *ctrl = chip->priv;
++      unsigned int to;
++      int ret;
++
++      /* figure out timeout based on what command is on */
++      switch (ctrl->last_cmd) {
++      default:
++      case NAND_CMD_ERASE1:
++      case NAND_CMD_ERASE2:
++              to = 1 << 16;
++              break;
++      case NAND_CMD_STATUS:
++      case NAND_CMD_RESET:
++              to = 256;
++              break;
++      case NAND_CMD_READID:
++              to = 1024;
++              break;
++      case NAND_CMD_READ1:
++      case NAND_CMD_READ0:
++              to = 2048;
++              break;
++      case NAND_CMD_PAGEPROG:
++              to = 4096;
++              break;
++      case NAND_CMD_READOOB:
++              to = 512;
++              break;
++      }
++
++      /* deliver deferred error code if any */
++      ret = ctrl->cmd_ret;
++      if (ret < 0)
++              ctrl->cmd_ret = 0;
++      else
++              ret = bcmnand_wait_cmd(ctrl, to);
++
++      /* Timeout */
++      if (ret < 0)
++              return NAND_STATUS_FAIL;
++
++      ret = bcmnand_reg_read(ctrl, NANDC_INT_STAT_FLASH_STATUS);
++
++      return ret;
++}
++
++/*
++ * NAND Interface - read_oob
++ */
++static int bcmnand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
++                          int page)
++{
++      struct bcmnand_ctrl *ctrl = chip->priv;
++      unsigned int n = ctrl->chip_num;
++      void __iomem *ctrl_spare;
++      unsigned int spare_per_sec, sector;
++      u64 nand_addr;
++
++      ctrl_spare = ctrl->core->io_addr + NANDC_SPARE_AREA_READ_OFF;
++
++      /* Set the page address for the following commands */
++      nand_addr = ((u64)page << chip->page_shift);
++      bcmnand_reg_write(ctrl, NANDC_CMD_EXT_ADDR, nand_addr >> 32);
++
++      spare_per_sec = mtd->oobsize >> ctrl->sec_per_page_shift;
++
++      /* Disable ECC validation for spare area reads */
++      bcmnand_reg_write(ctrl, NANDC_ACC_CTRL_RD_ECC(n), 0);
++
++      /* Loop all sectors in page */
++      for (sector = 0; sector < (1<<ctrl->sec_per_page_shift); sector++) {
++              unsigned int col;
++
++              col = (sector << ctrl->sector_size_shift);
++
++              /* Issue command to read partial page */
++              bcmnand_reg_write(ctrl, NANDC_CMD_ADDRESS, nand_addr + col);
++
++              bcmnand_reg_write(ctrl, NANDC_CMD_START_OPCODE,
++                                NANDC_CMD_OPCODE_SPARE_READ);
++
++              /* Wait for the command to complete */
++              if (bcmnand_wait_cmd(ctrl, (sector == 0) ? 10000 : 100))
++                      return -EIO;
++
++              if (!bcmnand_reg_read(ctrl, NANDC_INT_STAT_SPARE_VALID))
++                      return -EIO;
++
++              /* Set controller to Little Endian mode for copying */
++              bcmnand_reg_awrite(ctrl, NANDC_IDM_APB_LITTLE_ENDIAN, 1);
++
++              memcpy(chip->oob_poi + sector * spare_per_sec,
++                     ctrl_spare, spare_per_sec);
++
++              /* Return to Big Endian mode for commands etc */
++              bcmnand_reg_awrite(ctrl, NANDC_IDM_APB_LITTLE_ENDIAN, 0);
++      }
++
++      return 0;
++}
++
++/*
++ * NAND Interface - write_oob
++ */
++static int bcmnand_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
++                           int page)
++{
++      struct bcmnand_ctrl *ctrl = chip->priv;
++      unsigned int n = ctrl->chip_num;
++      void __iomem *ctrl_spare;
++      unsigned int spare_per_sec, sector, num_sec;
++      u64 nand_addr;
++      int to, status = 0;
++
++      ctrl_spare = ctrl->core->io_addr + NANDC_SPARE_AREA_WRITE_OFF;
++
++      /* Disable ECC generation for spare area writes */
++      bcmnand_reg_write(ctrl, NANDC_ACC_CTRL_WR_ECC(n), 0);
++
++      spare_per_sec = mtd->oobsize >> ctrl->sec_per_page_shift;
++
++      /* Set the page address for the following commands */
++      nand_addr = ((u64)page << chip->page_shift);
++      bcmnand_reg_write(ctrl, NANDC_CMD_EXT_ADDR, nand_addr >> 32);
++
++      /* Must allow partial programming to change spare area only */
++      bcmnand_reg_write(ctrl, NANDC_ACC_CTRL_PGM_PARTIAL(n), 1);
++
++      num_sec = 1 << ctrl->sec_per_page_shift;
++      /* Loop all sectors in page */
++      for (sector = 0; sector < num_sec; sector++) {
++              unsigned int col;
++
++              /* Spare area accessed by the data sector offset */
++              col = (sector << ctrl->sector_size_shift);
++
++              bcmnand_reg_write(ctrl, NANDC_CMD_ADDRESS, nand_addr + col);
++
++              /* Set controller to Little Endian mode for copying */
++              bcmnand_reg_awrite(ctrl, NANDC_IDM_APB_LITTLE_ENDIAN, 1);
++
++              memcpy(ctrl_spare, chip->oob_poi + sector * spare_per_sec,
++                     spare_per_sec);
++
++              /* Return to Big Endian mode for commands etc */
++              bcmnand_reg_awrite(ctrl, NANDC_IDM_APB_LITTLE_ENDIAN, 0);
++
++              /* Push spare bytes into internal buffer, last goes to flash */
++              bcmnand_reg_write(ctrl, NANDC_CMD_START_OPCODE,
++                                NANDC_CMD_OPCODE_SPARE_PROG);
++
++              if (sector == (num_sec - 1))
++                      to = 1 << 16;
++              else
++                      to = 1 << 10;
++
++              if (bcmnand_wait_cmd(ctrl, to))
++                      return -EIO;
++      }
++
++      /* Restore partial programming inhibition */
++      bcmnand_reg_write(ctrl, NANDC_ACC_CTRL_PGM_PARTIAL(n), 0);
++
++      status = bcmnand_waitfunc(mtd, chip);
++      return status & NAND_STATUS_FAIL ? -EIO : 0;
++}
++
++/*
++ * verify that a buffer is all erased
++ */
++static bool bcmnand_buf_erased(const void *buf, unsigned int len)
++{
++      unsigned int i;
++      const u32 *p = buf;
++
++      for (i = 0; i < (len >> 2); i++) {
++              if (p[i] != 0xffffffff)
++                      return false;
++      }
++      return true;
++}
++
++/*
++ * read a page, with or without ECC checking
++ */
++static int bcmnand_read_page_do(struct mtd_info *mtd, struct nand_chip *chip,
++                              uint8_t *buf, int page, bool ecc)
++{
++      struct bcmnand_ctrl *ctrl = chip->priv;
++      unsigned int n = ctrl->chip_num;
++      void __iomem *ctrl_cache;
++      void __iomem *ctrl_spare;
++      unsigned int data_bytes;
++      unsigned int spare_per_sec;
++      unsigned int sector, to = 1 << 16;
++      u32 err_soft_reg, err_hard_reg;
++      unsigned int hard_err_count = 0;
++      int ret;
++      u64 nand_addr;
++
++      ctrl_cache = ctrl->core->io_addr + NANDC_CACHE_OFF;
++      ctrl_spare = ctrl->core->io_addr + NANDC_SPARE_AREA_READ_OFF;
++
++      /* Reset  ECC error stats */
++      err_hard_reg = bcmnand_reg_read(ctrl, NANDC_UNCORR_ERR_COUNT);
++      err_soft_reg = bcmnand_reg_read(ctrl, NANDC_READ_CORR_BIT_COUNT);
++
++      spare_per_sec = mtd->oobsize >> ctrl->sec_per_page_shift;
++
++      /* Set the page address for the following commands */
++      nand_addr = ((u64)page << chip->page_shift);
++      bcmnand_reg_write(ctrl, NANDC_CMD_EXT_ADDR, nand_addr >> 32);
++
++      /* Enable ECC validation for ecc page reads */
++      bcmnand_reg_write(ctrl, NANDC_ACC_CTRL_RD_ECC(n), ecc);
++
++      /* Loop all sectors in page */
++      for (sector = 0; sector < (1 << ctrl->sec_per_page_shift); sector++) {
++              data_bytes  = 0;
++
++              /* Copy partial sectors sized by cache reg */
++              while (data_bytes < (1<<ctrl->sector_size_shift)) {
++                      unsigned int col;
++
++                      col = data_bytes + (sector << ctrl->sector_size_shift);
++
++                      bcmnand_reg_write(ctrl, NANDC_CMD_ADDRESS,
++                                        nand_addr + col);
++
++                      /* Issue command to read partial page */
++                      bcmnand_reg_write(ctrl, NANDC_CMD_START_OPCODE,
++                                        NANDC_CMD_OPCODE_PAGE_READ);
++
++                      /* Wait for the command to complete */
++                      ret = bcmnand_wait_cmd(ctrl, to);
++                      if (ret < 0)
++                              return ret;
++
++                      /* Set controller to Little Endian mode for copying */
++                      bcmnand_reg_awrite(ctrl, NANDC_IDM_APB_LITTLE_ENDIAN, 1);
++
++                      if (data_bytes == 0) {
++                              memcpy(chip->oob_poi + sector * spare_per_sec,
++                                     ctrl_spare, spare_per_sec);
++                      }
++
++                      memcpy(buf + col, ctrl_cache, NANDC_CACHE_SIZE);
++                      data_bytes += NANDC_CACHE_SIZE;
++
++                      /* Return to Big Endian mode for commands etc */
++                      bcmnand_reg_awrite(ctrl, NANDC_IDM_APB_LITTLE_ENDIAN, 0);
++
++                      /* Next iterations should go fast */
++                      to = 1 << 10;
++
++                      /* capture hard errors for each partial */
++                      if (err_hard_reg != bcmnand_reg_read(ctrl, NANDC_UNCORR_ERR_COUNT)) {
++                              int era = bcmnand_reg_read(ctrl, NANDC_INT_STAT_ERASED);
++
++                              if (!era &&
++                                  !bcmnand_buf_erased(buf + col, NANDC_CACHE_SIZE))
++                                      hard_err_count++;
++
++                              err_hard_reg = bcmnand_reg_read(ctrl,
++                                                      NANDC_UNCORR_ERR_COUNT);
++                      }
++              }
++      }
++
++      if (!ecc)
++              return 0;
++
++      /* Report hard ECC errors */
++      if (hard_err_count)
++              mtd->ecc_stats.failed++;
++
++      /* Get ECC soft error stats */
++      mtd->ecc_stats.corrected += err_soft_reg -
++                      bcmnand_reg_read(ctrl, NANDC_READ_CORR_BIT_COUNT);
++
++      return 0;
++}
++
++/*
++ * NAND Interface - read_page_ecc
++ */
++static int bcmnand_read_page_ecc(struct mtd_info *mtd, struct nand_chip *chip,
++                               uint8_t *buf, int oob_required, int page)
++{
++      return bcmnand_read_page_do(mtd, chip, buf, page, true);
++}
++
++/*
++ * NAND Interface - read_page_raw
++ */
++static int bcmnand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
++                               uint8_t *buf, int oob_required, int page)
++{
++      return bcmnand_read_page_do(mtd, chip, buf, page, true);
++}
++
++/*
++ * do page write, with or without ECC generation enabled
++ */
++static int bcmnand_write_page_do(struct mtd_info *mtd, struct nand_chip *chip,
++                               const uint8_t *buf, bool ecc)
++{
++      struct bcmnand_ctrl *ctrl = chip->priv;
++      unsigned int n = ctrl->chip_num;
++      void __iomem *ctrl_cache;
++      void __iomem *ctrl_spare;
++      unsigned int spare_per_sec, sector, num_sec;
++      unsigned int data_bytes, spare_bytes;
++      int i, to;
++      uint8_t *tmp_poi;
++      u32 nand_addr;
++
++      ctrl_cache = ctrl->core->io_addr + NANDC_CACHE_OFF;
++      ctrl_spare = ctrl->core->io_addr + NANDC_SPARE_AREA_WRITE_OFF;
++
++      /* Get start-of-page address */
++      nand_addr = bcmnand_reg_read(ctrl, NANDC_CMD_ADDRESS);
++
++      tmp_poi = kmalloc(mtd->oobsize, GFP_KERNEL);
++      if (!tmp_poi)
++              return -ENOMEM;
++
++      /* Retreive pre-existing OOB values */
++      memcpy(tmp_poi, chip->oob_poi, mtd->oobsize);
++      ctrl->cmd_ret = bcmnand_read_oob(mtd, chip,
++                                       nand_addr >> chip->page_shift);
++      if (ctrl->cmd_ret < 0) {
++              kfree(tmp_poi);
++              return ctrl->cmd_ret;
++      }
++
++      /* Apply new OOB data bytes just like they would end up on the chip */
++      for (i = 0; i < mtd->oobsize; i++)
++              chip->oob_poi[i] &= tmp_poi[i];
++      kfree(tmp_poi);
++
++      spare_per_sec = mtd->oobsize >> ctrl->sec_per_page_shift;
++
++      /* Enable ECC generation for ecc page write, if requested */
++      bcmnand_reg_write(ctrl, NANDC_ACC_CTRL_WR_ECC(n), ecc);
++
++      spare_bytes = 0;
++      num_sec = 1 << ctrl->sec_per_page_shift;
++
++      /* Loop all sectors in page */
++      for (sector = 0; sector < num_sec; sector++) {
++              data_bytes  = 0;
++
++              /* Copy partial sectors sized by cache reg */
++              while (data_bytes < (1<<ctrl->sector_size_shift)) {
++                      unsigned int col;
++
++                      col = data_bytes +
++                              (sector << ctrl->sector_size_shift);
++
++                      /* Set address of 512-byte sub-page */
++                      bcmnand_reg_write(ctrl, NANDC_CMD_ADDRESS,
++                                        nand_addr + col);
++
++                      /* Set controller to Little Endian mode for copying */
++                      bcmnand_reg_awrite(ctrl, NANDC_IDM_APB_LITTLE_ENDIAN,
++                                         1);
++
++                      /* Set spare area is written at each sector start */
++                      if (data_bytes == 0) {
++                              memcpy(ctrl_spare,
++                                      chip->oob_poi + spare_bytes,
++                                      spare_per_sec);
++                              spare_bytes += spare_per_sec;
++                      }
++
++                      /* Copy sub-page data */
++                      memcpy(ctrl_cache, buf + col, NANDC_CACHE_SIZE);
++                      data_bytes += NANDC_CACHE_SIZE;
++
++                      /* Return to Big Endian mode for commands etc */
++                      bcmnand_reg_awrite(ctrl, NANDC_IDM_APB_LITTLE_ENDIAN, 0);
++
++                      /* Push data into internal cache */
++                      bcmnand_reg_write(ctrl, NANDC_CMD_START_OPCODE,
++                                        NANDC_CMD_OPCODE_PAGE_PROG);
++
++                      /* Wait for the command to complete */
++                      if (sector == (num_sec - 1))
++                              to = 1 << 16;
++                      else
++                              to = 1 << 10;
++                      ctrl->cmd_ret = bcmnand_wait_cmd(ctrl, to);
++                      if (ctrl->cmd_ret < 0)
++                              return ctrl->cmd_ret;
++              }
++      }
++      return 0;
++}
++
++/*
++ * NAND Interface = write_page_ecc
++ */
++static int bcmnand_write_page_ecc(struct mtd_info *mtd, struct nand_chip *chip,
++                                const uint8_t *buf, int oob_required)
++{
++      return bcmnand_write_page_do(mtd, chip, buf, true);
++}
++
++/*
++ * NAND Interface = write_page_raw
++ */
++static int bcmnand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
++                                const uint8_t *buf, int oob_required)
++{
++      return bcmnand_write_page_do(mtd, chip, buf, false);
++}
++
++/*
++ * MTD Interface - read_byte
++ *
++ * This function emulates simple controllers behavior
++ * for just a few relevant commands
++ */
++static uint8_t bcmnand_read_byte(struct mtd_info *mtd)
++{
++      struct nand_chip *nand = mtd->priv;
++      struct bcmnand_ctrl *ctrl = nand->priv;
++      struct device *dev = &ctrl->core->dev;
++      uint8_t b = ~0;
++
++      switch (ctrl->last_cmd) {
++      case NAND_CMD_READID:
++              if (ctrl->id_byte_index < 8) {
++                      b = bcmnand_reg_read(ctrl, NANDC_DEVID_BYTE(
++                                                      ctrl->id_byte_index));
++                      ctrl->id_byte_index++;
++              }
++              break;
++      case NAND_CMD_READOOB:
++              if (ctrl->oob_index < mtd->oobsize)
++                      b = nand->oob_poi[ctrl->oob_index++];
++              break;
++      case NAND_CMD_STATUS:
++              b = bcmnand_reg_read(ctrl, NANDC_INT_STAT_FLASH_STATUS);
++              break;
++      default:
++              dev_err(dev, "got unkown command: 0x%x in read_byte\n",
++                      ctrl->last_cmd);
++      }
++      return b;
++}
++
++/*
++ * MTD Interface - read_word
++ *
++ * Can not be tested without x16 chip, but the SoC does not support x16 i/f.
++ */
++static u16 bcmnand_read_word(struct mtd_info *mtd)
++{
++      u16 w = ~0;
++
++      w = bcmnand_read_byte(mtd);
++      barrier();
++      w |= bcmnand_read_byte(mtd) << 8;
++
++      return w;
++}
++
++/*
++ * MTD Interface - select a chip from an array
++ */
++static void bcmnand_select_chip(struct mtd_info *mtd, int chip)
++{
++      struct nand_chip *nand = mtd->priv;
++      struct bcmnand_ctrl *ctrl = nand->priv;
++
++      ctrl->chip_num = chip;
++      bcmnand_reg_write(ctrl, NANDC_CMD_CS_SEL, chip);
++}
++
++/*
++ * NAND Interface - emulate low-level NAND commands
++ *
++ * Only a few low-level commands are really needed by generic NAND,
++ * and they do not call for CMD_LL operations the controller can support.
++ */
++static void bcmnand_cmdfunc(struct mtd_info *mtd, unsigned int command,
++                          int column, int page_addr)
++{
++      struct nand_chip *nand = mtd->priv;
++      struct bcmnand_ctrl *ctrl = nand->priv;
++      struct device *dev = &ctrl->core->dev;
++      u64 nand_addr;
++      unsigned int to = 1;
++
++      ctrl->last_cmd = command;
++
++      /* Set address for some commands */
++      switch (command) {
++      case NAND_CMD_ERASE1:
++              column = 0;
++              /*FALLTHROUGH*/
++      case NAND_CMD_SEQIN:
++      case NAND_CMD_READ0:
++      case NAND_CMD_READ1:
++              WARN_ON(column >= mtd->writesize);
++              nand_addr = (u64) column |
++                      ((u64)page_addr << nand->page_shift);
++              bcmnand_reg_write(ctrl, NANDC_CMD_EXT_ADDR, nand_addr >> 32);
++              bcmnand_reg_write(ctrl, NANDC_CMD_ADDRESS, nand_addr);
++              break;
++      case NAND_CMD_ERASE2:
++      case NAND_CMD_RESET:
++      case NAND_CMD_READID:
++      case NAND_CMD_READOOB:
++      case NAND_CMD_PAGEPROG:
++      default:
++              /* Do nothing, address not used */
++              break;
++      }
++
++      /* Issue appropriate command to controller */
++      switch (command) {
++      case NAND_CMD_SEQIN:
++              /* Only need to load command address, done */
++              return;
++
++      case NAND_CMD_RESET:
++              bcmnand_reg_write(ctrl, NANDC_CMD_START_OPCODE,
++                                NANDC_CMD_OPCODE_FLASH_RESET);
++              to = 1 << 8;
++              break;
++
++      case NAND_CMD_READID:
++              bcmnand_reg_write(ctrl, NANDC_CMD_START_OPCODE,
++                                NANDC_CMD_OPCODE_DEVID_READ);
++              ctrl->id_byte_index = 0;
++              to = 1 << 8;
++              break;
++
++      case NAND_CMD_READ0:
++      case NAND_CMD_READ1:
++              bcmnand_reg_write(ctrl, NANDC_CMD_START_OPCODE,
++                                NANDC_CMD_OPCODE_PAGE_READ);
++              to = 1 << 15;
++              break;
++      case NAND_CMD_STATUS:
++              bcmnand_reg_write(ctrl, NANDC_CMD_START_OPCODE,
++                                NANDC_CMD_OPCODE_STATUS_READ);
++              to = 1 << 8;
++              break;
++      case NAND_CMD_ERASE1:
++              return;
++
++      case NAND_CMD_ERASE2:
++              bcmnand_reg_write(ctrl, NANDC_CMD_START_OPCODE,
++                                NANDC_CMD_OPCODE_BLOCK_ERASE);
++              to = 1 << 18;
++              break;
++
++      case NAND_CMD_PAGEPROG:
++              /* Cmd already set from write_page */
++              return;
++
++      case NAND_CMD_READOOB:
++              /* Emulate simple interface */
++              bcmnand_read_oob(mtd, nand, page_addr);
++              ctrl->oob_index = 0;
++              return;
++
++      default:
++              dev_err(dev, "got unkown command: 0x%x in cmdfunc\n",
++                      ctrl->last_cmd);
++      }
++
++      /* Wait for command to complete */
++      ctrl->cmd_ret = bcmnand_wait_cmd(ctrl, to);
++
++}
++
++static int bcmnand_scan(struct mtd_info *mtd)
++{
++      struct nand_chip *nand = mtd->priv;
++      struct bcmnand_ctrl *ctrl = nand->priv;
++      struct device *dev = &ctrl->core->dev;
++      bool sector_1k = false;
++      unsigned int chip_num = 0;
++      int ecc_level = 0;
++      int ret;
++
++      ret = nand_scan_ident(mtd, NANDC_MAX_CHIPS, NULL);
++      if (ret)
++              return ret;
++
++      /* Get configuration from first chip */
++      sector_1k = bcmnand_reg_read(ctrl, NANDC_ACC_CTRL_SECTOR_1K(0));
++      ecc_level = bcmnand_reg_read(ctrl, NANDC_ACC_CTRL_ECC_LEVEL(0));
++      mtd->writesize_shift = nand->page_shift;
++
++      ctrl->ecc_level = ecc_level;
++      ctrl->sector_size_shift = sector_1k ? 10 : 9;
++
++      /* Configure spare area, tweak as needed */
++      do {
++              ctrl->sec_per_page_shift =
++                      mtd->writesize_shift - ctrl->sector_size_shift;
++
++              /* will return -EINVAL if OOB space exhausted */
++              ret = bcmnand_hw_ecc_layout(ctrl);
++
++              /* First try to bump sector size to 1k, then decrease level */
++              if (ret && nand->page_shift > 9 && ctrl->sector_size_shift < 10)
++                      ctrl->sector_size_shift = 10;
++              else if (ret)
++                      ctrl->ecc_level--;
++
++      } while (ret && ctrl->ecc_level > 0);
++
++      if (WARN_ON(ctrl->ecc_level == 0))
++              return -ENOENT;
++
++      if ((ctrl->sector_size_shift > 9) != (sector_1k == 1)) {
++              dev_info(dev, "sector size adjusted to 1k\n");
++              sector_1k = 1;
++      }
++
++      if (ecc_level != ctrl->ecc_level) {
++              dev_info(dev, "ECC level adjusted from %u to %u\n",
++                       ecc_level, ctrl->ecc_level);
++              ecc_level = ctrl->ecc_level;
++      }
++
++      /* handle the hardware chip config registers */
++      for (chip_num = 0; chip_num < nand->numchips; chip_num++) {
++              bcmnand_reg_write(ctrl, NANDC_ACC_CTRL_SECTOR_1K(chip_num),
++                                sector_1k);
++              bcmnand_reg_write(ctrl, NANDC_ACC_CTRL_ECC_LEVEL(chip_num),
++                                ecc_level);
++
++              /* Large pages: no partial page programming */
++              if (mtd->writesize > 512) {
++                      bcmnand_reg_write(ctrl,
++                              NANDC_ACC_CTRL_PGM_RDIN(chip_num), 0);
++                      bcmnand_reg_write(ctrl,
++                              NANDC_ACC_CTRL_PGM_PARTIAL(chip_num), 0);
++              }
++
++              /* Do not raise ECC error when reading erased pages */
++              /* This bit has only partial effect, driver needs to help */
++              bcmnand_reg_write(ctrl, NANDC_ACC_CTRL_ERA_ECC_ERR(chip_num),
++                                0);
++
++              bcmnand_reg_write(ctrl, NANDC_ACC_CTRL_PG_HIT(chip_num), 0);
++              bcmnand_reg_write(ctrl, NANDC_ACC_CTRL_PREFETCH(chip_num), 0);
++              bcmnand_reg_write(ctrl, NANDC_ACC_CTRL_CACHE_MODE(chip_num), 0);
++              bcmnand_reg_write(ctrl, NANDC_ACC_CTRL_CACHE_LASTPG(chip_num),
++                                0);
++
++              /* TBD: consolidate or at least verify the s/w and h/w geometries agree */
++      }
++
++      /* Allow writing on device */
++      if (!(nand->options & NAND_ROM))
++              bcmnand_reg_write(ctrl, NANDC_CS_NAND_WP, 0);
++
++      dev_dbg(dev, "layout.oobavail=%d\n", nand->ecc.layout->oobavail);
++
++      ret = nand_scan_tail(mtd);
++
++      if (nand->badblockbits == 0)
++              nand->badblockbits = 8;
++      if (WARN_ON((1 << nand->page_shift) != mtd->writesize))
++              return -EIO;
++
++      /* Spit out some key chip parameters as detected by nand_base */
++      dev_dbg(dev, "erasesize=%d writesize=%d oobsize=%d page_shift=%d badblockpos=%d badblockbits=%d\n",
++              mtd->erasesize, mtd->writesize, mtd->oobsize,
++              nand->page_shift, nand->badblockpos, nand->badblockbits);
++
++      return ret;
++}
++
++/*
++ * main intiailization function
++ */
++static int bcmnand_ctrl_init(struct bcmnand_ctrl *ctrl)
++{
++      unsigned int chip;
++      struct nand_chip *nand;
++      struct mtd_info *mtd;
++      struct device *dev = &ctrl->core->dev;
++      int ret;
++
++      /* Software variables init */
++      nand = &ctrl->nand;
++      mtd = &ctrl->mtd;
++
++      init_completion(&ctrl->op_completion);
++
++      mtd->priv = nand;
++      mtd->owner = THIS_MODULE;
++      mtd->name = KBUILD_MODNAME;
++
++      nand->priv = ctrl;
++
++      nand->chip_delay = 5;   /* not used */
++      nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)~0L;
++
++      if (bcmnand_reg_read(ctrl, NANDC_CONFIG_CHIP_WIDTH(0)))
++              nand->options |= NAND_BUSWIDTH_16;
++      nand->options |= NAND_SKIP_BBTSCAN;     /* Dont need BBTs */
++
++      nand->options |= NAND_NO_SUBPAGE_WRITE; /* Subpages unsupported */
++
++      nand->dev_ready                 = bcmnand_dev_ready;
++      nand->read_byte                 = bcmnand_read_byte;
++      nand->read_word                 = bcmnand_read_word;
++      nand->select_chip               = bcmnand_select_chip;
++      nand->cmdfunc                   = bcmnand_cmdfunc;
++      nand->waitfunc                  = bcmnand_waitfunc;
++
++      nand->ecc.mode                  = NAND_ECC_HW;
++      nand->ecc.read_page_raw         = bcmnand_read_page_raw;
++      nand->ecc.write_page_raw        = bcmnand_write_page_raw;
++      nand->ecc.read_page             = bcmnand_read_page_ecc;
++      nand->ecc.write_page            = bcmnand_write_page_ecc;
++      nand->ecc.read_oob              = bcmnand_read_oob;
++      nand->ecc.write_oob             = bcmnand_write_oob;
++
++      /* Set AUTO_CNFIG bit - try to auto-detect chips */
++      bcmnand_reg_write(ctrl, NANDC_CS_AUTO_CONFIG, 1);
++
++      usleep_range(1000, 1500);
++
++      /* Print out current chip config */
++      for (chip = 0; chip < NANDC_MAX_CHIPS; chip++) {
++              dev_dbg(dev, "chip[%d]: size=%#x block=%#x page=%#x ecc_level=%#x\n",
++                      chip,
++                      bcmnand_reg_read(ctrl, NANDC_CONFIG_CHIP_SIZE(chip)),
++                      bcmnand_reg_read(ctrl, NANDC_CONFIG_BLK_SIZE(chip)),
++                      bcmnand_reg_read(ctrl, NANDC_CONFIG_PAGE_SIZE(chip)),
++                      bcmnand_reg_read(ctrl, NANDC_ACC_CTRL_ECC_LEVEL(chip)));
++      }
++
++      dev_dbg(dev, "Nand controller is reads=%d\n",
++              bcmnand_reg_aread(ctrl, NANDC_IDM_IO_CTRL_RDY));
++
++      ret = bcmnand_scan(mtd);
++      if (ret) {
++              dev_err(dev, "scanning the nand flash chip failed with %i\n",
++                      ret);
++              return ret;
++      }
++
++      return 0;
++}
++
++static int bcmnand_idm_init(struct bcmnand_ctrl *ctrl)
++{
++      int irq_off;
++      unsigned int retries = 0x1000;
++      struct device *dev = &ctrl->core->dev;
++
++      if (bcmnand_reg_aread(ctrl, NANDC_IDM_RESET))
++              dev_info(dev, "stuck in reset\n");
++
++      bcmnand_reg_awrite(ctrl, NANDC_IDM_RESET, 1);
++      if (!bcmnand_reg_aread(ctrl, NANDC_IDM_RESET)) {
++              dev_err(dev, "reset of failed\n");
++              return -EIO;
++      }
++
++      while (bcmnand_reg_aread(ctrl, NANDC_IDM_RESET)) {
++              bcmnand_reg_awrite(ctrl, NANDC_IDM_RESET, 0);
++              cpu_relax();
++              usleep_range(100, 150);
++              if (!(retries--)) {
++                      dev_err(dev, "did not came back from reset\n");
++                      return -ETIMEDOUT;
++              }
++      }
++
++      bcmnand_reg_awrite(ctrl, NANDC_IDM_CLOCK_EN, 1);
++      bcmnand_reg_awrite(ctrl, NANDC_IDM_APB_LITTLE_ENDIAN, 0);
++      udelay(10);
++
++      dev_info(dev, "NAND Controller rev %d.%02d\n",
++              bcmnand_reg_read(ctrl, NANDC_REV_MAJOR),
++              bcmnand_reg_read(ctrl, NANDC_REV_MINOR));
++
++      usleep_range(250, 350);
++
++      /* Disable all IRQs */
++      for (irq_off = 0; irq_off < NANDC_IRQ_NUM; irq_off++)
++              bcmnand_reg_awrite(ctrl, NANDC_IDM_IRQ_N_EN(irq_off), 0);
++
++      return 0;
++}
++
++static const char * const part_probes[] = { "ofpart", "bcm47xxpart", NULL };
++
++/*
++ * Top-level init function
++ */
++static int bcmnand_probe(struct bcma_device *core)
++{
++      struct mtd_part_parser_data parser_data;
++      struct device *dev = &core->dev;
++      struct bcmnand_ctrl *ctrl;
++      int res, i, irq;
++
++      ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
++      if (!ctrl)
++              return -ENOMEM;
++
++      bcma_set_drvdata(core, ctrl);
++
++      ctrl->mtd.dev.parent = &core->dev;
++      ctrl->core = core;
++
++      /* Acquire all interrupt lines */
++      for (i = 0; i < NANDC_IRQ_NUM; i++) {
++              irq = bcma_core_irq(core, i);
++              if (!irq) {
++                      dev_err(dev, "IRQ idx %i not available\n", i);
++                      return -ENOENT;
++              }
++              res = devm_request_irq(dev, irq, bcmnand_isr, 0,
++                                     KBUILD_MODNAME, ctrl);
++              if (res < 0) {
++                      dev_err(dev, "problem requesting irq: %i (idx: %i)\n",
++                              irq, i);
++                      return res;
++              }
++      }
++
++      res = bcmnand_idm_init(ctrl);
++      if (res)
++              return res;
++
++      res = bcmnand_ctrl_init(ctrl);
++      if (res)
++              return res;
++
++      parser_data.of_node = dev->of_node;
++      res = mtd_device_parse_register(&ctrl->mtd, part_probes, &parser_data, NULL, 0);
++      if (res) {
++              dev_err(dev, "Failed to register MTD device: %d\n", res);
++              return res;
++      }
++      return 0;
++}
++
++static void bcmnand_remove(struct bcma_device *core)
++{
++      struct bcmnand_ctrl *ctrl = bcma_get_drvdata(core);
++
++      mtd_device_unregister(&ctrl->mtd);
++}
++
++static const struct bcma_device_id bcmnand_bcma_tbl[] = {
++      BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_NAND, BCMA_ANY_REV, BCMA_ANY_CLASS),
++      {},
++};
++MODULE_DEVICE_TABLE(bcma, bgmac_bcma_tbl);
++
++static struct bcma_driver bcmnand_bcma_driver = {
++      .name           = KBUILD_MODNAME,
++      .id_table       = bcmnand_bcma_tbl,
++      .probe          = bcmnand_probe,
++      .remove         = bcmnand_remove,
++};
++
++static int __init bcmnand_init(void)
++{
++      return bcma_driver_register(&bcmnand_bcma_driver);
++}
++
++static void __exit bcmnand_exit(void)
++{
++      bcma_driver_unregister(&bcmnand_bcma_driver);
++}
++
++module_init(bcmnand_init)
++module_exit(bcmnand_exit)
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Hauke Mehrtens");
++MODULE_DESCRIPTION("Northstar on-chip NAND Flash Controller driver");
diff --git a/target/linux/bcm53xx/patches-4.1/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch b/target/linux/bcm53xx/patches-4.1/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch
new file mode 100644 (file)
index 0000000..a3d0f75
--- /dev/null
@@ -0,0 +1,59 @@
+From 2a2af518266a29323cf30c3f9ba9ef2ceb1dd84b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Thu, 16 Oct 2014 20:52:16 +0200
+Subject: [PATCH] UBI: Detect EOF mark and erase all remaining blocks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+ drivers/mtd/ubi/attach.c | 5 +++++
+ drivers/mtd/ubi/io.c     | 4 ++++
+ drivers/mtd/ubi/ubi.h    | 1 +
+ 3 files changed, 10 insertions(+)
+
+--- a/drivers/mtd/ubi/attach.c
++++ b/drivers/mtd/ubi/attach.c
+@@ -95,6 +95,9 @@ static int self_check_ai(struct ubi_devi
+ static struct ubi_ec_hdr *ech;
+ static struct ubi_vid_hdr *vidh;
++/* Set on finding block with 0xdeadc0de, indicates erasing all blocks behind */
++bool erase_all_next;
++
+ /**
+  * add_to_list - add physical eraseblock to a list.
+  * @ai: attaching information
+@@ -1427,6 +1430,8 @@ int ubi_attach(struct ubi_device *ubi, i
+       if (!ai)
+               return -ENOMEM;
++      erase_all_next = false;
++
+ #ifdef CONFIG_MTD_UBI_FASTMAP
+       /* On small flash devices we disable fastmap in any case. */
+       if ((int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) <= UBI_FM_MAX_START) {
+--- a/drivers/mtd/ubi/io.c
++++ b/drivers/mtd/ubi/io.c
+@@ -755,6 +755,10 @@ int ubi_io_read_ec_hdr(struct ubi_device
+       }
+       magic = be32_to_cpu(ec_hdr->magic);
++      if (magic == 0xdeadc0de)
++              erase_all_next = true;
++      if (erase_all_next)
++              return read_err ? UBI_IO_FF_BITFLIPS : UBI_IO_FF;
+       if (magic != UBI_EC_HDR_MAGIC) {
+               if (mtd_is_eccerr(read_err))
+                       return UBI_IO_BAD_HDR_EBADMSG;
+--- a/drivers/mtd/ubi/ubi.h
++++ b/drivers/mtd/ubi/ubi.h
+@@ -781,6 +781,7 @@ extern struct mutex ubi_devices_mutex;
+ extern struct blocking_notifier_head ubi_notifiers;
+ /* attach.c */
++extern bool erase_all_next;
+ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
+                 int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips);
+ struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai,
diff --git a/target/linux/bcm53xx/patches-4.1/700-bgmac-add-support-for-the-3rd-bus-core-device.patch b/target/linux/bcm53xx/patches-4.1/700-bgmac-add-support-for-the-3rd-bus-core-device.patch
new file mode 100644 (file)
index 0000000..6be75bb
--- /dev/null
@@ -0,0 +1,63 @@
+From f5d5afc0b1402aae0f6a2350e43241603dbaff1e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Wed, 13 May 2015 10:46:47 +0200
+Subject: [PATCH] bgmac: add support for the 3rd bus core (device)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+So far we were supporting up to 2 cores but recent devices (e.g. Netgear
+R8000) may use 3rd as well. Lower ones (1st, 2nd) are usually used for
+some offloading then.
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+ drivers/net/ethernet/broadcom/bgmac.c | 28 +++++++++++++++++++++++-----
+ 1 file changed, 23 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/broadcom/bgmac.c
++++ b/drivers/net/ethernet/broadcom/bgmac.c
+@@ -1561,11 +1561,20 @@ static int bgmac_probe(struct bcma_devic
+       struct net_device *net_dev;
+       struct bgmac *bgmac;
+       struct ssb_sprom *sprom = &core->bus->sprom;
+-      u8 *mac = core->core_unit ? sprom->et1mac : sprom->et0mac;
++      u8 *mac;
+       int err;
+-      /* We don't support 2nd, 3rd, ... units, SPROM has to be adjusted */
+-      if (core->core_unit > 1) {
++      switch (core->core_unit) {
++      case 0:
++              mac = sprom->et0mac;
++              break;
++      case 1:
++              mac = sprom->et1mac;
++              break;
++      case 2:
++              mac = sprom->et2mac;
++              break;
++      default:
+               pr_err("Unsupported core_unit %d\n", core->core_unit);
+               return -ENOTSUPP;
+       }
+@@ -1600,8 +1609,17 @@ static int bgmac_probe(struct bcma_devic
+       }
+       bgmac->cmn = core->bus->drv_gmac_cmn.core;
+-      bgmac->phyaddr = core->core_unit ? sprom->et1phyaddr :
+-                       sprom->et0phyaddr;
++      switch (core->core_unit) {
++      case 0:
++              bgmac->phyaddr = sprom->et0phyaddr;
++              break;
++      case 1:
++              bgmac->phyaddr = sprom->et1phyaddr;
++              break;
++      case 2:
++              bgmac->phyaddr = sprom->et2phyaddr;
++              break;
++      }
+       bgmac->phyaddr &= BGMAC_PHY_MASK;
+       if (bgmac->phyaddr == BGMAC_PHY_MASK) {
+               bgmac_err(bgmac, "No PHY found\n");
diff --git a/target/linux/bcm53xx/patches-4.1/710-b53-add-hacky-CPU-port-fixes-for-devices-not-using-p.patch b/target/linux/bcm53xx/patches-4.1/710-b53-add-hacky-CPU-port-fixes-for-devices-not-using-p.patch
new file mode 100644 (file)
index 0000000..6015c4a
--- /dev/null
@@ -0,0 +1,35 @@
+From 4abdde3ad6bc0b3b157c4bf6ec0bf139d11d07e8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Wed, 13 May 2015 14:13:28 +0200
+Subject: [PATCH] b53: add hacky CPU port fixes for devices not using port 5
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+ drivers/net/phy/b53/b53_common.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/net/phy/b53/b53_common.c
++++ b/drivers/net/phy/b53/b53_common.c
+@@ -25,6 +25,7 @@
+ #include <linux/module.h>
+ #include <linux/switch.h>
+ #include <linux/platform_data/b53.h>
++#include <linux/of.h>
+ #include "b53_regs.h"
+ #include "b53_priv.h"
+@@ -1313,6 +1314,11 @@ static int b53_switch_init(struct b53_de
+                       sw_dev->cpu_port = 5;
+       }
++      if (of_machine_is_compatible("asus,rt-ac87u"))
++              sw_dev->cpu_port = 7;
++      else if (of_machine_is_compatible("netgear,r8000"))
++              sw_dev->cpu_port = 8;
++
+       /* cpu port is always last */
+       sw_dev->ports = sw_dev->cpu_port + 1;
+       dev->enabled_ports |= BIT(sw_dev->cpu_port);
diff --git a/target/linux/bcm53xx/patches-4.1/800-bcma-use-two-different-initcalls-if-built-in.patch b/target/linux/bcm53xx/patches-4.1/800-bcma-use-two-different-initcalls-if-built-in.patch
new file mode 100644 (file)
index 0000000..9f2cd39
--- /dev/null
@@ -0,0 +1,65 @@
+From 666bdfc027cde41a171862dc698987a378c8b66a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Mon, 9 Feb 2015 18:00:42 +0100
+Subject: [PATCH RFC] bcma: use two different initcalls if built-in
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This is needed as we can't initialize bus during fs_initcall.
+Initialization requires SPROM which depends on NVRAM which depends on
+mtd. Since mtd, spi, nand, spi-nor use standard module_init, we have to
+do the same in bcma.
+Without this we'll try to initialize SPROM without having a ready SPROM
+proviver registered using bcma_arch_register_fallback_sprom.
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+While this patch seems to work and I can compile bcma as built-in and
+module, I'm not too proud of it. I don't really like these #if(n)def
+tricks and I'm afraid bcma_modinit may be called even if
+bcma_modinit_early failed.
+
+Do you see any better idea of solving this?
+---
+ drivers/bcma/main.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+--- a/drivers/bcma/main.c
++++ b/drivers/bcma/main.c
+@@ -637,13 +637,25 @@ static int bcma_device_uevent(struct dev
+                             core->id.rev, core->id.class);
+ }
++/* Bus has to be registered early, before any bcma driver */
++static int __init bcma_modinit_early(void)
++{
++      return bus_register(&bcma_bus_type);
++}
++#ifndef MODULE
++fs_initcall(bcma_modinit_early);
++#endif
++
++/* Initialization has to be done later with SPI/mtd/NAND/SPROM available */
+ static int __init bcma_modinit(void)
+ {
+       int err;
+-      err = bus_register(&bcma_bus_type);
++#ifdef MODULE
++      err = bcma_modinit_early();
+       if (err)
+               return err;
++#endif
+       err = bcma_host_soc_register_driver();
+       if (err) {
+@@ -660,7 +672,7 @@ static int __init bcma_modinit(void)
+       return err;
+ }
+-fs_initcall(bcma_modinit);
++module_init(bcma_modinit);
+ static void __exit bcma_modexit(void)
+ {
diff --git a/target/linux/bcm53xx/patches-4.1/810-USB-bcma-make-helper-creating-platform-dev-more-gene.patch b/target/linux/bcm53xx/patches-4.1/810-USB-bcma-make-helper-creating-platform-dev-more-gene.patch
new file mode 100644 (file)
index 0000000..d331ae6
--- /dev/null
@@ -0,0 +1,73 @@
+From 5b4fed9fc917cc2bfc5297eeab03aeba5d340618 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Tue, 16 Jun 2015 12:33:46 +0200
+Subject: [PATCH] USB: bcma: make helper creating platform dev more generic
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Having "bool ohci" argument bounded us to two cases only and didn't
+allow re-using this code for XHCI.
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+ drivers/usb/host/bcma-hcd.c | 24 +++++++++++++-----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+--- a/drivers/usb/host/bcma-hcd.c
++++ b/drivers/usb/host/bcma-hcd.c
+@@ -249,7 +249,10 @@ static const struct usb_ehci_pdata ehci_
+ static const struct usb_ohci_pdata ohci_pdata = {
+ };
+-static struct platform_device *bcma_hcd_create_pdev(struct bcma_device *dev, bool ohci, u32 addr)
++static struct platform_device *bcma_hcd_create_pdev(struct bcma_device *dev,
++                                                  const char *name, u32 addr,
++                                                  const void *data,
++                                                  size_t size)
+ {
+       struct platform_device *hci_dev;
+       struct resource hci_res[2];
+@@ -264,8 +267,7 @@ static struct platform_device *bcma_hcd_
+       hci_res[1].start = dev->irq;
+       hci_res[1].flags = IORESOURCE_IRQ;
+-      hci_dev = platform_device_alloc(ohci ? "ohci-platform" :
+-                                      "ehci-platform" , 0);
++      hci_dev = platform_device_alloc(name, 0);
+       if (!hci_dev)
+               return ERR_PTR(-ENOMEM);
+@@ -276,12 +278,8 @@ static struct platform_device *bcma_hcd_
+                                           ARRAY_SIZE(hci_res));
+       if (ret)
+               goto err_alloc;
+-      if (ohci)
+-              ret = platform_device_add_data(hci_dev, &ohci_pdata,
+-                                             sizeof(ohci_pdata));
+-      else
+-              ret = platform_device_add_data(hci_dev, &ehci_pdata,
+-                                             sizeof(ehci_pdata));
++      if (data)
++              ret = platform_device_add_data(hci_dev, data, size);
+       if (ret)
+               goto err_alloc;
+       ret = platform_device_add(hci_dev);
+@@ -334,11 +332,15 @@ static int bcma_hcd_probe(struct bcma_de
+           && chipinfo->rev == 0)
+               ohci_addr = 0x18009000;
+-      usb_dev->ohci_dev = bcma_hcd_create_pdev(dev, true, ohci_addr);
++      usb_dev->ohci_dev = bcma_hcd_create_pdev(dev, "ohci-platform",
++                                               ohci_addr, &ohci_pdata,
++                                               sizeof(ohci_pdata));
+       if (IS_ERR(usb_dev->ohci_dev))
+               return PTR_ERR(usb_dev->ohci_dev);
+-      usb_dev->ehci_dev = bcma_hcd_create_pdev(dev, false, dev->addr);
++      usb_dev->ehci_dev = bcma_hcd_create_pdev(dev, "ehci-platform",
++                                               dev->addr, &ehci_pdata,
++                                               sizeof(ehci_pdata));
+       if (IS_ERR(usb_dev->ehci_dev)) {
+               err = PTR_ERR(usb_dev->ehci_dev);
+               goto err_unregister_ohci_dev;
diff --git a/target/linux/bcm53xx/patches-4.1/811-USB-bcma-use-separated-function-for-USB-2.0-initiali.patch b/target/linux/bcm53xx/patches-4.1/811-USB-bcma-use-separated-function-for-USB-2.0-initiali.patch
new file mode 100644 (file)
index 0000000..758b0ac
--- /dev/null
@@ -0,0 +1,102 @@
+From 4aed231f49954114d5ae23e97789e9aa540a0b70 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Tue, 16 Jun 2015 12:52:07 +0200
+Subject: [PATCH] USB: bcma: use separated function for USB 2.0 initialization
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This will allow adding USB 3.0 (XHCI) support cleanly.
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+ drivers/usb/host/bcma-hcd.c | 51 +++++++++++++++++++++++++++++++--------------
+ 1 file changed, 35 insertions(+), 16 deletions(-)
+
+--- a/drivers/usb/host/bcma-hcd.c
++++ b/drivers/usb/host/bcma-hcd.c
+@@ -34,6 +34,7 @@ MODULE_DESCRIPTION("Common USB driver fo
+ MODULE_LICENSE("GPL");
+ struct bcma_hcd_device {
++      struct bcma_device *core;
+       struct platform_device *ehci_dev;
+       struct platform_device *ohci_dev;
+ };
+@@ -293,27 +294,16 @@ err_alloc:
+       return ERR_PTR(ret);
+ }
+-static int bcma_hcd_probe(struct bcma_device *dev)
++static int bcma_hcd_usb20_init(struct bcma_hcd_device *usb_dev)
+ {
+-      int err;
++      struct bcma_device *dev = usb_dev->core;
++      struct bcma_chipinfo *chipinfo = &dev->bus->chipinfo;
+       u32 ohci_addr;
+-      struct bcma_hcd_device *usb_dev;
+-      struct bcma_chipinfo *chipinfo;
+-
+-      chipinfo = &dev->bus->chipinfo;
+-
+-      /* TODO: Probably need checks here; is the core connected? */
++      int err;
+       if (dma_set_mask_and_coherent(dev->dma_dev, DMA_BIT_MASK(32)))
+               return -EOPNOTSUPP;
+-      usb_dev = devm_kzalloc(&dev->dev, sizeof(struct bcma_hcd_device),
+-                             GFP_KERNEL);
+-      if (!usb_dev)
+-              return -ENOMEM;
+-
+-      bcma_hci_platform_power_gpio(dev, true);
+-
+       switch (dev->id.id) {
+       case BCMA_CORE_NS_USB20:
+               bcma_hcd_init_chip_arm(dev);
+@@ -346,7 +336,6 @@ static int bcma_hcd_probe(struct bcma_de
+               goto err_unregister_ohci_dev;
+       }
+-      bcma_set_drvdata(dev, usb_dev);
+       return 0;
+ err_unregister_ohci_dev:
+@@ -354,6 +343,36 @@ err_unregister_ohci_dev:
+       return err;
+ }
++static int bcma_hcd_probe(struct bcma_device *dev)
++{
++      int err;
++      struct bcma_hcd_device *usb_dev;
++
++      /* TODO: Probably need checks here; is the core connected? */
++
++      usb_dev = devm_kzalloc(&dev->dev, sizeof(struct bcma_hcd_device),
++                             GFP_KERNEL);
++      if (!usb_dev)
++              return -ENOMEM;
++      usb_dev->core = dev;
++
++      bcma_hci_platform_power_gpio(dev, true);
++
++      switch (dev->id.id) {
++      case BCMA_CORE_USB20_HOST:
++      case BCMA_CORE_NS_USB20:
++              err = bcma_hcd_usb20_init(usb_dev);
++              if (err)
++                      return err;
++              break;
++      default:
++              return -ENODEV;
++      }
++
++      bcma_set_drvdata(dev, usb_dev);
++      return 0;
++}
++
+ static void bcma_hcd_remove(struct bcma_device *dev)
+ {
+       struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev);
diff --git a/target/linux/bcm53xx/patches-4.1/812-USB-bcma-add-USB-3.0-support.patch b/target/linux/bcm53xx/patches-4.1/812-USB-bcma-add-USB-3.0-support.patch
new file mode 100644 (file)
index 0000000..3875da4
--- /dev/null
@@ -0,0 +1,274 @@
+From 12c6932caa6b1fce44d0f0c68ec77d4c00ac0be7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Tue, 16 Jun 2015 17:14:26 +0200
+Subject: [PATCH] USB: bcma: add USB 3.0 support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+ drivers/usb/host/bcma-hcd.c | 219 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 219 insertions(+)
+
+--- a/drivers/usb/host/bcma-hcd.c
++++ b/drivers/usb/host/bcma-hcd.c
+@@ -37,6 +37,7 @@ struct bcma_hcd_device {
+       struct bcma_device *core;
+       struct platform_device *ehci_dev;
+       struct platform_device *ohci_dev;
++      struct platform_device *xhci_dev;
+ };
+ /* Wait for bitmask in a register to get set or cleared.
+@@ -343,6 +344,215 @@ err_unregister_ohci_dev:
+       return err;
+ }
++static bool bcma_wait_reg(struct bcma_bus *bus, void __iomem *addr, u32 mask,
++                        u32 value, int timeout)
++{
++      unsigned long deadline = jiffies + timeout;
++      u32 val;
++
++      do {
++              val = readl(addr);
++              if ((val & mask) == value)
++                      return true;
++              cpu_relax();
++              udelay(10);
++      } while (!time_after_eq(jiffies, deadline));
++
++      pr_err("Timeout waiting for register %p\n", addr);
++
++      return false;
++}
++
++static void bcma_hcd_usb30_phy_init(struct bcma_hcd_device *bcma_hcd)
++{
++      struct bcma_device *core = bcma_hcd->core;
++      struct bcma_bus *bus = core->bus;
++      struct bcma_chipinfo *chipinfo = &bus->chipinfo;
++      struct bcma_drv_cc_b *ccb = &bus->drv_cc_b;
++      struct bcma_device *arm_core;
++      void __iomem *dmu = NULL;
++      u32 cru_straps_ctrl;
++
++      if (chipinfo->id != BCMA_CHIP_ID_BCM4707 &&
++          chipinfo->id != BCMA_CHIP_ID_BCM53018)
++              return;
++
++      arm_core = bcma_find_core(bus, BCMA_CORE_ARMCA9);
++      if (!arm_core)
++              return;
++
++      dmu = ioremap_nocache(arm_core->addr_s[0], 0x1000);
++      if (!dmu)
++              goto out;
++
++      /* Check strapping of PCIE/USB3 SEL */
++      cru_straps_ctrl = ioread32(dmu + 0x2a0);
++      if ((cru_straps_ctrl & 0x10) == 0)
++              goto out;
++
++      /* Perform USB3 system soft reset */
++      bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
++
++      /* Enable MDIO. Setting MDCDIV as 26  */
++      iowrite32(0x0000009a, ccb->mii + 0x000);
++      udelay(2);
++
++      switch (chipinfo->id) {
++      case BCMA_CHIP_ID_BCM4707:
++              if (chipinfo->rev == 4) {
++                      /* For NS-B0, USB3 PLL Block */
++                      bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++                      iowrite32(0x587e8000, ccb->mii + 0x004);
++
++                      /* Clear ana_pllSeqStart */
++                      bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++                      iowrite32(0x58061000, ccb->mii + 0x004);
++
++                      /* CMOS Divider ratio to 25 */
++                      bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++                      iowrite32(0x582a6400, ccb->mii + 0x004);
++
++                      /* Asserting PLL Reset */
++                      bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++                      iowrite32(0x582ec000, ccb->mii + 0x004);
++
++                      /* Deaaserting PLL Reset */
++                      bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++                      iowrite32(0x582e8000, ccb->mii + 0x004);
++
++                      /* Deasserting USB3 system reset */
++                      bcma_awrite32(core, BCMA_RESET_CTL, 0);
++
++                      /* Set ana_pllSeqStart */
++                      bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++                      iowrite32(0x58069000, ccb->mii + 0x004);
++
++                      /* RXPMD block */
++                      bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++                      iowrite32(0x587e8020, ccb->mii + 0x004);
++
++                      /* CDR int loop locking BW to 1 */
++                      bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++                      iowrite32(0x58120049, ccb->mii + 0x004);
++
++                      /* CDR int loop acquisition BW to 1 */
++                      bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++                      iowrite32(0x580e0049, ccb->mii + 0x004);
++
++                      /* CDR prop loop BW to 1 */
++                      bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++                      iowrite32(0x580a005c, ccb->mii + 0x004);
++
++                      /* Waiting MII Mgt interface idle */
++                      bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++              } else {
++                      /* PLL30 block */
++                      bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++                      iowrite32(0x587e8000, ccb->mii + 0x004);
++
++                      bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++                      iowrite32(0x582a6400, ccb->mii + 0x004);
++
++                      bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++                      iowrite32(0x587e80e0, ccb->mii + 0x004);
++
++                      bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++                      iowrite32(0x580a009c, ccb->mii + 0x004);
++
++                      /* Enable SSC */
++                      bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++                      iowrite32(0x587e8040, ccb->mii + 0x004);
++
++                      bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++                      iowrite32(0x580a21d3, ccb->mii + 0x004);
++
++                      bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++                      iowrite32(0x58061003, ccb->mii + 0x004);
++
++                      /* Waiting MII Mgt interface idle */
++                      bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++
++                      /* Deasserting USB3 system reset */
++                      bcma_awrite32(core, BCMA_RESET_CTL, 0);
++              }
++              break;
++      case BCMA_CHIP_ID_BCM53018:
++              /* USB3 PLL Block */
++              bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++              iowrite32(0x587e8000, ccb->mii + 0x004);
++
++              /* Assert Ana_Pllseq start */
++              bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++              iowrite32(0x58061000, ccb->mii + 0x004);
++
++              /* Assert CML Divider ratio to 26 */
++              bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++              iowrite32(0x582a6400, ccb->mii + 0x004);
++
++              /* Asserting PLL Reset */
++              bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++              iowrite32(0x582ec000, ccb->mii + 0x004);
++
++              /* Deaaserting PLL Reset */
++              bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++              iowrite32(0x582e8000, ccb->mii + 0x004);
++
++              /* Waiting MII Mgt interface idle */
++              bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++
++              /* Deasserting USB3 system reset */
++              bcma_awrite32(core, BCMA_RESET_CTL, 0);
++
++              /* PLL frequency monitor enable */
++              bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++              iowrite32(0x58069000, ccb->mii + 0x004);
++
++              /* PIPE Block */
++              bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++              iowrite32(0x587e8060, ccb->mii + 0x004);
++
++              /* CMPMAX & CMPMINTH setting */
++              bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++              iowrite32(0x580af30d, ccb->mii + 0x004);
++
++              /* DEGLITCH MIN & MAX setting */
++              bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++              iowrite32(0x580e6302, ccb->mii + 0x004);
++
++              /* TXPMD block */
++              bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++              iowrite32(0x587e8040, ccb->mii + 0x004);
++
++              /* Enabling SSC */
++              bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++              iowrite32(0x58061003, ccb->mii + 0x004);
++
++              /* Waiting MII Mgt interface idle */
++              bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
++
++              break;
++      }
++out:
++      if (dmu)
++              iounmap(dmu);
++}
++
++static int bcma_hcd_usb30_init(struct bcma_hcd_device *bcma_hcd)
++{
++      struct bcma_device *core = bcma_hcd->core;
++
++      bcma_core_enable(core, 0);
++
++      bcma_hcd_usb30_phy_init(bcma_hcd);
++
++      bcma_hcd->xhci_dev = bcma_hcd_create_pdev(core, "xhci-hcd", core->addr,
++                                                NULL, 0);
++      if (IS_ERR(bcma_hcd->ohci_dev))
++              return PTR_ERR(bcma_hcd->ohci_dev);
++
++      return 0;
++}
++
+ static int bcma_hcd_probe(struct bcma_device *dev)
+ {
+       int err;
+@@ -365,6 +575,11 @@ static int bcma_hcd_probe(struct bcma_de
+               if (err)
+                       return err;
+               break;
++      case BCMA_CORE_NS_USB30:
++              err = bcma_hcd_usb30_init(usb_dev);
++              if (err)
++                      return err;
++              break;
+       default:
+               return -ENODEV;
+       }
+@@ -378,11 +593,14 @@ static void bcma_hcd_remove(struct bcma_
+       struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev);
+       struct platform_device *ohci_dev = usb_dev->ohci_dev;
+       struct platform_device *ehci_dev = usb_dev->ehci_dev;
++      struct platform_device *xhci_dev = usb_dev->xhci_dev;
+       if (ohci_dev)
+               platform_device_unregister(ohci_dev);
+       if (ehci_dev)
+               platform_device_unregister(ehci_dev);
++      if (xhci_dev)
++              platform_device_unregister(xhci_dev);
+       bcma_core_disable(dev, 0);
+ }
+@@ -419,6 +637,7 @@ static int bcma_hcd_resume(struct bcma_d
+ static const struct bcma_device_id bcma_hcd_table[] = {
+       BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS),
+       BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB20, BCMA_ANY_REV, BCMA_ANY_CLASS),
++      BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB30, BCMA_ANY_REV, BCMA_ANY_CLASS),
+       {},
+ };
+ MODULE_DEVICE_TABLE(bcma, bcma_hcd_table);
diff --git a/target/linux/bcm53xx/patches-4.1/813-USB-bcma-fix-setting-VCC-GPIO-value.patch b/target/linux/bcm53xx/patches-4.1/813-USB-bcma-fix-setting-VCC-GPIO-value.patch
new file mode 100644 (file)
index 0000000..9ba3bde
--- /dev/null
@@ -0,0 +1,45 @@
+From bdc3b01d94b22f8b5f9621a1c37336e78f4f1bce Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Sun, 21 Jun 2015 12:09:57 +0200
+Subject: [PATCH] USB: bcma: fix setting VCC GPIO value
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+It wasn't working (on most of devices?) without setting GPIO direction
+and wasn't respecting ACTIVE_LOW flag.
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+ drivers/usb/host/bcma-hcd.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/host/bcma-hcd.c
++++ b/drivers/usb/host/bcma-hcd.c
+@@ -230,17 +230,22 @@ static void bcma_hcd_init_chip_arm(struc
+ static void bcma_hci_platform_power_gpio(struct bcma_device *dev, bool val)
+ {
++      enum of_gpio_flags of_flags;
+       int gpio;
+-      gpio = of_get_named_gpio(dev->dev.of_node, "vcc-gpio", 0);
++      gpio = of_get_named_gpio_flags(dev->dev.of_node, "vcc-gpio", 0, &of_flags);
+       if (!gpio_is_valid(gpio))
+               return;
+       if (val) {
+-              gpio_request(gpio, "bcma-hcd-gpio");
+-              gpio_set_value(gpio, 1);
++              unsigned long flags = 0;
++              bool active_low = !!(of_flags & OF_GPIO_ACTIVE_LOW);
++
++              flags |= active_low ? GPIOF_ACTIVE_LOW : 0;
++              flags |= active_low ? GPIOF_INIT_LOW : GPIOF_INIT_HIGH;
++              gpio_request_one(gpio, flags, "bcma-hcd-gpio");
+       } else {
+-              gpio_set_value(gpio, 0);
++              gpiod_set_value(gpio_to_desc(gpio), 0);
+               gpio_free(gpio);
+       }
+ }
diff --git a/target/linux/bcm53xx/patches-4.1/820-xhci-add-Broadcom-specific-fake-doorbell.patch b/target/linux/bcm53xx/patches-4.1/820-xhci-add-Broadcom-specific-fake-doorbell.patch
new file mode 100644 (file)
index 0000000..9a87a75
--- /dev/null
@@ -0,0 +1,94 @@
+From 9cc14ca0aae53c16d10ffea49848ac61a5015562 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Sun, 21 Jun 2015 11:10:49 +0200
+Subject: [PATCH] xhci: add Broadcom specific fake doorbell
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This fixes problem with controller seeing devices only in some small
+percentage of cold boots.
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+ drivers/usb/host/xhci.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 62 insertions(+)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -121,6 +121,64 @@ int xhci_halt(struct xhci_hcd *xhci)
+       return ret;
+ }
++#ifdef CONFIG_ARCH_BCM_5301X
++int xhci_fake_doorbell(struct xhci_hcd *xhci, int slot_id)
++{
++      unsigned int temp1, ret;
++
++      /* alloc a virt device for slot */
++      if (!xhci_alloc_virt_device(xhci, slot_id, 0, GFP_NOIO)) {
++              xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
++              return 1;
++        }
++
++      /* ring fake doorbell for slot_id ep 0 */
++      xhci_ring_ep_doorbell(xhci, slot_id, 0, 0);
++      mdelay(1);
++
++      /* read the status register to check if HSE is set or not? */
++      temp1 = readl(&xhci->op_regs->status);
++      xhci_dbg(xhci, "op reg status = %x\n",temp1);
++
++      /* clear HSE if set */
++      if(temp1 & STS_FATAL) {
++              xhci_dbg(xhci, "HSE problem detected\n");
++              temp1 &= ~(0x1fff);
++              temp1 |= STS_FATAL;
++              xhci_dbg(xhci, "temp1=%x\n",temp1);
++              writel(temp1, &xhci->op_regs->status);
++              mdelay(1);
++              temp1 = readl(&xhci->op_regs->status);
++              xhci_dbg(xhci, "After clear op reg status=%x\n", temp1);
++      }
++
++      /* Free virt device */
++      xhci_free_virt_device(xhci, slot_id);
++
++      /* Run the controller if needed */
++      temp1 = readl(&xhci->op_regs->command);
++      if (temp1 & CMD_RUN)
++              return 0;
++      temp1 |= (CMD_RUN);
++
++      writel(temp1, &xhci->op_regs->command);
++      /*
++       * Wait for the HCHalted Status bit to be 0 to indicate the host is running.
++       */
++      ret = xhci_handshake(xhci, &xhci->op_regs->status,
++                           STS_HALT, 0, XHCI_MAX_HALT_USEC);
++
++      if (ret == -ETIMEDOUT) {
++              xhci_err(xhci, "Host took too long to start, "
++                              "waited %u microseconds.\n",
++                              XHCI_MAX_HALT_USEC);
++              return 1;
++      }
++
++      return 0;
++}
++#endif /* CONFIG_ARCH_BCM_5301X */
++
+ /*
+  * Set the run bit and wait for the host to be running.
+  */
+@@ -145,6 +203,10 @@ static int xhci_start(struct xhci_hcd *x
+               xhci_err(xhci, "Host took too long to start, "
+                               "waited %u microseconds.\n",
+                               XHCI_MAX_HALT_USEC);
++#ifdef CONFIG_ARCH_BCM_5301X
++      xhci_fake_doorbell(xhci, 1);
++#endif /* CONFIG_ARCH_BCM_5301X */
++
+       if (!ret)
+               xhci->xhc_state &= ~XHCI_STATE_HALTED;
+       return ret;
diff --git a/target/linux/bcm53xx/patches-4.1/901-mtd-bcm47xxpart-workaround-for-Asus-RT-AC87U-asus-pa.patch b/target/linux/bcm53xx/patches-4.1/901-mtd-bcm47xxpart-workaround-for-Asus-RT-AC87U-asus-pa.patch
new file mode 100644 (file)
index 0000000..c1dfa92
--- /dev/null
@@ -0,0 +1,42 @@
+From 21500872c1dba33848ddcf6bea97d58772675d36 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Sun, 17 May 2015 14:00:52 +0200
+Subject: [PATCH] mtd: bcm47xxpart: workaround for Asus RT-AC87U "asus"
+ partition
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+---
+ drivers/mtd/bcm47xxpart.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/mtd/bcm47xxpart.c
++++ b/drivers/mtd/bcm47xxpart.c
+@@ -14,6 +14,7 @@
+ #include <linux/slab.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
++#include <linux/of.h>
+ #include <uapi/linux/magic.h>
+@@ -135,6 +136,17 @@ static int bcm47xxpart_parse(struct mtd_
+                       break;
+               }
++              /*
++               * Ugly workaround for Asus RT-AC87U and its "asus" partition.
++               * It uses JFFS2 which we don't (want to) detect. We should
++               * probably use DT to define partitions but we need a working
++               * TRX firmware splitter first.
++               */
++              if (of_machine_is_compatible("asus,rt-ac87u") && offset == 0x7ec0000) {
++                      bcm47xxpart_add_part(&parts[curr_part++], "asus", offset, MTD_WRITEABLE);
++                      continue;
++              }
++
+               /* Read beginning of the block */
+               if (mtd_read(master, offset, BCM47XXPART_BYTES_TO_READ,
+                            &bytes_read, (uint8_t *)buf) < 0) {