summaryrefslogtreecommitdiff
path: root/target/linux/bcm53xx
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm53xx')
-rw-r--r--target/linux/bcm53xx/Makefile28
-rw-r--r--target/linux/bcm53xx/base-files.mk3
-rw-r--r--target/linux/bcm53xx/base-files/etc/uci-defaults/02_network21
-rw-r--r--target/linux/bcm53xx/config-3.14235
-rw-r--r--target/linux/bcm53xx/image/Makefile56
-rw-r--r--target/linux/bcm53xx/patches-3.14/001-mtd-spi-nor.patch2443
-rw-r--r--target/linux/bcm53xx/patches-3.14/040-ARM-BCM5301X-initial-support-for-the-BCM5301X-BCM470.patch148
-rw-r--r--target/linux/bcm53xx/patches-3.14/041-ARM-BCM5301X-add-early-debugging-support.patch45
-rw-r--r--target/linux/bcm53xx/patches-3.14/042-ARM-BCM5301X-workaround-suppress-fault.patch93
-rw-r--r--target/linux/bcm53xx/patches-3.14/050-ARM-BCM5301X-add-dts-files-for-BCM4708-SoC.patch204
-rw-r--r--target/linux/bcm53xx/patches-3.14/110-bcm47xx-move-the-nvram-header-file-into-common-space.patch270
-rw-r--r--target/linux/bcm53xx/patches-3.14/111-bcm47xx-nvram-add-new-nvram-driver-with-dt-support.patch520
-rw-r--r--target/linux/bcm53xx/patches-3.14/112-bcm53xx-sprom-add-sprom-driver.patch667
-rw-r--r--target/linux/bcm53xx/patches-3.14/120-bcma-register-bcma-as-device-tree-driver.patch115
-rw-r--r--target/linux/bcm53xx/patches-3.14/121-bcma-get-irqs-from-dt.patch76
-rw-r--r--target/linux/bcm53xx/patches-3.14/123-bcma-get-sprom-from-devicetree.patch88
-rw-r--r--target/linux/bcm53xx/patches-3.14/130-ARM-BCM5301X-register-bcma-bus.patch74
-rw-r--r--target/linux/bcm53xx/patches-3.14/131-ARM-BCM5301X-add-restart-support.patch69
-rw-r--r--target/linux/bcm53xx/patches-3.14/140-bcma-only-map-wrap-if-it-is-not-null.patch32
-rw-r--r--target/linux/bcm53xx/patches-3.14/141-bcma-store-more-alternative-addresses.patch71
-rw-r--r--target/linux/bcm53xx/patches-3.14/142-bcma-add-support-for-chipcommon-B-core.patch180
-rw-r--r--target/linux/bcm53xx/patches-3.14/150-pci-do-not-probe-too-early.patch29
-rw-r--r--target/linux/bcm53xx/patches-3.14/160-bcma-add-PCI-IDs-for-more-devices.patch23
-rw-r--r--target/linux/bcm53xx/patches-3.14/170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch645
-rw-r--r--target/linux/bcm53xx/patches-3.14/180-spi-bcm53xx-driver-for-SPI-controller-on-Broadcom-bc.patch435
-rw-r--r--target/linux/bcm53xx/patches-3.14/900-bgmac-some-fixes-to-get-bgmac-work.patch33
-rw-r--r--target/linux/bcm53xx/profiles/100-Generic.mk19
27 files changed, 0 insertions, 6622 deletions
diff --git a/target/linux/bcm53xx/Makefile b/target/linux/bcm53xx/Makefile
deleted file mode 100644
index f9d7e32..0000000
--- a/target/linux/bcm53xx/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# Copyright (C) 2013 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-include $(TOPDIR)/rules.mk
-
-ARCH:=arm
-BOARD:=bcm53xx
-BOARDNAME:=Broadcom BCM47xx/53xx (ARM)
-FEATURES:=squashfs usb pci pcie gpio
-MAINTAINER:=Hauke Mehrtens <hauke@hauke-m.de>
-CPU_TYPE:=cortex-a9
-
-LINUX_VERSION:=3.14.16
-
-include $(INCLUDE_DIR)/target.mk
-
-define Target/Description
- Build firmware images for Broadcom based BCM47xx/53xx routers with ARM CPU, *not* MIPS.
-endef
-
-KERNELNAME:="zImage dtbs"
-
-DEFAULT_PACKAGES += swconfig wpad-mini
-
-$(eval $(call BuildTarget))
diff --git a/target/linux/bcm53xx/base-files.mk b/target/linux/bcm53xx/base-files.mk
deleted file mode 100644
index fdd2c71..0000000
--- a/target/linux/bcm53xx/base-files.mk
+++ /dev/null
@@ -1,3 +0,0 @@
-define Package/base-files/install-target
- rm -f $(1)/etc/config/network
-endef
diff --git a/target/linux/bcm53xx/base-files/etc/uci-defaults/02_network b/target/linux/bcm53xx/base-files/etc/uci-defaults/02_network
deleted file mode 100644
index 7517d07..0000000
--- a/target/linux/bcm53xx/base-files/etc/uci-defaults/02_network
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/sh
-#
-# Copyright (C) 2011 OpenWrt.org
-#
-
-[ -e /etc/config/network ] && exit 0
-
-touch /etc/config/network
-
-. /lib/functions/uci-defaults.sh
-
-ucidef_set_interface_loopback
-
-ucidef_set_interfaces_lan_wan "eth0.1" "eth0.2"
-ucidef_add_switch "switch0" "1" "1"
-ucidef_add_switch_vlan "switch0" "1" "0 1 2 3 5t"
-ucidef_add_switch_vlan "switch0" "2" "4 5t"
-
-uci commit network
-
-exit 0
diff --git a/target/linux/bcm53xx/config-3.14 b/target/linux/bcm53xx/config-3.14
deleted file mode 100644
index f703522..0000000
--- a/target/linux/bcm53xx/config-3.14
+++ /dev/null
@@ -1,235 +0,0 @@
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_ARCH_BCM=y
-CONFIG_ARCH_BCM_5301X=y
-# CONFIG_ARCH_BCM_MOBILE is not set
-CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
-CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
-CONFIG_ARCH_HAS_TICK_BROADCAST=y
-CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=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_NEEDS_CPU_IDLE_COUPLED is not set
-CONFIG_ARCH_NR_GPIO=0
-# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
-# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
-CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=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_ARM=y
-CONFIG_ARM_APPENDED_DTB=y
-# CONFIG_ARM_ATAG_DTB_COMPAT is not set
-# CONFIG_ARM_CPU_SUSPEND is not set
-CONFIG_ARM_GIC=y
-CONFIG_ARM_GLOBAL_TIMER=y
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-# CONFIG_ARM_LPAE is not set
-CONFIG_ARM_NR_BANKS=8
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-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_BCM53XX_SPROM=y
-CONFIG_BCMA=y
-CONFIG_BCMA_BLOCKIO=y
-CONFIG_BCMA_DEBUG=y
-CONFIG_BCMA_DRIVER_GMAC_CMN=y
-CONFIG_BCMA_HOST_PCI=y
-CONFIG_BCMA_HOST_PCI_POSSIBLE=y
-CONFIG_BCMA_HOST_SOC=y
-# CONFIG_BCM_KONA_WDT is not set
-CONFIG_BGMAC=y
-CONFIG_CACHE_L2X0=y
-CONFIG_CACHE_PL310=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_CLKDEV_LOOKUP=y
-CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=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_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_BCM_5301X=y
-# CONFIG_DEBUG_BCM_KONA_UART is not set
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL=y
-CONFIG_DEBUG_LL_INCLUDE="debug/pl01x.S"
-# CONFIG_DEBUG_LL_UART_8250 is not set
-# CONFIG_DEBUG_LL_UART_PL01X is not set
-# CONFIG_DEBUG_UART_8250 is not set
-CONFIG_DEBUG_UART_PHYS=0x18000300
-CONFIG_DEBUG_UART_PL01X=y
-CONFIG_DEBUG_UART_VIRT=0xf1000300
-CONFIG_DEBUG_UNCOMPRESS=y
-CONFIG_DEBUG_USER=y
-CONFIG_DTC=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_FRAME_POINTER=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IO=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_NET_UTILS=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
-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_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_HZ_FIXED=0
-CONFIG_HZ_PERIODIC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IOMMU_HELPER=y
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_KTIME_SCALAR=y
-CONFIG_MDIO_BOARDINFO=y
-CONFIG_MIGHT_HAVE_PCI=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MTD_BCM47XX_PARTS=y
-# CONFIG_MTD_PHYSMAP_OF is not set
-CONFIG_MTD_SPI_NOR=y
-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_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=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_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_PCI_BCMA=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PHYLIB=y
-# CONFIG_PL310_ERRATA_588369 is not set
-# CONFIG_PL310_ERRATA_727915 is not set
-# CONFIG_PL310_ERRATA_753970 is not set
-# CONFIG_PL310_ERRATA_769419 is not set
-# CONFIG_PREEMPT_RCU is not set
-CONFIG_RCU_STALL_COMMON=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_SCHED_HRTICK=y
-# CONFIG_SCSI_DMA 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_MASTER=y
-CONFIG_STOP_MACHINE=y
-CONFIG_SWCONFIG=y
-CONFIG_SWIOTLB=y
-# CONFIG_SWP_EMULATE is not set
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-# CONFIG_THUMB2_KERNEL is not set
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TREE_RCU=y
-CONFIG_UID16=y
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-CONFIG_VECTORS_BASE=0xffff0000
-# CONFIG_VFP is not set
-# 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_ZONE_DMA_FLAG=0
diff --git a/target/linux/bcm53xx/image/Makefile b/target/linux/bcm53xx/image/Makefile
deleted file mode 100644
index 61bc39c..0000000
--- a/target/linux/bcm53xx/image/Makefile
+++ /dev/null
@@ -1,56 +0,0 @@
-#
-# Copyright (C) 2013 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-include $(TOPDIR)/rules.mk
-include $(INCLUDE_DIR)/image.mk
-
-define Image/Prepare
- rm -f $(KDIR)/fs_mark
- echo -ne '\xde\xad\xc0\xde' > $(KDIR)/fs_mark
- $(call prepare_generic_squashfs,$(KDIR)/fs_mark)
-endef
-
-define Image/Build/Initramfs
- $(call Image/Build/Initramfs/Chk,bcm4708-netgear-r6250,U12H245T00_NETGEAR,2,initramfs)
-endef
-
-define Image/Build/Initramfs/Chk
- $(call Image/Build/Initramfs/DTB,$(1))
- $(STAGING_DIR_HOST)/bin/mkchkimg -o $(BIN_DIR)/openwrt-$(1)-$(4).chk -k $(KDIR)/$(IMG_PREFIX)-$(4)-$(1).trx -b $(2) -r $(3)
-endef
-
-define Image/Build/Initramfs/DTB
- $(call Image/Build/DTB,zImage-initramfs,$(1))
- $(STAGING_DIR_HOST)/bin/trx -o $(KDIR)/$(IMG_PREFIX)-initramfs-$(1).trx \
- -f $(KDIR)/zImage-initramfs-$(1).lzma
-endef
-
-define Image/Build/squashfs/DTB
- $(call Image/Build/DTB,zImage,$(1))
- $(STAGING_DIR_HOST)/bin/trx -o $(KDIR)/$(IMG_PREFIX)-squashfs-$(1).trx \
- -f $(KDIR)/zImage-$(1).lzma \
- -a 1024 -f $(KDIR)/root.squashfs -a 0x10000 -A $(KDIR)/fs_mark
-endef
-
-define Image/Build/squashfs/Chk
- $(call Image/Build/squashfs/DTB,$(1))
- $(STAGING_DIR_HOST)/bin/mkchkimg -o $(BIN_DIR)/openwrt-$(1)-$(4).chk -k $(KDIR)/$(IMG_PREFIX)-$(4)-$(1).trx -b $(2) -r $(3)
-endef
-
-define Image/Build/DTB
- rm -f $(KDIR)/$(1)-$(2).lzma
- rm -f $(KDIR)/$(1)-$(2).dts
- cat $(KDIR)/$(1) $(DTS_DIR)/$(2).dtb > $(KDIR)/$(1)-$(2).dts;
- $(STAGING_DIR_HOST)/bin/lzma e $(KDIR)/$(1)-$(2).dts $(KDIR)/$(1)-$(2).lzma -d16
-endef
-
-define Image/Build
- $(call Image/Build/$(1),$(1))
- $(call Image/Build/squashfs/Chk,bcm4708-netgear-r6250,U12H245T00_NETGEAR,2,squashfs)
-endef
-
-
-$(eval $(call BuildImage))
diff --git a/target/linux/bcm53xx/patches-3.14/001-mtd-spi-nor.patch b/target/linux/bcm53xx/patches-3.14/001-mtd-spi-nor.patch
deleted file mode 100644
index fb916ca..0000000
--- a/target/linux/bcm53xx/patches-3.14/001-mtd-spi-nor.patch
+++ /dev/null
@@ -1,2443 +0,0 @@
-This patches adds the SPI-NOR device support code form kernel 3.17-rc1.
-This patch does not contain any further code not in this mainline kernel.
-
---- a/drivers/mtd/Kconfig
-+++ b/drivers/mtd/Kconfig
-@@ -394,6 +394,8 @@ source "drivers/mtd/onenand/Kconfig"
-
- source "drivers/mtd/lpddr/Kconfig"
-
-+source "drivers/mtd/spi-nor/Kconfig"
-+
- source "drivers/mtd/ubi/Kconfig"
-
- endif # MTD
---- a/drivers/mtd/Makefile
-+++ b/drivers/mtd/Makefile
-@@ -39,4 +39,5 @@ inftl-objs := inftlcore.o inftlmount.o
-
- obj-y += chips/ lpddr/ maps/ devices/ nand/ onenand/ tests/
-
-+obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/
- obj-$(CONFIG_MTD_UBI) += ubi/
---- /dev/null
-+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
-@@ -0,0 +1,1009 @@
-+/*
-+ * Freescale QuadSPI driver.
-+ *
-+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ */
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/interrupt.h>
-+#include <linux/errno.h>
-+#include <linux/platform_device.h>
-+#include <linux/sched.h>
-+#include <linux/delay.h>
-+#include <linux/io.h>
-+#include <linux/clk.h>
-+#include <linux/err.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/timer.h>
-+#include <linux/jiffies.h>
-+#include <linux/completion.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/mtd/spi-nor.h>
-+
-+/* The registers */
-+#define QUADSPI_MCR 0x00
-+#define QUADSPI_MCR_RESERVED_SHIFT 16
-+#define QUADSPI_MCR_RESERVED_MASK (0xF << QUADSPI_MCR_RESERVED_SHIFT)
-+#define QUADSPI_MCR_MDIS_SHIFT 14
-+#define QUADSPI_MCR_MDIS_MASK (1 << QUADSPI_MCR_MDIS_SHIFT)
-+#define QUADSPI_MCR_CLR_TXF_SHIFT 11
-+#define QUADSPI_MCR_CLR_TXF_MASK (1 << QUADSPI_MCR_CLR_TXF_SHIFT)
-+#define QUADSPI_MCR_CLR_RXF_SHIFT 10
-+#define QUADSPI_MCR_CLR_RXF_MASK (1 << QUADSPI_MCR_CLR_RXF_SHIFT)
-+#define QUADSPI_MCR_DDR_EN_SHIFT 7
-+#define QUADSPI_MCR_DDR_EN_MASK (1 << QUADSPI_MCR_DDR_EN_SHIFT)
-+#define QUADSPI_MCR_END_CFG_SHIFT 2
-+#define QUADSPI_MCR_END_CFG_MASK (3 << QUADSPI_MCR_END_CFG_SHIFT)
-+#define QUADSPI_MCR_SWRSTHD_SHIFT 1
-+#define QUADSPI_MCR_SWRSTHD_MASK (1 << QUADSPI_MCR_SWRSTHD_SHIFT)
-+#define QUADSPI_MCR_SWRSTSD_SHIFT 0
-+#define QUADSPI_MCR_SWRSTSD_MASK (1 << QUADSPI_MCR_SWRSTSD_SHIFT)
-+
-+#define QUADSPI_IPCR 0x08
-+#define QUADSPI_IPCR_SEQID_SHIFT 24
-+#define QUADSPI_IPCR_SEQID_MASK (0xF << QUADSPI_IPCR_SEQID_SHIFT)
-+
-+#define QUADSPI_BUF0CR 0x10
-+#define QUADSPI_BUF1CR 0x14
-+#define QUADSPI_BUF2CR 0x18
-+#define QUADSPI_BUFXCR_INVALID_MSTRID 0xe
-+
-+#define QUADSPI_BUF3CR 0x1c
-+#define QUADSPI_BUF3CR_ALLMST_SHIFT 31
-+#define QUADSPI_BUF3CR_ALLMST (1 << QUADSPI_BUF3CR_ALLMST_SHIFT)
-+
-+#define QUADSPI_BFGENCR 0x20
-+#define QUADSPI_BFGENCR_PAR_EN_SHIFT 16
-+#define QUADSPI_BFGENCR_PAR_EN_MASK (1 << (QUADSPI_BFGENCR_PAR_EN_SHIFT))
-+#define QUADSPI_BFGENCR_SEQID_SHIFT 12
-+#define QUADSPI_BFGENCR_SEQID_MASK (0xF << QUADSPI_BFGENCR_SEQID_SHIFT)
-+
-+#define QUADSPI_BUF0IND 0x30
-+#define QUADSPI_BUF1IND 0x34
-+#define QUADSPI_BUF2IND 0x38
-+#define QUADSPI_SFAR 0x100
-+
-+#define QUADSPI_SMPR 0x108
-+#define QUADSPI_SMPR_DDRSMP_SHIFT 16
-+#define QUADSPI_SMPR_DDRSMP_MASK (7 << QUADSPI_SMPR_DDRSMP_SHIFT)
-+#define QUADSPI_SMPR_FSDLY_SHIFT 6
-+#define QUADSPI_SMPR_FSDLY_MASK (1 << QUADSPI_SMPR_FSDLY_SHIFT)
-+#define QUADSPI_SMPR_FSPHS_SHIFT 5
-+#define QUADSPI_SMPR_FSPHS_MASK (1 << QUADSPI_SMPR_FSPHS_SHIFT)
-+#define QUADSPI_SMPR_HSENA_SHIFT 0
-+#define QUADSPI_SMPR_HSENA_MASK (1 << QUADSPI_SMPR_HSENA_SHIFT)
-+
-+#define QUADSPI_RBSR 0x10c
-+#define QUADSPI_RBSR_RDBFL_SHIFT 8
-+#define QUADSPI_RBSR_RDBFL_MASK (0x3F << QUADSPI_RBSR_RDBFL_SHIFT)
-+
-+#define QUADSPI_RBCT 0x110
-+#define QUADSPI_RBCT_WMRK_MASK 0x1F
-+#define QUADSPI_RBCT_RXBRD_SHIFT 8
-+#define QUADSPI_RBCT_RXBRD_USEIPS (0x1 << QUADSPI_RBCT_RXBRD_SHIFT)
-+
-+#define QUADSPI_TBSR 0x150
-+#define QUADSPI_TBDR 0x154
-+#define QUADSPI_SR 0x15c
-+#define QUADSPI_SR_IP_ACC_SHIFT 1
-+#define QUADSPI_SR_IP_ACC_MASK (0x1 << QUADSPI_SR_IP_ACC_SHIFT)
-+#define QUADSPI_SR_AHB_ACC_SHIFT 2
-+#define QUADSPI_SR_AHB_ACC_MASK (0x1 << QUADSPI_SR_AHB_ACC_SHIFT)
-+
-+#define QUADSPI_FR 0x160
-+#define QUADSPI_FR_TFF_MASK 0x1
-+
-+#define QUADSPI_SFA1AD 0x180
-+#define QUADSPI_SFA2AD 0x184
-+#define QUADSPI_SFB1AD 0x188
-+#define QUADSPI_SFB2AD 0x18c
-+#define QUADSPI_RBDR 0x200
-+
-+#define QUADSPI_LUTKEY 0x300
-+#define QUADSPI_LUTKEY_VALUE 0x5AF05AF0
-+
-+#define QUADSPI_LCKCR 0x304
-+#define QUADSPI_LCKER_LOCK 0x1
-+#define QUADSPI_LCKER_UNLOCK 0x2
-+
-+#define QUADSPI_RSER 0x164
-+#define QUADSPI_RSER_TFIE (0x1 << 0)
-+
-+#define QUADSPI_LUT_BASE 0x310
-+
-+/*
-+ * The definition of the LUT register shows below:
-+ *
-+ * ---------------------------------------------------
-+ * | INSTR1 | PAD1 | OPRND1 | INSTR0 | PAD0 | OPRND0 |
-+ * ---------------------------------------------------
-+ */
-+#define OPRND0_SHIFT 0
-+#define PAD0_SHIFT 8
-+#define INSTR0_SHIFT 10
-+#define OPRND1_SHIFT 16
-+
-+/* Instruction set for the LUT register. */
-+#define LUT_STOP 0
-+#define LUT_CMD 1
-+#define LUT_ADDR 2
-+#define LUT_DUMMY 3
-+#define LUT_MODE 4
-+#define LUT_MODE2 5
-+#define LUT_MODE4 6
-+#define LUT_READ 7
-+#define LUT_WRITE 8
-+#define LUT_JMP_ON_CS 9
-+#define LUT_ADDR_DDR 10
-+#define LUT_MODE_DDR 11
-+#define LUT_MODE2_DDR 12
-+#define LUT_MODE4_DDR 13
-+#define LUT_READ_DDR 14
-+#define LUT_WRITE_DDR 15
-+#define LUT_DATA_LEARN 16
-+
-+/*
-+ * The PAD definitions for LUT register.
-+ *
-+ * The pad stands for the lines number of IO[0:3].
-+ * For example, the Quad read need four IO lines, so you should
-+ * set LUT_PAD4 which means we use four IO lines.
-+ */
-+#define LUT_PAD1 0
-+#define LUT_PAD2 1
-+#define LUT_PAD4 2
-+
-+/* Oprands for the LUT register. */
-+#define ADDR24BIT 0x18
-+#define ADDR32BIT 0x20
-+
-+/* Macros for constructing the LUT register. */
-+#define LUT0(ins, pad, opr) \
-+ (((opr) << OPRND0_SHIFT) | ((LUT_##pad) << PAD0_SHIFT) | \
-+ ((LUT_##ins) << INSTR0_SHIFT))
-+
-+#define LUT1(ins, pad, opr) (LUT0(ins, pad, opr) << OPRND1_SHIFT)
-+
-+/* other macros for LUT register. */
-+#define QUADSPI_LUT(x) (QUADSPI_LUT_BASE + (x) * 4)
-+#define QUADSPI_LUT_NUM 64
-+
-+/* SEQID -- we can have 16 seqids at most. */
-+#define SEQID_QUAD_READ 0
-+#define SEQID_WREN 1
-+#define SEQID_WRDI 2
-+#define SEQID_RDSR 3
-+#define SEQID_SE 4
-+#define SEQID_CHIP_ERASE 5
-+#define SEQID_PP 6
-+#define SEQID_RDID 7
-+#define SEQID_WRSR 8
-+#define SEQID_RDCR 9
-+#define SEQID_EN4B 10
-+#define SEQID_BRWR 11
-+
-+enum fsl_qspi_devtype {
-+ FSL_QUADSPI_VYBRID,
-+ FSL_QUADSPI_IMX6SX,
-+};
-+
-+struct fsl_qspi_devtype_data {
-+ enum fsl_qspi_devtype devtype;
-+ int rxfifo;
-+ int txfifo;
-+};
-+
-+static struct fsl_qspi_devtype_data vybrid_data = {
-+ .devtype = FSL_QUADSPI_VYBRID,
-+ .rxfifo = 128,
-+ .txfifo = 64
-+};
-+
-+static struct fsl_qspi_devtype_data imx6sx_data = {
-+ .devtype = FSL_QUADSPI_IMX6SX,
-+ .rxfifo = 128,
-+ .txfifo = 512
-+};
-+
-+#define FSL_QSPI_MAX_CHIP 4
-+struct fsl_qspi {
-+ struct mtd_info mtd[FSL_QSPI_MAX_CHIP];
-+ struct spi_nor nor[FSL_QSPI_MAX_CHIP];
-+ void __iomem *iobase;
-+ void __iomem *ahb_base; /* Used when read from AHB bus */
-+ u32 memmap_phy;
-+ struct clk *clk, *clk_en;
-+ struct device *dev;
-+ struct completion c;
-+ struct fsl_qspi_devtype_data *devtype_data;
-+ u32 nor_size;
-+ u32 nor_num;
-+ u32 clk_rate;
-+ unsigned int chip_base_addr; /* We may support two chips. */
-+};
-+
-+static inline int is_vybrid_qspi(struct fsl_qspi *q)
-+{
-+ return q->devtype_data->devtype == FSL_QUADSPI_VYBRID;
-+}
-+
-+static inline int is_imx6sx_qspi(struct fsl_qspi *q)
-+{
-+ return q->devtype_data->devtype == FSL_QUADSPI_IMX6SX;
-+}
-+
-+/*
-+ * An IC bug makes us to re-arrange the 32-bit data.
-+ * The following chips, such as IMX6SLX, have fixed this bug.
-+ */
-+static inline u32 fsl_qspi_endian_xchg(struct fsl_qspi *q, u32 a)
-+{
-+ return is_vybrid_qspi(q) ? __swab32(a) : a;
-+}
-+
-+static inline void fsl_qspi_unlock_lut(struct fsl_qspi *q)
-+{
-+ writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
-+ writel(QUADSPI_LCKER_UNLOCK, q->iobase + QUADSPI_LCKCR);
-+}
-+
-+static inline void fsl_qspi_lock_lut(struct fsl_qspi *q)
-+{
-+ writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
-+ writel(QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR);
-+}
-+
-+static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id)
-+{
-+ struct fsl_qspi *q = dev_id;
-+ u32 reg;
-+
-+ /* clear interrupt */
-+ reg = readl(q->iobase + QUADSPI_FR);
-+ writel(reg, q->iobase + QUADSPI_FR);
-+
-+ if (reg & QUADSPI_FR_TFF_MASK)
-+ complete(&q->c);
-+
-+ dev_dbg(q->dev, "QUADSPI_FR : 0x%.8x:0x%.8x\n", q->chip_base_addr, reg);
-+ return IRQ_HANDLED;
-+}
-+
-+static void fsl_qspi_init_lut(struct fsl_qspi *q)
-+{
-+ void __iomem *base = q->iobase;
-+ int rxfifo = q->devtype_data->rxfifo;
-+ u32 lut_base;
-+ u8 cmd, addrlen, dummy;
-+ int i;
-+
-+ fsl_qspi_unlock_lut(q);
-+
-+ /* Clear all the LUT table */
-+ for (i = 0; i < QUADSPI_LUT_NUM; i++)
-+ writel(0, base + QUADSPI_LUT_BASE + i * 4);
-+
-+ /* Quad Read */
-+ lut_base = SEQID_QUAD_READ * 4;
-+
-+ if (q->nor_size <= SZ_16M) {
-+ cmd = SPINOR_OP_READ_1_1_4;
-+ addrlen = ADDR24BIT;
-+ dummy = 8;
-+ } else {
-+ /* use the 4-byte address */
-+ cmd = SPINOR_OP_READ_1_1_4;
-+ addrlen = ADDR32BIT;
-+ dummy = 8;
-+ }
-+
-+ writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
-+ base + QUADSPI_LUT(lut_base));
-+ writel(LUT0(DUMMY, PAD1, dummy) | LUT1(READ, PAD4, rxfifo),
-+ base + QUADSPI_LUT(lut_base + 1));
-+
-+ /* Write enable */
-+ lut_base = SEQID_WREN * 4;
-+ writel(LUT0(CMD, PAD1, SPINOR_OP_WREN), base + QUADSPI_LUT(lut_base));
-+
-+ /* Page Program */
-+ lut_base = SEQID_PP * 4;
-+
-+ if (q->nor_size <= SZ_16M) {
-+ cmd = SPINOR_OP_PP;
-+ addrlen = ADDR24BIT;
-+ } else {
-+ /* use the 4-byte address */
-+ cmd = SPINOR_OP_PP;
-+ addrlen = ADDR32BIT;
-+ }
-+
-+ writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
-+ base + QUADSPI_LUT(lut_base));
-+ writel(LUT0(WRITE, PAD1, 0), base + QUADSPI_LUT(lut_base + 1));
-+
-+ /* Read Status */
-+ lut_base = SEQID_RDSR * 4;
-+ writel(LUT0(CMD, PAD1, SPINOR_OP_RDSR) | LUT1(READ, PAD1, 0x1),
-+ base + QUADSPI_LUT(lut_base));
-+
-+ /* Erase a sector */
-+ lut_base = SEQID_SE * 4;
-+
-+ if (q->nor_size <= SZ_16M) {
-+ cmd = SPINOR_OP_SE;
-+ addrlen = ADDR24BIT;
-+ } else {
-+ /* use the 4-byte address */
-+ cmd = SPINOR_OP_SE;
-+ addrlen = ADDR32BIT;
-+ }
-+
-+ writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
-+ base + QUADSPI_LUT(lut_base));
-+
-+ /* Erase the whole chip */
-+ lut_base = SEQID_CHIP_ERASE * 4;
-+ writel(LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
-+ base + QUADSPI_LUT(lut_base));
-+
-+ /* READ ID */
-+ lut_base = SEQID_RDID * 4;
-+ writel(LUT0(CMD, PAD1, SPINOR_OP_RDID) | LUT1(READ, PAD1, 0x8),
-+ base + QUADSPI_LUT(lut_base));
-+
-+ /* Write Register */
-+ lut_base = SEQID_WRSR * 4;
-+ writel(LUT0(CMD, PAD1, SPINOR_OP_WRSR) | LUT1(WRITE, PAD1, 0x2),
-+ base + QUADSPI_LUT(lut_base));
-+
-+ /* Read Configuration Register */
-+ lut_base = SEQID_RDCR * 4;
-+ writel(LUT0(CMD, PAD1, SPINOR_OP_RDCR) | LUT1(READ, PAD1, 0x1),
-+ base + QUADSPI_LUT(lut_base));
-+
-+ /* Write disable */
-+ lut_base = SEQID_WRDI * 4;
-+ writel(LUT0(CMD, PAD1, SPINOR_OP_WRDI), base + QUADSPI_LUT(lut_base));
-+
-+ /* Enter 4 Byte Mode (Micron) */
-+ lut_base = SEQID_EN4B * 4;
-+ writel(LUT0(CMD, PAD1, SPINOR_OP_EN4B), base + QUADSPI_LUT(lut_base));
-+
-+ /* Enter 4 Byte Mode (Spansion) */
-+ lut_base = SEQID_BRWR * 4;
-+ writel(LUT0(CMD, PAD1, SPINOR_OP_BRWR), base + QUADSPI_LUT(lut_base));
-+
-+ fsl_qspi_lock_lut(q);
-+}
-+
-+/* Get the SEQID for the command */
-+static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
-+{
-+ switch (cmd) {
-+ case SPINOR_OP_READ_1_1_4:
-+ return SEQID_QUAD_READ;
-+ case SPINOR_OP_WREN:
-+ return SEQID_WREN;
-+ case SPINOR_OP_WRDI:
-+ return SEQID_WRDI;
-+ case SPINOR_OP_RDSR:
-+ return SEQID_RDSR;
-+ case SPINOR_OP_SE:
-+ return SEQID_SE;
-+ case SPINOR_OP_CHIP_ERASE:
-+ return SEQID_CHIP_ERASE;
-+ case SPINOR_OP_PP:
-+ return SEQID_PP;
-+ case SPINOR_OP_RDID:
-+ return SEQID_RDID;
-+ case SPINOR_OP_WRSR:
-+ return SEQID_WRSR;
-+ case SPINOR_OP_RDCR:
-+ return SEQID_RDCR;
-+ case SPINOR_OP_EN4B:
-+ return SEQID_EN4B;
-+ case SPINOR_OP_BRWR:
-+ return SEQID_BRWR;
-+ default:
-+ dev_err(q->dev, "Unsupported cmd 0x%.2x\n", cmd);
-+ break;
-+ }
-+ return -EINVAL;
-+}
-+
-+static int
-+fsl_qspi_runcmd(struct fsl_qspi *q, u8 cmd, unsigned int addr, int len)
-+{
-+ void __iomem *base = q->iobase;
-+ int seqid;
-+ u32 reg, reg2;
-+ int err;
-+
-+ init_completion(&q->c);
-+ dev_dbg(q->dev, "to 0x%.8x:0x%.8x, len:%d, cmd:%.2x\n",
-+ q->chip_base_addr, addr, len, cmd);
-+
-+ /* save the reg */
-+ reg = readl(base + QUADSPI_MCR);
-+
-+ writel(q->memmap_phy + q->chip_base_addr + addr, base + QUADSPI_SFAR);
-+ writel(QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS,
-+ base + QUADSPI_RBCT);
-+ writel(reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR);
-+
-+ do {
-+ reg2 = readl(base + QUADSPI_SR);
-+ if (reg2 & (QUADSPI_SR_IP_ACC_MASK | QUADSPI_SR_AHB_ACC_MASK)) {
-+ udelay(1);
-+ dev_dbg(q->dev, "The controller is busy, 0x%x\n", reg2);
-+ continue;
-+ }
-+ break;
-+ } while (1);
-+
-+ /* trigger the LUT now */
-+ seqid = fsl_qspi_get_seqid(q, cmd);
-+ writel((seqid << QUADSPI_IPCR_SEQID_SHIFT) | len, base + QUADSPI_IPCR);
-+
-+ /* Wait for the interrupt. */
-+ err = wait_for_completion_timeout(&q->c, msecs_to_jiffies(1000));
-+ if (!err) {
-+ dev_err(q->dev,
-+ "cmd 0x%.2x timeout, addr@%.8x, FR:0x%.8x, SR:0x%.8x\n",
-+ cmd, addr, readl(base + QUADSPI_FR),
-+ readl(base + QUADSPI_SR));
-+ err = -ETIMEDOUT;
-+ } else {
-+ err = 0;
-+ }
-+
-+ /* restore the MCR */
-+ writel(reg, base + QUADSPI_MCR);
-+
-+ return err;
-+}
-+
-+/* Read out the data from the QUADSPI_RBDR buffer registers. */
-+static void fsl_qspi_read_data(struct fsl_qspi *q, int len, u8 *rxbuf)
-+{
-+ u32 tmp;
-+ int i = 0;
-+
-+ while (len > 0) {
-+ tmp = readl(q->iobase + QUADSPI_RBDR + i * 4);
-+ tmp = fsl_qspi_endian_xchg(q, tmp);
-+ dev_dbg(q->dev, "chip addr:0x%.8x, rcv:0x%.8x\n",
-+ q->chip_base_addr, tmp);
-+
-+ if (len >= 4) {
-+ *((u32 *)rxbuf) = tmp;
-+ rxbuf += 4;
-+ } else {
-+ memcpy(rxbuf, &tmp, len);
-+ break;
-+ }
-+
-+ len -= 4;
-+ i++;
-+ }
-+}
-+
-+/*
-+ * If we have changed the content of the flash by writing or erasing,
-+ * we need to invalidate the AHB buffer. If we do not do so, we may read out
-+ * the wrong data. The spec tells us reset the AHB domain and Serial Flash
-+ * domain at the same time.
-+ */
-+static inline void fsl_qspi_invalid(struct fsl_qspi *q)
-+{
-+ u32 reg;
-+
-+ reg = readl(q->iobase + QUADSPI_MCR);
-+ reg |= QUADSPI_MCR_SWRSTHD_MASK | QUADSPI_MCR_SWRSTSD_MASK;
-+ writel(reg, q->iobase + QUADSPI_MCR);
-+
-+ /*
-+ * The minimum delay : 1 AHB + 2 SFCK clocks.
-+ * Delay 1 us is enough.
-+ */
-+ udelay(1);
-+
-+ reg &= ~(QUADSPI_MCR_SWRSTHD_MASK | QUADSPI_MCR_SWRSTSD_MASK);
-+ writel(reg, q->iobase + QUADSPI_MCR);
-+}
-+
-+static int fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
-+ u8 opcode, unsigned int to, u32 *txbuf,
-+ unsigned count, size_t *retlen)
-+{
-+ int ret, i, j;
-+ u32 tmp;
-+
-+ dev_dbg(q->dev, "to 0x%.8x:0x%.8x, len : %d\n",
-+ q->chip_base_addr, to, count);
-+
-+ /* clear the TX FIFO. */
-+ tmp = readl(q->iobase + QUADSPI_MCR);
-+ writel(tmp | QUADSPI_MCR_CLR_RXF_MASK, q->iobase + QUADSPI_MCR);
-+
-+ /* fill the TX data to the FIFO */
-+ for (j = 0, i = ((count + 3) / 4); j < i; j++) {
-+ tmp = fsl_qspi_endian_xchg(q, *txbuf);
-+ writel(tmp, q->iobase + QUADSPI_TBDR);
-+ txbuf++;
-+ }
-+
-+ /* Trigger it */
-+ ret = fsl_qspi_runcmd(q, opcode, to, count);
-+
-+ if (ret == 0 && retlen)
-+ *retlen += count;
-+
-+ return ret;
-+}
-+
-+static void fsl_qspi_set_map_addr(struct fsl_qspi *q)
-+{
-+ int nor_size = q->nor_size;
-+ void __iomem *base = q->iobase;
-+
-+ writel(nor_size + q->memmap_phy, base + QUADSPI_SFA1AD);
-+ writel(nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD);
-+ writel(nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD);
-+ writel(nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD);
-+}
-+
-+/*
-+ * There are two different ways to read out the data from the flash:
-+ * the "IP Command Read" and the "AHB Command Read".
-+ *
-+ * The IC guy suggests we use the "AHB Command Read" which is faster
-+ * then the "IP Command Read". (What's more is that there is a bug in
-+ * the "IP Command Read" in the Vybrid.)
-+ *
-+ * After we set up the registers for the "AHB Command Read", we can use
-+ * the memcpy to read the data directly. A "missed" access to the buffer
-+ * causes the controller to clear the buffer, and use the sequence pointed
-+ * by the QUADSPI_BFGENCR[SEQID] to initiate a read from the flash.
-+ */
-+static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
-+{
-+ void __iomem *base = q->iobase;
-+ int seqid;
-+
-+ /* AHB configuration for access buffer 0/1/2 .*/
-+ writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR);
-+ writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR);
-+ writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR);
-+ writel(QUADSPI_BUF3CR_ALLMST, base + QUADSPI_BUF3CR);
-+
-+ /* We only use the buffer3 */
-+ writel(0, base + QUADSPI_BUF0IND);
-+ writel(0, base + QUADSPI_BUF1IND);
-+ writel(0, base + QUADSPI_BUF2IND);
-+
-+ /* Set the default lut sequence for AHB Read. */
-+ seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
-+ writel(seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
-+ q->iobase + QUADSPI_BFGENCR);
-+}
-+
-+/* We use this function to do some basic init for spi_nor_scan(). */
-+static int fsl_qspi_nor_setup(struct fsl_qspi *q)
-+{
-+ void __iomem *base = q->iobase;
-+ u32 reg;
-+ int ret;
-+
-+ /* the default frequency, we will change it in the future.*/
-+ ret = clk_set_rate(q->clk, 66000000);
-+ if (ret)
-+ return ret;
-+
-+ /* Init the LUT table. */
-+ fsl_qspi_init_lut(q);
-+
-+ /* Disable the module */
-+ writel(QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
-+ base + QUADSPI_MCR);
-+
-+ reg = readl(base + QUADSPI_SMPR);
-+ writel(reg & ~(QUADSPI_SMPR_FSDLY_MASK
-+ | QUADSPI_SMPR_FSPHS_MASK
-+ | QUADSPI_SMPR_HSENA_MASK
-+ | QUADSPI_SMPR_DDRSMP_MASK), base + QUADSPI_SMPR);
-+
-+ /* Enable the module */
-+ writel(QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK,
-+ base + QUADSPI_MCR);
-+
-+ /* enable the interrupt */
-+ writel(QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER);
-+
-+ return 0;
-+}
-+
-+static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
-+{
-+ unsigned long rate = q->clk_rate;
-+ int ret;
-+
-+ if (is_imx6sx_qspi(q))
-+ rate *= 4;
-+
-+ ret = clk_set_rate(q->clk, rate);
-+ if (ret)
-+ return ret;
-+
-+ /* Init the LUT table again. */
-+ fsl_qspi_init_lut(q);
-+
-+ /* Init for AHB read */
-+ fsl_qspi_init_abh_read(q);
-+
-+ return 0;
-+}
-+
-+static struct of_device_id fsl_qspi_dt_ids[] = {
-+ { .compatible = "fsl,vf610-qspi", .data = (void *)&vybrid_data, },
-+ { .compatible = "fsl,imx6sx-qspi", .data = (void *)&imx6sx_data, },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids);
-+
-+static void fsl_qspi_set_base_addr(struct fsl_qspi *q, struct spi_nor *nor)
-+{
-+ q->chip_base_addr = q->nor_size * (nor - q->nor);
-+}
-+
-+static int fsl_qspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
-+{
-+ int ret;
-+ struct fsl_qspi *q = nor->priv;
-+
-+ ret = fsl_qspi_runcmd(q, opcode, 0, len);
-+ if (ret)
-+ return ret;
-+
-+ fsl_qspi_read_data(q, len, buf);
-+ return 0;
-+}
-+
-+static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len,
-+ int write_enable)
-+{
-+ struct fsl_qspi *q = nor->priv;
-+ int ret;
-+
-+ if (!buf) {
-+ ret = fsl_qspi_runcmd(q, opcode, 0, 1);
-+ if (ret)
-+ return ret;
-+
-+ if (opcode == SPINOR_OP_CHIP_ERASE)
-+ fsl_qspi_invalid(q);
-+
-+ } else if (len > 0) {
-+ ret = fsl_qspi_nor_write(q, nor, opcode, 0,
-+ (u32 *)buf, len, NULL);
-+ } else {
-+ dev_err(q->dev, "invalid cmd %d\n", opcode);
-+ ret = -EINVAL;
-+ }
-+
-+ return ret;
-+}
-+
-+static void fsl_qspi_write(struct spi_nor *nor, loff_t to,
-+ size_t len, size_t *retlen, const u_char *buf)
-+{
-+ struct fsl_qspi *q = nor->priv;
-+
-+ fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
-+ (u32 *)buf, len, retlen);
-+
-+ /* invalid the data in the AHB buffer. */
-+ fsl_qspi_invalid(q);
-+}
-+
-+static int fsl_qspi_read(struct spi_nor *nor, loff_t from,
-+ size_t len, size_t *retlen, u_char *buf)
-+{
-+ struct fsl_qspi *q = nor->priv;
-+ u8 cmd = nor->read_opcode;
-+ int ret;
-+
-+ dev_dbg(q->dev, "cmd [%x],read from (0x%p, 0x%.8x, 0x%.8x),len:%d\n",
-+ cmd, q->ahb_base, q->chip_base_addr, (unsigned int)from, len);
-+
-+ /* Wait until the previous command is finished. */
-+ ret = nor->wait_till_ready(nor);
-+ if (ret)
-+ return ret;
-+
-+ /* Read out the data directly from the AHB buffer.*/
-+ memcpy(buf, q->ahb_base + q->chip_base_addr + from, len);
-+
-+ *retlen += len;
-+ return 0;
-+}
-+
-+static int fsl_qspi_erase(struct spi_nor *nor, loff_t offs)
-+{
-+ struct fsl_qspi *q = nor->priv;
-+ int ret;
-+
-+ dev_dbg(nor->dev, "%dKiB at 0x%08x:0x%08x\n",
-+ nor->mtd->erasesize / 1024, q->chip_base_addr, (u32)offs);
-+
-+ /* Wait until finished previous write command. */
-+ ret = nor->wait_till_ready(nor);
-+ if (ret)
-+ return ret;
-+
-+ /* Send write enable, then erase commands. */
-+ ret = nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0, 0);
-+ if (ret)
-+ return ret;
-+
-+ ret = fsl_qspi_runcmd(q, nor->erase_opcode, offs, 0);
-+ if (ret)
-+ return ret;
-+
-+ fsl_qspi_invalid(q);
-+ return 0;
-+}
-+
-+static int fsl_qspi_prep(struct spi_nor *nor, enum spi_nor_ops ops)
-+{
-+ struct fsl_qspi *q = nor->priv;
-+ int ret;
-+
-+ ret = clk_enable(q->clk_en);
-+ if (ret)
-+ return ret;
-+
-+ ret = clk_enable(q->clk);
-+ if (ret) {
-+ clk_disable(q->clk_en);
-+ return ret;
-+ }
-+
-+ fsl_qspi_set_base_addr(q, nor);
-+ return 0;
-+}
-+
-+static void fsl_qspi_unprep(struct spi_nor *nor, enum spi_nor_ops ops)
-+{
-+ struct fsl_qspi *q = nor->priv;
-+
-+ clk_disable(q->clk);
-+ clk_disable(q->clk_en);
-+}
-+
-+static int fsl_qspi_probe(struct platform_device *pdev)
-+{
-+ struct device_node *np = pdev->dev.of_node;
-+ struct mtd_part_parser_data ppdata;
-+ struct device *dev = &pdev->dev;
-+ struct fsl_qspi *q;
-+ struct resource *res;
-+ struct spi_nor *nor;
-+ struct mtd_info *mtd;
-+ int ret, i = 0;
-+ bool has_second_chip = false;
-+ const struct of_device_id *of_id =
-+ of_match_device(fsl_qspi_dt_ids, &pdev->dev);
-+
-+ q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
-+ if (!q)
-+ return -ENOMEM;
-+
-+ q->nor_num = of_get_child_count(dev->of_node);
-+ if (!q->nor_num || q->nor_num > FSL_QSPI_MAX_CHIP)
-+ return -ENODEV;
-+
-+ /* find the resources */
-+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "QuadSPI");
-+ q->iobase = devm_ioremap_resource(dev, res);
-+ if (IS_ERR(q->iobase)) {
-+ ret = PTR_ERR(q->iobase);
-+ goto map_failed;
-+ }
-+
-+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-+ "QuadSPI-memory");
-+ q->ahb_base = devm_ioremap_resource(dev, res);
-+ if (IS_ERR(q->ahb_base)) {
-+ ret = PTR_ERR(q->ahb_base);
-+ goto map_failed;
-+ }
-+ q->memmap_phy = res->start;
-+
-+ /* find the clocks */
-+ q->clk_en = devm_clk_get(dev, "qspi_en");
-+ if (IS_ERR(q->clk_en)) {
-+ ret = PTR_ERR(q->clk_en);
-+ goto map_failed;
-+ }
-+
-+ q->clk = devm_clk_get(dev, "qspi");
-+ if (IS_ERR(q->clk)) {
-+ ret = PTR_ERR(q->clk);
-+ goto map_failed;
-+ }
-+
-+ ret = clk_prepare_enable(q->clk_en);
-+ if (ret) {
-+ dev_err(dev, "can not enable the qspi_en clock\n");
-+ goto map_failed;
-+ }
-+
-+ ret = clk_prepare_enable(q->clk);
-+ if (ret) {
-+ clk_disable_unprepare(q->clk_en);
-+ dev_err(dev, "can not enable the qspi clock\n");
-+ goto map_failed;
-+ }
-+
-+ /* find the irq */
-+ ret = platform_get_irq(pdev, 0);
-+ if (ret < 0) {
-+ dev_err(dev, "failed to get the irq\n");
-+ goto irq_failed;
-+ }
-+
-+ ret = devm_request_irq(dev, ret,
-+ fsl_qspi_irq_handler, 0, pdev->name, q);
-+ if (ret) {
-+ dev_err(dev, "failed to request irq.\n");
-+ goto irq_failed;
-+ }
-+
-+ q->dev = dev;
-+ q->devtype_data = (struct fsl_qspi_devtype_data *)of_id->data;
-+ platform_set_drvdata(pdev, q);
-+
-+ ret = fsl_qspi_nor_setup(q);
-+ if (ret)
-+ goto irq_failed;
-+
-+ if (of_get_property(np, "fsl,qspi-has-second-chip", NULL))
-+ has_second_chip = true;
-+
-+ /* iterate the subnodes. */
-+ for_each_available_child_of_node(dev->of_node, np) {
-+ const struct spi_device_id *id;
-+ char modalias[40];
-+
-+ /* skip the holes */
-+ if (!has_second_chip)
-+ i *= 2;
-+
-+ nor = &q->nor[i];
-+ mtd = &q->mtd[i];
-+
-+ nor->mtd = mtd;
-+ nor->dev = dev;
-+ nor->priv = q;
-+ mtd->priv = nor;
-+
-+ /* fill the hooks */
-+ nor->read_reg = fsl_qspi_read_reg;
-+ nor->write_reg = fsl_qspi_write_reg;
-+ nor->read = fsl_qspi_read;
-+ nor->write = fsl_qspi_write;
-+ nor->erase = fsl_qspi_erase;
-+
-+ nor->prepare = fsl_qspi_prep;
-+ nor->unprepare = fsl_qspi_unprep;
-+
-+ if (of_modalias_node(np, modalias, sizeof(modalias)) < 0)
-+ goto map_failed;
-+
-+ id = spi_nor_match_id(modalias);
-+ if (!id)
-+ goto map_failed;
-+
-+ ret = of_property_read_u32(np, "spi-max-frequency",
-+ &q->clk_rate);
-+ if (ret < 0)
-+ goto map_failed;
-+
-+ /* set the chip address for READID */
-+ fsl_qspi_set_base_addr(q, nor);
-+
-+ ret = spi_nor_scan(nor, id, SPI_NOR_QUAD);
-+ if (ret)
-+ goto map_failed;
-+
-+ ppdata.of_node = np;
-+ ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
-+ if (ret)
-+ goto map_failed;
-+
-+ /* Set the correct NOR size now. */
-+ if (q->nor_size == 0) {
-+ q->nor_size = mtd->size;
-+
-+ /* Map the SPI NOR to accessiable address */
-+ fsl_qspi_set_map_addr(q);
-+ }
-+
-+ /*
-+ * The TX FIFO is 64 bytes in the Vybrid, but the Page Program
-+ * may writes 265 bytes per time. The write is working in the
-+ * unit of the TX FIFO, not in the unit of the SPI NOR's page
-+ * size.
-+ *
-+ * So shrink the spi_nor->page_size if it is larger then the
-+ * TX FIFO.
-+ */
-+ if (nor->page_size > q->devtype_data->txfifo)
-+ nor->page_size = q->devtype_data->txfifo;
-+
-+ i++;
-+ }
-+
-+ /* finish the rest init. */
-+ ret = fsl_qspi_nor_setup_last(q);
-+ if (ret)
-+ goto last_init_failed;
-+
-+ clk_disable(q->clk);
-+ clk_disable(q->clk_en);
-+ dev_info(dev, "QuadSPI SPI NOR flash driver\n");
-+ return 0;
-+
-+last_init_failed:
-+ for (i = 0; i < q->nor_num; i++)
-+ mtd_device_unregister(&q->mtd[i]);
-+
-+irq_failed:
-+ clk_disable_unprepare(q->clk);
-+ clk_disable_unprepare(q->clk_en);
-+map_failed:
-+ dev_err(dev, "Freescale QuadSPI probe failed\n");
-+ return ret;
-+}
-+
-+static int fsl_qspi_remove(struct platform_device *pdev)
-+{
-+ struct fsl_qspi *q = platform_get_drvdata(pdev);
-+ int i;
-+
-+ for (i = 0; i < q->nor_num; i++)
-+ mtd_device_unregister(&q->mtd[i]);
-+
-+ /* disable the hardware */
-+ writel(QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
-+ writel(0x0, q->iobase + QUADSPI_RSER);
-+
-+ clk_unprepare(q->clk);
-+ clk_unprepare(q->clk_en);
-+ return 0;
-+}
-+
-+static struct platform_driver fsl_qspi_driver = {
-+ .driver = {
-+ .name = "fsl-quadspi",
-+ .bus = &platform_bus_type,
-+ .owner = THIS_MODULE,
-+ .of_match_table = fsl_qspi_dt_ids,
-+ },
-+ .probe = fsl_qspi_probe,
-+ .remove = fsl_qspi_remove,
-+};
-+module_platform_driver(fsl_qspi_driver);
-+
-+MODULE_DESCRIPTION("Freescale QuadSPI Controller Driver");
-+MODULE_AUTHOR("Freescale Semiconductor Inc.");
-+MODULE_LICENSE("GPL v2");
---- /dev/null
-+++ b/drivers/mtd/spi-nor/Kconfig
-@@ -0,0 +1,17 @@
-+menuconfig MTD_SPI_NOR
-+ tristate "SPI-NOR device support"
-+ depends on MTD
-+ help
-+ This is the framework for the SPI NOR which can be used by the SPI
-+ device drivers and the SPI-NOR device driver.
-+
-+if MTD_SPI_NOR
-+
-+config SPI_FSL_QUADSPI
-+ tristate "Freescale Quad SPI controller"
-+ depends on ARCH_MXC
-+ help
-+ This enables support for the Quad SPI controller in master mode.
-+ We only connect the NOR to this controller now.
-+
-+endif # MTD_SPI_NOR
---- /dev/null
-+++ b/drivers/mtd/spi-nor/Makefile
-@@ -0,0 +1,2 @@
-+obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o
-+obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o
---- /dev/null
-+++ b/drivers/mtd/spi-nor/spi-nor.c
-@@ -0,0 +1,1160 @@
-+/*
-+ * Based on m25p80.c, by Mike Lavender (mike@steroidmicros.com), with
-+ * influence from lart.c (Abraham Van Der Merwe) and mtd_dataflash.c
-+ *
-+ * Copyright (C) 2005, Intec Automation Inc.
-+ * Copyright (C) 2014, Freescale Semiconductor, Inc.
-+ *
-+ * This code is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/err.h>
-+#include <linux/errno.h>
-+#include <linux/module.h>
-+#include <linux/device.h>
-+#include <linux/mutex.h>
-+#include <linux/math64.h>
-+
-+#include <linux/mtd/cfi.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/of_platform.h>
-+#include <linux/spi/flash.h>
-+#include <linux/mtd/spi-nor.h>
-+
-+/* Define max times to check status register before we give up. */
-+#define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */
-+
-+#define JEDEC_MFR(_jedec_id) ((_jedec_id) >> 16)
-+
-+/*
-+ * Read the status register, returning its value in the location
-+ * Return the status register value.
-+ * Returns negative if error occurred.
-+ */
-+static int read_sr(struct spi_nor *nor)
-+{
-+ int ret;
-+ u8 val;
-+
-+ ret = nor->read_reg(nor, SPINOR_OP_RDSR, &val, 1);
-+ if (ret < 0) {
-+ pr_err("error %d reading SR\n", (int) ret);
-+ return ret;
-+ }
-+
-+ return val;
-+}
-+
-+/*
-+ * Read the flag status register, returning its value in the location
-+ * Return the status register value.
-+ * Returns negative if error occurred.
-+ */
-+static int read_fsr(struct spi_nor *nor)
-+{
-+ int ret;
-+ u8 val;
-+
-+ ret = nor->read_reg(nor, SPINOR_OP_RDFSR, &val, 1);
-+ if (ret < 0) {
-+ pr_err("error %d reading FSR\n", ret);
-+ return ret;
-+ }
-+
-+ return val;
-+}
-+
-+/*
-+ * Read configuration register, returning its value in the
-+ * location. Return the configuration register value.
-+ * Returns negative if error occured.
-+ */
-+static int read_cr(struct spi_nor *nor)
-+{
-+ int ret;
-+ u8 val;
-+
-+ ret = nor->read_reg(nor, SPINOR_OP_RDCR, &val, 1);
-+ if (ret < 0) {
-+ dev_err(nor->dev, "error %d reading CR\n", ret);
-+ return ret;
-+ }
-+
-+ return val;
-+}
-+
-+/*
-+ * Dummy Cycle calculation for different type of read.
-+ * It can be used to support more commands with
-+ * different dummy cycle requirements.
-+ */
-+static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
-+{
-+ switch (nor->flash_read) {
-+ case SPI_NOR_FAST:
-+ case SPI_NOR_DUAL:
-+ case SPI_NOR_QUAD:
-+ return 1;
-+ case SPI_NOR_NORMAL:
-+ return 0;
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * Write status register 1 byte
-+ * Returns negative if error occurred.
-+ */
-+static inline int write_sr(struct spi_nor *nor, u8 val)
-+{
-+ nor->cmd_buf[0] = val;
-+ return nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 1, 0);
-+}
-+
-+/*
-+ * Set write enable latch with Write Enable command.
-+ * Returns negative if error occurred.
-+ */
-+static inline int write_enable(struct spi_nor *nor)
-+{
-+ return nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0, 0);
-+}
-+
-+/*
-+ * Send write disble instruction to the chip.
-+ */
-+static inline int write_disable(struct spi_nor *nor)
-+{
-+ return nor->write_reg(nor, SPINOR_OP_WRDI, NULL, 0, 0);
-+}
-+
-+static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
-+{
-+ return mtd->priv;
-+}
-+
-+/* Enable/disable 4-byte addressing mode. */
-+static inline int set_4byte(struct spi_nor *nor, u32 jedec_id, int enable)
-+{
-+ int status;
-+ bool need_wren = false;
-+ u8 cmd;
-+
-+ switch (JEDEC_MFR(jedec_id)) {
-+ case CFI_MFR_ST: /* Micron, actually */
-+ /* Some Micron need WREN command; all will accept it */
-+ need_wren = true;
-+ case CFI_MFR_MACRONIX:
-+ case 0xEF /* winbond */:
-+ if (need_wren)
-+ write_enable(nor);
-+
-+ cmd = enable ? SPINOR_OP_EN4B : SPINOR_OP_EX4B;
-+ status = nor->write_reg(nor, cmd, NULL, 0, 0);
-+ if (need_wren)
-+ write_disable(nor);
-+
-+ return status;
-+ default:
-+ /* Spansion style */
-+ nor->cmd_buf[0] = enable << 7;
-+ return nor->write_reg(nor, SPINOR_OP_BRWR, nor->cmd_buf, 1, 0);
-+ }
-+}
-+
-+static int spi_nor_wait_till_ready(struct spi_nor *nor)
-+{
-+ unsigned long deadline;
-+ int sr;
-+
-+ deadline = jiffies + MAX_READY_WAIT_JIFFIES;
-+
-+ do {
-+ cond_resched();
-+
-+ sr = read_sr(nor);
-+ if (sr < 0)
-+ break;
-+ else if (!(sr & SR_WIP))
-+ return 0;
-+ } while (!time_after_eq(jiffies, deadline));
-+
-+ return -ETIMEDOUT;
-+}
-+
-+static int spi_nor_wait_till_fsr_ready(struct spi_nor *nor)
-+{
-+ unsigned long deadline;
-+ int sr;
-+ int fsr;
-+
-+ deadline = jiffies + MAX_READY_WAIT_JIFFIES;
-+
-+ do {
-+ cond_resched();
-+
-+ sr = read_sr(nor);
-+ if (sr < 0) {
-+ break;
-+ } else if (!(sr & SR_WIP)) {
-+ fsr = read_fsr(nor);
-+ if (fsr < 0)
-+ break;
-+ if (fsr & FSR_READY)
-+ return 0;
-+ }
-+ } while (!time_after_eq(jiffies, deadline));
-+
-+ return -ETIMEDOUT;
-+}
-+
-+/*
-+ * Service routine to read status register until ready, or timeout occurs.
-+ * Returns non-zero if error.
-+ */
-+static int wait_till_ready(struct spi_nor *nor)
-+{
-+ return nor->wait_till_ready(nor);
-+}
-+
-+/*
-+ * Erase the whole flash memory
-+ *
-+ * Returns 0 if successful, non-zero otherwise.
-+ */
-+static int erase_chip(struct spi_nor *nor)
-+{
-+ int ret;
-+
-+ dev_dbg(nor->dev, " %lldKiB\n", (long long)(nor->mtd->size >> 10));
-+
-+ /* Wait until finished previous write command. */
-+ ret = wait_till_ready(nor);
-+ if (ret)
-+ return ret;
-+
-+ /* Send write enable, then erase commands. */
-+ write_enable(nor);
-+
-+ return nor->write_reg(nor, SPINOR_OP_CHIP_ERASE, NULL, 0, 0);
-+}
-+
-+static int spi_nor_lock_and_prep(struct spi_nor *nor, enum spi_nor_ops ops)
-+{
-+ int ret = 0;
-+
-+ mutex_lock(&nor->lock);
-+
-+ if (nor->prepare) {
-+ ret = nor->prepare(nor, ops);
-+ if (ret) {
-+ dev_err(nor->dev, "failed in the preparation.\n");
-+ mutex_unlock(&nor->lock);
-+ return ret;
-+ }
-+ }
-+ return ret;
-+}
-+
-+static void spi_nor_unlock_and_unprep(struct spi_nor *nor, enum spi_nor_ops ops)
-+{
-+ if (nor->unprepare)
-+ nor->unprepare(nor, ops);
-+ mutex_unlock(&nor->lock);
-+}
-+
-+/*
-+ * Erase an address range on the nor chip. The address range may extend
-+ * one or more erase sectors. Return an error is there is a problem erasing.
-+ */
-+static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
-+{
-+ struct spi_nor *nor = mtd_to_spi_nor(mtd);
-+ u32 addr, len;
-+ uint32_t rem;
-+ int ret;
-+
-+ dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr,
-+ (long long)instr->len);
-+
-+ div_u64_rem(instr->len, mtd->erasesize, &rem);
-+ if (rem)
-+ return -EINVAL;
-+
-+ addr = instr->addr;
-+ len = instr->len;
-+
-+ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_ERASE);
-+ if (ret)
-+ return ret;
-+
-+ /* whole-chip erase? */
-+ if (len == mtd->size) {
-+ if (erase_chip(nor)) {
-+ ret = -EIO;
-+ goto erase_err;
-+ }
-+
-+ /* REVISIT in some cases we could speed up erasing large regions
-+ * by using SPINOR_OP_SE instead of SPINOR_OP_BE_4K. We may have set up
-+ * to use "small sector erase", but that's not always optimal.
-+ */
-+
-+ /* "sector"-at-a-time erase */
-+ } else {
-+ while (len) {
-+ if (nor->erase(nor, addr)) {
-+ ret = -EIO;
-+ goto erase_err;
-+ }
-+
-+ addr += mtd->erasesize;
-+ len -= mtd->erasesize;
-+ }
-+ }
-+
-+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
-+
-+ instr->state = MTD_ERASE_DONE;
-+ mtd_erase_callback(instr);
-+
-+ return ret;
-+
-+erase_err:
-+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
-+ instr->state = MTD_ERASE_FAILED;
-+ return ret;
-+}
-+
-+static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
-+{
-+ struct spi_nor *nor = mtd_to_spi_nor(mtd);
-+ uint32_t offset = ofs;
-+ uint8_t status_old, status_new;
-+ int ret = 0;
-+
-+ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_LOCK);
-+ if (ret)
-+ return ret;
-+
-+ /* Wait until finished previous command */
-+ ret = wait_till_ready(nor);
-+ if (ret)
-+ goto err;
-+
-+ status_old = read_sr(nor);
-+
-+ if (offset < mtd->size - (mtd->size / 2))
-+ status_new = status_old | SR_BP2 | SR_BP1 | SR_BP0;
-+ else if (offset < mtd->size - (mtd->size / 4))
-+ status_new = (status_old & ~SR_BP0) | SR_BP2 | SR_BP1;
-+ else if (offset < mtd->size - (mtd->size / 8))
-+ status_new = (status_old & ~SR_BP1) | SR_BP2 | SR_BP0;
-+ else if (offset < mtd->size - (mtd->size / 16))
-+ status_new = (status_old & ~(SR_BP0 | SR_BP1)) | SR_BP2;
-+ else if (offset < mtd->size - (mtd->size / 32))
-+ status_new = (status_old & ~SR_BP2) | SR_BP1 | SR_BP0;
-+ else if (offset < mtd->size - (mtd->size / 64))
-+ status_new = (status_old & ~(SR_BP2 | SR_BP0)) | SR_BP1;
-+ else
-+ status_new = (status_old & ~(SR_BP2 | SR_BP1)) | SR_BP0;
-+
-+ /* Only modify protection if it will not unlock other areas */
-+ if ((status_new & (SR_BP2 | SR_BP1 | SR_BP0)) >
-+ (status_old & (SR_BP2 | SR_BP1 | SR_BP0))) {
-+ write_enable(nor);
-+ ret = write_sr(nor, status_new);
-+ if (ret)
-+ goto err;
-+ }
-+
-+err:
-+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK);
-+ return ret;
-+}
-+
-+static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
-+{
-+ struct spi_nor *nor = mtd_to_spi_nor(mtd);
-+ uint32_t offset = ofs;
-+ uint8_t status_old, status_new;
-+ int ret = 0;
-+
-+ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_UNLOCK);
-+ if (ret)
-+ return ret;
-+
-+ /* Wait until finished previous command */
-+ ret = wait_till_ready(nor);
-+ if (ret)
-+ goto err;
-+
-+ status_old = read_sr(nor);
-+
-+ if (offset+len > mtd->size - (mtd->size / 64))
-+ status_new = status_old & ~(SR_BP2 | SR_BP1 | SR_BP0);
-+ else if (offset+len > mtd->size - (mtd->size / 32))
-+ status_new = (status_old & ~(SR_BP2 | SR_BP1)) | SR_BP0;
-+ else if (offset+len > mtd->size - (mtd->size / 16))
-+ status_new = (status_old & ~(SR_BP2 | SR_BP0)) | SR_BP1;
-+ else if (offset+len > mtd->size - (mtd->size / 8))
-+ status_new = (status_old & ~SR_BP2) | SR_BP1 | SR_BP0;
-+ else if (offset+len > mtd->size - (mtd->size / 4))
-+ status_new = (status_old & ~(SR_BP0 | SR_BP1)) | SR_BP2;
-+ else if (offset+len > mtd->size - (mtd->size / 2))
-+ status_new = (status_old & ~SR_BP1) | SR_BP2 | SR_BP0;
-+ else
-+ status_new = (status_old & ~SR_BP0) | SR_BP2 | SR_BP1;
-+
-+ /* Only modify protection if it will not lock other areas */
-+ if ((status_new & (SR_BP2 | SR_BP1 | SR_BP0)) <
-+ (status_old & (SR_BP2 | SR_BP1 | SR_BP0))) {
-+ write_enable(nor);
-+ ret = write_sr(nor, status_new);
-+ if (ret)
-+ goto err;
-+ }
-+
-+err:
-+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK);
-+ return ret;
-+}
-+
-+struct flash_info {
-+ /* JEDEC id zero means "no ID" (most older chips); otherwise it has
-+ * a high byte of zero plus three data bytes: the manufacturer id,
-+ * then a two byte device id.
-+ */
-+ u32 jedec_id;
-+ u16 ext_id;
-+
-+ /* The size listed here is what works with SPINOR_OP_SE, which isn't
-+ * necessarily called a "sector" by the vendor.
-+ */
-+ unsigned sector_size;
-+ u16 n_sectors;
-+
-+ u16 page_size;
-+ u16 addr_width;
-+
-+ u16 flags;
-+#define SECT_4K 0x01 /* SPINOR_OP_BE_4K works uniformly */
-+#define SPI_NOR_NO_ERASE 0x02 /* No erase command needed */
-+#define SST_WRITE 0x04 /* use SST byte programming */
-+#define SPI_NOR_NO_FR 0x08 /* Can't do fastread */
-+#define SECT_4K_PMC 0x10 /* SPINOR_OP_BE_4K_PMC works uniformly */
-+#define SPI_NOR_DUAL_READ 0x20 /* Flash supports Dual Read */
-+#define SPI_NOR_QUAD_READ 0x40 /* Flash supports Quad Read */
-+#define USE_FSR 0x80 /* use flag status register */
-+};
-+
-+#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \
-+ ((kernel_ulong_t)&(struct flash_info) { \
-+ .jedec_id = (_jedec_id), \
-+ .ext_id = (_ext_id), \
-+ .sector_size = (_sector_size), \
-+ .n_sectors = (_n_sectors), \
-+ .page_size = 256, \
-+ .flags = (_flags), \
-+ })
-+
-+#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags) \
-+ ((kernel_ulong_t)&(struct flash_info) { \
-+ .sector_size = (_sector_size), \
-+ .n_sectors = (_n_sectors), \
-+ .page_size = (_page_size), \
-+ .addr_width = (_addr_width), \
-+ .flags = (_flags), \
-+ })
-+
-+/* NOTE: double check command sets and memory organization when you add
-+ * more nor chips. This current list focusses on newer chips, which
-+ * have been converging on command sets which including JEDEC ID.
-+ */
-+const struct spi_device_id spi_nor_ids[] = {
-+ /* Atmel -- some are (confusingly) marketed as "DataFlash" */
-+ { "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4, SECT_4K) },
-+ { "at25fs040", INFO(0x1f6604, 0, 64 * 1024, 8, SECT_4K) },
-+
-+ { "at25df041a", INFO(0x1f4401, 0, 64 * 1024, 8, SECT_4K) },
-+ { "at25df321a", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) },
-+ { "at25df641", INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) },
-+
-+ { "at26f004", INFO(0x1f0400, 0, 64 * 1024, 8, SECT_4K) },
-+ { "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) },
-+ { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) },
-+ { "at26df321", INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) },
-+
-+ { "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) },
-+
-+ /* EON -- en25xxx */
-+ { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) },
-+ { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) },
-+ { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) },
-+ { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },
-+ { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) },
-+ { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) },
-+ { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) },
-+
-+ /* ESMT */
-+ { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K) },
-+
-+ /* Everspin */
-+ { "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
-+ { "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
-+
-+ /* GigaDevice */
-+ { "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64, SECT_4K) },
-+ { "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, SECT_4K) },
-+
-+ /* Intel/Numonyx -- xxxs33b */
-+ { "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) },
-+ { "320s33b", INFO(0x898912, 0, 64 * 1024, 64, 0) },
-+ { "640s33b", INFO(0x898913, 0, 64 * 1024, 128, 0) },
-+
-+ /* Macronix */
-+ { "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4, SECT_4K) },
-+ { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) },
-+ { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) },
-+ { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) },
-+ { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) },
-+ { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) },
-+ { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) },
-+ { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
-+ { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
-+ { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
-+ { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
-+ { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) },
-+ { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
-+
-+ /* Micron */
-+ { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, 0) },
-+ { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
-+ { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
-+ { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
-+ { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K) },
-+ { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, USE_FSR) },
-+ { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, USE_FSR) },
-+
-+ /* PMC */
-+ { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
-+ { "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) },
-+ { "pm25lq032", INFO(0x7f9d46, 0, 64 * 1024, 64, SECT_4K) },
-+
-+ /* Spansion -- single (large) sector size only, at least
-+ * for the chips listed here (without boot sectors).
-+ */
-+ { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-+ { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, 0) },
-+ { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
-+ { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-+ { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-+ { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
-+ { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) },
-+ { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) },
-+ { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, 0) },
-+ { "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, 0) },
-+ { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) },
-+ { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) },
-+ { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32, 0) },
-+ { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) },
-+ { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) },
-+ { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) },
-+ { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, SECT_4K) },
-+ { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
-+
-+ /* SST -- large erase sizes are "overlays", "sectors" are 4K */
-+ { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) },
-+ { "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
-+ { "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) },
-+ { "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) },
-+ { "sst25vf064c", INFO(0xbf254b, 0, 64 * 1024, 128, SECT_4K) },
-+ { "sst25wf512", INFO(0xbf2501, 0, 64 * 1024, 1, SECT_4K | SST_WRITE) },
-+ { "sst25wf010", INFO(0xbf2502, 0, 64 * 1024, 2, SECT_4K | SST_WRITE) },
-+ { "sst25wf020", INFO(0xbf2503, 0, 64 * 1024, 4, SECT_4K | SST_WRITE) },
-+ { "sst25wf040", INFO(0xbf2504, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) },
-+
-+ /* ST Microelectronics -- newer production may have feature updates */
-+ { "m25p05", INFO(0x202010, 0, 32 * 1024, 2, 0) },
-+ { "m25p10", INFO(0x202011, 0, 32 * 1024, 4, 0) },
-+ { "m25p20", INFO(0x202012, 0, 64 * 1024, 4, 0) },
-+ { "m25p40", INFO(0x202013, 0, 64 * 1024, 8, 0) },
-+ { "m25p80", INFO(0x202014, 0, 64 * 1024, 16, 0) },
-+ { "m25p16", INFO(0x202015, 0, 64 * 1024, 32, 0) },
-+ { "m25p32", INFO(0x202016, 0, 64 * 1024, 64, 0) },
-+ { "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 0) },
-+ { "m25p128", INFO(0x202018, 0, 256 * 1024, 64, 0) },
-+ { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, 0) },
-+
-+ { "m25p05-nonjedec", INFO(0, 0, 32 * 1024, 2, 0) },
-+ { "m25p10-nonjedec", INFO(0, 0, 32 * 1024, 4, 0) },
-+ { "m25p20-nonjedec", INFO(0, 0, 64 * 1024, 4, 0) },
-+ { "m25p40-nonjedec", INFO(0, 0, 64 * 1024, 8, 0) },
-+ { "m25p80-nonjedec", INFO(0, 0, 64 * 1024, 16, 0) },
-+ { "m25p16-nonjedec", INFO(0, 0, 64 * 1024, 32, 0) },
-+ { "m25p32-nonjedec", INFO(0, 0, 64 * 1024, 64, 0) },
-+ { "m25p64-nonjedec", INFO(0, 0, 64 * 1024, 128, 0) },
-+ { "m25p128-nonjedec", INFO(0, 0, 256 * 1024, 64, 0) },
-+
-+ { "m45pe10", INFO(0x204011, 0, 64 * 1024, 2, 0) },
-+ { "m45pe80", INFO(0x204014, 0, 64 * 1024, 16, 0) },
-+ { "m45pe16", INFO(0x204015, 0, 64 * 1024, 32, 0) },
-+
-+ { "m25pe20", INFO(0x208012, 0, 64 * 1024, 4, 0) },
-+ { "m25pe80", INFO(0x208014, 0, 64 * 1024, 16, 0) },
-+ { "m25pe16", INFO(0x208015, 0, 64 * 1024, 32, SECT_4K) },
-+
-+ { "m25px16", INFO(0x207115, 0, 64 * 1024, 32, SECT_4K) },
-+ { "m25px32", INFO(0x207116, 0, 64 * 1024, 64, SECT_4K) },
-+ { "m25px32-s0", INFO(0x207316, 0, 64 * 1024, 64, SECT_4K) },
-+ { "m25px32-s1", INFO(0x206316, 0, 64 * 1024, 64, SECT_4K) },
-+ { "m25px64", INFO(0x207117, 0, 64 * 1024, 128, 0) },
-+
-+ /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
-+ { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) },
-+ { "w25x20", INFO(0xef3012, 0, 64 * 1024, 4, SECT_4K) },
-+ { "w25x40", INFO(0xef3013, 0, 64 * 1024, 8, SECT_4K) },
-+ { "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) },
-+ { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) },
-+ { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) },
-+ { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) },
-+ { "w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64, SECT_4K) },
-+ { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
-+ { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
-+ { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
-+ { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) },
-+ { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) },
-+ { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
-+ { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) },
-+
-+ /* Catalyst / On Semiconductor -- non-JEDEC */
-+ { "cat25c11", CAT25_INFO( 16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
-+ { "cat25c03", CAT25_INFO( 32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
-+ { "cat25c09", CAT25_INFO( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
-+ { "cat25c17", CAT25_INFO( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
-+ { "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
-+ { },
-+};
-+EXPORT_SYMBOL_GPL(spi_nor_ids);
-+
-+static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
-+{
-+ int tmp;
-+ u8 id[5];
-+ u32 jedec;
-+ u16 ext_jedec;
-+ struct flash_info *info;
-+
-+ tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, 5);
-+ if (tmp < 0) {
-+ dev_dbg(nor->dev, " error %d reading JEDEC ID\n", tmp);
-+ return ERR_PTR(tmp);
-+ }
-+ jedec = id[0];
-+ jedec = jedec << 8;
-+ jedec |= id[1];
-+ jedec = jedec << 8;
-+ jedec |= id[2];
-+
-+ ext_jedec = id[3] << 8 | id[4];
-+
-+ for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) {
-+ info = (void *)spi_nor_ids[tmp].driver_data;
-+ if (info->jedec_id == jedec) {
-+ if (info->ext_id == 0 || info->ext_id == ext_jedec)
-+ return &spi_nor_ids[tmp];
-+ }
-+ }
-+ dev_err(nor->dev, "unrecognized JEDEC id %06x\n", jedec);
-+ return ERR_PTR(-ENODEV);
-+}
-+
-+static const struct spi_device_id *jedec_probe(struct spi_nor *nor)
-+{
-+ return nor->read_id(nor);
-+}
-+
-+static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t *retlen, u_char *buf)
-+{
-+ struct spi_nor *nor = mtd_to_spi_nor(mtd);
-+ int ret;
-+
-+ dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len);
-+
-+ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_READ);
-+ if (ret)
-+ return ret;
-+
-+ ret = nor->read(nor, from, len, retlen, buf);
-+
-+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_READ);
-+ return ret;
-+}
-+
-+static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf)
-+{
-+ struct spi_nor *nor = mtd_to_spi_nor(mtd);
-+ size_t actual;
-+ int ret;
-+
-+ dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len);
-+
-+ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_WRITE);
-+ if (ret)
-+ return ret;
-+
-+ /* Wait until finished previous write command. */
-+ ret = wait_till_ready(nor);
-+ if (ret)
-+ goto time_out;
-+
-+ write_enable(nor);
-+
-+ nor->sst_write_second = false;
-+
-+ actual = to % 2;
-+ /* Start write from odd address. */
-+ if (actual) {
-+ nor->program_opcode = SPINOR_OP_BP;
-+
-+ /* write one byte. */
-+ nor->write(nor, to, 1, retlen, buf);
-+ ret = wait_till_ready(nor);
-+ if (ret)
-+ goto time_out;
-+ }
-+ to += actual;
-+
-+ /* Write out most of the data here. */
-+ for (; actual < len - 1; actual += 2) {
-+ nor->program_opcode = SPINOR_OP_AAI_WP;
-+
-+ /* write two bytes. */
-+ nor->write(nor, to, 2, retlen, buf + actual);
-+ ret = wait_till_ready(nor);
-+ if (ret)
-+ goto time_out;
-+ to += 2;
-+ nor->sst_write_second = true;
-+ }
-+ nor->sst_write_second = false;
-+
-+ write_disable(nor);
-+ ret = wait_till_ready(nor);
-+ if (ret)
-+ goto time_out;
-+
-+ /* Write out trailing byte if it exists. */
-+ if (actual != len) {
-+ write_enable(nor);
-+
-+ nor->program_opcode = SPINOR_OP_BP;
-+ nor->write(nor, to, 1, retlen, buf + actual);
-+
-+ ret = wait_till_ready(nor);
-+ if (ret)
-+ goto time_out;
-+ write_disable(nor);
-+ }
-+time_out:
-+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);
-+ return ret;
-+}
-+
-+/*
-+ * Write an address range to the nor chip. Data must be written in
-+ * FLASH_PAGESIZE chunks. The address range may be any size provided
-+ * it is within the physical boundaries.
-+ */
-+static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf)
-+{
-+ struct spi_nor *nor = mtd_to_spi_nor(mtd);
-+ u32 page_offset, page_size, i;
-+ int ret;
-+
-+ dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len);
-+
-+ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_WRITE);
-+ if (ret)
-+ return ret;
-+
-+ /* Wait until finished previous write command. */
-+ ret = wait_till_ready(nor);
-+ if (ret)
-+ goto write_err;
-+
-+ write_enable(nor);
-+
-+ page_offset = to & (nor->page_size - 1);
-+
-+ /* do all the bytes fit onto one page? */
-+ if (page_offset + len <= nor->page_size) {
-+ nor->write(nor, to, len, retlen, buf);
-+ } else {
-+ /* the size of data remaining on the first page */
-+ page_size = nor->page_size - page_offset;
-+ nor->write(nor, to, page_size, retlen, buf);
-+
-+ /* write everything in nor->page_size chunks */
-+ for (i = page_size; i < len; i += page_size) {
-+ page_size = len - i;
-+ if (page_size > nor->page_size)
-+ page_size = nor->page_size;
-+
-+ wait_till_ready(nor);
-+ write_enable(nor);
-+
-+ nor->write(nor, to + i, page_size, retlen, buf + i);
-+ }
-+ }
-+
-+write_err:
-+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);
-+ return 0;
-+}
-+
-+static int macronix_quad_enable(struct spi_nor *nor)
-+{
-+ int ret, val;
-+
-+ val = read_sr(nor);
-+ write_enable(nor);
-+
-+ nor->cmd_buf[0] = val | SR_QUAD_EN_MX;
-+ nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 1, 0);
-+
-+ if (wait_till_ready(nor))
-+ return 1;
-+
-+ ret = read_sr(nor);
-+ if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) {
-+ dev_err(nor->dev, "Macronix Quad bit not set\n");
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+/*
-+ * Write status Register and configuration register with 2 bytes
-+ * The first byte will be written to the status register, while the
-+ * second byte will be written to the configuration register.
-+ * Return negative if error occured.
-+ */
-+static int write_sr_cr(struct spi_nor *nor, u16 val)
-+{
-+ nor->cmd_buf[0] = val & 0xff;
-+ nor->cmd_buf[1] = (val >> 8);
-+
-+ return nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 2, 0);
-+}
-+
-+static int spansion_quad_enable(struct spi_nor *nor)
-+{
-+ int ret;
-+ int quad_en = CR_QUAD_EN_SPAN << 8;
-+
-+ write_enable(nor);
-+
-+ ret = write_sr_cr(nor, quad_en);
-+ if (ret < 0) {
-+ dev_err(nor->dev,
-+ "error while writing configuration register\n");
-+ return -EINVAL;
-+ }
-+
-+ /* read back and check it */
-+ ret = read_cr(nor);
-+ if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) {
-+ dev_err(nor->dev, "Spansion Quad bit not set\n");
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int set_quad_mode(struct spi_nor *nor, u32 jedec_id)
-+{
-+ int status;
-+
-+ switch (JEDEC_MFR(jedec_id)) {
-+ case CFI_MFR_MACRONIX:
-+ status = macronix_quad_enable(nor);
-+ if (status) {
-+ dev_err(nor->dev, "Macronix quad-read not enabled\n");
-+ return -EINVAL;
-+ }
-+ return status;
-+ default:
-+ status = spansion_quad_enable(nor);
-+ if (status) {
-+ dev_err(nor->dev, "Spansion quad-read not enabled\n");
-+ return -EINVAL;
-+ }
-+ return status;
-+ }
-+}
-+
-+static int spi_nor_check(struct spi_nor *nor)
-+{
-+ if (!nor->dev || !nor->read || !nor->write ||
-+ !nor->read_reg || !nor->write_reg || !nor->erase) {
-+ pr_err("spi-nor: please fill all the necessary fields!\n");
-+ return -EINVAL;
-+ }
-+
-+ if (!nor->read_id)
-+ nor->read_id = spi_nor_read_id;
-+ if (!nor->wait_till_ready)
-+ nor->wait_till_ready = spi_nor_wait_till_ready;
-+
-+ return 0;
-+}
-+
-+int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id,
-+ enum read_mode mode)
-+{
-+ struct flash_info *info;
-+ struct flash_platform_data *data;
-+ struct device *dev = nor->dev;
-+ struct mtd_info *mtd = nor->mtd;
-+ struct device_node *np = dev->of_node;
-+ int ret;
-+ int i;
-+
-+ ret = spi_nor_check(nor);
-+ if (ret)
-+ return ret;
-+
-+ /* Platform data helps sort out which chip type we have, as
-+ * well as how this board partitions it. If we don't have
-+ * a chip ID, try the JEDEC id commands; they'll work for most
-+ * newer chips, even if we don't recognize the particular chip.
-+ */
-+ data = dev_get_platdata(dev);
-+ if (data && data->type) {
-+ const struct spi_device_id *plat_id;
-+
-+ for (i = 0; i < ARRAY_SIZE(spi_nor_ids) - 1; i++) {
-+ plat_id = &spi_nor_ids[i];
-+ if (strcmp(data->type, plat_id->name))
-+ continue;
-+ break;
-+ }
-+
-+ if (i < ARRAY_SIZE(spi_nor_ids) - 1)
-+ id = plat_id;
-+ else
-+ dev_warn(dev, "unrecognized id %s\n", data->type);
-+ }
-+
-+ info = (void *)id->driver_data;
-+
-+ if (info->jedec_id) {
-+ const struct spi_device_id *jid;
-+
-+ jid = jedec_probe(nor);
-+ if (IS_ERR(jid)) {
-+ return PTR_ERR(jid);
-+ } else if (jid != id) {
-+ /*
-+ * JEDEC knows better, so overwrite platform ID. We
-+ * can't trust partitions any longer, but we'll let
-+ * mtd apply them anyway, since some partitions may be
-+ * marked read-only, and we don't want to lose that
-+ * information, even if it's not 100% accurate.
-+ */
-+ dev_warn(dev, "found %s, expected %s\n",
-+ jid->name, id->name);
-+ id = jid;
-+ info = (void *)jid->driver_data;
-+ }
-+ }
-+
-+ mutex_init(&nor->lock);
-+
-+ /*
-+ * Atmel, SST and Intel/Numonyx serial nor tend to power
-+ * up with the software protection bits set
-+ */
-+
-+ if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ATMEL ||
-+ JEDEC_MFR(info->jedec_id) == CFI_MFR_INTEL ||
-+ JEDEC_MFR(info->jedec_id) == CFI_MFR_SST) {
-+ write_enable(nor);
-+ write_sr(nor, 0);
-+ }
-+
-+ if (data && data->name)
-+ mtd->name = data->name;
-+ else
-+ mtd->name = dev_name(dev);
-+
-+ mtd->type = MTD_NORFLASH;
-+ mtd->writesize = 1;
-+ mtd->flags = MTD_CAP_NORFLASH;
-+ mtd->size = info->sector_size * info->n_sectors;
-+ mtd->_erase = spi_nor_erase;
-+ mtd->_read = spi_nor_read;
-+
-+ /* nor protection support for STmicro chips */
-+ if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ST) {
-+ mtd->_lock = spi_nor_lock;
-+ mtd->_unlock = spi_nor_unlock;
-+ }
-+
-+ /* sst nor chips use AAI word program */
-+ if (info->flags & SST_WRITE)
-+ mtd->_write = sst_write;
-+ else
-+ mtd->_write = spi_nor_write;
-+
-+ if ((info->flags & USE_FSR) &&
-+ nor->wait_till_ready == spi_nor_wait_till_ready)
-+ nor->wait_till_ready = spi_nor_wait_till_fsr_ready;
-+
-+ /* prefer "small sector" erase if possible */
-+ if (info->flags & SECT_4K) {
-+ nor->erase_opcode = SPINOR_OP_BE_4K;
-+ mtd->erasesize = 4096;
-+ } else if (info->flags & SECT_4K_PMC) {
-+ nor->erase_opcode = SPINOR_OP_BE_4K_PMC;
-+ mtd->erasesize = 4096;
-+ } else {
-+ nor->erase_opcode = SPINOR_OP_SE;
-+ mtd->erasesize = info->sector_size;
-+ }
-+
-+ if (info->flags & SPI_NOR_NO_ERASE)
-+ mtd->flags |= MTD_NO_ERASE;
-+
-+ mtd->dev.parent = dev;
-+ nor->page_size = info->page_size;
-+ mtd->writebufsize = nor->page_size;
-+
-+ if (np) {
-+ /* If we were instantiated by DT, use it */
-+ if (of_property_read_bool(np, "m25p,fast-read"))
-+ nor->flash_read = SPI_NOR_FAST;
-+ else
-+ nor->flash_read = SPI_NOR_NORMAL;
-+ } else {
-+ /* If we weren't instantiated by DT, default to fast-read */
-+ nor->flash_read = SPI_NOR_FAST;
-+ }
-+
-+ /* Some devices cannot do fast-read, no matter what DT tells us */
-+ if (info->flags & SPI_NOR_NO_FR)
-+ nor->flash_read = SPI_NOR_NORMAL;
-+
-+ /* Quad/Dual-read mode takes precedence over fast/normal */
-+ if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) {
-+ ret = set_quad_mode(nor, info->jedec_id);
-+ if (ret) {
-+ dev_err(dev, "quad mode not supported\n");
-+ return ret;
-+ }
-+ nor->flash_read = SPI_NOR_QUAD;
-+ } else if (mode == SPI_NOR_DUAL && info->flags & SPI_NOR_DUAL_READ) {
-+ nor->flash_read = SPI_NOR_DUAL;
-+ }
-+
-+ /* Default commands */
-+ switch (nor->flash_read) {
-+ case SPI_NOR_QUAD:
-+ nor->read_opcode = SPINOR_OP_READ_1_1_4;
-+ break;
-+ case SPI_NOR_DUAL:
-+ nor->read_opcode = SPINOR_OP_READ_1_1_2;
-+ break;
-+ case SPI_NOR_FAST:
-+ nor->read_opcode = SPINOR_OP_READ_FAST;
-+ break;
-+ case SPI_NOR_NORMAL:
-+ nor->read_opcode = SPINOR_OP_READ;
-+ break;
-+ default:
-+ dev_err(dev, "No Read opcode defined\n");
-+ return -EINVAL;
-+ }
-+
-+ nor->program_opcode = SPINOR_OP_PP;
-+
-+ if (info->addr_width)
-+ nor->addr_width = info->addr_width;
-+ else if (mtd->size > 0x1000000) {
-+ /* enable 4-byte addressing if the device exceeds 16MiB */
-+ nor->addr_width = 4;
-+ if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
-+ /* Dedicated 4-byte command set */
-+ switch (nor->flash_read) {
-+ case SPI_NOR_QUAD:
-+ nor->read_opcode = SPINOR_OP_READ4_1_1_4;
-+ break;
-+ case SPI_NOR_DUAL:
-+ nor->read_opcode = SPINOR_OP_READ4_1_1_2;
-+ break;
-+ case SPI_NOR_FAST:
-+ nor->read_opcode = SPINOR_OP_READ4_FAST;
-+ break;
-+ case SPI_NOR_NORMAL:
-+ nor->read_opcode = SPINOR_OP_READ4;
-+ break;
-+ }
-+ nor->program_opcode = SPINOR_OP_PP_4B;
-+ /* No small sector erase for 4-byte command set */
-+ nor->erase_opcode = SPINOR_OP_SE_4B;
-+ mtd->erasesize = info->sector_size;
-+ } else
-+ set_4byte(nor, info->jedec_id, 1);
-+ } else {
-+ nor->addr_width = 3;
-+ }
-+
-+ nor->read_dummy = spi_nor_read_dummy_cycles(nor);
-+
-+ dev_info(dev, "%s (%lld Kbytes)\n", id->name,
-+ (long long)mtd->size >> 10);
-+
-+ dev_dbg(dev,
-+ "mtd .name = %s, .size = 0x%llx (%lldMiB), "
-+ ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
-+ mtd->name, (long long)mtd->size, (long long)(mtd->size >> 20),
-+ mtd->erasesize, mtd->erasesize / 1024, mtd->numeraseregions);
-+
-+ if (mtd->numeraseregions)
-+ for (i = 0; i < mtd->numeraseregions; i++)
-+ dev_dbg(dev,
-+ "mtd.eraseregions[%d] = { .offset = 0x%llx, "
-+ ".erasesize = 0x%.8x (%uKiB), "
-+ ".numblocks = %d }\n",
-+ i, (long long)mtd->eraseregions[i].offset,
-+ mtd->eraseregions[i].erasesize,
-+ mtd->eraseregions[i].erasesize / 1024,
-+ mtd->eraseregions[i].numblocks);
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(spi_nor_scan);
-+
-+const struct spi_device_id *spi_nor_match_id(char *name)
-+{
-+ const struct spi_device_id *id = spi_nor_ids;
-+
-+ while (id->name[0]) {
-+ if (!strcmp(name, id->name))
-+ return id;
-+ id++;
-+ }
-+ return NULL;
-+}
-+EXPORT_SYMBOL_GPL(spi_nor_match_id);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Huang Shijie <shijie8@gmail.com>");
-+MODULE_AUTHOR("Mike Lavender");
-+MODULE_DESCRIPTION("framework for SPI NOR");
---- /dev/null
-+++ b/include/linux/mtd/spi-nor.h
-@@ -0,0 +1,218 @@
-+/*
-+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ */
-+
-+#ifndef __LINUX_MTD_SPI_NOR_H
-+#define __LINUX_MTD_SPI_NOR_H
-+
-+/*
-+ * Note on opcode nomenclature: some opcodes have a format like
-+ * SPINOR_OP_FUNCTION{4,}_x_y_z. The numbers x, y, and z stand for the number
-+ * of I/O lines used for the opcode, address, and data (respectively). The
-+ * FUNCTION has an optional suffix of '4', to represent an opcode which
-+ * requires a 4-byte (32-bit) address.
-+ */
-+
-+/* Flash opcodes. */
-+#define SPINOR_OP_WREN 0x06 /* Write enable */
-+#define SPINOR_OP_RDSR 0x05 /* Read status register */
-+#define SPINOR_OP_WRSR 0x01 /* Write status register 1 byte */
-+#define SPINOR_OP_READ 0x03 /* Read data bytes (low frequency) */
-+#define SPINOR_OP_READ_FAST 0x0b /* Read data bytes (high frequency) */
-+#define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual SPI) */
-+#define SPINOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad SPI) */
-+#define SPINOR_OP_PP 0x02 /* Page program (up to 256 bytes) */
-+#define SPINOR_OP_BE_4K 0x20 /* Erase 4KiB block */
-+#define SPINOR_OP_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */
-+#define SPINOR_OP_BE_32K 0x52 /* Erase 32KiB block */
-+#define SPINOR_OP_CHIP_ERASE 0xc7 /* Erase whole flash chip */
-+#define SPINOR_OP_SE 0xd8 /* Sector erase (usually 64KiB) */
-+#define SPINOR_OP_RDID 0x9f /* Read JEDEC ID */
-+#define SPINOR_OP_RDCR 0x35 /* Read configuration register */
-+#define SPINOR_OP_RDFSR 0x70 /* Read flag status register */
-+
-+/* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
-+#define SPINOR_OP_READ4 0x13 /* Read data bytes (low frequency) */
-+#define SPINOR_OP_READ4_FAST 0x0c /* Read data bytes (high frequency) */
-+#define SPINOR_OP_READ4_1_1_2 0x3c /* Read data bytes (Dual SPI) */
-+#define SPINOR_OP_READ4_1_1_4 0x6c /* Read data bytes (Quad SPI) */
-+#define SPINOR_OP_PP_4B 0x12 /* Page program (up to 256 bytes) */
-+#define SPINOR_OP_SE_4B 0xdc /* Sector erase (usually 64KiB) */
-+
-+/* Used for SST flashes only. */
-+#define SPINOR_OP_BP 0x02 /* Byte program */
-+#define SPINOR_OP_WRDI 0x04 /* Write disable */
-+#define SPINOR_OP_AAI_WP 0xad /* Auto address increment word program */
-+
-+/* Used for Macronix and Winbond flashes. */
-+#define SPINOR_OP_EN4B 0xb7 /* Enter 4-byte mode */
-+#define SPINOR_OP_EX4B 0xe9 /* Exit 4-byte mode */
-+
-+/* Used for Spansion flashes only. */
-+#define SPINOR_OP_BRWR 0x17 /* Bank register write */
-+
-+/* Status Register bits. */
-+#define SR_WIP 1 /* Write in progress */
-+#define SR_WEL 2 /* Write enable latch */
-+/* meaning of other SR_* bits may differ between vendors */
-+#define SR_BP0 4 /* Block protect 0 */
-+#define SR_BP1 8 /* Block protect 1 */
-+#define SR_BP2 0x10 /* Block protect 2 */
-+#define SR_SRWD 0x80 /* SR write protect */
-+
-+#define SR_QUAD_EN_MX 0x40 /* Macronix Quad I/O */
-+
-+/* Flag Status Register bits */
-+#define FSR_READY 0x80
-+
-+/* Configuration Register bits. */
-+#define CR_QUAD_EN_SPAN 0x2 /* Spansion Quad I/O */
-+
-+enum read_mode {
-+ SPI_NOR_NORMAL = 0,
-+ SPI_NOR_FAST,
-+ SPI_NOR_DUAL,
-+ SPI_NOR_QUAD,
-+};
-+
-+/**
-+ * struct spi_nor_xfer_cfg - Structure for defining a Serial Flash transfer
-+ * @wren: command for "Write Enable", or 0x00 for not required
-+ * @cmd: command for operation
-+ * @cmd_pins: number of pins to send @cmd (1, 2, 4)
-+ * @addr: address for operation
-+ * @addr_pins: number of pins to send @addr (1, 2, 4)
-+ * @addr_width: number of address bytes
-+ * (3,4, or 0 for address not required)
-+ * @mode: mode data
-+ * @mode_pins: number of pins to send @mode (1, 2, 4)
-+ * @mode_cycles: number of mode cycles (0 for mode not required)
-+ * @dummy_cycles: number of dummy cycles (0 for dummy not required)
-+ */
-+struct spi_nor_xfer_cfg {
-+ u8 wren;
-+ u8 cmd;
-+ u8 cmd_pins;
-+ u32 addr;
-+ u8 addr_pins;
-+ u8 addr_width;
-+ u8 mode;
-+ u8 mode_pins;
-+ u8 mode_cycles;
-+ u8 dummy_cycles;
-+};
-+
-+#define SPI_NOR_MAX_CMD_SIZE 8
-+enum spi_nor_ops {
-+ SPI_NOR_OPS_READ = 0,
-+ SPI_NOR_OPS_WRITE,
-+ SPI_NOR_OPS_ERASE,
-+ SPI_NOR_OPS_LOCK,
-+ SPI_NOR_OPS_UNLOCK,
-+};
-+
-+/**
-+ * struct spi_nor - Structure for defining a the SPI NOR layer
-+ * @mtd: point to a mtd_info structure
-+ * @lock: the lock for the read/write/erase/lock/unlock operations
-+ * @dev: point to a spi device, or a spi nor controller device.
-+ * @page_size: the page size of the SPI NOR
-+ * @addr_width: number of address bytes
-+ * @erase_opcode: the opcode for erasing a sector
-+ * @read_opcode: the read opcode
-+ * @read_dummy: the dummy needed by the read operation
-+ * @program_opcode: the program opcode
-+ * @flash_read: the mode of the read
-+ * @sst_write_second: used by the SST write operation
-+ * @cfg: used by the read_xfer/write_xfer
-+ * @cmd_buf: used by the write_reg
-+ * @prepare: [OPTIONAL] do some preparations for the
-+ * read/write/erase/lock/unlock operations
-+ * @unprepare: [OPTIONAL] do some post work after the
-+ * read/write/erase/lock/unlock operations
-+ * @read_xfer: [OPTIONAL] the read fundamental primitive
-+ * @write_xfer: [OPTIONAL] the writefundamental primitive
-+ * @read_reg: [DRIVER-SPECIFIC] read out the register
-+ * @write_reg: [DRIVER-SPECIFIC] write data to the register
-+ * @read_id: [REPLACEABLE] read out the ID data, and find
-+ * the proper spi_device_id
-+ * @wait_till_ready: [REPLACEABLE] wait till the NOR becomes ready
-+ * @read: [DRIVER-SPECIFIC] read data from the SPI NOR
-+ * @write: [DRIVER-SPECIFIC] write data to the SPI NOR
-+ * @erase: [DRIVER-SPECIFIC] erase a sector of the SPI NOR
-+ * at the offset @offs
-+ * @priv: the private data
-+ */
-+struct spi_nor {
-+ struct mtd_info *mtd;
-+ struct mutex lock;
-+ struct device *dev;
-+ u32 page_size;
-+ u8 addr_width;
-+ u8 erase_opcode;
-+ u8 read_opcode;
-+ u8 read_dummy;
-+ u8 program_opcode;
-+ enum read_mode flash_read;
-+ bool sst_write_second;
-+ struct spi_nor_xfer_cfg cfg;
-+ u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE];
-+
-+ int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops);
-+ void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops);
-+ int (*read_xfer)(struct spi_nor *nor, struct spi_nor_xfer_cfg *cfg,
-+ u8 *buf, size_t len);
-+ int (*write_xfer)(struct spi_nor *nor, struct spi_nor_xfer_cfg *cfg,
-+ u8 *buf, size_t len);
-+ int (*read_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len);
-+ int (*write_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len,
-+ int write_enable);
-+ const struct spi_device_id *(*read_id)(struct spi_nor *nor);
-+ int (*wait_till_ready)(struct spi_nor *nor);
-+
-+ int (*read)(struct spi_nor *nor, loff_t from,
-+ size_t len, size_t *retlen, u_char *read_buf);
-+ void (*write)(struct spi_nor *nor, loff_t to,
-+ size_t len, size_t *retlen, const u_char *write_buf);
-+ int (*erase)(struct spi_nor *nor, loff_t offs);
-+
-+ void *priv;
-+};
-+
-+/**
-+ * spi_nor_scan() - scan the SPI NOR
-+ * @nor: the spi_nor structure
-+ * @id: the spi_device_id provided by the driver
-+ * @mode: the read mode supported by the driver
-+ *
-+ * The drivers can use this fuction to scan the SPI NOR.
-+ * In the scanning, it will try to get all the necessary information to
-+ * fill the mtd_info{} and the spi_nor{}.
-+ *
-+ * The board may assigns a spi_device_id with @id which be used to compared with
-+ * the spi_device_id detected by the scanning.
-+ *
-+ * Return: 0 for success, others for failure.
-+ */
-+int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id,
-+ enum read_mode mode);
-+extern const struct spi_device_id spi_nor_ids[];
-+
-+/**
-+ * spi_nor_match_id() - find the spi_device_id by the name
-+ * @name: the name of the spi_device_id
-+ *
-+ * The drivers use this function to find the spi_device_id
-+ * specified by the @name.
-+ *
-+ * Return: returns the right spi_device_id pointer on success,
-+ * and returns NULL on failure.
-+ */
-+const struct spi_device_id *spi_nor_match_id(char *name);
-+
-+#endif
diff --git a/target/linux/bcm53xx/patches-3.14/040-ARM-BCM5301X-initial-support-for-the-BCM5301X-BCM470.patch b/target/linux/bcm53xx/patches-3.14/040-ARM-BCM5301X-initial-support-for-the-BCM5301X-BCM470.patch
deleted file mode 100644
index c12d8df..0000000
--- a/target/linux/bcm53xx/patches-3.14/040-ARM-BCM5301X-initial-support-for-the-BCM5301X-BCM470.patch
+++ /dev/null
@@ -1,148 +0,0 @@
-From 5b293ebe757213993ae93b6cbbf5e1d09b75ac2f Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Tue, 4 Feb 2014 00:01:43 +0100
-Subject: [PATCH 1/3] ARM: BCM5301X: initial support for the BCM5301X/BCM470X
- SoCs with ARM CPU
-
-This patch adds support for the BCM5301X/BCM470X SoCs with an ARM CPUs.
-Currently just booting to a shell is working and nothing else, no
-Ethernet, wifi, flash, ...
-I have some pending patches to make Ethernet work for this device.
-Mostly device tree support for bcma is missing.
-
-This SoC is used in small office and home router with Broadcom SoCs
-it's internal name is Northstar. This code should support the BCM4707,
-BCM4708, BCM4709, BCM53010, BCM53011 and BCM53012 SoC. It uses one or
-two ARM Cortex A9 Cores, some highlights are 2 PCIe 2.0 controllers,
-4 Gigabit Ethernet MACs and a USB 3.0 host controller.
-
-This SoC uses a dual core CPU, but this is currently not implemented.
-More information about this SoC can be found here:
-http://www.anandtech.com/show/5925/broadcom-announces-bcm4708x-and-bcm5301x-socs-for-80211ac-routers
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
-Acked-by: Arnd Bergmann <arnd@arndb.de>
-Acked-by: Christian Daudt <bcm@fixthebug.org>
-Signed-off-by: Matt Porter <mporter@linaro.org>
----
- Documentation/devicetree/bindings/arm/bcm4708.txt | 8 ++++++
- MAINTAINERS | 8 ++++++
- arch/arm/configs/multi_v7_defconfig | 1 +
- arch/arm/mach-bcm/Kconfig | 26 +++++++++++++++++++
- arch/arm/mach-bcm/Makefile | 1 +
- arch/arm/mach-bcm/bcm_5301x.c | 28 +++++++++++++++++++++
- 6 files changed, 72 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/arm/bcm4708.txt
- create mode 100644 arch/arm/mach-bcm/bcm_5301x.c
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/arm/bcm4708.txt
-@@ -0,0 +1,8 @@
-+Broadcom BCM4708 device tree bindings
-+-------------------------------------------
-+
-+Boards with the BCM4708 SoC shall have the following properties:
-+
-+Required root node property:
-+
-+compatible = "brcm,bcm4708";
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -1883,6 +1883,14 @@ F: arch/arm/boot/dts/bcm2835*
- F: arch/arm/configs/bcm2835_defconfig
- F: drivers/*/*bcm2835*
-
-+BROADCOM BCM5301X ARM ARCHICTURE
-+M: Hauke Mehrtens <hauke@hauke-m.de>
-+L: linux-arm-kernel@lists.infradead.org
-+S: Maintained
-+F: arch/arm/mach-bcm/bcm_5301x.c
-+F: arch/arm/boot/dts/bcm5301x.dtsi
-+F: arch/arm/boot/dts/bcm470*
-+
- BROADCOM TG3 GIGABIT ETHERNET DRIVER
- M: Nithin Nayak Sujir <nsujir@broadcom.com>
- M: Michael Chan <mchan@broadcom.com>
---- a/arch/arm/configs/multi_v7_defconfig
-+++ b/arch/arm/configs/multi_v7_defconfig
-@@ -11,6 +11,7 @@ CONFIG_ARCH_MVEBU=y
- CONFIG_MACH_ARMADA_370=y
- CONFIG_MACH_ARMADA_XP=y
- CONFIG_ARCH_BCM=y
-+CONFIG_ARCH_BCM_5301X=y
- CONFIG_ARCH_BCM_MOBILE=y
- CONFIG_ARCH_BERLIN=y
- CONFIG_MACH_BERLIN_BG2=y
---- a/arch/arm/mach-bcm/Kconfig
-+++ b/arch/arm/mach-bcm/Kconfig
-@@ -32,6 +32,32 @@ config ARCH_BCM_MOBILE
- BCM11130, BCM11140, BCM11351, BCM28145 and
- BCM28155 variants.
-
-+config ARCH_BCM_5301X
-+ bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7
-+ depends on MMU
-+ select ARM_GIC
-+ select CACHE_L2X0
-+ select HAVE_ARM_SCU if SMP
-+ select HAVE_ARM_TWD if SMP
-+ select HAVE_SMP
-+ select COMMON_CLK
-+ select GENERIC_CLOCKEVENTS
-+ select ARM_GLOBAL_TIMER
-+ select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
-+ select MIGHT_HAVE_PCI
-+ help
-+ Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores.
-+
-+ This is a network SoC line mostly used in home routers and
-+ wifi access points, it's internal name is Northstar.
-+ This inclused the following SoC: BCM53010, BCM53011, BCM53012,
-+ BCM53014, BCM53015, BCM53016, BCM53017, BCM53018, BCM4707,
-+ BCM4708 and BCM4709.
-+
-+ Do not confuse this with the BCM4760 which is a totally
-+ different SoC or with the older BCM47XX and BCM53XX based
-+ network SoC using a MIPS CPU, they are supported by arch/mips/bcm47xx
-+
- endmenu
-
- endif
---- a/arch/arm/mach-bcm/Makefile
-+++ b/arch/arm/mach-bcm/Makefile
-@@ -13,3 +13,4 @@
- obj-$(CONFIG_ARCH_BCM_MOBILE) := board_bcm281xx.o bcm_kona_smc.o bcm_kona_smc_asm.o kona.o
- plus_sec := $(call as-instr,.arch_extension sec,+sec)
- AFLAGS_bcm_kona_smc_asm.o :=-Wa,-march=armv7-a$(plus_sec)
-+obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o
---- /dev/null
-+++ b/arch/arm/mach-bcm/bcm_5301x.c
-@@ -0,0 +1,28 @@
-+/*
-+ * Broadcom BCM470X / BCM5301X ARM platform code.
-+ *
-+ * Copyright 2013 Hauke Mehrtens <hauke@hauke-m.de>
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+#include <linux/of_platform.h>
-+#include <asm/hardware/cache-l2x0.h>
-+
-+#include <asm/mach/arch.h>
-+
-+
-+static void __init bcm5301x_dt_init(void)
-+{
-+ l2x0_of_init(0, ~0UL);
-+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-+}
-+
-+static const char __initconst *bcm5301x_dt_compat[] = {
-+ "brcm,bcm4708",
-+ NULL,
-+};
-+
-+DT_MACHINE_START(BCM5301X, "BCM5301X")
-+ .init_machine = bcm5301x_dt_init,
-+ .dt_compat = bcm5301x_dt_compat,
-+MACHINE_END
diff --git a/target/linux/bcm53xx/patches-3.14/041-ARM-BCM5301X-add-early-debugging-support.patch b/target/linux/bcm53xx/patches-3.14/041-ARM-BCM5301X-add-early-debugging-support.patch
deleted file mode 100644
index 2e028a8..0000000
--- a/target/linux/bcm53xx/patches-3.14/041-ARM-BCM5301X-add-early-debugging-support.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 065802756b20d878c83290c115f212fc1631cba7 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Tue, 4 Feb 2014 00:01:44 +0100
-Subject: [PATCH 2/3] ARM: BCM5301X: add early debugging support
-
-This adds support for early debugging of BCM5301X SoC.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
-Acked-by: Arnd Bergmann <arnd@arndb.de>
-Acked-by: Christian Daudt <bcm@fixthebug.org>
-Signed-off-by: Matt Porter <mporter@linaro.org>
----
- arch/arm/Kconfig.debug | 7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/arch/arm/Kconfig.debug
-+++ b/arch/arm/Kconfig.debug
-@@ -106,6 +106,11 @@ choice
- depends on ARCH_BCM2835
- select DEBUG_UART_PL01X
-
-+ config DEBUG_BCM_5301X
-+ bool "Kernel low-level debugging on BCM5301X UART1"
-+ depends on ARCH_BCM_5301X
-+ select DEBUG_UART_PL01X
-+
- config DEBUG_BCM_KONA_UART
- bool "Kernel low-level debugging messages via BCM KONA UART"
- depends on ARCH_BCM
-@@ -1023,6 +1028,7 @@ config DEBUG_UART_PHYS
- default 0x101f1000 if ARCH_VERSATILE
- default 0x101fb000 if DEBUG_NOMADIK_UART
- default 0x16000000 if ARCH_INTEGRATOR
-+ default 0x18000300 if DEBUG_BCM_5301X
- default 0x1c090000 if DEBUG_VEXPRESS_UART0_RS1
- default 0x20060000 if DEBUG_RK29_UART0
- default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2
-@@ -1071,6 +1077,7 @@ config DEBUG_UART_VIRT
- default 0xf0009000 if DEBUG_CNS3XXX
- default 0xf01fb000 if DEBUG_NOMADIK_UART
- default 0xf0201000 if DEBUG_BCM2835
-+ default 0xf1000300 if DEBUG_BCM_5301X
- default 0xf11f1000 if ARCH_VERSATILE
- default 0xf1600000 if ARCH_INTEGRATOR
- default 0xf1c28000 if DEBUG_SUNXI_UART0
diff --git a/target/linux/bcm53xx/patches-3.14/042-ARM-BCM5301X-workaround-suppress-fault.patch b/target/linux/bcm53xx/patches-3.14/042-ARM-BCM5301X-workaround-suppress-fault.patch
deleted file mode 100644
index 41a9dd1..0000000
--- a/target/linux/bcm53xx/patches-3.14/042-ARM-BCM5301X-workaround-suppress-fault.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From fdf4850cb5b2e5e549a18b8b41abb001bfb19e9c Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Tue, 4 Feb 2014 00:01:46 +0100
-Subject: [PATCH 3/3] ARM: BCM5301X: workaround suppress fault
-
-Without this patch I am getting a unhandled fault exception like this
-one after "Freeing unused kernel memory":
-
-Freeing unused kernel memory: 1260K (c02c1000 - c03fc000)
-Unhandled fault: imprecise external abort (0x1c06) at 0xb6f89005
-Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000007
-
-The address which is here 0xb6f89005 changes from boot to boot, with a
-new build the changes are bigger. With kernel 3.10 I have also seen
-this fault at different places in the boot process, but starting with
-3.11 they are always occurring after the "Freeing unused kernel memory"
-message. I never was able to completely boot to userspace without this
-handler. The abort code is constant 0x1c06. This fault just happens
-once in the boot process I have never seen it happing twice or more.
-
-I also tried changing the CPSR.A bit to 0 in init_early, with this code
-like Afzal suggested, but that did not change anything:
-asm volatile("mrs r12, cpsr\n"
- "bic r12, r12, #0x00000100\n"
- "msr cpsr_c, r12" ::: "r12", "cc", "memory");
-
-Disabling the L2 cache by building with CONFIG_CACHE_L2X0 unset did not
-help.
-
-This workaround was copied from the vendor code including most of the
-comments. It says it they think this is caused by the CFE boot loader
-used on this device. I do not have any access to any datasheet or
-errata document to check this.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
-Acked-by: Arnd Bergmann <arnd@arndb.de>
-Acked-by: Christian Daudt <bcm@fixthebug.org>
-Signed-off-by: Matt Porter <mporter@linaro.org>
----
- arch/arm/mach-bcm/bcm_5301x.c | 33 +++++++++++++++++++++++++++++++++
- 1 file changed, 33 insertions(+)
-
---- a/arch/arm/mach-bcm/bcm_5301x.c
-+++ b/arch/arm/mach-bcm/bcm_5301x.c
-@@ -9,8 +9,40 @@
- #include <asm/hardware/cache-l2x0.h>
-
- #include <asm/mach/arch.h>
-+#include <asm/siginfo.h>
-+#include <asm/signal.h>
-
-
-+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) {
-+ first_fault = false;
-+
-+ /*
-+ * These faults with code 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);
-+
-+ /* Returning non-zero causes fault display and panic */
-+ return 0;
-+ }
-+
-+ /* Others should cause a fault */
-+ return 1;
-+}
-+
-+static void __init bcm5301x_init_early(void)
-+{
-+ /* Install our hook */
-+ hook_fault_code(16 + 6, bcm5301x_abort_handler, SIGBUS, BUS_OBJERR,
-+ "imprecise external abort");
-+}
-+
- static void __init bcm5301x_dt_init(void)
- {
- l2x0_of_init(0, ~0UL);
-@@ -23,6 +55,7 @@ static const char __initconst *bcm5301x_
- };
-
- DT_MACHINE_START(BCM5301X, "BCM5301X")
-+ .init_early = bcm5301x_init_early,
- .init_machine = bcm5301x_dt_init,
- .dt_compat = bcm5301x_dt_compat,
- MACHINE_END
diff --git a/target/linux/bcm53xx/patches-3.14/050-ARM-BCM5301X-add-dts-files-for-BCM4708-SoC.patch b/target/linux/bcm53xx/patches-3.14/050-ARM-BCM5301X-add-dts-files-for-BCM4708-SoC.patch
deleted file mode 100644
index 4e98ec8..0000000
--- a/target/linux/bcm53xx/patches-3.14/050-ARM-BCM5301X-add-dts-files-for-BCM4708-SoC.patch
+++ /dev/null
@@ -1,204 +0,0 @@
-From d27509f19b5f93ea3425cfef782bb3c6541cd44d Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Tue, 4 Feb 2014 00:01:45 +0100
-Subject: [PATCH] ARM: BCM5301X: add dts files for BCM4708 SoC
-
-This uses the newly added BCM5301X SoC code.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
-Acked-by: Arnd Bergmann <arnd@arndb.de>
-Acked-by: Christian Daudt <bcm@fixthebug.org>
-Signed-off-by: Matt Porter <mporter@linaro.org>
----
- arch/arm/boot/dts/Makefile | 1 +
- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 35 ++++++++++
- arch/arm/boot/dts/bcm4708.dtsi | 34 ++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 95 +++++++++++++++++++++++++++
- 4 files changed, 165 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm4708-netgear-r6250.dts
- create mode 100644 arch/arm/boot/dts/bcm4708.dtsi
- create mode 100644 arch/arm/boot/dts/bcm5301x.dtsi
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -50,6 +50,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rp
- dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm11351-brt.dtb \
- bcm28155-ap.dtb
- dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
-+dtb-$(CONFIG_ARCH_BCM_5301X) += bcm4708-netgear-r6250.dtb
- dtb-$(CONFIG_ARCH_BERLIN) += \
- berlin2-sony-nsz-gs7.dtb \
- berlin2cd-google-chromecast.dtb
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -0,0 +1,35 @@
-+/*
-+ * Broadcom BCM470X / BCM5301X arm platform code.
-+ * DTS for Netgear R6250 V1
-+ *
-+ * Copyright 2013 Hauke Mehrtens <hauke@hauke-m.de>
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm4708.dtsi"
-+
-+/ {
-+ compatible = "netgear,r6250v1", "brcm,bcm4708";
-+ model = "Netgear R6250 V1 (BCM4708)";
-+
-+ chosen {
-+ bootargs = "console=ttyS0,115200";
-+ };
-+
-+ memory {
-+ reg = <0x00000000 0x08000000>;
-+ };
-+
-+ chipcommonA {
-+ uart0: serial@0300 {
-+ status = "okay";
-+ };
-+
-+ uart1: serial@0400 {
-+ status = "okay";
-+ };
-+ };
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm4708.dtsi
-@@ -0,0 +1,34 @@
-+/*
-+ * Broadcom BCM470X / BCM5301X ARM platform code.
-+ * DTS for BCM4708 SoC.
-+ *
-+ * Copyright 2013-2014 Hauke Mehrtens <hauke@hauke-m.de>
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+#include "bcm5301x.dtsi"
-+
-+/ {
-+ compatible = "brcm,bcm4708";
-+
-+ cpus {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ cpu@0 {
-+ device_type = "cpu";
-+ compatible = "arm,cortex-a9";
-+ next-level-cache = <&L2>;
-+ reg = <0x0>;
-+ };
-+
-+ cpu@1 {
-+ device_type = "cpu";
-+ compatible = "arm,cortex-a9";
-+ next-level-cache = <&L2>;
-+ reg = <0x1>;
-+ };
-+ };
-+
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -0,0 +1,95 @@
-+/*
-+ * Broadcom BCM470X / BCM5301X ARM platform code.
-+ * Generic DTS part for all BCM53010, BCM53011, BCM53012, BCM53014, BCM53015,
-+ * BCM53016, BCM53017, BCM53018, BCM4707, BCM4708 and BCM4709 SoCs
-+ *
-+ * Copyright 2013-2014 Hauke Mehrtens <hauke@hauke-m.de>
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+#include <dt-bindings/interrupt-controller/irq.h>
-+#include <dt-bindings/interrupt-controller/arm-gic.h>
-+#include "skeleton.dtsi"
-+
-+/ {
-+ interrupt-parent = <&gic>;
-+
-+ chipcommonA {
-+ compatible = "simple-bus";
-+ ranges = <0x00000000 0x18000000 0x00001000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ uart0: serial@0300 {
-+ compatible = "ns16550";
-+ reg = <0x0300 0x100>;
-+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-+ clock-frequency = <100000000>;
-+ status = "disabled";
-+ };
-+
-+ uart1: serial@0400 {
-+ compatible = "ns16550";
-+ reg = <0x0400 0x100>;
-+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-+ clock-frequency = <100000000>;
-+ status = "disabled";
-+ };
-+ };
-+
-+ mpcore {
-+ compatible = "simple-bus";
-+ ranges = <0x00000000 0x19020000 0x00003000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ scu@0000 {
-+ compatible = "arm,cortex-a9-scu";
-+ reg = <0x0000 0x100>;
-+ };
-+
-+ timer@0200 {
-+ compatible = "arm,cortex-a9-global-timer";
-+ reg = <0x0200 0x100>;
-+ interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&clk_periph>;
-+ };
-+
-+ local-timer@0600 {
-+ compatible = "arm,cortex-a9-twd-timer";
-+ reg = <0x0600 0x100>;
-+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&clk_periph>;
-+ };
-+
-+ gic: interrupt-controller@1000 {
-+ compatible = "arm,cortex-a9-gic";
-+ #interrupt-cells = <3>;
-+ #address-cells = <0>;
-+ interrupt-controller;
-+ reg = <0x1000 0x1000>,
-+ <0x0100 0x100>;
-+ };
-+
-+ L2: cache-controller@2000 {
-+ compatible = "arm,pl310-cache";
-+ reg = <0x2000 0x1000>;
-+ cache-unified;
-+ cache-level = <2>;
-+ };
-+ };
-+
-+ clocks {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ /* As long as we do not have a real clock driver us this
-+ * fixed clock */
-+ clk_periph: periph {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ clock-frequency = <400000000>;
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-3.14/110-bcm47xx-move-the-nvram-header-file-into-common-space.patch b/target/linux/bcm53xx/patches-3.14/110-bcm47xx-move-the-nvram-header-file-into-common-space.patch
deleted file mode 100644
index 85b9ab3..0000000
--- a/target/linux/bcm53xx/patches-3.14/110-bcm47xx-move-the-nvram-header-file-into-common-space.patch
+++ /dev/null
@@ -1,270 +0,0 @@
-From bd489dfe8c0d7495645cbc8b8c283217ba816fab Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Sun, 4 May 2014 16:35:42 +0200
-Subject: [PATCH 02/15] bcm47xx: move the nvram header file into common space
-
-Moving mach-bcm47xx/bcm47xx_nvram.h makes it possible to reuse this
-header on the arm bcm47xx (BCM5301X) devices. This way a driver gets
-the correct functions to access the nvram depending on the SoC it boots
-for.
----
- arch/mips/bcm47xx/board.c | 2 +-
- arch/mips/bcm47xx/nvram.c | 2 +-
- arch/mips/bcm47xx/setup.c | 2 +-
- arch/mips/bcm47xx/sprom.c | 2 +-
- arch/mips/bcm47xx/time.c | 2 +-
- arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h | 53 ------------------
- drivers/net/ethernet/broadcom/b44.c | 8 +--
- drivers/net/ethernet/broadcom/bgmac.c | 2 +-
- drivers/ssb/driver_chipcommon_pmu.c | 6 +-
- include/linux/bcm47xx_nvram.h | 65 ++++++++++++++++++++++
- 10 files changed, 73 insertions(+), 71 deletions(-)
- delete mode 100644 arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h
- create mode 100644 include/linux/bcm47xx_nvram.h
-
---- a/arch/mips/bcm47xx/board.c
-+++ b/arch/mips/bcm47xx/board.c
-@@ -2,7 +2,7 @@
- #include <linux/export.h>
- #include <linux/string.h>
- #include <bcm47xx_board.h>
--#include <bcm47xx_nvram.h>
-+#include <linux/bcm47xx_nvram.h>
-
- struct bcm47xx_board_type {
- const enum bcm47xx_board board;
---- a/arch/mips/bcm47xx/nvram.c
-+++ b/arch/mips/bcm47xx/nvram.c
-@@ -17,7 +17,7 @@
- #include <linux/kernel.h>
- #include <linux/string.h>
- #include <asm/addrspace.h>
--#include <bcm47xx_nvram.h>
-+#include <linux/bcm47xx_nvram.h>
- #include <asm/mach-bcm47xx/bcm47xx.h>
-
- static char nvram_buf[NVRAM_SPACE];
---- a/arch/mips/bcm47xx/setup.c
-+++ b/arch/mips/bcm47xx/setup.c
-@@ -42,7 +42,7 @@
- #include <asm/reboot.h>
- #include <asm/time.h>
- #include <bcm47xx.h>
--#include <bcm47xx_nvram.h>
-+#include <linux/bcm47xx_nvram.h>
- #include <bcm47xx_board.h>
-
- union bcm47xx_bus bcm47xx_bus;
---- a/arch/mips/bcm47xx/sprom.c
-+++ b/arch/mips/bcm47xx/sprom.c
-@@ -27,7 +27,7 @@
- */
-
- #include <bcm47xx.h>
--#include <bcm47xx_nvram.h>
-+#include <linux/bcm47xx_nvram.h>
-
- static void create_key(const char *prefix, const char *postfix,
- const char *name, char *buf, int len)
---- a/arch/mips/bcm47xx/time.c
-+++ b/arch/mips/bcm47xx/time.c
-@@ -27,7 +27,7 @@
- #include <linux/ssb/ssb.h>
- #include <asm/time.h>
- #include <bcm47xx.h>
--#include <bcm47xx_nvram.h>
-+#include <linux/bcm47xx_nvram.h>
- #include <bcm47xx_board.h>
-
- void __init plat_time_init(void)
---- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h
-+++ /dev/null
-@@ -1,53 +0,0 @@
--/*
-- * Copyright (C) 2005, Broadcom Corporation
-- * Copyright (C) 2006, Felix Fietkau <nbd@openwrt.org>
-- *
-- * This program is free software; you can redistribute it and/or modify it
-- * under the terms of the GNU General Public License as published by the
-- * Free Software Foundation; either version 2 of the License, or (at your
-- * option) any later version.
-- */
--
--#ifndef __BCM47XX_NVRAM_H
--#define __BCM47XX_NVRAM_H
--
--#include <linux/types.h>
--#include <linux/kernel.h>
--
--struct nvram_header {
-- u32 magic;
-- u32 len;
-- u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
-- u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */
-- u32 config_ncdl; /* ncdl values for memc */
--};
--
--#define NVRAM_HEADER 0x48534C46 /* 'FLSH' */
--#define NVRAM_VERSION 1
--#define NVRAM_HEADER_SIZE 20
--#define NVRAM_SPACE 0x8000
--
--#define FLASH_MIN 0x00020000 /* Minimum flash size */
--
--#define NVRAM_MAX_VALUE_LEN 255
--#define NVRAM_MAX_PARAM_LEN 64
--
--extern int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len);
--
--static inline void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6])
--{
-- if (strchr(buf, ':'))
-- sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0],
-- &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
-- &macaddr[5]);
-- else if (strchr(buf, '-'))
-- sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0],
-- &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
-- &macaddr[5]);
-- else
-- printk(KERN_WARNING "Can not parse mac address: %s\n", buf);
--}
--
--int bcm47xx_nvram_gpio_pin(const char *name);
--
--#endif /* __BCM47XX_NVRAM_H */
---- a/drivers/net/ethernet/broadcom/b44.c
-+++ b/drivers/net/ethernet/broadcom/b44.c
-@@ -31,6 +31,7 @@
- #include <linux/ssb/ssb.h>
- #include <linux/slab.h>
- #include <linux/phy.h>
-+#include <linux/bcm47xx_nvram.h>
-
- #include <asm/uaccess.h>
- #include <asm/io.h>
-@@ -399,8 +400,6 @@ static void b44_set_flow_ctrl(struct b44
- __b44_set_flow_ctrl(bp, pause_enab);
- }
-
--#ifdef CONFIG_BCM47XX
--#include <bcm47xx_nvram.h>
- static void b44_wap54g10_workaround(struct b44 *bp)
- {
- char buf[20];
-@@ -429,11 +428,6 @@ static void b44_wap54g10_workaround(stru
- error:
- pr_warning("PHY: cannot reset MII transceiver isolate bit\n");
- }
--#else
--static inline void b44_wap54g10_workaround(struct b44 *bp)
--{
--}
--#endif
-
- static int b44_setup_phy(struct b44 *bp)
- {
---- a/drivers/net/ethernet/broadcom/bgmac.c
-+++ b/drivers/net/ethernet/broadcom/bgmac.c
-@@ -17,7 +17,7 @@
- #include <linux/interrupt.h>
- #include <linux/dma-mapping.h>
- #include <linux/platform_data/b53.h>
--#include <bcm47xx_nvram.h>
-+#include <linux/bcm47xx_nvram.h>
-
- static const struct bcma_device_id bgmac_bcma_tbl[] = {
- BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS),
---- a/drivers/ssb/driver_chipcommon_pmu.c
-+++ b/drivers/ssb/driver_chipcommon_pmu.c
-@@ -13,9 +13,7 @@
- #include <linux/ssb/ssb_driver_chipcommon.h>
- #include <linux/delay.h>
- #include <linux/export.h>
--#ifdef CONFIG_BCM47XX
--#include <bcm47xx_nvram.h>
--#endif
-+#include <linux/bcm47xx_nvram.h>
-
- #include "ssb_private.h"
-
-@@ -320,11 +318,9 @@ static void ssb_pmu_pll_init(struct ssb_
- u32 crystalfreq = 0; /* in kHz. 0 = keep default freq. */
-
- if (bus->bustype == SSB_BUSTYPE_SSB) {
--#ifdef CONFIG_BCM47XX
- char buf[20];
- if (bcm47xx_nvram_getenv("xtalfreq", buf, sizeof(buf)) >= 0)
- crystalfreq = simple_strtoul(buf, NULL, 0);
--#endif
- }
-
- switch (bus->chip_id) {
---- /dev/null
-+++ b/include/linux/bcm47xx_nvram.h
-@@ -0,0 +1,65 @@
-+/*
-+ * Copyright (C) 2005, Broadcom Corporation
-+ * Copyright (C) 2006, Felix Fietkau <nbd@openwrt.org>
-+ * Copyright (C) 2014 Hauke Mehrtens <hauke@hauke-m.de>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ */
-+
-+#ifndef __BCM47XX_NVRAM_H
-+#define __BCM47XX_NVRAM_H
-+
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+
-+struct nvram_header {
-+ u32 magic;
-+ u32 len;
-+ u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
-+ u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */
-+ u32 config_ncdl; /* ncdl values for memc */
-+};
-+
-+#define NVRAM_HEADER 0x48534C46 /* 'FLSH' */
-+#define NVRAM_VERSION 1
-+#define NVRAM_HEADER_SIZE 20
-+#define NVRAM_SPACE 0x8000
-+
-+#define FLASH_MIN 0x00020000 /* Minimum flash size */
-+
-+#define NVRAM_MAX_VALUE_LEN 255
-+#define NVRAM_MAX_PARAM_LEN 64
-+
-+#ifdef CONFIG_BCM47XX
-+int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len);
-+
-+int bcm47xx_nvram_gpio_pin(const char *name);
-+#else
-+static inline int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len)
-+{
-+ return -ENXIO;
-+}
-+
-+static inline int bcm47xx_nvram_gpio_pin(const char *name)
-+{
-+ return -ENXIO;
-+}
-+#endif
-+
-+static inline void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6])
-+{
-+ if (strchr(buf, ':'))
-+ sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0],
-+ &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
-+ &macaddr[5]);
-+ else if (strchr(buf, '-'))
-+ sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0],
-+ &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
-+ &macaddr[5]);
-+ else
-+ pr_warn("Can not parse mac address: %s\n", buf);
-+}
-+#endif /* __BCM47XX_NVRAM_H */
diff --git a/target/linux/bcm53xx/patches-3.14/111-bcm47xx-nvram-add-new-nvram-driver-with-dt-support.patch b/target/linux/bcm53xx/patches-3.14/111-bcm47xx-nvram-add-new-nvram-driver-with-dt-support.patch
deleted file mode 100644
index a53e86d..0000000
--- a/target/linux/bcm53xx/patches-3.14/111-bcm47xx-nvram-add-new-nvram-driver-with-dt-support.patch
+++ /dev/null
@@ -1,520 +0,0 @@
-From 60a413ed5bc7917f1612df441240f458163b10c1 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Sat, 3 May 2014 22:54:59 +0200
-Subject: [PATCH 03/15] bcm47xx-nvram: add new nvram driver with dt support
-
-This adds a new nvrm driver which uses device tree to provide nvram
-access to other drivers. You have to specify the memory ranges where
-the flash chip is mapped and this driver will search there for some
-nvram and parse it. Other drivers can use this driver to access the
-device nvram. The nvram is used to store board configurations like the
-mac address and also for configuration values in the vendor firmware.
----
- arch/mips/bcm47xx/board.c | 36 +++---
- arch/mips/bcm47xx/nvram.c | 7 +-
- arch/mips/bcm47xx/setup.c | 4 +-
- arch/mips/bcm47xx/sprom.c | 4 +-
- arch/mips/bcm47xx/time.c | 2 +-
- drivers/misc/Kconfig | 5 +
- drivers/misc/Makefile | 1 +
- drivers/misc/bcm47xx-nvram.c | 211 ++++++++++++++++++++++++++++++++++
- drivers/net/ethernet/broadcom/b44.c | 2 +-
- drivers/net/ethernet/broadcom/bgmac.c | 4 +-
- drivers/ssb/driver_chipcommon_pmu.c | 2 +-
- include/linux/bcm47xx_nvram.h | 16 ++-
- 12 files changed, 259 insertions(+), 35 deletions(-)
- create mode 100644 drivers/misc/bcm47xx-nvram.c
-
---- a/arch/mips/bcm47xx/board.c
-+++ b/arch/mips/bcm47xx/board.c
-@@ -196,50 +196,50 @@ static __init const struct bcm47xx_board
- const struct bcm47xx_board_type_list2 *e2;
- const struct bcm47xx_board_type_list3 *e3;
-
-- if (bcm47xx_nvram_getenv("model_name", buf1, sizeof(buf1)) >= 0) {
-+ if (bcm47xx_nvram_getenv(NULL, "model_name", buf1, sizeof(buf1)) >= 0) {
- for (e1 = bcm47xx_board_list_model_name; e1->value1; e1++) {
- if (!strcmp(buf1, e1->value1))
- return &e1->board;
- }
- }
-
-- if (bcm47xx_nvram_getenv("model_no", buf1, sizeof(buf1)) >= 0) {
-+ if (bcm47xx_nvram_getenv(NULL, "model_no", buf1, sizeof(buf1)) >= 0) {
- for (e1 = bcm47xx_board_list_model_no; e1->value1; e1++) {
- if (strstarts(buf1, e1->value1))
- return &e1->board;
- }
- }
-
-- if (bcm47xx_nvram_getenv("machine_name", buf1, sizeof(buf1)) >= 0) {
-+ if (bcm47xx_nvram_getenv(NULL, "machine_name", buf1, sizeof(buf1)) >= 0) {
- for (e1 = bcm47xx_board_list_machine_name; e1->value1; e1++) {
- if (strstarts(buf1, e1->value1))
- return &e1->board;
- }
- }
-
-- if (bcm47xx_nvram_getenv("hardware_version", buf1, sizeof(buf1)) >= 0) {
-+ if (bcm47xx_nvram_getenv(NULL, "hardware_version", buf1, sizeof(buf1)) >= 0) {
- for (e1 = bcm47xx_board_list_hardware_version; e1->value1; e1++) {
- if (strstarts(buf1, e1->value1))
- return &e1->board;
- }
- }
-
-- if (bcm47xx_nvram_getenv("productid", buf1, sizeof(buf1)) >= 0) {
-+ if (bcm47xx_nvram_getenv(NULL, "productid", buf1, sizeof(buf1)) >= 0) {
- for (e1 = bcm47xx_board_list_productid; e1->value1; e1++) {
- if (!strcmp(buf1, e1->value1))
- return &e1->board;
- }
- }
-
-- if (bcm47xx_nvram_getenv("ModelId", buf1, sizeof(buf1)) >= 0) {
-+ if (bcm47xx_nvram_getenv(NULL, "ModelId", buf1, sizeof(buf1)) >= 0) {
- for (e1 = bcm47xx_board_list_ModelId; e1->value1; e1++) {
- if (!strcmp(buf1, e1->value1))
- return &e1->board;
- }
- }
-
-- if (bcm47xx_nvram_getenv("melco_id", buf1, sizeof(buf1)) >= 0 ||
-- bcm47xx_nvram_getenv("buf1falo_id", buf1, sizeof(buf1)) >= 0) {
-+ if (bcm47xx_nvram_getenv(NULL, "melco_id", buf1, sizeof(buf1)) >= 0 ||
-+ bcm47xx_nvram_getenv(NULL, "buf1falo_id", buf1, sizeof(buf1)) >= 0) {
- /* buffalo hardware, check id for specific hardware matches */
- for (e1 = bcm47xx_board_list_melco_id; e1->value1; e1++) {
- if (!strcmp(buf1, e1->value1))
-@@ -247,8 +247,8 @@ static __init const struct bcm47xx_board
- }
- }
-
-- if (bcm47xx_nvram_getenv("boot_hw_model", buf1, sizeof(buf1)) >= 0 &&
-- bcm47xx_nvram_getenv("boot_hw_ver", buf2, sizeof(buf2)) >= 0) {
-+ if (bcm47xx_nvram_getenv(NULL, "boot_hw_model", buf1, sizeof(buf1)) >= 0 &&
-+ bcm47xx_nvram_getenv(NULL, "boot_hw_ver", buf2, sizeof(buf2)) >= 0) {
- for (e2 = bcm47xx_board_list_boot_hw; e2->value1; e2++) {
- if (!strcmp(buf1, e2->value1) &&
- !strcmp(buf2, e2->value2))
-@@ -256,16 +256,16 @@ static __init const struct bcm47xx_board
- }
- }
-
-- if (bcm47xx_nvram_getenv("board_id", buf1, sizeof(buf1)) >= 0) {
-+ if (bcm47xx_nvram_getenv(NULL, "board_id", buf1, sizeof(buf1)) >= 0) {
- for (e1 = bcm47xx_board_list_board_id; e1->value1; e1++) {
- if (!strcmp(buf1, e1->value1))
- return &e1->board;
- }
- }
-
-- if (bcm47xx_nvram_getenv("boardtype", buf1, sizeof(buf1)) >= 0 &&
-- bcm47xx_nvram_getenv("boardnum", buf2, sizeof(buf2)) >= 0 &&
-- bcm47xx_nvram_getenv("boardrev", buf3, sizeof(buf3)) >= 0) {
-+ if (bcm47xx_nvram_getenv(NULL, "boardtype", buf1, sizeof(buf1)) >= 0 &&
-+ bcm47xx_nvram_getenv(NULL, "boardnum", buf2, sizeof(buf2)) >= 0 &&
-+ bcm47xx_nvram_getenv(NULL, "boardrev", buf3, sizeof(buf3)) >= 0) {
- for (e3 = bcm47xx_board_list_board; e3->value1; e3++) {
- if (!strcmp(buf1, e3->value1) &&
- !strcmp(buf2, e3->value2) &&
-@@ -286,7 +286,7 @@ void __init bcm47xx_board_detect(void)
- return;
-
- /* check if the nvram is available */
-- err = bcm47xx_nvram_getenv("boardtype", buf, sizeof(buf));
-+ err = bcm47xx_nvram_getenv(NULL, "boardtype", buf, sizeof(buf));
-
- /* init of nvram failed, probably too early now */
- if (err == -ENXIO) {
---- a/arch/mips/bcm47xx/nvram.c
-+++ b/arch/mips/bcm47xx/nvram.c
-@@ -158,7 +158,8 @@ static int nvram_init(void)
- return -ENXIO;
- }
-
--int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len)
-+int bcm47xx_nvram_getenv(const struct device *dev, const char *name, char *val,
-+ size_t val_len)
- {
- char *var, *value, *end, *eq;
- int err;
-@@ -190,7 +191,7 @@ int bcm47xx_nvram_getenv(char *name, cha
- }
- EXPORT_SYMBOL(bcm47xx_nvram_getenv);
-
--int bcm47xx_nvram_gpio_pin(const char *name)
-+int bcm47xx_nvram_gpio_pin(const struct device *dev, const char *name)
- {
- int i, err;
- char nvram_var[10];
-@@ -200,7 +201,7 @@ int bcm47xx_nvram_gpio_pin(const char *n
- err = snprintf(nvram_var, sizeof(nvram_var), "gpio%i", i);
- if (err <= 0)
- continue;
-- err = bcm47xx_nvram_getenv(nvram_var, buf, sizeof(buf));
-+ err = bcm47xx_nvram_getenv(dev, nvram_var, buf, sizeof(buf));
- if (err <= 0)
- continue;
- if (!strcmp(name, buf))
---- a/arch/mips/bcm47xx/setup.c
-+++ b/arch/mips/bcm47xx/setup.c
-@@ -123,7 +123,7 @@ static int bcm47xx_get_invariants(struct
- memset(&iv->sprom, 0, sizeof(struct ssb_sprom));
- bcm47xx_fill_sprom(&iv->sprom, NULL, false);
-
-- if (bcm47xx_nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
-+ if (bcm47xx_nvram_getenv(NULL, "cardbus", buf, sizeof(buf)) >= 0)
- iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
-
- return 0;
-@@ -146,7 +146,7 @@ static void __init bcm47xx_register_ssb(
- panic("Failed to initialize SSB bus (err %d)", err);
-
- mcore = &bcm47xx_bus.ssb.mipscore;
-- if (bcm47xx_nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
-+ if (bcm47xx_nvram_getenv(NULL, "kernel_args", buf, sizeof(buf)) >= 0) {
- if (strstr(buf, "console=ttyS1")) {
- struct ssb_serial_port port;
-
---- a/arch/mips/bcm47xx/sprom.c
-+++ b/arch/mips/bcm47xx/sprom.c
-@@ -50,10 +50,10 @@ static int get_nvram_var(const char *pre
-
- create_key(prefix, postfix, name, key, sizeof(key));
-
-- err = bcm47xx_nvram_getenv(key, buf, len);
-+ err = bcm47xx_nvram_getenv(NULL, key, buf, len);
- if (fallback && err == -ENOENT && prefix) {
- create_key(NULL, postfix, name, key, sizeof(key));
-- err = bcm47xx_nvram_getenv(key, buf, len);
-+ err = bcm47xx_nvram_getenv(NULL, key, buf, len);
- }
- return err;
- }
---- a/arch/mips/bcm47xx/time.c
-+++ b/arch/mips/bcm47xx/time.c
-@@ -61,7 +61,7 @@ void __init plat_time_init(void)
- }
-
- if (chip_id == 0x5354) {
-- len = bcm47xx_nvram_getenv("clkfreq", buf, sizeof(buf));
-+ len = bcm47xx_nvram_getenv(NULL, "clkfreq", buf, sizeof(buf));
- if (len >= 0 && !strncmp(buf, "200", 4))
- hz = 100000000;
- }
---- a/drivers/misc/Kconfig
-+++ b/drivers/misc/Kconfig
-@@ -515,6 +515,11 @@ config SRAM
- the genalloc API. It is supposed to be used for small on-chip SRAM
- areas found on many SoCs.
-
-+config BCM47XX_NVRAM
-+ tristate "BCM47XX nvram driver"
-+ help
-+ This adds support for the brcm47xx nvram driver.
-+
- source "drivers/misc/c2port/Kconfig"
- source "drivers/misc/eeprom/Kconfig"
- source "drivers/misc/cb710/Kconfig"
---- a/drivers/misc/Makefile
-+++ b/drivers/misc/Makefile
-@@ -54,3 +54,4 @@ obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lat
- obj-$(CONFIG_SRAM) += sram.o
- obj-y += mic/
- obj-$(CONFIG_GENWQE) += genwqe/
-+obj-$(CONFIG_BCM47XX_NVRAM) += bcm47xx-nvram.o
---- /dev/null
-+++ b/drivers/misc/bcm47xx-nvram.c
-@@ -0,0 +1,211 @@
-+/*
-+ * BCM947xx nvram variable access
-+ *
-+ * Copyright (C) 2005 Broadcom Corporation
-+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
-+ * Copyright (C) 2010-2014 Hauke Mehrtens <hauke@hauke-m.de>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/string.h>
-+#include <linux/of_address.h>
-+#include <linux/device.h>
-+#include <linux/platform_device.h>
-+#include <linux/io.h>
-+#include <linux/bcm47xx_nvram.h>
-+
-+struct bcm47xx_nvram {
-+ size_t nvram_len;
-+ char *nvram_buf;
-+};
-+
-+static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000};
-+
-+static u32 find_nvram_size(void __iomem *end)
-+{
-+ struct nvram_header *header;
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) {
-+ header = (struct nvram_header *)(end - nvram_sizes[i]);
-+ if (header->magic == NVRAM_HEADER)
-+ return nvram_sizes[i];
-+ }
-+
-+ return 0;
-+}
-+
-+/* Probe for NVRAM header */
-+static int nvram_find_and_copy(struct device *dev, void __iomem *base,
-+ size_t len, char **nvram_buf,
-+ size_t *nvram_len)
-+{
-+ struct nvram_header *header;
-+ int i;
-+ u32 off;
-+ u32 *src, *dst;
-+ u32 size;
-+
-+ /* TODO: when nvram is on nand flash check for bad blocks first. */
-+ off = FLASH_MIN;
-+ while (off <= len) {
-+ /* Windowed flash access */
-+ size = find_nvram_size(base + off);
-+ if (size) {
-+ header = (struct nvram_header *)(base + off - size);
-+ goto found;
-+ }
-+ off <<= 1;
-+ }
-+
-+ /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
-+ header = (struct nvram_header *)(base + 4096);
-+ if (header->magic == NVRAM_HEADER) {
-+ size = NVRAM_SPACE;
-+ goto found;
-+ }
-+
-+ header = (struct nvram_header *)(base + 1024);
-+ if (header->magic == NVRAM_HEADER) {
-+ size = NVRAM_SPACE;
-+ goto found;
-+ }
-+
-+ *nvram_buf = NULL;
-+ *nvram_len = 0;
-+ pr_err("no nvram found\n");
-+ return -ENXIO;
-+
-+found:
-+ if (header->len > size)
-+ pr_err("The nvram size accoridng to the header seems to be bigger than the partition on flash\n");
-+ *nvram_len = min_t(u32, header->len, size);
-+
-+ *nvram_buf = devm_kzalloc(dev, *nvram_len, GFP_KERNEL);
-+ if (!*nvram_buf)
-+ return -ENOMEM;
-+
-+ src = (u32 *) header;
-+ dst = (u32 *) *nvram_buf;
-+ for (i = 0; i < sizeof(struct nvram_header); i += 4)
-+ *dst++ = *src++;
-+ for (; i < *nvram_len; i += 4)
-+ *dst++ = le32_to_cpu(*src++);
-+
-+ return 0;
-+}
-+
-+int bcm47xx_nvram_getenv(const struct device *dev, const char *name, char *val, size_t val_len)
-+{
-+ char *var, *value, *end, *eq;
-+ struct bcm47xx_nvram *nvram;
-+
-+ if (!dev)
-+ return -ENODEV;
-+
-+ nvram = dev_get_drvdata(dev);
-+
-+ if (!name || !nvram || !nvram->nvram_len)
-+ return -EINVAL;
-+
-+ /* Look for name=value and return value */
-+ var = nvram->nvram_buf + sizeof(struct nvram_header);
-+ end = nvram->nvram_buf + nvram->nvram_len - 2;
-+ end[0] = end[1] = '\0';
-+ for (; *var; var = value + strlen(value) + 1) {
-+ eq = strchr(var, '=');
-+ if (!eq)
-+ break;
-+ value = eq + 1;
-+ if ((eq - var) == strlen(name) &&
-+ strncmp(var, name, (eq - var)) == 0) {
-+ return snprintf(val, val_len, "%s", value);
-+ }
-+ }
-+ return -ENOENT;
-+}
-+EXPORT_SYMBOL(bcm47xx_nvram_getenv);
-+
-+int bcm47xx_nvram_gpio_pin(const struct device *dev, const char *name)
-+{
-+ int i, err;
-+ char nvram_var[10];
-+ char buf[30];
-+
-+ if (!dev)
-+ return -ENODEV;
-+
-+ for (i = 0; i < 32; i++) {
-+ err = snprintf(nvram_var, sizeof(nvram_var), "gpio%i", i);
-+ if (err <= 0)
-+ continue;
-+ err = bcm47xx_nvram_getenv(dev, nvram_var, buf, sizeof(buf));
-+ if (err <= 0)
-+ continue;
-+ if (!strcmp(name, buf))
-+ return i;
-+ }
-+ return -ENOENT;
-+}
-+EXPORT_SYMBOL(bcm47xx_nvram_gpio_pin);
-+
-+static int bcm47xx_nvram_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct device_node *np = dev->of_node;
-+ struct bcm47xx_nvram *nvram;
-+ int err;
-+ struct resource flash_mem;
-+ void __iomem *mmio;
-+
-+ /* Alloc */
-+ nvram = devm_kzalloc(dev, sizeof(*nvram), GFP_KERNEL);
-+ if (!nvram)
-+ return -ENOMEM;
-+
-+ err = of_address_to_resource(np, 0, &flash_mem);
-+ if (err)
-+ return err;
-+
-+ mmio = ioremap_nocache(flash_mem.start, resource_size(&flash_mem));
-+ if (!mmio)
-+ return -ENOMEM;
-+
-+ err = nvram_find_and_copy(dev, mmio, resource_size(&flash_mem), &nvram->nvram_buf, &nvram->nvram_len);
-+ if (err)
-+ goto err_unmap_mmio;
-+
-+ platform_set_drvdata(pdev, nvram);
-+
-+err_unmap_mmio:
-+ iounmap(mmio);
-+ return err;
-+}
-+
-+static const struct of_device_id bcm47xx_nvram_of_match_table[] = {
-+ { .compatible = "brcm,bcm47xx-nvram", },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, mvebu_pcie_of_match_table);
-+
-+static struct platform_driver bcm47xx_nvram_driver = {
-+ .driver = {
-+ .owner = THIS_MODULE,
-+ .name = "bcm47xx-nvram",
-+ .of_match_table = bcm47xx_nvram_of_match_table,
-+ /* driver unloading/unbinding currently not supported */
-+ .suppress_bind_attrs = true,
-+ },
-+ .probe = bcm47xx_nvram_probe,
-+};
-+module_platform_driver(bcm47xx_nvram_driver);
-+
-+MODULE_AUTHOR("Hauke Mehrtens <hauke@hauke-m.de>");
-+MODULE_LICENSE("GPLv2");
---- a/drivers/net/ethernet/broadcom/b44.c
-+++ b/drivers/net/ethernet/broadcom/b44.c
-@@ -411,7 +411,7 @@ static void b44_wap54g10_workaround(stru
- * see https://dev.openwrt.org/ticket/146
- * check and reset bit "isolate"
- */
-- if (bcm47xx_nvram_getenv("boardnum", buf, sizeof(buf)) < 0)
-+ if (bcm47xx_nvram_getenv(NULL, "boardnum", buf, sizeof(buf)) < 0)
- return;
- if (simple_strtoul(buf, NULL, 0) == 2) {
- err = __b44_readphy(bp, 0, MII_BMCR, &val);
---- a/drivers/net/ethernet/broadcom/bgmac.c
-+++ b/drivers/net/ethernet/broadcom/bgmac.c
-@@ -974,7 +974,7 @@ static void bgmac_chip_reset(struct bgma
- BGMAC_CHIPCTL_1_IF_TYPE_MII;
- char buf[4];
-
-- if (bcm47xx_nvram_getenv("et_swtype", buf, sizeof(buf)) > 0) {
-+ if (bcm47xx_nvram_getenv(NULL, "et_swtype", buf, sizeof(buf)) > 0) {
- if (kstrtou8(buf, 0, &et_swtype))
- bgmac_err(bgmac, "Failed to parse et_swtype (%s)\n",
- buf);
-@@ -1534,7 +1534,7 @@ static int bgmac_probe(struct bcma_devic
- }
-
- bgmac->int_mask = BGMAC_IS_ERRMASK | BGMAC_IS_RX | BGMAC_IS_TX_MASK;
-- if (bcm47xx_nvram_getenv("et0_no_txint", NULL, 0) == 0)
-+ if (bcm47xx_nvram_getenv(NULL, "et0_no_txint", NULL, 0) == 0)
- bgmac->int_mask &= ~BGMAC_IS_TX_MASK;
-
- /* TODO: reset the external phy. Specs are needed */
---- a/drivers/ssb/driver_chipcommon_pmu.c
-+++ b/drivers/ssb/driver_chipcommon_pmu.c
-@@ -319,7 +319,7 @@ static void ssb_pmu_pll_init(struct ssb_
-
- if (bus->bustype == SSB_BUSTYPE_SSB) {
- char buf[20];
-- if (bcm47xx_nvram_getenv("xtalfreq", buf, sizeof(buf)) >= 0)
-+ if (bcm47xx_nvram_getenv(NULL, "xtalfreq", buf, sizeof(buf)) >= 0)
- crystalfreq = simple_strtoul(buf, NULL, 0);
- }
-
---- a/include/linux/bcm47xx_nvram.h
-+++ b/include/linux/bcm47xx_nvram.h
-@@ -15,6 +15,8 @@
- #include <linux/types.h>
- #include <linux/kernel.h>
-
-+struct device;
-+
- struct nvram_header {
- u32 magic;
- u32 len;
-@@ -33,17 +35,21 @@ struct nvram_header {
- #define NVRAM_MAX_VALUE_LEN 255
- #define NVRAM_MAX_PARAM_LEN 64
-
--#ifdef CONFIG_BCM47XX
--int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len);
-+#if defined(CONFIG_BCM47XX) || defined(CONFIG_BCM47XX_NVRAM)
-+int bcm47xx_nvram_getenv(const struct device *dev, const char *name, char *val,
-+ size_t val_len);
-
--int bcm47xx_nvram_gpio_pin(const char *name);
-+int bcm47xx_nvram_gpio_pin(const struct device *dev, const char *name);
- #else
--static inline int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len)
-+static inline int bcm47xx_nvram_getenv(const struct device *dev,
-+ const char *name, char *val,
-+ size_t val_len)
- {
- return -ENXIO;
- }
-
--static inline int bcm47xx_nvram_gpio_pin(const char *name)
-+static inline int bcm47xx_nvram_gpio_pin(const struct device *dev,
-+ const char *name)
- {
- return -ENXIO;
- }
diff --git a/target/linux/bcm53xx/patches-3.14/112-bcm53xx-sprom-add-sprom-driver.patch b/target/linux/bcm53xx/patches-3.14/112-bcm53xx-sprom-add-sprom-driver.patch
deleted file mode 100644
index d8cdeb5..0000000
--- a/target/linux/bcm53xx/patches-3.14/112-bcm53xx-sprom-add-sprom-driver.patch
+++ /dev/null
@@ -1,667 +0,0 @@
-From b113f9d3e140f18e63cbf3408b3dcde372242dc8 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 04/15] bcm53xx-sprom: add sprom driver
-
-This driver needs an nvram driver and fetches the sprom values from the
-sprom 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.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/misc/Kconfig | 5 +
- drivers/misc/Makefile | 1 +
- drivers/misc/bcm53xx-sprom.c | 625 +++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 631 insertions(+)
- create mode 100644 drivers/misc/bcm53xx-sprom.c
-
---- a/drivers/misc/Kconfig
-+++ b/drivers/misc/Kconfig
-@@ -520,6 +520,11 @@ config BCM47XX_NVRAM
- help
- This adds support for the brcm47xx nvram driver.
-
-+config BCM53XX_SPROM
-+ tristate "BCM53XX sprom driver"
-+ help
-+ This adds support for the brcm53xx sprom driver.
-+
- source "drivers/misc/c2port/Kconfig"
- source "drivers/misc/eeprom/Kconfig"
- source "drivers/misc/cb710/Kconfig"
---- a/drivers/misc/Makefile
-+++ b/drivers/misc/Makefile
-@@ -55,3 +55,4 @@ obj-$(CONFIG_SRAM) += sram.o
- obj-y += mic/
- obj-$(CONFIG_GENWQE) += genwqe/
- obj-$(CONFIG_BCM47XX_NVRAM) += bcm47xx-nvram.o
-+obj-$(CONFIG_BCM53XX_SPROM) += bcm53xx-sprom.o
---- /dev/null
-+++ b/drivers/misc/bcm53xx-sprom.c
-@@ -0,0 +1,625 @@
-+/*
-+ * BCM947xx nvram variable access
-+ *
-+ * Copyright (C) 2005 Broadcom Corporation
-+ * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>
-+ * Copyright (C) 2006 Michael Buesch <m@bues.ch>
-+ * Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org>
-+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
-+ * Copyright (C) 2010-2014 Hauke Mehrtens <hauke@hauke-m.de>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/string.h>
-+#include <linux/of_address.h>
-+#include <linux/device.h>
-+#include <linux/platform_device.h>
-+#include <linux/of_platform.h>
-+#include <linux/io.h>
-+#include <linux/ssb/ssb.h>
-+#include <linux/bcm47xx_nvram.h>
-+
-+struct bcm53xx_sprom_fill {
-+ const char *prefix;
-+ bool fallback;
-+ int (*getenv)(const struct bcm53xx_sprom_fill *fill, const char *name, char *val, size_t val_len);
-+ const void *priv;
-+};
-+
-+static void create_key(const char *prefix, const char *postfix,
-+ const char *name, char *buf, int len)
-+{
-+ if (prefix && postfix)
-+ snprintf(buf, len, "%s%s%s", prefix, name, postfix);
-+ else if (prefix)
-+ snprintf(buf, len, "%s%s", prefix, name);
-+ else if (postfix)
-+ snprintf(buf, len, "%s%s", name, postfix);
-+ else
-+ snprintf(buf, len, "%s", name);
-+}
-+
-+static int get_nvram_var(const struct bcm53xx_sprom_fill *fill, const char *postfix,
-+ const char *name, char *buf, int len)
-+{
-+ char key[40];
-+ int err;
-+
-+ create_key(fill->prefix, postfix, name, key, sizeof(key));
-+
-+ err = fill->getenv(fill, key, buf, len);
-+ if (fill->fallback && err == -ENOENT && fill->prefix) {
-+ create_key(NULL, postfix, name, key, sizeof(key));
-+ err = fill->getenv(fill, key, buf, len);
-+ }
-+ return err;
-+}
-+
-+#define NVRAM_READ_VAL(type) \
-+static void nvram_read_ ## type (const struct bcm53xx_sprom_fill *fill, \
-+ const char *postfix, const char *name, \
-+ type *val, type allset) \
-+{ \
-+ char buf[100]; \
-+ int err; \
-+ type var; \
-+ \
-+ err = get_nvram_var(fill, postfix, name, buf, sizeof(buf)); \
-+ if (err < 0) \
-+ return; \
-+ err = kstrto ## type(strim(buf), 0, &var); \
-+ if (err) { \
-+ pr_warn("can not parse nvram name %s%s%s with value %s got %i\n", \
-+ fill->prefix, name, postfix, buf, err); \
-+ return; \
-+ } \
-+ if (allset && var == allset) \
-+ return; \
-+ *val = var; \
-+}
-+
-+NVRAM_READ_VAL(u8)
-+NVRAM_READ_VAL(s8)
-+NVRAM_READ_VAL(u16)
-+NVRAM_READ_VAL(u32)
-+
-+#undef NVRAM_READ_VAL
-+
-+static void nvram_read_u32_2(const struct bcm53xx_sprom_fill *fill, const char *name,
-+ u16 *val_lo, u16 *val_hi)
-+{
-+ char buf[100];
-+ int err;
-+ u32 val;
-+
-+ err = get_nvram_var(fill, NULL, name, buf, sizeof(buf));
-+ if (err < 0)
-+ return;
-+ err = kstrtou32(strim(buf), 0, &val);
-+ if (err) {
-+ pr_warn("can not parse nvram name %s%s with value %s got %i\n",
-+ fill->prefix, name, buf, err);
-+ return;
-+ }
-+ *val_lo = (val & 0x0000FFFFU);
-+ *val_hi = (val & 0xFFFF0000U) >> 16;
-+}
-+
-+static void nvram_read_leddc(const struct bcm53xx_sprom_fill *fill, const char *name,
-+ u8 *leddc_on_time, u8 *leddc_off_time)
-+{
-+ char buf[100];
-+ int err;
-+ u32 val;
-+
-+ err = get_nvram_var(fill, NULL, name, buf, sizeof(buf));
-+ if (err < 0)
-+ return;
-+ err = kstrtou32(strim(buf), 0, &val);
-+ if (err) {
-+ pr_warn("can not parse nvram name %s%s with value %s got %i\n",
-+ fill->prefix, name, buf, err);
-+ return;
-+ }
-+
-+ if (val == 0xffff || val == 0xffffffff)
-+ return;
-+
-+ *leddc_on_time = val & 0xff;
-+ *leddc_off_time = (val >> 16) & 0xff;
-+}
-+
-+static void nvram_read_macaddr(const struct bcm53xx_sprom_fill *fill, const char *name,
-+ u8 val[6])
-+{
-+ char buf[100];
-+ int err;
-+
-+ err = get_nvram_var(fill, NULL, name, buf, sizeof(buf));
-+ if (err < 0)
-+ return;
-+
-+ bcm47xx_nvram_parse_macaddr(buf, val);
-+}
-+
-+static void nvram_read_alpha2(const struct bcm53xx_sprom_fill *fill, const char *name,
-+ char val[2])
-+{
-+ char buf[10];
-+ int err;
-+
-+ err = get_nvram_var(fill, NULL, name, buf, sizeof(buf));
-+ if (err < 0)
-+ return;
-+ if (buf[0] == '0')
-+ return;
-+ if (strlen(buf) > 2) {
-+ pr_warn("alpha2 is too long %s\n", buf);
-+ return;
-+ }
-+ memcpy(val, buf, 2);
-+}
-+
-+static void bcm53xx_sprom_fill_r1234589(struct ssb_sprom *sprom,
-+ const struct bcm53xx_sprom_fill *fill)
-+{
-+ nvram_read_u8(fill, NULL, "ledbh0", &sprom->gpio0, 0xff);
-+ nvram_read_u8(fill, NULL, "ledbh1", &sprom->gpio1, 0xff);
-+ nvram_read_u8(fill, NULL, "ledbh2", &sprom->gpio2, 0xff);
-+ nvram_read_u8(fill, NULL, "ledbh3", &sprom->gpio3, 0xff);
-+ nvram_read_u8(fill, NULL, "aa2g", &sprom->ant_available_bg, 0);
-+ nvram_read_u8(fill, NULL, "aa5g", &sprom->ant_available_a, 0);
-+ nvram_read_s8(fill, NULL, "ag0", &sprom->antenna_gain.a0, 0);
-+ nvram_read_s8(fill, NULL, "ag1", &sprom->antenna_gain.a1, 0);
-+ nvram_read_alpha2(fill, "ccode", sprom->alpha2);
-+}
-+
-+static void bcm53xx_sprom_fill_r12389(struct ssb_sprom *sprom,
-+ const struct bcm53xx_sprom_fill *fill)
-+{
-+ nvram_read_u16(fill, NULL, "pa0b0", &sprom->pa0b0, 0);
-+ nvram_read_u16(fill, NULL, "pa0b1", &sprom->pa0b1, 0);
-+ nvram_read_u16(fill, NULL, "pa0b2", &sprom->pa0b2, 0);
-+ nvram_read_u8(fill, NULL, "pa0itssit", &sprom->itssi_bg, 0);
-+ nvram_read_u8(fill, NULL, "pa0maxpwr", &sprom->maxpwr_bg, 0);
-+ nvram_read_u16(fill, NULL, "pa1b0", &sprom->pa1b0, 0);
-+ nvram_read_u16(fill, NULL, "pa1b1", &sprom->pa1b1, 0);
-+ nvram_read_u16(fill, NULL, "pa1b2", &sprom->pa1b2, 0);
-+ nvram_read_u8(fill, NULL, "pa1itssit", &sprom->itssi_a, 0);
-+ nvram_read_u8(fill, NULL, "pa1maxpwr", &sprom->maxpwr_a, 0);
-+}
-+
-+static void bcm53xx_sprom_fill_r1(struct ssb_sprom *sprom,
-+ const struct bcm53xx_sprom_fill *fill)
-+{
-+ nvram_read_u16(fill, NULL, "boardflags", &sprom->boardflags_lo, 0);
-+ nvram_read_u8(fill, NULL, "cc", &sprom->country_code, 0);
-+}
-+
-+static void bcm53xx_sprom_fill_r2389(struct ssb_sprom *sprom,
-+ const struct bcm53xx_sprom_fill *fill)
-+{
-+ nvram_read_u8(fill, NULL, "opo", &sprom->opo, 0);
-+ nvram_read_u16(fill, NULL, "pa1lob0", &sprom->pa1lob0, 0);
-+ nvram_read_u16(fill, NULL, "pa1lob1", &sprom->pa1lob1, 0);
-+ nvram_read_u16(fill, NULL, "pa1lob2", &sprom->pa1lob2, 0);
-+ nvram_read_u16(fill, NULL, "pa1hib0", &sprom->pa1hib0, 0);
-+ nvram_read_u16(fill, NULL, "pa1hib1", &sprom->pa1hib1, 0);
-+ nvram_read_u16(fill, NULL, "pa1hib2", &sprom->pa1hib2, 0);
-+ nvram_read_u8(fill, NULL, "pa1lomaxpwr", &sprom->maxpwr_al, 0);
-+ nvram_read_u8(fill, NULL, "pa1himaxpwr", &sprom->maxpwr_ah, 0);
-+}
-+
-+static void bcm53xx_sprom_fill_r389(struct ssb_sprom *sprom,
-+ const struct bcm53xx_sprom_fill *fill)
-+{
-+ nvram_read_u8(fill, NULL, "bxa2g", &sprom->bxa2g, 0);
-+ nvram_read_u8(fill, NULL, "rssisav2g", &sprom->rssisav2g, 0);
-+ nvram_read_u8(fill, NULL, "rssismc2g", &sprom->rssismc2g, 0);
-+ nvram_read_u8(fill, NULL, "rssismf2g", &sprom->rssismf2g, 0);
-+ nvram_read_u8(fill, NULL, "bxa5g", &sprom->bxa5g, 0);
-+ nvram_read_u8(fill, NULL, "rssisav5g", &sprom->rssisav5g, 0);
-+ nvram_read_u8(fill, NULL, "rssismc5g", &sprom->rssismc5g, 0);
-+ nvram_read_u8(fill, NULL, "rssismf5g", &sprom->rssismf5g, 0);
-+ nvram_read_u8(fill, NULL, "tri2g", &sprom->tri2g, 0);
-+ nvram_read_u8(fill, NULL, "tri5g", &sprom->tri5g, 0);
-+ nvram_read_u8(fill, NULL, "tri5gl", &sprom->tri5gl, 0);
-+ nvram_read_u8(fill, NULL, "tri5gh", &sprom->tri5gh, 0);
-+ nvram_read_s8(fill, NULL, "rxpo2g", &sprom->rxpo2g, 0);
-+ nvram_read_s8(fill, NULL, "rxpo5g", &sprom->rxpo5g, 0);
-+}
-+
-+static void bcm53xx_sprom_fill_r3(struct ssb_sprom *sprom,
-+ const struct bcm53xx_sprom_fill *fill)
-+{
-+ nvram_read_u8(fill, NULL, "regrev", &sprom->regrev, 0);
-+ nvram_read_leddc(fill, "leddc", &sprom->leddc_on_time,
-+ &sprom->leddc_off_time);
-+}
-+
-+static void bcm53xx_sprom_fill_r4589(struct ssb_sprom *sprom,
-+ const struct bcm53xx_sprom_fill *fill)
-+{
-+ nvram_read_u8(fill, NULL, "regrev", &sprom->regrev, 0);
-+ nvram_read_s8(fill, NULL, "ag2", &sprom->antenna_gain.a2, 0);
-+ nvram_read_s8(fill, NULL, "ag3", &sprom->antenna_gain.a3, 0);
-+ nvram_read_u8(fill, NULL, "txchain", &sprom->txchain, 0xf);
-+ nvram_read_u8(fill, NULL, "rxchain", &sprom->rxchain, 0xf);
-+ nvram_read_u8(fill, NULL, "antswitch", &sprom->antswitch, 0xff);
-+ nvram_read_leddc(fill, "leddc", &sprom->leddc_on_time,
-+ &sprom->leddc_off_time);
-+}
-+
-+static void bcm53xx_sprom_fill_r458(struct ssb_sprom *sprom,
-+ const struct bcm53xx_sprom_fill *fill)
-+{
-+ nvram_read_u16(fill, NULL, "cck2gpo", &sprom->cck2gpo, 0);
-+ nvram_read_u32(fill, NULL, "ofdm2gpo", &sprom->ofdm2gpo, 0);
-+ nvram_read_u32(fill, NULL, "ofdm5gpo", &sprom->ofdm5gpo, 0);
-+ nvram_read_u32(fill, NULL, "ofdm5glpo", &sprom->ofdm5glpo, 0);
-+ nvram_read_u32(fill, NULL, "ofdm5ghpo", &sprom->ofdm5ghpo, 0);
-+ nvram_read_u16(fill, NULL, "cddpo", &sprom->cddpo, 0);
-+ nvram_read_u16(fill, NULL, "stbcpo", &sprom->stbcpo, 0);
-+ nvram_read_u16(fill, NULL, "bw40po", &sprom->bw40po, 0);
-+ nvram_read_u16(fill, NULL, "bwduppo", &sprom->bwduppo, 0);
-+ nvram_read_u16(fill, NULL, "mcs2gpo0", &sprom->mcs2gpo[0], 0);
-+ nvram_read_u16(fill, NULL, "mcs2gpo1", &sprom->mcs2gpo[1], 0);
-+ nvram_read_u16(fill, NULL, "mcs2gpo2", &sprom->mcs2gpo[2], 0);
-+ nvram_read_u16(fill, NULL, "mcs2gpo3", &sprom->mcs2gpo[3], 0);
-+ nvram_read_u16(fill, NULL, "mcs2gpo4", &sprom->mcs2gpo[4], 0);
-+ nvram_read_u16(fill, NULL, "mcs2gpo5", &sprom->mcs2gpo[5], 0);
-+ nvram_read_u16(fill, NULL, "mcs2gpo6", &sprom->mcs2gpo[6], 0);
-+ nvram_read_u16(fill, NULL, "mcs2gpo7", &sprom->mcs2gpo[7], 0);
-+ nvram_read_u16(fill, NULL, "mcs5gpo0", &sprom->mcs5gpo[0], 0);
-+ nvram_read_u16(fill, NULL, "mcs5gpo1", &sprom->mcs5gpo[1], 0);
-+ nvram_read_u16(fill, NULL, "mcs5gpo2", &sprom->mcs5gpo[2], 0);
-+ nvram_read_u16(fill, NULL, "mcs5gpo3", &sprom->mcs5gpo[3], 0);
-+ nvram_read_u16(fill, NULL, "mcs5gpo4", &sprom->mcs5gpo[4], 0);
-+ nvram_read_u16(fill, NULL, "mcs5gpo5", &sprom->mcs5gpo[5], 0);
-+ nvram_read_u16(fill, NULL, "mcs5gpo6", &sprom->mcs5gpo[6], 0);
-+ nvram_read_u16(fill, NULL, "mcs5gpo7", &sprom->mcs5gpo[7], 0);
-+ nvram_read_u16(fill, NULL, "mcs5glpo0", &sprom->mcs5glpo[0], 0);
-+ nvram_read_u16(fill, NULL, "mcs5glpo1", &sprom->mcs5glpo[1], 0);
-+ nvram_read_u16(fill, NULL, "mcs5glpo2", &sprom->mcs5glpo[2], 0);
-+ nvram_read_u16(fill, NULL, "mcs5glpo3", &sprom->mcs5glpo[3], 0);
-+ nvram_read_u16(fill, NULL, "mcs5glpo4", &sprom->mcs5glpo[4], 0);
-+ nvram_read_u16(fill, NULL, "mcs5glpo5", &sprom->mcs5glpo[5], 0);
-+ nvram_read_u16(fill, NULL, "mcs5glpo6", &sprom->mcs5glpo[6], 0);
-+ nvram_read_u16(fill, NULL, "mcs5glpo7", &sprom->mcs5glpo[7], 0);
-+ nvram_read_u16(fill, NULL, "mcs5ghpo0", &sprom->mcs5ghpo[0], 0);
-+ nvram_read_u16(fill, NULL, "mcs5ghpo1", &sprom->mcs5ghpo[1], 0);
-+ nvram_read_u16(fill, NULL, "mcs5ghpo2", &sprom->mcs5ghpo[2], 0);
-+ nvram_read_u16(fill, NULL, "mcs5ghpo3", &sprom->mcs5ghpo[3], 0);
-+ nvram_read_u16(fill, NULL, "mcs5ghpo4", &sprom->mcs5ghpo[4], 0);
-+ nvram_read_u16(fill, NULL, "mcs5ghpo5", &sprom->mcs5ghpo[5], 0);
-+ nvram_read_u16(fill, NULL, "mcs5ghpo6", &sprom->mcs5ghpo[6], 0);
-+ nvram_read_u16(fill, NULL, "mcs5ghpo7", &sprom->mcs5ghpo[7], 0);
-+}
-+
-+static void bcm53xx_sprom_fill_r45(struct ssb_sprom *sprom,
-+ const struct bcm53xx_sprom_fill *fill)
-+{
-+ nvram_read_u8(fill, NULL, "txpid2ga0", &sprom->txpid2g[0], 0);
-+ nvram_read_u8(fill, NULL, "txpid2ga1", &sprom->txpid2g[1], 0);
-+ nvram_read_u8(fill, NULL, "txpid2ga2", &sprom->txpid2g[2], 0);
-+ nvram_read_u8(fill, NULL, "txpid2ga3", &sprom->txpid2g[3], 0);
-+ nvram_read_u8(fill, NULL, "txpid5ga0", &sprom->txpid5g[0], 0);
-+ nvram_read_u8(fill, NULL, "txpid5ga1", &sprom->txpid5g[1], 0);
-+ nvram_read_u8(fill, NULL, "txpid5ga2", &sprom->txpid5g[2], 0);
-+ nvram_read_u8(fill, NULL, "txpid5ga3", &sprom->txpid5g[3], 0);
-+ nvram_read_u8(fill, NULL, "txpid5gla0", &sprom->txpid5gl[0], 0);
-+ nvram_read_u8(fill, NULL, "txpid5gla1", &sprom->txpid5gl[1], 0);
-+ nvram_read_u8(fill, NULL, "txpid5gla2", &sprom->txpid5gl[2], 0);
-+ nvram_read_u8(fill, NULL, "txpid5gla3", &sprom->txpid5gl[3], 0);
-+ nvram_read_u8(fill, NULL, "txpid5gha0", &sprom->txpid5gh[0], 0);
-+ nvram_read_u8(fill, NULL, "txpid5gha1", &sprom->txpid5gh[1], 0);
-+ nvram_read_u8(fill, NULL, "txpid5gha2", &sprom->txpid5gh[2], 0);
-+ nvram_read_u8(fill, NULL, "txpid5gha3", &sprom->txpid5gh[3], 0);
-+}
-+
-+static void bcm53xx_sprom_fill_r89(struct ssb_sprom *sprom,
-+ const struct bcm53xx_sprom_fill *fill)
-+{
-+ nvram_read_u8(fill, NULL, "tssipos2g", &sprom->fem.ghz2.tssipos, 0);
-+ nvram_read_u8(fill, NULL, "extpagain2g", &sprom->fem.ghz2.extpa_gain, 0);
-+ nvram_read_u8(fill, NULL, "pdetrange2g", &sprom->fem.ghz2.pdet_range, 0);
-+ nvram_read_u8(fill, NULL, "triso2g", &sprom->fem.ghz2.tr_iso, 0);
-+ nvram_read_u8(fill, NULL, "antswctl2g", &sprom->fem.ghz2.antswlut, 0);
-+ nvram_read_u8(fill, NULL, "tssipos5g", &sprom->fem.ghz5.tssipos, 0);
-+ nvram_read_u8(fill, NULL, "extpagain5g", &sprom->fem.ghz5.extpa_gain, 0);
-+ nvram_read_u8(fill, NULL, "pdetrange5g", &sprom->fem.ghz5.pdet_range, 0);
-+ nvram_read_u8(fill, NULL, "triso5g", &sprom->fem.ghz5.tr_iso, 0);
-+ nvram_read_u8(fill, NULL, "antswctl5g", &sprom->fem.ghz5.antswlut, 0);
-+ nvram_read_u8(fill, NULL, "tempthresh", &sprom->tempthresh, 0);
-+ nvram_read_u8(fill, NULL, "tempoffset", &sprom->tempoffset, 0);
-+ nvram_read_u16(fill, NULL, "rawtempsense", &sprom->rawtempsense, 0);
-+ nvram_read_u8(fill, NULL, "measpower", &sprom->measpower, 0);
-+ nvram_read_u8(fill, NULL, "tempsense_slope", &sprom->tempsense_slope, 0);
-+ nvram_read_u8(fill, NULL, "tempcorrx", &sprom->tempcorrx, 0);
-+ nvram_read_u8(fill, NULL, "tempsense_option", &sprom->tempsense_option, 0);
-+ nvram_read_u8(fill, NULL, "freqoffset_corr", &sprom->freqoffset_corr, 0);
-+ nvram_read_u8(fill, NULL, "iqcal_swp_dis", &sprom->iqcal_swp_dis, 0);
-+ nvram_read_u8(fill, NULL, "hw_iqcal_en", &sprom->hw_iqcal_en, 0);
-+ nvram_read_u8(fill, NULL, "elna2g", &sprom->elna2g, 0);
-+ nvram_read_u8(fill, NULL, "elna5g", &sprom->elna5g, 0);
-+ nvram_read_u8(fill, NULL, "phycal_tempdelta", &sprom->phycal_tempdelta, 0);
-+ nvram_read_u8(fill, NULL, "temps_period", &sprom->temps_period, 0);
-+ nvram_read_u8(fill, NULL, "temps_hysteresis", &sprom->temps_hysteresis, 0);
-+ nvram_read_u8(fill, NULL, "measpower1", &sprom->measpower1, 0);
-+ nvram_read_u8(fill, NULL, "measpower2", &sprom->measpower2, 0);
-+ nvram_read_u8(fill, NULL, "rxgainerr2ga0", &sprom->rxgainerr2ga[0], 0);
-+ nvram_read_u8(fill, NULL, "rxgainerr2ga1", &sprom->rxgainerr2ga[1], 0);
-+ nvram_read_u8(fill, NULL, "rxgainerr2ga2", &sprom->rxgainerr2ga[2], 0);
-+ nvram_read_u8(fill, NULL, "rxgainerr5gla0", &sprom->rxgainerr5gla[0], 0);
-+ nvram_read_u8(fill, NULL, "rxgainerr5gla1", &sprom->rxgainerr5gla[1], 0);
-+ nvram_read_u8(fill, NULL, "rxgainerr5gla2", &sprom->rxgainerr5gla[2], 0);
-+ nvram_read_u8(fill, NULL, "rxgainerr5gma0", &sprom->rxgainerr5gma[0], 0);
-+ nvram_read_u8(fill, NULL, "rxgainerr5gma1", &sprom->rxgainerr5gma[1], 0);
-+ nvram_read_u8(fill, NULL, "rxgainerr5gma2", &sprom->rxgainerr5gma[2], 0);
-+ nvram_read_u8(fill, NULL, "rxgainerr5gha0", &sprom->rxgainerr5gha[0], 0);
-+ nvram_read_u8(fill, NULL, "rxgainerr5gha1", &sprom->rxgainerr5gha[1], 0);
-+ nvram_read_u8(fill, NULL, "rxgainerr5gha2", &sprom->rxgainerr5gha[2], 0);
-+ nvram_read_u8(fill, NULL, "rxgainerr5gua0", &sprom->rxgainerr5gua[0], 0);
-+ nvram_read_u8(fill, NULL, "rxgainerr5gua1", &sprom->rxgainerr5gua[1], 0);
-+ nvram_read_u8(fill, NULL, "rxgainerr5gua2", &sprom->rxgainerr5gua[2], 0);
-+ nvram_read_u8(fill, NULL, "noiselvl2ga0", &sprom->noiselvl2ga[0], 0);
-+ nvram_read_u8(fill, NULL, "noiselvl2ga1", &sprom->noiselvl2ga[1], 0);
-+ nvram_read_u8(fill, NULL, "noiselvl2ga2", &sprom->noiselvl2ga[2], 0);
-+ nvram_read_u8(fill, NULL, "noiselvl5gla0", &sprom->noiselvl5gla[0], 0);
-+ nvram_read_u8(fill, NULL, "noiselvl5gla1", &sprom->noiselvl5gla[1], 0);
-+ nvram_read_u8(fill, NULL, "noiselvl5gla2", &sprom->noiselvl5gla[2], 0);
-+ nvram_read_u8(fill, NULL, "noiselvl5gma0", &sprom->noiselvl5gma[0], 0);
-+ nvram_read_u8(fill, NULL, "noiselvl5gma1", &sprom->noiselvl5gma[1], 0);
-+ nvram_read_u8(fill, NULL, "noiselvl5gma2", &sprom->noiselvl5gma[2], 0);
-+ nvram_read_u8(fill, NULL, "noiselvl5gha0", &sprom->noiselvl5gha[0], 0);
-+ nvram_read_u8(fill, NULL, "noiselvl5gha1", &sprom->noiselvl5gha[1], 0);
-+ nvram_read_u8(fill, NULL, "noiselvl5gha2", &sprom->noiselvl5gha[2], 0);
-+ nvram_read_u8(fill, NULL, "noiselvl5gua0", &sprom->noiselvl5gua[0], 0);
-+ nvram_read_u8(fill, NULL, "noiselvl5gua1", &sprom->noiselvl5gua[1], 0);
-+ nvram_read_u8(fill, NULL, "noiselvl5gua2", &sprom->noiselvl5gua[2], 0);
-+ nvram_read_u8(fill, NULL, "pcieingress_war", &sprom->pcieingress_war, 0);
-+}
-+
-+static void bcm53xx_sprom_fill_r9(struct ssb_sprom *sprom,
-+ const struct bcm53xx_sprom_fill *fill)
-+{
-+ nvram_read_u16(fill, NULL, "cckbw202gpo", &sprom->cckbw202gpo, 0);
-+ nvram_read_u16(fill, NULL, "cckbw20ul2gpo", &sprom->cckbw20ul2gpo, 0);
-+ nvram_read_u32(fill, NULL, "legofdmbw202gpo", &sprom->legofdmbw202gpo, 0);
-+ nvram_read_u32(fill, NULL, "legofdmbw20ul2gpo", &sprom->legofdmbw20ul2gpo, 0);
-+ nvram_read_u32(fill, NULL, "legofdmbw205glpo", &sprom->legofdmbw205glpo, 0);
-+ nvram_read_u32(fill, NULL, "legofdmbw20ul5glpo", &sprom->legofdmbw20ul5glpo, 0);
-+ nvram_read_u32(fill, NULL, "legofdmbw205gmpo", &sprom->legofdmbw205gmpo, 0);
-+ nvram_read_u32(fill, NULL, "legofdmbw20ul5gmpo", &sprom->legofdmbw20ul5gmpo, 0);
-+ nvram_read_u32(fill, NULL, "legofdmbw205ghpo", &sprom->legofdmbw205ghpo, 0);
-+ nvram_read_u32(fill, NULL, "legofdmbw20ul5ghpo", &sprom->legofdmbw20ul5ghpo, 0);
-+ nvram_read_u32(fill, NULL, "mcsbw202gpo", &sprom->mcsbw202gpo, 0);
-+ nvram_read_u32(fill, NULL, "mcsbw20ul2gpo", &sprom->mcsbw20ul2gpo, 0);
-+ nvram_read_u32(fill, NULL, "mcsbw402gpo", &sprom->mcsbw402gpo, 0);
-+ nvram_read_u32(fill, NULL, "mcsbw205glpo", &sprom->mcsbw205glpo, 0);
-+ nvram_read_u32(fill, NULL, "mcsbw20ul5glpo", &sprom->mcsbw20ul5glpo, 0);
-+ nvram_read_u32(fill, NULL, "mcsbw405glpo", &sprom->mcsbw405glpo, 0);
-+ nvram_read_u32(fill, NULL, "mcsbw205gmpo", &sprom->mcsbw205gmpo, 0);
-+ nvram_read_u32(fill, NULL, "mcsbw20ul5gmpo", &sprom->mcsbw20ul5gmpo, 0);
-+ nvram_read_u32(fill, NULL, "mcsbw405gmpo", &sprom->mcsbw405gmpo, 0);
-+ nvram_read_u32(fill, NULL, "mcsbw205ghpo", &sprom->mcsbw205ghpo, 0);
-+ nvram_read_u32(fill, NULL, "mcsbw20ul5ghpo", &sprom->mcsbw20ul5ghpo, 0);
-+ nvram_read_u32(fill, NULL, "mcsbw405ghpo", &sprom->mcsbw405ghpo, 0);
-+ nvram_read_u16(fill, NULL, "mcs32po", &sprom->mcs32po, 0);
-+ nvram_read_u16(fill, NULL, "legofdm40duppo", &sprom->legofdm40duppo, 0);
-+ nvram_read_u8(fill, NULL, "sar2g", &sprom->sar2g, 0);
-+ nvram_read_u8(fill, NULL, "sar5g", &sprom->sar5g, 0);
-+}
-+
-+static void bcm53xx_sprom_fill_path_r4589(struct ssb_sprom *sprom,
-+ const struct bcm53xx_sprom_fill *fill)
-+{
-+ char postfix[2];
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) {
-+ struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i];
-+ snprintf(postfix, sizeof(postfix), "%i", i);
-+ nvram_read_u8(fill, postfix, "maxp2ga", &pwr_info->maxpwr_2g, 0);
-+ nvram_read_u8(fill, postfix, "itt2ga", &pwr_info->itssi_2g, 0);
-+ nvram_read_u8(fill, postfix, "itt5ga", &pwr_info->itssi_5g, 0);
-+ nvram_read_u16(fill, postfix, "pa2gw0a", &pwr_info->pa_2g[0], 0);
-+ nvram_read_u16(fill, postfix, "pa2gw1a", &pwr_info->pa_2g[1], 0);
-+ nvram_read_u16(fill, postfix, "pa2gw2a", &pwr_info->pa_2g[2], 0);
-+ nvram_read_u8(fill, postfix, "maxp5ga", &pwr_info->maxpwr_5g, 0);
-+ nvram_read_u8(fill, postfix, "maxp5gha", &pwr_info->maxpwr_5gh, 0);
-+ nvram_read_u8(fill, postfix, "maxp5gla", &pwr_info->maxpwr_5gl, 0);
-+ nvram_read_u16(fill, postfix, "pa5gw0a", &pwr_info->pa_5g[0], 0);
-+ nvram_read_u16(fill, postfix, "pa5gw1a", &pwr_info->pa_5g[1], 0);
-+ nvram_read_u16(fill, postfix, "pa5gw2a", &pwr_info->pa_5g[2], 0);
-+ nvram_read_u16(fill, postfix, "pa5glw0a", &pwr_info->pa_5gl[0], 0);
-+ nvram_read_u16(fill, postfix, "pa5glw1a", &pwr_info->pa_5gl[1], 0);
-+ nvram_read_u16(fill, postfix, "pa5glw2a", &pwr_info->pa_5gl[2], 0);
-+ nvram_read_u16(fill, postfix, "pa5ghw0a", &pwr_info->pa_5gh[0], 0);
-+ nvram_read_u16(fill, postfix, "pa5ghw1a", &pwr_info->pa_5gh[1], 0);
-+ nvram_read_u16(fill, postfix, "pa5ghw2a", &pwr_info->pa_5gh[2], 0);
-+ }
-+}
-+
-+static void bcm53xx_sprom_fill_path_r45(struct ssb_sprom *sprom,
-+ const struct bcm53xx_sprom_fill *fill)
-+{
-+ char postfix[2];
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) {
-+ struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i];
-+ snprintf(postfix, sizeof(postfix), "%i", i);
-+ nvram_read_u16(fill, postfix, "pa2gw3a", &pwr_info->pa_2g[3], 0);
-+ nvram_read_u16(fill, postfix, "pa5gw3a", &pwr_info->pa_5g[3], 0);
-+ nvram_read_u16(fill, postfix, "pa5glw3a", &pwr_info->pa_5gl[3], 0);
-+ nvram_read_u16(fill, postfix, "pa5ghw3a", &pwr_info->pa_5gh[3], 0);
-+ }
-+}
-+
-+static void bcm53xx_sprom_fill_ethernet(struct ssb_sprom *sprom,
-+ const struct bcm53xx_sprom_fill *fill)
-+{
-+ nvram_read_macaddr(fill, "et0macaddr", sprom->et0mac);
-+ nvram_read_u8(fill, NULL, "et0mdcport", &sprom->et0mdcport, 0);
-+ nvram_read_u8(fill, NULL, "et0phyaddr", &sprom->et0phyaddr, 0);
-+
-+ nvram_read_macaddr(fill, "et1macaddr", sprom->et1mac);
-+ nvram_read_u8(fill, NULL, "et1mdcport", &sprom->et1mdcport, 0);
-+ nvram_read_u8(fill, NULL, "et1phyaddr", &sprom->et1phyaddr, 0);
-+
-+ nvram_read_macaddr(fill, "macaddr", sprom->il0mac);
-+ nvram_read_macaddr(fill, "il0macaddr", sprom->il0mac);
-+}
-+
-+static void bcm53xx_sprom_fill_board_data(struct ssb_sprom *sprom,
-+ const struct bcm53xx_sprom_fill *fill)
-+{
-+ nvram_read_u16(fill, NULL, "boardrev", &sprom->board_rev, 0);
-+ nvram_read_u16(fill, NULL, "boardnum", &sprom->board_num, 0);
-+ nvram_read_u16(fill, NULL, "boardtype", &sprom->board_type, 0);
-+ nvram_read_u32_2(fill, "boardflags", &sprom->boardflags_lo,
-+ &sprom->boardflags_hi);
-+ nvram_read_u32_2(fill, "boardflags2", &sprom->boardflags2_lo,
-+ &sprom->boardflags2_hi);
-+}
-+
-+static void bcm53xx_sprom_fill(struct ssb_sprom *sprom,
-+ const struct bcm53xx_sprom_fill *fill)
-+{
-+ bcm53xx_sprom_fill_ethernet(sprom, fill);
-+ bcm53xx_sprom_fill_board_data(sprom, fill);
-+
-+ nvram_read_u8(fill, NULL, "sromrev", &sprom->revision, 0);
-+
-+ switch (sprom->revision) {
-+ case 1:
-+ bcm53xx_sprom_fill_r1234589(sprom, fill);
-+ bcm53xx_sprom_fill_r12389(sprom, fill);
-+ bcm53xx_sprom_fill_r1(sprom, fill);
-+ break;
-+ case 2:
-+ bcm53xx_sprom_fill_r1234589(sprom, fill);
-+ bcm53xx_sprom_fill_r12389(sprom, fill);
-+ bcm53xx_sprom_fill_r2389(sprom, fill);
-+ break;
-+ case 3:
-+ bcm53xx_sprom_fill_r1234589(sprom, fill);
-+ bcm53xx_sprom_fill_r12389(sprom, fill);
-+ bcm53xx_sprom_fill_r2389(sprom, fill);
-+ bcm53xx_sprom_fill_r389(sprom, fill);
-+ bcm53xx_sprom_fill_r3(sprom, fill);
-+ break;
-+ case 4:
-+ case 5:
-+ bcm53xx_sprom_fill_r1234589(sprom, fill);
-+ bcm53xx_sprom_fill_r4589(sprom, fill);
-+ bcm53xx_sprom_fill_r458(sprom, fill);
-+ bcm53xx_sprom_fill_r45(sprom, fill);
-+ bcm53xx_sprom_fill_path_r4589(sprom, fill);
-+ bcm53xx_sprom_fill_path_r45(sprom, fill);
-+ break;
-+ case 8:
-+ bcm53xx_sprom_fill_r1234589(sprom, fill);
-+ bcm53xx_sprom_fill_r12389(sprom, fill);
-+ bcm53xx_sprom_fill_r2389(sprom, fill);
-+ bcm53xx_sprom_fill_r389(sprom, fill);
-+ bcm53xx_sprom_fill_r4589(sprom, fill);
-+ bcm53xx_sprom_fill_r458(sprom, fill);
-+ bcm53xx_sprom_fill_r89(sprom, fill);
-+ bcm53xx_sprom_fill_path_r4589(sprom, fill);
-+ break;
-+ case 9:
-+ bcm53xx_sprom_fill_r1234589(sprom, fill);
-+ bcm53xx_sprom_fill_r12389(sprom, fill);
-+ bcm53xx_sprom_fill_r2389(sprom, fill);
-+ bcm53xx_sprom_fill_r389(sprom, fill);
-+ bcm53xx_sprom_fill_r4589(sprom, fill);
-+ bcm53xx_sprom_fill_r89(sprom, fill);
-+ bcm53xx_sprom_fill_r9(sprom, fill);
-+ bcm53xx_sprom_fill_path_r4589(sprom, fill);
-+ break;
-+ default:
-+ pr_warn("Unsupported SPROM revision %d detected. Will extract v1\n",
-+ sprom->revision);
-+ sprom->revision = 1;
-+ bcm53xx_sprom_fill_r1234589(sprom, fill);
-+ bcm53xx_sprom_fill_r12389(sprom, fill);
-+ bcm53xx_sprom_fill_r1(sprom, fill);
-+ }
-+}
-+
-+static int bcm53xx_sprom_getenv(const struct bcm53xx_sprom_fill *fill,
-+ const char *name, char *val, size_t val_len)
-+{
-+ const struct platform_device *nvram_dev = fill->priv;
-+
-+ return bcm47xx_nvram_getenv(&nvram_dev->dev, name, val, val_len);
-+};
-+
-+static int bcm53xx_sprom_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct device_node *np = dev->of_node;
-+ struct ssb_sprom *sprom;
-+ const phandle *handle;
-+ struct device_node *nvram_node;
-+ struct platform_device *nvram_dev;
-+ struct bcm53xx_sprom_fill fill;
-+
-+ /* Alloc */
-+ sprom = devm_kzalloc(dev, sizeof(*sprom), GFP_KERNEL);
-+ if (!sprom)
-+ return -ENOMEM;
-+
-+ handle = of_get_property(np, "nvram", NULL);
-+ if (!handle)
-+ return -ENOMEM;
-+
-+ nvram_node = of_find_node_by_phandle(be32_to_cpup(handle));
-+ if (!nvram_node)
-+ return -ENOMEM;
-+
-+ nvram_dev = of_find_device_by_node(nvram_node);
-+ if (!nvram_dev)
-+ return -ENOMEM;
-+
-+ fill.prefix = NULL;
-+ fill.fallback = false;
-+ fill.getenv = bcm53xx_sprom_getenv;
-+ fill.priv = nvram_dev;
-+
-+ bcm53xx_sprom_fill(sprom, &fill);
-+
-+ platform_set_drvdata(pdev, sprom);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id bcm53xx_sprom_of_match_table[] = {
-+ { .compatible = "brcm,bcm53xx-sprom", },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, mvebu_pcie_of_match_table);
-+
-+static struct platform_driver bcm53xx_sprom_driver = {
-+ .driver = {
-+ .owner = THIS_MODULE,
-+ .name = "bcm53xx-sprom",
-+ .of_match_table = bcm53xx_sprom_of_match_table,
-+ /* driver unloading/unbinding currently not supported */
-+ .suppress_bind_attrs = true,
-+ },
-+ .probe = bcm53xx_sprom_probe,
-+};
-+module_platform_driver(bcm53xx_sprom_driver);
-+
-+MODULE_AUTHOR("Hauke Mehrtens <hauke@hauke-m.de>");
-+MODULE_LICENSE("GPLv2");
diff --git a/target/linux/bcm53xx/patches-3.14/120-bcma-register-bcma-as-device-tree-driver.patch b/target/linux/bcm53xx/patches-3.14/120-bcma-register-bcma-as-device-tree-driver.patch
deleted file mode 100644
index 0db670a..0000000
--- a/target/linux/bcm53xx/patches-3.14/120-bcma-register-bcma-as-device-tree-driver.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-From bb5d497aeceb8d9f36a1d990538389b54748dfcd Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Mon, 6 Jan 2014 23:29:15 +0100
-Subject: [PATCH 05/15] bcma: register bcma as device tree driver
-
-This driver is used by the bcm53xx ARM SoC code.Now it is possible to
-give the address of the chipcommon core in device tree.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/bcma/host_soc.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++
- include/linux/bcma/bcma.h | 2 ++
- 2 files changed, 72 insertions(+)
-
---- a/drivers/bcma/host_soc.c
-+++ b/drivers/bcma/host_soc.c
-@@ -7,6 +7,9 @@
-
- #include "bcma_private.h"
- #include "scan.h"
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <linux/of_address.h>
- #include <linux/bcma/bcma.h>
- #include <linux/bcma/bcma_soc.h>
-
-@@ -173,6 +176,7 @@ int __init bcma_host_soc_register(struct
- /* Host specific */
- bus->hosttype = BCMA_HOSTTYPE_SOC;
- bus->ops = &bcma_host_soc_ops;
-+ bus->host_pdev = NULL;
-
- /* Register */
- err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
-@@ -181,3 +185,69 @@ int __init bcma_host_soc_register(struct
-
- return err;
- }
-+
-+#ifdef CONFIG_OF
-+static int bcma_host_soc_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct device_node *np = dev->of_node;
-+ struct bcma_bus *bus;
-+ int err;
-+
-+ /* Alloc */
-+ bus = devm_kzalloc(dev, sizeof(*bus), GFP_KERNEL);
-+ if (!bus)
-+ return -ENOMEM;
-+
-+ /* Map MMIO */
-+ bus->mmio = of_iomap(np, 0);
-+ if (!bus->mmio)
-+ return -ENOMEM;
-+
-+ /* Host specific */
-+ bus->hosttype = BCMA_HOSTTYPE_SOC;
-+ bus->ops = &bcma_host_soc_ops;
-+ bus->host_pdev = pdev;
-+
-+ /* Register */
-+ err = bcma_bus_register(bus);
-+ if (err)
-+ goto err_unmap_mmio;
-+
-+ platform_set_drvdata(pdev, bus);
-+
-+ return err;
-+
-+err_unmap_mmio:
-+ iounmap(bus->mmio);
-+ return err;
-+}
-+
-+static int bcma_host_soc_remove(struct platform_device *pdev)
-+{
-+ struct bcma_bus *bus = platform_get_drvdata(pdev);
-+
-+ bcma_bus_unregister(bus);
-+ iounmap(bus->mmio);
-+ platform_set_drvdata(pdev, NULL);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id bcma_host_soc_of_match[] = {
-+ { .compatible = "brcm,bus-aix", },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, bcma_host_soc_of_match);
-+
-+static struct platform_driver bcma_host_soc_driver = {
-+ .driver = {
-+ .name = "bcma-host-soc",
-+ .owner = THIS_MODULE,
-+ .of_match_table = bcma_host_soc_of_match,
-+ },
-+ .probe = bcma_host_soc_probe,
-+ .remove = bcma_host_soc_remove,
-+};
-+module_platform_driver(bcma_host_soc_driver);
-+#endif /* CONFIG_OF */
---- a/include/linux/bcma/bcma.h
-+++ b/include/linux/bcma/bcma.h
-@@ -323,6 +323,8 @@ struct bcma_bus {
- struct pci_dev *host_pci;
- /* Pointer to the SDIO device (only for BCMA_HOSTTYPE_SDIO) */
- struct sdio_func *host_sdio;
-+ /* Pointer to platform device (only for BCMA_HOSTTYPE_SOC) */
-+ struct platform_device *host_pdev;
- };
-
- struct bcma_chipinfo chipinfo;
diff --git a/target/linux/bcm53xx/patches-3.14/121-bcma-get-irqs-from-dt.patch b/target/linux/bcm53xx/patches-3.14/121-bcma-get-irqs-from-dt.patch
deleted file mode 100644
index f81541f..0000000
--- a/target/linux/bcm53xx/patches-3.14/121-bcma-get-irqs-from-dt.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From 3e59da41882a408064cd23f4c9124a7938bdb91f Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Thu, 9 Jan 2014 19:40:14 +0100
-Subject: [PATCH 06/15] bcma: get irqs from dt
-
-If bcma was registered with device tree it will search for some nodes
-with the irq number and add it to the core configuration.
----
- drivers/bcma/main.c | 42 +++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 41 insertions(+), 1 deletion(-)
-
---- a/drivers/bcma/main.c
-+++ b/drivers/bcma/main.c
-@@ -10,6 +10,8 @@
- #include <linux/platform_device.h>
- #include <linux/bcma/bcma.h>
- #include <linux/slab.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_address.h>
-
- MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
- MODULE_LICENSE("GPL");
-@@ -120,6 +122,38 @@ static void bcma_release_core_dev(struct
- kfree(core);
- }
-
-+static struct device_node *bcma_of_find_child_device(struct platform_device *parent,
-+ struct bcma_device *core)
-+{
-+ struct device_node *node;
-+ u64 size;
-+ const __be32 *reg;
-+
-+ if (!parent || !parent->dev.of_node)
-+ return NULL;
-+
-+ for_each_child_of_node(parent->dev.of_node, node) {
-+ reg = of_get_address(node, 0, &size, 0);
-+ if (!reg)
-+ continue;
-+ if (be32_to_cpup(reg) == core->addr)
-+ return node;
-+ }
-+ return NULL;
-+}
-+
-+static void bcma_of_fill_device(struct platform_device *parent,
-+ struct bcma_device *core)
-+{
-+ struct device_node *node;
-+
-+ node = bcma_of_find_child_device(parent, core);
-+ if (!node)
-+ return;
-+ core->dev.of_node = node;
-+ core->irq = irq_of_parse_and_map(node, 0);
-+}
-+
- static int bcma_register_cores(struct bcma_bus *bus)
- {
- struct bcma_device *core;
-@@ -155,7 +189,13 @@ static int bcma_register_cores(struct bc
- break;
- case BCMA_HOSTTYPE_SOC:
- core->dev.dma_mask = &core->dev.coherent_dma_mask;
-- core->dma_dev = &core->dev;
-+ if (bus->host_pdev) {
-+ core->dma_dev = &bus->host_pdev->dev;
-+ core->dev.parent = &bus->host_pdev->dev;
-+ bcma_of_fill_device(bus->host_pdev, core);
-+ } else {
-+ core->dma_dev = &core->dev;
-+ }
- break;
- case BCMA_HOSTTYPE_SDIO:
- break;
diff --git a/target/linux/bcm53xx/patches-3.14/123-bcma-get-sprom-from-devicetree.patch b/target/linux/bcm53xx/patches-3.14/123-bcma-get-sprom-from-devicetree.patch
deleted file mode 100644
index 0bf1308..0000000
--- a/target/linux/bcm53xx/patches-3.14/123-bcma-get-sprom-from-devicetree.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From 5d94449a92e4121b408e7cb8931a47984135eeea Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Sun, 4 May 2014 14:34:31 +0200
-Subject: [PATCH 07/15] bcma: get sprom from devicetree
-
-This patch make it possible to device an sprom provider in device tree
-and get the sprom from this driver. Every time there is such a provider
-it gets asked for a sprom.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/bcma/sprom.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 50 insertions(+), 1 deletion(-)
-
---- a/drivers/bcma/sprom.c
-+++ b/drivers/bcma/sprom.c
-@@ -15,6 +15,8 @@
- #include <linux/io.h>
- #include <linux/dma-mapping.h>
- #include <linux/slab.h>
-+#include <linux/of.h>
-+#include <linux/of_platform.h>
-
- static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out);
-
-@@ -46,6 +48,46 @@ int bcma_arch_register_fallback_sprom(in
- return 0;
- }
-
-+#ifdef CONFIG_OF
-+static int bcma_fill_sprom_with_dt(struct bcma_bus *bus,
-+ struct ssb_sprom *out)
-+{
-+ const phandle *handle;
-+ struct device_node *sprom_node;
-+ struct platform_device *sprom_dev;
-+ struct ssb_sprom *sprom;
-+
-+ if (!bus->host_pdev || !bus->host_pdev->dev.of_node)
-+ return -ENOENT;
-+
-+ handle = of_get_property(bus->host_pdev->dev.of_node, "sprom", NULL);
-+ if (!handle)
-+ return -ENOENT;
-+
-+ sprom_node = of_find_node_by_phandle(be32_to_cpup(handle));
-+ if (!sprom_node)
-+ return -ENOENT;
-+
-+ sprom_dev = of_find_device_by_node(sprom_node);
-+ if (!sprom_dev)
-+ return -ENOENT;
-+
-+ sprom = platform_get_drvdata(sprom_dev);
-+ if (!sprom)
-+ return -ENOENT;
-+
-+ memcpy(out, sprom, sizeof(*out));
-+
-+ return 0;
-+}
-+#else
-+static int bcma_fill_sprom_with_dt(struct bcma_bus *bus,
-+ struct ssb_sprom *out)
-+{
-+ return -ENOENT;
-+}
-+#endif
-+
- static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus,
- struct ssb_sprom *out)
- {
-@@ -580,7 +622,14 @@ int bcma_sprom_get(struct bcma_bus *bus)
- u16 *sprom;
- size_t sprom_sizes[] = { SSB_SPROMSIZE_WORDS_R4,
- SSB_SPROMSIZE_WORDS_R10, };
-- int i, err = 0;
-+ int i, err;
-+
-+ err = bcma_fill_sprom_with_dt(bus, &bus->sprom);
-+ if (err == 0) {
-+ bcma_info(bus, "Found sprom from device tree provider\n");
-+ return 0;
-+ }
-+ err = 0;
-
- if (!bus->drv_cc.core)
- return -EOPNOTSUPP;
diff --git a/target/linux/bcm53xx/patches-3.14/130-ARM-BCM5301X-register-bcma-bus.patch b/target/linux/bcm53xx/patches-3.14/130-ARM-BCM5301X-register-bcma-bus.patch
deleted file mode 100644
index 9d01f33..0000000
--- a/target/linux/bcm53xx/patches-3.14/130-ARM-BCM5301X-register-bcma-bus.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 23bcd5e7cb2aaee48ba8b2351f032a230d948b6f Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Sat, 25 Jan 2014 17:03:07 +0100
-Subject: [PATCH 08/15] ARM: BCM5301X: register bcma bus
-
----
- arch/arm/boot/dts/bcm4708.dtsi | 58 ++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 58 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4708.dtsi
-+++ b/arch/arm/boot/dts/bcm4708.dtsi
-@@ -31,4 +31,62 @@
- };
- };
-
-+ nvram0: nvram@0 {
-+ compatible = "brcm,bcm47xx-nvram";
-+ reg = <0x1c000000 0x01000000>;
-+ };
-+
-+ sprom0: sprom@0 {
-+ compatible = "brcm,bcm53xx-sprom";
-+ nvram = <&nvram0>;
-+ };
-+
-+ aix@18000000 {
-+ compatible = "brcm,bus-aix";
-+ reg = <0x18000000 0x1000>;
-+ ranges = <0x00000000 0x18000000 0x00100000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ sprom = <&sprom0>;
-+
-+ usb2@0 {
-+ reg = <0x18021000 0x1000>;
-+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-+ };
-+
-+ usb3@0 {
-+ reg = <0x18023000 0x1000>;
-+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
-+ };
-+
-+ gmac@0 {
-+ reg = <0x18024000 0x1000>;
-+ interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
-+ };
-+
-+ gmac@1 {
-+ reg = <0x18025000 0x1000>;
-+ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
-+ };
-+
-+ gmac@2 {
-+ reg = <0x18026000 0x1000>;
-+ interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
-+ };
-+
-+ gmac@3 {
-+ reg = <0x18027000 0x1000>;
-+ interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
-+ };
-+
-+ pcie@0 {
-+ reg = <0x18012000 0x1000>;
-+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
-+ };
-+
-+ pcie@1 {
-+ reg = <0x18013000 0x1000>;
-+ interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
-+ };
-+ };
- };
diff --git a/target/linux/bcm53xx/patches-3.14/131-ARM-BCM5301X-add-restart-support.patch b/target/linux/bcm53xx/patches-3.14/131-ARM-BCM5301X-add-restart-support.patch
deleted file mode 100644
index 46464dc..0000000
--- a/target/linux/bcm53xx/patches-3.14/131-ARM-BCM5301X-add-restart-support.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From 28b11a8b1258214b3b5d58bb6e3bbcb0fc9fd4fe Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Thu, 31 Jul 2014 07:28:05 +0200
-Subject: [PATCH] ARM: BCM5301X: add restart 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>
----
- arch/arm/mach-bcm/bcm_5301x.c | 31 +++++++++++++++++++++++++++++++
- 1 file changed, 31 insertions(+)
-
---- a/arch/arm/mach-bcm/bcm_5301x.c
-+++ b/arch/arm/mach-bcm/bcm_5301x.c
-@@ -12,9 +12,26 @@
- #include <asm/siginfo.h>
- #include <asm/signal.h>
-
-+#include <linux/bcma/bcma.h>
-
- static bool first_fault = true;
-
-+static struct bcma_bus *bcm5301x_get_bcma_bus(void)
-+{
-+ struct device_node *np;
-+ struct platform_device *pdev;
-+
-+ np = of_find_compatible_node(NULL, NULL, "brcm,bus-aix");
-+ if (!np)
-+ return NULL;
-+
-+ pdev = of_find_device_by_node(np);
-+ if (!pdev)
-+ return NULL;
-+
-+ return platform_get_drvdata(pdev);
-+}
-+
- static int bcm5301x_abort_handler(unsigned long addr, unsigned int fsr,
- struct pt_regs *regs)
- {
-@@ -49,6 +66,19 @@ static void __init bcm5301x_dt_init(void
- of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
- }
-
-+static void bcm5301x_restart(enum reboot_mode mode, const char *cmd)
-+{
-+ struct bcma_bus *bus = bcm5301x_get_bcma_bus();
-+
-+ if (bus)
-+ bcma_chipco_watchdog_timer_set(&bus->drv_cc, 1);
-+ else
-+ pr_warn("Unable to access bcma bus\n");
-+
-+ while (1)
-+ ;
-+}
-+
- static const char __initconst *bcm5301x_dt_compat[] = {
- "brcm,bcm4708",
- NULL,
-@@ -57,5 +87,6 @@ static const char __initconst *bcm5301x_
- DT_MACHINE_START(BCM5301X, "BCM5301X")
- .init_early = bcm5301x_init_early,
- .init_machine = bcm5301x_dt_init,
-+ .restart = bcm5301x_restart,
- .dt_compat = bcm5301x_dt_compat,
- MACHINE_END
diff --git a/target/linux/bcm53xx/patches-3.14/140-bcma-only-map-wrap-if-it-is-not-null.patch b/target/linux/bcm53xx/patches-3.14/140-bcma-only-map-wrap-if-it-is-not-null.patch
deleted file mode 100644
index 30e03e3..0000000
--- a/target/linux/bcm53xx/patches-3.14/140-bcma-only-map-wrap-if-it-is-not-null.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From f8ea60bbaf880d8d8d99fde3b5155f472e00141f Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Mon, 12 May 2014 20:16:39 +0200
-Subject: [PATCH 09/15] bcma: only map wrap if it is not null
-
-The chipcommon B core does not have a wrap address and it would fail here.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/bcma/scan.c | 11 +++++++----
- 1 file changed, 7 insertions(+), 4 deletions(-)
-
---- a/drivers/bcma/scan.c
-+++ b/drivers/bcma/scan.c
-@@ -421,10 +421,13 @@ static int bcma_get_next_core(struct bcm
- core->io_addr = ioremap_nocache(core->addr, BCMA_CORE_SIZE);
- if (!core->io_addr)
- return -ENOMEM;
-- core->io_wrap = ioremap_nocache(core->wrap, BCMA_CORE_SIZE);
-- if (!core->io_wrap) {
-- iounmap(core->io_addr);
-- return -ENOMEM;
-+ if (core->wrap) {
-+ core->io_wrap = ioremap_nocache(core->wrap,
-+ BCMA_CORE_SIZE);
-+ if (!core->io_wrap) {
-+ iounmap(core->io_addr);
-+ return -ENOMEM;
-+ }
- }
- }
- return 0;
diff --git a/target/linux/bcm53xx/patches-3.14/141-bcma-store-more-alternative-addresses.patch b/target/linux/bcm53xx/patches-3.14/141-bcma-store-more-alternative-addresses.patch
deleted file mode 100644
index bb3ce62..0000000
--- a/target/linux/bcm53xx/patches-3.14/141-bcma-store-more-alternative-addresses.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 9317024aa1d8df94d3b021bc23b57f02a435e96c Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Mon, 12 May 2014 21:57:53 +0200
-Subject: [PATCH 10/15] bcma: store more alternative addresses
-
-Each core could have more than one alternative address. There are cores
-with 8 alternative addresses for different functions. The PHY control
-in the Chip common B core is done through the 2. alternative address
-and not the first one.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/bcma/scan.c | 9 +++++----
- drivers/usb/host/bcma-hcd.c | 2 +-
- include/linux/bcma/bcma.h | 2 +-
- 3 files changed, 7 insertions(+), 6 deletions(-)
-
---- a/drivers/bcma/scan.c
-+++ b/drivers/bcma/scan.c
-@@ -276,7 +276,7 @@ static int bcma_get_next_core(struct bcm
- struct bcma_device *core)
- {
- u32 tmp;
-- u8 i, j;
-+ u8 i, j, k;
- s32 cia, cib;
- u8 ports[2], wrappers[2];
-
-@@ -367,6 +367,7 @@ static int bcma_get_next_core(struct bcm
- core->addr = tmp;
-
- /* get & parse slave ports */
-+ k = 0;
- for (i = 0; i < ports[1]; i++) {
- for (j = 0; ; j++) {
- tmp = bcma_erom_get_addr_desc(bus, eromptr,
-@@ -376,9 +377,9 @@ static int bcma_get_next_core(struct bcm
- /* pr_debug("erom: slave port %d "
- * "has %d descriptors\n", i, j); */
- break;
-- } else {
-- if (i == 0 && j == 0)
-- core->addr1 = tmp;
-+ } else if (k < 8) {
-+ core->addr_s[k] = tmp;
-+ k++;
- }
- }
- }
---- a/drivers/usb/host/bcma-hcd.c
-+++ b/drivers/usb/host/bcma-hcd.c
-@@ -237,7 +237,7 @@ static int bcma_hcd_probe(struct bcma_de
- bcma_hcd_init_chip(dev);
-
- /* In AI chips EHCI is addrspace 0, OHCI is 1 */
-- ohci_addr = dev->addr1;
-+ ohci_addr = dev->addr_s[0];
- if ((chipinfo->id == 0x5357 || chipinfo->id == 0x4749)
- && chipinfo->rev == 0)
- ohci_addr = 0x18009000;
---- a/include/linux/bcma/bcma.h
-+++ b/include/linux/bcma/bcma.h
-@@ -267,7 +267,7 @@ struct bcma_device {
- u8 core_unit;
-
- u32 addr;
-- u32 addr1;
-+ u32 addr_s[8];
- u32 wrap;
-
- void __iomem *io_addr;
diff --git a/target/linux/bcm53xx/patches-3.14/142-bcma-add-support-for-chipcommon-B-core.patch b/target/linux/bcm53xx/patches-3.14/142-bcma-add-support-for-chipcommon-B-core.patch
deleted file mode 100644
index 312f63b..0000000
--- a/target/linux/bcm53xx/patches-3.14/142-bcma-add-support-for-chipcommon-B-core.patch
+++ /dev/null
@@ -1,180 +0,0 @@
-From 6c0df4a483e41ef129caa8948b3bcde7f91de197 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Mon, 12 May 2014 20:33:15 +0200
-Subject: [PATCH 11/15] bcma: add support for chipcommon B core
-
-This core is used on BCM4708 to configure the PCIe and USB3 PHYs and it
-contains the addresses to the Device Management unit. This will be used
-by the PCIe driver first.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/bcma/Makefile | 1 +
- drivers/bcma/bcma_private.h | 4 ++
- drivers/bcma/driver_chipcommon_b.c | 59 +++++++++++++++++++++++++++++
- drivers/bcma/main.c | 10 +++++
- drivers/bcma/scan.c | 1 +
- include/linux/bcma/bcma.h | 1 +
- include/linux/bcma/bcma_driver_chipcommon.h | 8 ++++
- 7 files changed, 84 insertions(+)
- create mode 100644 drivers/bcma/driver_chipcommon_b.c
-
---- a/drivers/bcma/Makefile
-+++ b/drivers/bcma/Makefile
-@@ -1,5 +1,6 @@
- bcma-y += main.o scan.o core.o sprom.o
- bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
-+bcma-y += driver_chipcommon_b.o
- bcma-$(CONFIG_BCMA_SFLASH) += driver_chipcommon_sflash.o
- bcma-$(CONFIG_BCMA_NFLASH) += driver_chipcommon_nflash.o
- bcma-y += driver_pci.o
---- a/drivers/bcma/bcma_private.h
-+++ b/drivers/bcma/bcma_private.h
-@@ -50,6 +50,10 @@ void bcma_chipco_serial_init(struct bcma
- extern struct platform_device bcma_pflash_dev;
- #endif /* CONFIG_BCMA_DRIVER_MIPS */
-
-+/* driver_chipcommon_b.c */
-+int bcma_core_chipcommon_b_init(struct bcma_drv_cc_b *ccb);
-+void bcma_core_chipcommon_b_free(struct bcma_drv_cc_b *ccb);
-+
- /* driver_chipcommon_pmu.c */
- u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc);
- u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc);
---- /dev/null
-+++ b/drivers/bcma/driver_chipcommon_b.c
-@@ -0,0 +1,59 @@
-+/*
-+ * Broadcom specific AMBA
-+ * ChipCommon B Unit driver
-+ *
-+ * Copyright 2011, 2014, Hauke Mehrtens <hauke@hauke-m.de>
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+#include "bcma_private.h"
-+#include <linux/export.h>
-+#include <linux/bcma/bcma.h>
-+
-+static bool bcma_wait_reg(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_warn("Timeout waiting for register %p!\n", addr);
-+
-+ return false;
-+}
-+
-+void bcma_chipco_b_mii_write(struct bcma_drv_cc_b *ccb, u32 offset, u32 value)
-+{
-+ writel(offset, ccb->mii + 0x00);
-+ bcma_wait_reg(ccb->mii + 0x00, 0x0100, 0x0000, 100);
-+ writel(value, ccb->mii + 0x04);
-+ bcma_wait_reg(ccb->mii + 0x00, 0x0100, 0x0000, 100);
-+}
-+EXPORT_SYMBOL_GPL(bcma_chipco_b_mii_write);
-+
-+int bcma_core_chipcommon_b_init(struct bcma_drv_cc_b *ccb)
-+{
-+ if (ccb->setup_done)
-+ return 0;
-+
-+ ccb->setup_done = 1;
-+ ccb->mii = ioremap_nocache(ccb->core->addr_s[1], BCMA_CORE_SIZE);
-+ if (!ccb->mii)
-+ return -ENOMEM;
-+
-+ return 0;
-+}
-+
-+void bcma_core_chipcommon_b_free(struct bcma_drv_cc_b *ccb)
-+{
-+ if (ccb->mii)
-+ iounmap(ccb->mii);
-+}
---- a/drivers/bcma/main.c
-+++ b/drivers/bcma/main.c
-@@ -164,6 +164,7 @@ static int bcma_register_cores(struct bc
- switch (core->id.id) {
- case BCMA_CORE_4706_CHIPCOMMON:
- case BCMA_CORE_CHIPCOMMON:
-+ case BCMA_CORE_NS_CHIPCOMMON_B:
- case BCMA_CORE_PCI:
- case BCMA_CORE_PCIE:
- case BCMA_CORE_PCIE2:
-@@ -301,6 +302,13 @@ int bcma_bus_register(struct bcma_bus *b
- bcma_core_chipcommon_init(&bus->drv_cc);
- }
-
-+ /* Init CC core */
-+ core = bcma_find_core(bus, BCMA_CORE_NS_CHIPCOMMON_B);
-+ if (core) {
-+ bus->drv_cc_b.core = core;
-+ bcma_core_chipcommon_b_init(&bus->drv_cc_b);
-+ }
-+
- /* Init MIPS core */
- core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
- if (core) {
-@@ -355,6 +363,8 @@ void bcma_bus_unregister(struct bcma_bus
- else if (err)
- bcma_err(bus, "Can not unregister GPIO driver: %i\n", err);
-
-+ bcma_core_chipcommon_b_free(&bus->drv_cc_b);
-+
- cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
- cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE);
- cores[2] = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON);
---- a/drivers/bcma/scan.c
-+++ b/drivers/bcma/scan.c
-@@ -314,6 +314,7 @@ static int bcma_get_next_core(struct bcm
- /* Some specific cores don't need wrappers */
- switch (core->id.id) {
- case BCMA_CORE_4706_MAC_GBIT_COMMON:
-+ case BCMA_CORE_NS_CHIPCOMMON_B:
- /* Not used yet: case BCMA_CORE_OOB_ROUTER: */
- break;
- default:
---- a/include/linux/bcma/bcma.h
-+++ b/include/linux/bcma/bcma.h
-@@ -338,6 +338,7 @@ struct bcma_bus {
- u8 num;
-
- struct bcma_drv_cc drv_cc;
-+ struct bcma_drv_cc_b drv_cc_b;
- struct bcma_drv_pci drv_pci[2];
- struct bcma_drv_pcie2 drv_pcie2;
- struct bcma_drv_mips drv_mips;
---- a/include/linux/bcma/bcma_driver_chipcommon.h
-+++ b/include/linux/bcma/bcma_driver_chipcommon.h
-@@ -644,6 +644,12 @@ struct bcma_drv_cc {
- #endif
- };
-
-+struct bcma_drv_cc_b {
-+ struct bcma_device *core;
-+ u8 setup_done:1;
-+ void __iomem *mii;
-+};
-+
- /* Register access */
- #define bcma_cc_read32(cc, offset) \
- bcma_read32((cc)->core, offset)
-@@ -699,4 +705,6 @@ extern void bcma_pmu_spuravoid_pllupdate
-
- extern u32 bcma_pmu_get_bus_clock(struct bcma_drv_cc *cc);
-
-+void bcma_chipco_b_mii_write(struct bcma_drv_cc_b *ccb, u32 offset, u32 value);
-+
- #endif /* LINUX_BCMA_DRIVER_CC_H_ */
diff --git a/target/linux/bcm53xx/patches-3.14/150-pci-do-not-probe-too-early.patch b/target/linux/bcm53xx/patches-3.14/150-pci-do-not-probe-too-early.patch
deleted file mode 100644
index 23e8a02..0000000
--- a/target/linux/bcm53xx/patches-3.14/150-pci-do-not-probe-too-early.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From ea422113a5d2778347db6136d95f45a50e2f2d29 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Thu, 29 May 2014 20:54:15 +0200
-Subject: [PATCH 13/15] pci: do not probe too early
-
-Probing is done before the PCIe bridge is fully activated and the
-address spaces does not get assigned to the PCIe devices. Without the
-address space the driver can not register to this device. With this
-patch the driver reregistration is done later.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/pci/probe.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
---- a/drivers/pci/probe.c
-+++ b/drivers/pci/probe.c
-@@ -1912,7 +1912,10 @@ struct pci_bus *pci_scan_root_bus(struct
- if (!found)
- pci_bus_update_busn_res_end(b, max);
-
-- pci_bus_add_devices(b);
-+ /* this should be done in arch/arm/kernel/bios32.c, because the
-+ resources for the PCI devices are initilized later and doing
-+ it here will fail. */
-+ /* pci_bus_add_devices(b); */
- return b;
- }
- EXPORT_SYMBOL(pci_scan_root_bus);
diff --git a/target/linux/bcm53xx/patches-3.14/160-bcma-add-PCI-IDs-for-more-devices.patch b/target/linux/bcm53xx/patches-3.14/160-bcma-add-PCI-IDs-for-more-devices.patch
deleted file mode 100644
index 83b72b4..0000000
--- a/target/linux/bcm53xx/patches-3.14/160-bcma-add-PCI-IDs-for-more-devices.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From a0d83e0ad20f6dde0a71ed07da12ca3be8bbdc01 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Sun, 18 May 2014 17:15:24 +0200
-Subject: [PATCH 12/15] bcma: add PCI IDs for more devices
-
-This adds the PCI IDs for the BCM4360 and BCM43227.
-Both devices were found on a Netgear R6250 with a BCM4708 ARM SoC.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/bcma/host_pci.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/bcma/host_pci.c
-+++ b/drivers/bcma/host_pci.c
-@@ -282,6 +282,7 @@ static const struct pci_device_id bcma_p
- { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) },
- { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) },
- { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
-+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43227) },
- { 0, },
- };
- MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl);
diff --git a/target/linux/bcm53xx/patches-3.14/170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch b/target/linux/bcm53xx/patches-3.14/170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch
deleted file mode 100644
index 4e32ed8..0000000
--- a/target/linux/bcm53xx/patches-3.14/170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch
+++ /dev/null
@@ -1,645 +0,0 @@
-From 7475eee716d11f487076f78f26a6e403c06d0c76 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 14/15] pcie2-bcma: add new PCIe2 driver for bcma
-
-This driver supports the PCIe controller found on the BCM4708 and
-similar SoCs. The controller itself is automatically detected by bcma.
-
-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/pcie2-bcma.c | 594 ++++++++++++++++++++++++++++++++++++++++++
- 4 files changed, 603 insertions(+)
- create mode 100644 drivers/pci/host/pcie2-bcma.c
-
---- a/arch/arm/mach-bcm/Kconfig
-+++ b/arch/arm/mach-bcm/Kconfig
-@@ -45,6 +45,7 @@ config ARCH_BCM_5301X
- select ARM_GLOBAL_TIMER
- select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
- select MIGHT_HAVE_PCI
-+ 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
-@@ -33,4 +33,11 @@ config PCI_RCAR_GEN2
- There are 3 internal PCI controllers available with a single
- built-in EHCI/OHCI host controller present on each one.
-
-+config PCI_BCMA
-+ bool "BCMA PCIe2 host controller"
-+ depends on BCMA && OF
-+ help
-+ Say Y here if you want to support a simple generic PCI host
-+ controller, such as the one emulated by kvmtool.
-+
- endmenu
---- a/drivers/pci/host/Makefile
-+++ b/drivers/pci/host/Makefile
-@@ -4,3 +4,4 @@ obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
- obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
- obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
- obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
-+obj-$(CONFIG_PCI_BCMA) += pcie2-bcma.o
---- /dev/null
-+++ b/drivers/pci/host/pcie2-bcma.c
-@@ -0,0 +1,594 @@
-+/*
-+ * 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.
-+ *
-+ * TODO:
-+ * MSI interrupts,
-+ * DRAM > 128 MBytes (e.g. DMA zones)
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/bug.h>
-+#include <linux/delay.h>
-+#include <linux/pci.h>
-+#include <linux/io.h>
-+#include <linux/ioport.h>
-+#include <linux/interrupt.h>
-+#include <linux/bcma/bcma.h>
-+
-+#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */
-+
-+/*
-+ * Register offset definitions
-+ */
-+#define SOC_PCIE_CONTROL 0x000 /* a.k.a. CLK_CONTROL reg */
-+#define SOC_PCIE_PM_STATUS 0x008
-+#define SOC_PCIE_PM_CONTROL 0x00c /* in EP mode only ! */
-+
-+#define SOC_PCIE_EXT_CFG_ADDR 0x120
-+#define SOC_PCIE_EXT_CFG_DATA 0x124
-+#define SOC_PCIE_CFG_ADDR 0x1f8
-+#define SOC_PCIE_CFG_DATA 0x1fc
-+
-+#define SOC_PCIE_SYS_RC_INTX_EN 0x330
-+#define SOC_PCIE_SYS_RC_INTX_CSR 0x334
-+#define SOC_PCIE_SYS_HOST_INTR_EN 0x344
-+#define SOC_PCIE_SYS_HOST_INTR_CSR 0x348
-+
-+#define SOC_PCIE_HDR_OFF 0x400 /* 256 bytes per function */
-+
-+/* 32-bit 4KB in-bound mapping windows for Function 0..3, n=0..7 */
-+#define SOC_PCIE_SYS_IMAP0(f, n) (0xc00 + ((f) << 9)((n) << 2))
-+/* 64-bit in-bound mapping windows for func 0..3 */
-+#define SOC_PCIE_SYS_IMAP1(f) (0xc80 + ((f) << 3))
-+#define SOC_PCIE_SYS_IMAP2(f) (0xcc0 + ((f) << 3))
-+/* 64-bit in-bound address range n=0..2 */
-+#define SOC_PCIE_SYS_IARR(n) (0xd00 + ((n) << 3))
-+/* 64-bit out-bound address filter n=0..2 */
-+#define SOC_PCIE_SYS_OARR(n) (0xd20 + ((n) << 3))
-+/* 64-bit out-bound mapping windows n=0..2 */
-+#define SOC_PCIE_SYS_OMAP(n) (0xd40 + ((n) << 3))
-+
-+#define BCM4360_D11AC_ID 0x43a0
-+#define BCM4360_D11AC2G_ID 0x43a1
-+#define BCM4360_D11AC5G_ID 0x43a2
-+#define BCM4352_D11AC_ID 0x43b1 /* 4352 802.11ac dualband device */
-+#define BCM4352_D11AC2G_ID 0x43b2 /* 4352 802.11ac 2.4G device */
-+#define BCM4352_D11AC5G_ID 0x43b3 /* 4352 802.11ac 5G device */
-+
-+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 bdev->irq;
-+}
-+
-+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, SOC_PCIE_EXT_CFG_ADDR, where & 0xffc);
-+ return SOC_PCIE_EXT_CFG_DATA;
-+ } else {
-+ if (fn > 1)
-+ return 0;
-+ addr_reg = (busno & 0xff) << 20 | (slot << 15) | (fn << 12) |
-+ (where & 0xffc) | (1 & 0x3);
-+
-+ bcma_write32(bdev, SOC_PCIE_CFG_ADDR, addr_reg);
-+ return SOC_PCIE_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;
-+
-+ base = bcma_pcie2_cfg_base(bdev, busno, devfn, where);
-+
-+ if (!base)
-+ return ~0UL;
-+
-+ data_reg = bcma_read32(bdev, base);
-+
-+ /* NS: CLASS field is R/O, and set to wrong 0x200 value */
-+ if (busno == 0 && devfn == 0) {
-+ /*
-+ * RC's class is 0x0280, but Linux PCI driver needs 0x604
-+ * for a PCIe bridge. So we must fixup the class code
-+ * to 0x604 here.
-+ */
-+ if ((where & 0xffc) == PCI_CLASS_REVISION) {
-+ data_reg &= 0xff;
-+ data_reg |= 0x604 << 16;
-+ }
-+ }
-+ /* HEADER_TYPE=00 indicates the port in EP mode */
-+
-+ if (size == 4) {
-+ return data_reg;
-+ } else {
-+ u32 mask = (1 << (size * 8)) - 1;
-+ int 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 u8 bcma_pcie2_read_config8(struct bcma_device *bdev, int busno,
-+ unsigned int devfn, int where)
-+{
-+ return bcma_pcie2_read_config(bdev, busno, devfn, where, 1);
-+}
-+
-+static u16 bcma_pcie2_read_config16(struct bcma_device *bdev, int busno,
-+ unsigned int devfn, int where)
-+{
-+ return bcma_pcie2_read_config(bdev, busno, devfn, where, 2);
-+}
-+
-+static u32 bcma_pcie2_read_config32(struct bcma_device *bdev, int busno,
-+ unsigned int devfn, int where)
-+{
-+ return bcma_pcie2_read_config(bdev, busno, devfn, where, 4);
-+}
-+
-+static void bcma_pcie2_write_config8(struct bcma_device *bdev, int busno,
-+ unsigned int devfn, int where, u8 val)
-+{
-+ return bcma_pcie2_write_config(bdev, busno, devfn, where, 1, val);
-+}
-+
-+static void bcma_pcie2_write_config16(struct bcma_device *bdev, int busno,
-+ unsigned int devfn, int where, u16 val)
-+{
-+ return bcma_pcie2_write_config(bdev, busno, devfn, where, 2, val);
-+}
-+
-+static void bcma_pcie2_write_config32(struct bcma_device *bdev, int busno,
-+ unsigned int devfn, int where, u32 val)
-+{
-+ return bcma_pcie2_write_config(bdev, busno, devfn, where, 4, val);
-+}
-+
-+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;
-+}
-+
-+/*
-+ * 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, u32 allow_gen2)
-+{
-+ u32 devfn = 0;
-+ u8 tmp8;
-+ u32 tmp32;
-+
-+ tmp32 = bcma_pcie2_read_config32(bdev, 0, devfn, 0xdc);
-+ tmp32 &= ~0xf;
-+ if (allow_gen2)
-+ tmp32 |= 2;
-+ else {
-+ /* force PCIE GEN1 */
-+ tmp32 |= 1;
-+ }
-+ bcma_pcie2_write_config32(bdev, 0, devfn, 0xdc, tmp32);
-+
-+ /* See if the port is in EP mode, indicated by header type 00 */
-+ tmp8 = bcma_pcie2_read_config8(bdev, 0, devfn, PCI_HEADER_TYPE);
-+ if (tmp8 != PCI_HEADER_TYPE_BRIDGE) {
-+ dev_info(&bdev->dev, "Port %d in End-Point mode - ignored\n",
-+ bdev->core_unit);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+/*
-+ * Initializte the PCIe controller
-+ */
-+static void bcma_pcie2_hw_init(struct bcma_device *bdev)
-+{
-+ u32 devfn = 0;
-+ u32 tmp32;
-+ u16 tmp16;
-+
-+ /* Change MPS and MRRS to 512 */
-+ tmp16 = bcma_pcie2_read_config16(bdev, 0, devfn, 0x4d4);
-+ tmp16 &= ~7;
-+ tmp16 |= 2;
-+ bcma_pcie2_write_config16(bdev, 0, devfn, 0x4d4, tmp16);
-+
-+ tmp32 = bcma_pcie2_read_config32(bdev, 0, devfn, 0xb4);
-+ tmp32 &= ~((7 << 12) | (7 << 5));
-+ tmp32 |= (2 << 12) | (2 << 5);
-+ bcma_pcie2_write_config32(bdev, 0, devfn, 0xb4, tmp32);
-+
-+ /* Turn-on Root-Complex (RC) mode, from reset defailt 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, SOC_PCIE_CONTROL, 0x3);
-+ udelay(250);
-+ bcma_write32(bdev, SOC_PCIE_CONTROL, 0x1);
-+ mdelay(250);
-+
-+ /* TBD: take care of PM, check we're on */
-+}
-+
-+/*
-+ * Setup the address translation
-+ */
-+static void bcma_pcie2_map_init(struct bcma_device *bdev)
-+{
-+ unsigned size, i;
-+ u32 addr;
-+
-+ /*
-+ * NOTE:
-+ * All PCI-to-CPU address mapping are 1:1 for simplicity
-+ */
-+
-+ /* Outbound address translation setup */
-+ size = SZ_128M;
-+ addr = bdev->addr_s[0];
-+ BUG_ON(!addr);
-+ BUG_ON(addr & ((1 << 25) - 1)); /* 64MB alignment */
-+
-+ for (i = 0; i < 3; i++) {
-+ const unsigned win_size = SZ_64M;
-+ /* 64-bit LE regs, write low word, high is 0 at reset */
-+ bcma_write32(bdev, SOC_PCIE_SYS_OMAP(i), addr);
-+ bcma_write32(bdev, SOC_PCIE_SYS_OARR(i), addr|0x1);
-+ addr += win_size;
-+ if (size >= win_size)
-+ size -= win_size;
-+ if (size == 0)
-+ break;
-+ }
-+ WARN_ON(size > 0);
-+
-+ /*
-+ * 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
-+ */
-+ size = SZ_128M;
-+ addr = PHYS_OFFSET;
-+
-+ size >>= 20; /* In MB */
-+ size &= 0xff; /* Size is an 8-bit field */
-+
-+ WARN_ON(size == 0);
-+ /* 64-bit LE regs, write low word, high is 0 at reset */
-+ bcma_write32(bdev, SOC_PCIE_SYS_IMAP1(0), addr | 0x1);
-+ bcma_write32(bdev, SOC_PCIE_SYS_IARR(1), addr | size);
-+
-+#ifdef CONFIG_SPARSEMEM
-+ addr = PHYS_OFFSET2;
-+ bcma_write32(bdev, SOC_PCIE_SYS_IMAP2(0), addr | 0x1);
-+ bcma_write32(bdev, SOC_PCIE_SYS_IARR(2), addr | size);
-+#endif
-+}
-+
-+/*
-+ * Setup PCIE Host bridge
-+ */
-+static void bcma_pcie2_bridge_init(struct bcma_device *bdev)
-+{
-+ u32 devfn = 0;
-+ u8 tmp8;
-+ u16 tmp16;
-+
-+ bcma_pcie2_write_config8(bdev, 0, devfn, PCI_PRIMARY_BUS, 0);
-+ bcma_pcie2_write_config8(bdev, 0, devfn, PCI_SECONDARY_BUS, 1);
-+ bcma_pcie2_write_config8(bdev, 0, devfn, PCI_SUBORDINATE_BUS, 4);
-+
-+ tmp8 = bcma_pcie2_read_config8(bdev, 0, devfn, PCI_PRIMARY_BUS);
-+ tmp8 = bcma_pcie2_read_config8(bdev, 0, devfn, PCI_SECONDARY_BUS);
-+ tmp8 = bcma_pcie2_read_config8(bdev, 0, devfn, PCI_SUBORDINATE_BUS);
-+
-+ /* MEM_BASE, MEM_LIM require 1MB alignment */
-+ BUG_ON((bdev->addr_s[0] >> 16) & 0xf);
-+ bcma_pcie2_write_config16(bdev, 0, devfn, PCI_MEMORY_BASE,
-+ bdev->addr_s[0] >> 16);
-+ BUG_ON(((bdev->addr_s[0] + SZ_128M) >> 16) & 0xf);
-+ bcma_pcie2_write_config16(bdev, 0, devfn, PCI_MEMORY_LIMIT,
-+ (bdev->addr_s[0] + SZ_128M) >> 16);
-+
-+ /* These registers are not supported on the NS */
-+ bcma_pcie2_write_config16(bdev, 0, devfn, PCI_IO_BASE_UPPER16, 0);
-+ bcma_pcie2_write_config16(bdev, 0, devfn, PCI_IO_LIMIT_UPPER16, 0);
-+
-+ /* Force class to that of a Bridge */
-+ bcma_pcie2_write_config16(bdev, 0, devfn, PCI_CLASS_DEVICE,
-+ PCI_CLASS_BRIDGE_PCI);
-+
-+ tmp16 = bcma_pcie2_read_config16(bdev, 0, devfn, PCI_CLASS_DEVICE);
-+ tmp16 = bcma_pcie2_read_config16(bdev, 0, devfn, PCI_MEMORY_BASE);
-+ tmp16 = bcma_pcie2_read_config16(bdev, 0, devfn, PCI_MEMORY_LIMIT);
-+}
-+
-+static int bcma_pcie2_allow_gen2_rc(struct bcma_device *bdev)
-+{
-+ u32 vendorid, devid, chipid, chiprev;
-+ u32 val, bar;
-+ void __iomem *base;
-+ int allow = 1;
-+
-+ /* Read PCI vendor/device ID's */
-+ bcma_write32(bdev, SOC_PCIE_CFG_ADDR, 0x0);
-+ val = bcma_read32(bdev, SOC_PCIE_CFG_DATA);
-+ vendorid = val & 0xffff;
-+ devid = val >> 16;
-+ if (vendorid == PCI_VENDOR_ID_BROADCOM &&
-+ (devid == BCMA_CHIP_ID_BCM4360 || devid == BCM4360_D11AC_ID ||
-+ devid == BCM4360_D11AC2G_ID || devid == BCM4360_D11AC5G_ID ||
-+ devid == BCM4352_D11AC_ID || devid == BCM4352_D11AC2G_ID ||
-+ devid == BCM4352_D11AC5G_ID)) {
-+ /* Config BAR0 */
-+ bar = bdev->addr_s[0];
-+ bcma_write32(bdev, SOC_PCIE_CFG_ADDR, 0x10);
-+ bcma_write32(bdev, SOC_PCIE_CFG_DATA, bar);
-+ /* Config BAR0 window to access chipc */
-+ bcma_write32(bdev, SOC_PCIE_CFG_ADDR, 0x80);
-+ bcma_write32(bdev, SOC_PCIE_CFG_DATA, SI_ENUM_BASE);
-+
-+ /* Enable memory resource */
-+ bcma_write32(bdev, SOC_PCIE_CFG_ADDR, 0x4);
-+ val = bcma_read32(bdev, SOC_PCIE_CFG_DATA);
-+ val |= PCI_COMMAND_MEMORY;
-+ bcma_write32(bdev, SOC_PCIE_CFG_DATA, val);
-+ /* Enable memory and bus master */
-+ bcma_write32(bdev, SOC_PCIE_HDR_OFF + 4, 0x6);
-+
-+ /* Read CHIP ID */
-+ base = ioremap(bar, 0x1000);
-+ val = __raw_readl(base);
-+ iounmap(base);
-+ chipid = val & 0xffff;
-+ chiprev = (val >> 16) & 0xf;
-+ if ((chipid == BCMA_CHIP_ID_BCM4360 ||
-+ chipid == BCMA_CHIP_ID_BCM43460 ||
-+ chipid == BCMA_CHIP_ID_BCM4352) && (chiprev < 3))
-+ allow = 0;
-+ }
-+ return allow;
-+}
-+
-+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 allow_gen2, linkfail;
-+ 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) {
-+ dev_info(&bdev->dev, "requesting resource at 0x%x failed\n",
-+ bdev->addr_s[0]);
-+ return -EINVAL;
-+ }
-+ res->start = bdev->addr_s[0];
-+ res->end = res->start + SZ_128M - 1;
-+ res->name = "PCIe Configuration 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) {
-+ dev_info(&bdev->dev, "requesting resource at 0x%x failed\n",
-+ bdev->addr_s[0]);
-+ return -EINVAL;
-+ }
-+ res->start = bdev->addr_s[0];
-+ res->end = res->start + SZ_128M - 1;
-+ res->name = "PCIe Configuration Space";
-+ res->flags = IORESOURCE_IO;
-+
-+ pci_add_resource(&sys->resources, res);
-+
-+ for (allow_gen2 = 0; allow_gen2 <= 1; allow_gen2++) {
-+ bcma_pcie2_hw_init(bdev);
-+ bcma_pcie2_map_init(bdev);
-+
-+ /*
-+ * Skip inactive ports -
-+ * will need to change this for hot-plugging
-+ */
-+ linkfail = bcma_pcie2_check_link(bdev, allow_gen2);
-+ if (linkfail)
-+ break;
-+
-+ bcma_pcie2_bridge_init(bdev);
-+
-+ if (allow_gen2 == 0) {
-+ if (bcma_pcie2_allow_gen2_rc(bdev) == 0)
-+ break;
-+ dev_info(&bdev->dev, "switching to GEN2\n");
-+ }
-+ }
-+
-+ if (linkfail)
-+ return -1;
-+
-+ return 1;
-+}
-+
-+/*
-+ * Methods for accessing configuration registers
-+ */
-+static struct pci_ops bcma_pcie2_ops = {
-+ .read = bcma_pcie2_read_config_pci,
-+ .write = bcma_pcie2_write_config_pci,
-+};
-+
-+static int bcma_pcie2_probe(struct bcma_device *bdev)
-+{
-+ struct hw_pci hw;
-+
-+ dev_info(&bdev->dev, "scanning bus\n");
-+
-+ hw = (struct hw_pci) {
-+ .nr_controllers = 1,
-+ .domain = bdev->core_unit,
-+ .private_data = (void **)&bdev,
-+ .setup = bcma_pcie2_setup,
-+ .map_irq = bcma_pcie2_map_irq,
-+ .ops = &bcma_pcie2_ops,
-+ };
-+
-+ /* Announce this port to ARM/PCI common code */
-+ pci_common_init_dev(&bdev->dev, &hw);
-+
-+ /* Setup virtual-wire interrupts */
-+ bcma_write32(bdev, SOC_PCIE_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),
-+ BCMA_CORETABLE_END
-+};
-+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("PCIe Gen2 driver for BCMA");
-+MODULE_LICENSE("GPLv2");
diff --git a/target/linux/bcm53xx/patches-3.14/180-spi-bcm53xx-driver-for-SPI-controller-on-Broadcom-bc.patch b/target/linux/bcm53xx/patches-3.14/180-spi-bcm53xx-driver-for-SPI-controller-on-Broadcom-bc.patch
deleted file mode 100644
index f79e729..0000000
--- a/target/linux/bcm53xx/patches-3.14/180-spi-bcm53xx-driver-for-SPI-controller-on-Broadcom-bc.patch
+++ /dev/null
@@ -1,435 +0,0 @@
-From a59f3fa1dd4cb284171a53cb7a614ad947c544f6 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Wed, 13 Aug 2014 14:11:39 +0200
-Subject: [PATCH V2] spi: bcm53xx: driver for SPI controller on Broadcom bcma
- SoC
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Broadcom 53xx ARM SoCs use bcma bus that contains various cores (AKA
-devices). If board has a serial flash, it's connected over SPI and the
-bcma bus includes a SPI controller. Example log from such a board:
-bus0: Found chip with id 53010, rev 0x00 and package 0x02
-(...)
-bus0: Core 18 found: SPI flash controller (manuf 0x4BF, id 0x50A, rev 0x01, class 0x0)
-
-This patch adds a bcma driver for SPI core, it registers SPI master
-controller and "bcm53xxspiflash" SPI device.
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
-Since RFC: Add Signed-off-by
- Update to compile on top of for-next
-V2: Use wait timeout
- Describe bcm53xxspi_calc_timeout a bit
- Use devm_spi_register_master
-
-Thanks Mark for your comments!
----
- drivers/spi/Kconfig | 6 +
- drivers/spi/Makefile | 1 +
- drivers/spi/spi-bcm53xx.c | 295 ++++++++++++++++++++++++++++++++++++++++++++++
- drivers/spi/spi-bcm53xx.h | 72 +++++++++++
- 4 files changed, 374 insertions(+)
- create mode 100644 drivers/spi/spi-bcm53xx.c
- create mode 100644 drivers/spi/spi-bcm53xx.h
-
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -112,6 +112,12 @@ config SPI_AU1550
- If you say yes to this option, support will be included for the
- PSC SPI controller found on Au1550, Au1200 and Au1300 series.
-
-+config SPI_BCM53XX
-+ tristate "Broadcom BCM53xx SPI controller"
-+ depends on ARCH_BCM_5301X
-+ help
-+ Enable support for the SPI controller on Broadcom BCM53xx ARM SoCs.
-+
- config SPI_BCM63XX
- tristate "Broadcom BCM63xx SPI controller"
- depends on BCM63XX
---- a/drivers/spi/Makefile
-+++ b/drivers/spi/Makefile
-@@ -15,6 +15,7 @@ obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o
- obj-$(CONFIG_SPI_ATH79) += spi-ath79.o
- obj-$(CONFIG_SPI_AU1550) += spi-au1550.o
- obj-$(CONFIG_SPI_BCM2835) += spi-bcm2835.o
-+obj-$(CONFIG_SPI_BCM53XX) += spi-bcm53xx.o
- obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o
- obj-$(CONFIG_SPI_BCM63XX_HSSPI) += spi-bcm63xx-hsspi.o
- obj-$(CONFIG_SPI_BFIN5XX) += spi-bfin5xx.o
---- /dev/null
-+++ b/drivers/spi/spi-bcm53xx.c
-@@ -0,0 +1,295 @@
-+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/delay.h>
-+#include <linux/bcma/bcma.h>
-+#include <linux/spi/spi.h>
-+
-+#include "spi-bcm53xx.h"
-+
-+#define BCM53XXSPI_MAX_SPI_BAUD 13500000 /* 216 MHz? */
-+
-+/* The longest observed required wait was 19 ms */
-+#define BCM53XXSPI_SPE_TIMEOUT_MS 80
-+
-+struct bcm53xxspi {
-+ struct bcma_device *core;
-+ struct spi_master *master;
-+
-+ size_t read_offset;
-+};
-+
-+static inline u32 bcm53xxspi_read(struct bcm53xxspi *b53spi, u16 offset)
-+{
-+ return bcma_read32(b53spi->core, offset);
-+}
-+
-+static inline void bcm53xxspi_write(struct bcm53xxspi *b53spi, u16 offset,
-+ u32 value)
-+{
-+ bcma_write32(b53spi->core, offset, value);
-+}
-+
-+static inline unsigned int bcm53xxspi_calc_timeout(size_t len)
-+{
-+ /* Do some magic calculation based on length and buad. Add 10% and 1. */
-+ return (len * 9000 / BCM53XXSPI_MAX_SPI_BAUD * 110 / 100) + 1;
-+}
-+
-+static int bcm53xxspi_wait(struct bcm53xxspi *b53spi, unsigned int timeout_ms)
-+{
-+ unsigned long deadline;
-+ u32 tmp;
-+
-+ /* SPE bit has to be 0 before we read MSPI STATUS */
-+ deadline = jiffies + BCM53XXSPI_SPE_TIMEOUT_MS * HZ / 1000;
-+ do {
-+ tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_SPCR2);
-+ if (!(tmp & B53SPI_MSPI_SPCR2_SPE))
-+ break;
-+ udelay(5);
-+ } while (!time_after_eq(jiffies, deadline));
-+
-+ if (tmp & B53SPI_MSPI_SPCR2_SPE)
-+ goto spi_timeout;
-+
-+ /* Check status */
-+ deadline = jiffies + timeout_ms * HZ / 1000;
-+ do {
-+ tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_MSPI_STATUS);
-+ if (tmp & B53SPI_MSPI_MSPI_STATUS_SPIF) {
-+ bcm53xxspi_write(b53spi, B53SPI_MSPI_MSPI_STATUS, 0);
-+ return 0;
-+ }
-+
-+ cpu_relax();
-+ udelay(100);
-+ } while (!time_after_eq(jiffies, deadline));
-+
-+spi_timeout:
-+ bcm53xxspi_write(b53spi, B53SPI_MSPI_MSPI_STATUS, 0);
-+
-+ pr_err("Timeout waiting for SPI to be ready!\n");
-+
-+ return -EBUSY;
-+}
-+
-+static void bcm53xxspi_buf_write(struct bcm53xxspi *b53spi, u8 *w_buf,
-+ size_t len, bool cont)
-+{
-+ u32 tmp;
-+ int i;
-+
-+ for (i = 0; i < len; i++) {
-+ /* Transmit Register File MSB */
-+ bcm53xxspi_write(b53spi, B53SPI_MSPI_TXRAM + 4 * (i * 2),
-+ (unsigned int)w_buf[i]);
-+ }
-+
-+ for (i = 0; i < len; i++) {
-+ tmp = B53SPI_CDRAM_CONT | B53SPI_CDRAM_PCS_DISABLE_ALL |
-+ B53SPI_CDRAM_PCS_DSCK;
-+ if (!cont && i == len - 1)
-+ tmp &= ~B53SPI_CDRAM_CONT;
-+ tmp &= ~0x1;
-+ /* Command Register File */
-+ bcm53xxspi_write(b53spi, B53SPI_MSPI_CDRAM + 4 * i, tmp);
-+ }
-+
-+ /* Set queue pointers */
-+ bcm53xxspi_write(b53spi, B53SPI_MSPI_NEWQP, 0);
-+ bcm53xxspi_write(b53spi, B53SPI_MSPI_ENDQP, len - 1);
-+
-+ if (cont)
-+ bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 1);
-+
-+ /* Start SPI transfer */
-+ tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_SPCR2);
-+ tmp |= B53SPI_MSPI_SPCR2_SPE;
-+ if (cont)
-+ tmp |= B53SPI_MSPI_SPCR2_CONT_AFTER_CMD;
-+ bcm53xxspi_write(b53spi, B53SPI_MSPI_SPCR2, tmp);
-+
-+ /* Wait for SPI to finish */
-+ bcm53xxspi_wait(b53spi, bcm53xxspi_calc_timeout(len));
-+
-+ if (!cont)
-+ bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 0);
-+
-+ b53spi->read_offset = len;
-+}
-+
-+static void bcm53xxspi_buf_read(struct bcm53xxspi *b53spi, u8 *r_buf,
-+ size_t len, bool cont)
-+{
-+ u32 tmp;
-+ int i;
-+
-+ for (i = 0; i < b53spi->read_offset + len; i++) {
-+ tmp = B53SPI_CDRAM_CONT | B53SPI_CDRAM_PCS_DISABLE_ALL |
-+ B53SPI_CDRAM_PCS_DSCK;
-+ if (!cont && i == b53spi->read_offset + len - 1)
-+ tmp &= ~B53SPI_CDRAM_CONT;
-+ tmp &= ~0x1;
-+ /* Command Register File */
-+ bcm53xxspi_write(b53spi, B53SPI_MSPI_CDRAM + 4 * i, tmp);
-+ }
-+
-+ /* Set queue pointers */
-+ bcm53xxspi_write(b53spi, B53SPI_MSPI_NEWQP, 0);
-+ bcm53xxspi_write(b53spi, B53SPI_MSPI_ENDQP,
-+ b53spi->read_offset + len - 1);
-+
-+ if (cont)
-+ bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 1);
-+
-+ /* Start SPI transfer */
-+ tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_SPCR2);
-+ tmp |= B53SPI_MSPI_SPCR2_SPE;
-+ if (cont)
-+ tmp |= B53SPI_MSPI_SPCR2_CONT_AFTER_CMD;
-+ bcm53xxspi_write(b53spi, B53SPI_MSPI_SPCR2, tmp);
-+
-+ /* Wait for SPI to finish */
-+ bcm53xxspi_wait(b53spi, bcm53xxspi_calc_timeout(len));
-+
-+ if (!cont)
-+ bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 0);
-+
-+ for (i = 0; i < len; ++i) {
-+ int offset = b53spi->read_offset + i;
-+
-+ /* Data stored in the transmit register file LSB */
-+ r_buf[i] = (u8)bcm53xxspi_read(b53spi, B53SPI_MSPI_RXRAM + 4 * (1 + offset * 2));
-+ }
-+
-+ b53spi->read_offset = 0;
-+}
-+
-+static int bcm53xxspi_transfer_one(struct spi_master *master,
-+ struct spi_device *spi,
-+ struct spi_transfer *t)
-+{
-+ struct bcm53xxspi *b53spi = spi_master_get_devdata(master);
-+ u8 *buf;
-+ size_t left;
-+
-+ if (t->tx_buf) {
-+ buf = (u8 *)t->tx_buf;
-+ left = t->len;
-+ while (left) {
-+ size_t to_write = min_t(size_t, 16, left);
-+ bool cont = left - to_write > 0;
-+
-+ bcm53xxspi_buf_write(b53spi, buf, to_write, cont);
-+ left -= to_write;
-+ buf += to_write;
-+ }
-+ }
-+
-+ if (t->rx_buf) {
-+ buf = (u8 *)t->rx_buf;
-+ left = t->len;
-+ while (left) {
-+ size_t to_read = min_t(size_t, 16 - b53spi->read_offset,
-+ left);
-+ bool cont = left - to_read > 0;
-+
-+ bcm53xxspi_buf_read(b53spi, buf, to_read, cont);
-+ left -= to_read;
-+ buf += to_read;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+/**************************************************
-+ * BCMA
-+ **************************************************/
-+
-+struct spi_board_info bcm53xx_info = {
-+ .modalias = "bcm53xxspiflash",
-+};
-+
-+static const struct bcma_device_id bcm53xxspi_bcma_tbl[] = {
-+ BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_QSPI, BCMA_ANY_REV, BCMA_ANY_CLASS),
-+ BCMA_CORETABLE_END
-+};
-+MODULE_DEVICE_TABLE(bcma, bcm53xxspi_bcma_tbl);
-+
-+static int bcm53xxspi_bcma_probe(struct bcma_device *core)
-+{
-+ struct bcm53xxspi *b53spi;
-+ struct spi_master *master;
-+ int err;
-+
-+ if (core->bus->drv_cc.core->id.rev != 42) {
-+ pr_err("SPI on SoC with unsupported ChipCommon rev\n");
-+ return -ENOTSUPP;
-+ }
-+
-+ master = spi_alloc_master(&core->dev, sizeof(*b53spi));
-+ if (!master)
-+ return -ENOMEM;
-+
-+ b53spi = spi_master_get_devdata(master);
-+ b53spi->master = master;
-+ b53spi->core = core;
-+
-+ master->transfer_one = bcm53xxspi_transfer_one;
-+
-+ bcma_set_drvdata(core, b53spi);
-+
-+ err = devm_spi_register_master(&core->dev, master);
-+ if (err) {
-+ spi_master_put(master);
-+ bcma_set_drvdata(core, NULL);
-+ goto out;
-+ }
-+
-+ /* Broadcom SoCs (at least with the CC rev 42) use SPI for flash only */
-+ spi_new_device(master, &bcm53xx_info);
-+
-+out:
-+ return err;
-+}
-+
-+static void bcm53xxspi_bcma_remove(struct bcma_device *core)
-+{
-+ struct bcm53xxspi *b53spi = bcma_get_drvdata(core);
-+
-+ spi_unregister_master(b53spi->master);
-+}
-+
-+static struct bcma_driver bcm53xxspi_bcma_driver = {
-+ .name = KBUILD_MODNAME,
-+ .id_table = bcm53xxspi_bcma_tbl,
-+ .probe = bcm53xxspi_bcma_probe,
-+ .remove = bcm53xxspi_bcma_remove,
-+};
-+
-+/**************************************************
-+ * Init & exit
-+ **************************************************/
-+
-+static int __init bcm53xxspi_module_init(void)
-+{
-+ int err = 0;
-+
-+ err = bcma_driver_register(&bcm53xxspi_bcma_driver);
-+ if (err)
-+ pr_err("Failed to register bcma driver: %d\n", err);
-+
-+ return err;
-+}
-+
-+static void __exit bcm53xxspi_module_exit(void)
-+{
-+ bcma_driver_unregister(&bcm53xxspi_bcma_driver);
-+}
-+
-+module_init(bcm53xxspi_module_init);
-+module_exit(bcm53xxspi_module_exit);
---- /dev/null
-+++ b/drivers/spi/spi-bcm53xx.h
-@@ -0,0 +1,72 @@
-+#ifndef SPI_BCM53XX_H
-+#define SPI_BCM53XX_H
-+
-+#define B53SPI_BSPI_REVISION_ID 0x000
-+#define B53SPI_BSPI_SCRATCH 0x004
-+#define B53SPI_BSPI_MAST_N_BOOT_CTRL 0x008
-+#define B53SPI_BSPI_BUSY_STATUS 0x00c
-+#define B53SPI_BSPI_INTR_STATUS 0x010
-+#define B53SPI_BSPI_B0_STATUS 0x014
-+#define B53SPI_BSPI_B0_CTRL 0x018
-+#define B53SPI_BSPI_B1_STATUS 0x01c
-+#define B53SPI_BSPI_B1_CTRL 0x020
-+#define B53SPI_BSPI_STRAP_OVERRIDE_CTRL 0x024
-+#define B53SPI_BSPI_FLEX_MODE_ENABLE 0x028
-+#define B53SPI_BSPI_BITS_PER_CYCLE 0x02c
-+#define B53SPI_BSPI_BITS_PER_PHASE 0x030
-+#define B53SPI_BSPI_CMD_AND_MODE_BYTE 0x034
-+#define B53SPI_BSPI_BSPI_FLASH_UPPER_ADDR_BYTE 0x038
-+#define B53SPI_BSPI_BSPI_XOR_VALUE 0x03c
-+#define B53SPI_BSPI_BSPI_XOR_ENABLE 0x040
-+#define B53SPI_BSPI_BSPI_PIO_MODE_ENABLE 0x044
-+#define B53SPI_BSPI_BSPI_PIO_IODIR 0x048
-+#define B53SPI_BSPI_BSPI_PIO_DATA 0x04c
-+
-+/* RAF */
-+#define B53SPI_RAF_START_ADDR 0x100
-+#define B53SPI_RAF_NUM_WORDS 0x104
-+#define B53SPI_RAF_CTRL 0x108
-+#define B53SPI_RAF_FULLNESS 0x10c
-+#define B53SPI_RAF_WATERMARK 0x110
-+#define B53SPI_RAF_STATUS 0x114
-+#define B53SPI_RAF_READ_DATA 0x118
-+#define B53SPI_RAF_WORD_CNT 0x11c
-+#define B53SPI_RAF_CURR_ADDR 0x120
-+
-+/* MSPI */
-+#define B53SPI_MSPI_SPCR0_LSB 0x200
-+#define B53SPI_MSPI_SPCR0_MSB 0x204
-+#define B53SPI_MSPI_SPCR1_LSB 0x208
-+#define B53SPI_MSPI_SPCR1_MSB 0x20c
-+#define B53SPI_MSPI_NEWQP 0x210
-+#define B53SPI_MSPI_ENDQP 0x214
-+#define B53SPI_MSPI_SPCR2 0x218
-+#define B53SPI_MSPI_SPCR2_SPE 0x00000040
-+#define B53SPI_MSPI_SPCR2_CONT_AFTER_CMD 0x00000080
-+#define B53SPI_MSPI_MSPI_STATUS 0x220
-+#define B53SPI_MSPI_MSPI_STATUS_SPIF 0x00000001
-+#define B53SPI_MSPI_CPTQP 0x224
-+#define B53SPI_MSPI_TXRAM 0x240 /* 32 registers, up to 0x2b8 */
-+#define B53SPI_MSPI_RXRAM 0x2c0 /* 32 registers, up to 0x33c */
-+#define B53SPI_MSPI_CDRAM 0x340 /* 16 registers, up to 0x37c */
-+#define B53SPI_CDRAM_PCS_PCS0 0x00000001
-+#define B53SPI_CDRAM_PCS_PCS1 0x00000002
-+#define B53SPI_CDRAM_PCS_PCS2 0x00000004
-+#define B53SPI_CDRAM_PCS_PCS3 0x00000008
-+#define B53SPI_CDRAM_PCS_DISABLE_ALL 0x0000000f
-+#define B53SPI_CDRAM_PCS_DSCK 0x00000010
-+#define B53SPI_CDRAM_BITSE 0x00000040
-+#define B53SPI_CDRAM_CONT 0x00000080
-+#define B53SPI_MSPI_WRITE_LOCK 0x380
-+#define B53SPI_MSPI_DISABLE_FLUSH_GEN 0x384
-+
-+/* Interrupt */
-+#define B53SPI_INTR_RAF_LR_FULLNESS_REACHED 0x3a0
-+#define B53SPI_INTR_RAF_LR_TRUNCATED 0x3a4
-+#define B53SPI_INTR_RAF_LR_IMPATIENT 0x3a8
-+#define B53SPI_INTR_RAF_LR_SESSION_DONE 0x3ac
-+#define B53SPI_INTR_RAF_LR_OVERREAD 0x3b0
-+#define B53SPI_INTR_MSPI_DONE 0x3b4
-+#define B53SPI_INTR_MSPI_HALT_SET_TRANSACTION_DONE 0x3b8
-+
-+#endif /* SPI_BCM53XX_H */
diff --git a/target/linux/bcm53xx/patches-3.14/900-bgmac-some-fixes-to-get-bgmac-work.patch b/target/linux/bcm53xx/patches-3.14/900-bgmac-some-fixes-to-get-bgmac-work.patch
deleted file mode 100644
index caf2f33..0000000
--- a/target/linux/bcm53xx/patches-3.14/900-bgmac-some-fixes-to-get-bgmac-work.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 0bd576e93a188fd3aab769b622fb3d35fa9bc7a7 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Sat, 3 May 2014 19:55:38 +0200
-Subject: [PATCH 15/15] bgmac: some fixes to get bgmac work
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/net/ethernet/broadcom/Kconfig | 2 +-
- drivers/net/phy/phy_device.c | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/broadcom/Kconfig
-+++ b/drivers/net/ethernet/broadcom/Kconfig
-@@ -131,7 +131,7 @@ config BNX2X_SRIOV
-
- config BGMAC
- tristate "BCMA bus GBit core support"
-- depends on BCMA_HOST_SOC && HAS_DMA && BCM47XX
-+ depends on BCMA_HOST_SOC && HAS_DMA
- select PHYLIB
- ---help---
- This driver supports GBit MAC and BCM4706 GBit MAC cores on BCMA bus.
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -898,7 +898,7 @@ int genphy_update_link(struct phy_device
- return status;
-
- if ((status & BMSR_LSTATUS) == 0)
-- phydev->link = 0;
-+ phydev->link = 1;
- else
- phydev->link = 1;
-
diff --git a/target/linux/bcm53xx/profiles/100-Generic.mk b/target/linux/bcm53xx/profiles/100-Generic.mk
deleted file mode 100644
index ce5a826..0000000
--- a/target/linux/bcm53xx/profiles/100-Generic.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Copyright (C) 2013 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-define Profile/Generic
- NAME:=Broadcom SoC, BCM43xx WiFi (b43, default)
- PACKAGES:=kmod-b43
-endef
-
-define Profile/Generic/Description
- Package set compatible with hardware any Broadcom BCM47xx or BCM535x
- SoC with a ARM CPU like the BCM4707, BCM4708, BCM4709, BCM53010
-endef
-
-$(eval $(call Profile,Generic))
-