diff --git a/target/linux/mvebu/config-4.1 b/target/linux/mvebu/config-4.1
new file mode 100644
index 0000000..6739c51
--- /dev/null
+++ b/target/linux/mvebu/config-4.1
@@ -0,0 +1,368 @@
+CONFIG_ALIGNMENT_TRAP=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
+CONFIG_ARCH_HAS_SG_CHAIN=y
+CONFIG_ARCH_HAS_TICK_BROADCAST=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MULTIPLATFORM=y
+# CONFIG_ARCH_MULTI_CPU_AUTO is not set
+CONFIG_ARCH_MULTI_V6_V7=y
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARCH_MVEBU=y
+CONFIG_ARCH_NR_GPIO=0
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
+CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
+CONFIG_ARCH_SUPPORTS_UPROBES=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_USE_BUILTIN_BSWAP=y
+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_ARM=y
+CONFIG_ARMADA_370_CLK=y
+CONFIG_ARMADA_370_XP_TIMER=y
+CONFIG_ARMADA_38X_CLK=y
+CONFIG_ARMADA_XP_CLK=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set
+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y
+# CONFIG_ARM_CPUIDLE is not set
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARM_CRYPTO=y
+CONFIG_ARM_ERRATA_720789=y
+CONFIG_ARM_GIC=y
+CONFIG_ARM_HAS_SG_CHAIN=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+# CONFIG_ARM_LPAE is not set
+CONFIG_ARM_MVEBU_V7_CPUIDLE=y
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y
+CONFIG_ATAGS=y
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_BOUNCE=y
+# CONFIG_CACHE_FEROCEON_L2 is not set
+CONFIG_CACHE_L2X0=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLKSRC_OF=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_COMMON_CLK=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+# 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_FREQ=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_GOV_COMMON=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_HAS_ASID=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_PJ4B=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_RMAP=y
+# CONFIG_CPU_THERMAL is not set
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_V7=y
+CONFIG_CRC16=y
+CONFIG_CRYPTO_AES_ARM=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA1_ARM=y
+CONFIG_CRYPTO_SHA256_ARM=y
+CONFIG_CRYPTO_XZ=y
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_INCLUDE="debug/8250.S"
+CONFIG_DEBUG_MVEBU_UART0=y
+# CONFIG_DEBUG_MVEBU_UART0_ALTERNATE is not set
+# CONFIG_DEBUG_MVEBU_UART1_ALTERNATE is not set
+CONFIG_DEBUG_UART_8250=y
+# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set
+CONFIG_DEBUG_UART_8250_SHIFT=2
+# CONFIG_DEBUG_UART_8250_WORD is not set
+CONFIG_DEBUG_UART_PHYS=0xd0012000
+CONFIG_DEBUG_UART_VIRT=0xfec12000
+CONFIG_DEBUG_UNCOMPRESS=y
+CONFIG_DEBUG_USER=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_ENGINE_RAID=y
+CONFIG_DMA_OF=y
+CONFIG_DTC=y
+# CONFIG_DW_DMAC_PCI is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_FIXED_PHY=y
+CONFIG_FRAME_POINTER=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IO=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_MSI_IRQ=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_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_GPIO_MVEBU=y
+CONFIG_GPIO_MVEBU_PWM=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_ARCH_AUDITSYSCALL=y
+CONFIG_HAVE_ARCH_BITREVERSE=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_ARM_SCU=y
+CONFIG_HAVE_ARM_TWD=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_HAVE_BPF_JIT=y
+CONFIG_HAVE_CC_STACKPROTECTOR=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_CLK_PREPARE=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_HAVE_IDE=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZ4=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_HAVE_NET_DSA=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_OPTPROBES=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_HAVE_PERF_REGS=y
+CONFIG_HAVE_PERF_USER_STACK_DUMP=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_SMP=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_UID16=y
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
+CONFIG_HIGHMEM=y
+# CONFIG_HIGHPTE is not set
+# CONFIG_HSU_DMA_PCI is not set
+CONFIG_HZ_FIXED=0
+CONFIG_HZ_PERIODIC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IOMMU_HELPER=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+# CONFIG_IWMMXT is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MACH_ARMADA_370=y
+# CONFIG_MACH_ARMADA_375 is not set
+CONFIG_MACH_ARMADA_38X=y
+# CONFIG_MACH_ARMADA_39X is not set
+CONFIG_MACH_ARMADA_XP=y
+# CONFIG_MACH_DOVE is not set
+CONFIG_MACH_MVEBU_ANY=y
+CONFIG_MACH_MVEBU_V7=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MANGLE_BOOTARGS=y
+CONFIG_MARVELL_PHY=y
+CONFIG_MDIO_BOARDINFO=y
+CONFIG_MEMORY=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_MIGHT_HAVE_PCI=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ECC=y
+CONFIG_MTD_NAND_PXA3xx=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+CONFIG_MTD_UBI_BLOCK=y
+# CONFIG_MTD_UBI_FASTMAP is not set
+# CONFIG_MTD_UBI_GLUEBI is not set
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UIMAGE_SPLIT=y
+CONFIG_MULTI_IRQ_HANDLER=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_MVEBU_CLK_COMMON=y
+CONFIG_MVEBU_CLK_COREDIV=y
+CONFIG_MVEBU_CLK_CPU=y
+CONFIG_MVEBU_DEVBUS=y
+CONFIG_MVEBU_MBUS=y
+CONFIG_MVMDIO=y
+CONFIG_MVNETA=y
+CONFIG_MVSW61XX_PHY=y
+CONFIG_MV_XOR=y
+CONFIG_NEED_DMA_MAP_STATE=y
+# CONFIG_NEON is not set
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_NO_BOOTMEM=y
+CONFIG_NR_CPUS=4
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_ADDRESS_PCI=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_MTD=y
+CONFIG_OF_NET=y
+CONFIG_OF_PCI=y
+CONFIG_OF_PCI_IRQ=y
+CONFIG_OF_RESERVED_MEM=y
+CONFIG_OLD_SIGACTION=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PCI=y
+# CONFIG_PCIE_IPROC is not set
+# CONFIG_PCI_DOMAINS_GENERIC is not set
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MVEBU=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_ARMADA_370=y
+CONFIG_PINCTRL_ARMADA_38X=y
+CONFIG_PINCTRL_ARMADA_XP=y
+CONFIG_PINCTRL_MVEBU=y
+# CONFIG_PINCTRL_SINGLE is not set
+CONFIG_PJ4B_ERRATA_4742=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_PLAT_ORION=y
+CONFIG_PM_OPP=y
+CONFIG_PWM=y
+CONFIG_PWM_SYSFS=y
+CONFIG_RCU_STALL_COMMON=y
+CONFIG_REGMAP=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+# CONFIG_REGULATOR_GPIO is not set
+# CONFIG_REGULATOR_PWM is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_DRV_MV is not set
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_SCHED_HRTICK=y
+# CONFIG_SCSI_DMA is not set
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_SOC_BUS=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_ORION=y
+CONFIG_SRCU=y
+CONFIG_STOP_MACHINE=y
+CONFIG_SWCONFIG=y
+CONFIG_SWIOTLB=y
+CONFIG_SWP_EMULATE=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_STATS=y
+CONFIG_TREE_RCU=y
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_XZ=y
+CONFIG_UBIFS_FS_ZLIB=y
+CONFIG_UID16=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_USB_PHY=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USE_OF=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_XPS=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_BCJ=y
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZONE_DMA_FLAG=0
diff --git a/target/linux/mvebu/patches-4.1/002-add_mamba_powertables.patch b/target/linux/mvebu/patches-4.1/002-add_mamba_powertables.patch
new file mode 100644
index 0000000..d6e5f37
--- /dev/null
+++ b/target/linux/mvebu/patches-4.1/002-add_mamba_powertables.patch
@@ -0,0 +1,105 @@
+Index: linux-4.1.6/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+===================================================================
+--- linux-4.1.6.orig/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
++++ linux-4.1.6/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+@@ -84,12 +84,100 @@
+ 			pcie@2,0 {
+ 				/* Port 0, Lane 1 */
+ 				status = "okay";
++
++				mwlwifi {
++					marvell,5ghz = <0>;
++					marvell,chainmask = <4 4>;
++					marvell,powertable {
++						FCC =
++							<1 0 0x17 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>,
++							<2 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
++							<3 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
++							<4 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
++							<5 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
++							<6 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
++							<7 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
++							<8 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
++							<9 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
++							<10 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
++							<11 0 0x17 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>;
++
++						ETSI =
++							<1 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++							<2 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++							<3 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++							<4 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++							<5 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++							<6 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++							<7 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++							<8 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++							<9 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++							<10 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++							<11 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++							<12 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++							<13 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>;
++					};
++				};
+ 			};
+ 
+ 			/* Second mini-PCIe port */
+ 			pcie@3,0 {
+ 				/* Port 0, Lane 3 */
+ 				status = "okay";
++
++				mwlwifi {
++					marvell,2ghz = <0>;
++					marvell,chainmask = <4 4>;
++					marvell,powertable {
++						FCC =
++							<36 0 0x8 0x8 0x8 0x8 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
++							<40 0 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
++							<44 0 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
++							<48 0 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
++							<52 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>,
++							<56 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>,
++							<60 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>,
++							<64 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>,
++							<100 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++							<104 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++							<108 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++							<112 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++							<116 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++							<120 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++							<124 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++							<128 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++							<132 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++							<136 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++							<140 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++							<149 0 0x16 0x16 0x16 0x16 0x14 0x14 0x14 0x14 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>,
++							<153 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>,
++							<157 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>,
++							<161 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>,
++							<165 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>;
++
++						ETSI =
++							<36 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++							<40 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++							<44 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++							<48 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++							<52 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++							<56 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++							<60 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++							<64 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++							<100 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++							<104 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++							<108 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++							<112 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++							<116 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++							<120 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++							<124 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++							<128 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++							<132 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++							<136 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++							<140 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++							<149 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>;
++					};
++				};
+ 			};
+ 		};
+ 
diff --git a/target/linux/mvebu/patches-4.1/003-add_mamba_switch.patch b/target/linux/mvebu/patches-4.1/003-add_mamba_switch.patch
new file mode 100644
index 0000000..2dc395e
--- /dev/null
+++ b/target/linux/mvebu/patches-4.1/003-add_mamba_switch.patch
@@ -0,0 +1,21 @@
+Index: linux-4.1.6/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+===================================================================
+--- linux-4.1.6.orig/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
++++ linux-4.1.6/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+@@ -465,6 +465,16 @@
+ 			};
+ 		};
+ 	};
++
++	mvsw61xx {
++		compatible = "marvell,88e6172";
++		status = "okay";
++		reg = <0x10>;
++
++		mii-bus = <&mdio>;
++		cpu-port-0 = <5>;
++		cpu-port-1 = <6>;
++	};
+ };
+ 
+ &pinctrl {
diff --git a/target/linux/mvebu/patches-4.1/005-build_linksys_a385_dts.patch b/target/linux/mvebu/patches-4.1/005-build_linksys_a385_dts.patch
new file mode 100644
index 0000000..7ef323e
--- /dev/null
+++ b/target/linux/mvebu/patches-4.1/005-build_linksys_a385_dts.patch
@@ -0,0 +1,13 @@
+Index: linux-4.1.6/arch/arm/boot/dts/Makefile
+===================================================================
+--- linux-4.1.6.orig/arch/arm/boot/dts/Makefile
++++ linux-4.1.6/arch/arm/boot/dts/Makefile
+@@ -633,6 +633,8 @@ dtb-$(CONFIG_MACH_ARMADA_375) += \
+ 	armada-375-db.dtb
+ dtb-$(CONFIG_MACH_ARMADA_38X) += \
+ 	armada-385-db-ap.dtb \
++	armada-385-linksys-caiman.dtb \
++	armada-385-linksys-cobra.dtb \
+ 	armada-388-db.dtb \
+ 	armada-388-gp.dtb \
+ 	armada-388-rd.dtb
diff --git a/target/linux/mvebu/patches-4.1/022-ARM-mvebu-A385-AP-Enable-the-NAND-controller.patch b/target/linux/mvebu/patches-4.1/022-ARM-mvebu-A385-AP-Enable-the-NAND-controller.patch
new file mode 100644
index 0000000..e2ee99c
--- /dev/null
+++ b/target/linux/mvebu/patches-4.1/022-ARM-mvebu-A385-AP-Enable-the-NAND-controller.patch
@@ -0,0 +1,36 @@
+From 7eb1f09ec8e25aa2fc3f6fc5fc9405d9f917d503 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Thu, 11 Dec 2014 14:14:58 +0100
+Subject: [PATCH 1/2] ARM: mvebu: A385-AP: Enable the NAND controller
+
+The A385 AP has a 1GB NAND chip. Enable it.
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ arch/arm/boot/dts/armada-385-db-ap.dts | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+Index: linux-4.1.6/arch/arm/boot/dts/armada-385-db-ap.dts
+===================================================================
+--- linux-4.1.6.orig/arch/arm/boot/dts/armada-385-db-ap.dts
++++ linux-4.1.6/arch/arm/boot/dts/armada-385-db-ap.dts
+@@ -174,6 +174,19 @@
+ 				status = "okay";
+ 				usb-phy = <&usb3_phy>;
+ 			};
++
++			nfc: flash@d0000 {
++				status = "okay";
++				#address-cells = <1>;
++				#size-cells = <1>;
++
++				num-cs = <1>;
++				nand-ecc-strength = <4>;
++				nand-ecc-step-size = <512>;
++				marvell,nand-keep-config;
++				marvell,nand-enable-arbiter;
++				nand-on-flash-bbt;
++			};
+ 		};
+ 
+ 		pcie-controller {
diff --git a/target/linux/mvebu/patches-4.1/050-leds_tlc59116_document_binding.patch b/target/linux/mvebu/patches-4.1/050-leds_tlc59116_document_binding.patch
new file mode 100644
index 0000000..0505d61
--- /dev/null
+++ b/target/linux/mvebu/patches-4.1/050-leds_tlc59116_document_binding.patch
@@ -0,0 +1,53 @@
+Document the binding for the TLC59116 LED driver.
+
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+---
+ .../devicetree/bindings/leds/leds-tlc59116.txt     | 40 ++++++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/leds/leds-tlc59116.txt
+
+Index: linux-4.1.6/Documentation/devicetree/bindings/leds/leds-tlc59116.txt
+===================================================================
+--- /dev/null
++++ linux-4.1.6/Documentation/devicetree/bindings/leds/leds-tlc59116.txt
+@@ -0,0 +1,40 @@
++LEDs connected to tcl59116
++
++Required properties
++- compatible: should be "ti,tlc59116"
++- #address-cells: must be 1
++- #size-cells: must be 0
++- reg: typically 0x68
++
++Each led is represented as a sub-node of the ti,,tlc59116.
++See Documentation/devicetree/bindings/leds/common.txt
++
++LED sub-node properties:
++- reg: number of LED line, 0 to 15
++- label: (optional) name of LED
++- linux,default-trigger : (optional)
++
++Examples:
++
++tlc59116@68 {
++	#address-cells = <1>;
++	#size-cells = <0>;
++	compatible = "ti,tlc59116";
++	reg = <0x68>;
++
++	wan@0 {
++		label = "wrt1900ac:amber:wan";
++		reg = <0x0>;
++	};
++
++	2g@2 {
++		label = "wrt1900ac:white:2g";
++		reg = <0x2>;
++	};
++
++	alive@9 {
++		label = "wrt1900ac:green:alive";
++		reg = <0x9>;
++		linux,default_trigger = "heartbeat";
++	};
++};
diff --git a/target/linux/mvebu/patches-4.1/051-leds_tlc59116_add_driver.patch b/target/linux/mvebu/patches-4.1/051-leds_tlc59116_add_driver.patch
new file mode 100644
index 0000000..e1b6ae9
--- /dev/null
+++ b/target/linux/mvebu/patches-4.1/051-leds_tlc59116_add_driver.patch
@@ -0,0 +1,303 @@
+The TLC59116 is an I2C bus controlled 16-channel LED driver.  Each LED
+output has its own 8-bit fixed-frequency PWM controller to control the
+brightness of the LED.
+
+This is based on a driver from Belkin, but has been extensively
+rewritten.
+
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+---
+ drivers/leds/Kconfig         |   8 ++
+ drivers/leds/Makefile        |   1 +
+ drivers/leds/leds-tlc59116.c | 252 +++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 261 insertions(+)
+ create mode 100644 drivers/leds/leds-tlc59116.c
+
+Index: linux-4.1.6/drivers/leds/Kconfig
+===================================================================
+--- linux-4.1.6.orig/drivers/leds/Kconfig
++++ linux-4.1.6/drivers/leds/Kconfig
+@@ -467,6 +467,14 @@ config LEDS_TCA6507
+ 	  LED driver chips accessed via the I2C bus.
+ 	  Driver support brightness control and hardware-assisted blinking.
+ 
++config LEDS_TLC59116
++	tristate "LED driver for TLC59116F controllers"
++	depends on LEDS_CLASS && I2C
++	select REGMAP_I2C
++	help
++	  This option enables support for Texas Instruments TLC59116F
++	  LED controller.
++
+ config LEDS_MAX8997
+ 	tristate "LED support for MAX8997 PMIC"
+ 	depends on LEDS_CLASS && MFD_MAX8997
+Index: linux-4.1.6/drivers/leds/Makefile
+===================================================================
+--- linux-4.1.6.orig/drivers/leds/Makefile
++++ linux-4.1.6/drivers/leds/Makefile
+@@ -31,6 +31,7 @@ obj-$(CONFIG_LEDS_LP8501)		+= leds-lp850
+ obj-$(CONFIG_LEDS_LP8788)		+= leds-lp8788.o
+ obj-$(CONFIG_LEDS_LP8860)		+= leds-lp8860.o
+ obj-$(CONFIG_LEDS_TCA6507)		+= leds-tca6507.o
++obj-$(CONFIG_LEDS_TLC59116)		+= leds-tlc59116.o
+ obj-$(CONFIG_LEDS_CLEVO_MAIL)		+= leds-clevo-mail.o
+ obj-$(CONFIG_LEDS_IPAQ_MICRO)		+= leds-ipaq-micro.o
+ obj-$(CONFIG_LEDS_HP6XX)		+= leds-hp6xx.o
+Index: linux-4.1.6/drivers/leds/leds-tlc59116.c
+===================================================================
+--- /dev/null
++++ linux-4.1.6/drivers/leds/leds-tlc59116.c
+@@ -0,0 +1,252 @@
++/*
++ * Copyright 2014 Belkin Inc.
++ * Copyright 2014 Andrew Lunn <andrew@lunn.ch>
++ *
++ * 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; version 2 of the License.
++ */
++
++#include <linux/i2c.h>
++#include <linux/leds.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/regmap.h>
++#include <linux/slab.h>
++#include <linux/workqueue.h>
++
++#define TLC59116_LEDS		16
++
++#define TLC59116_REG_MODE1	0x00
++#define MODE1_RESPON_ADDR_MASK	0xF0
++#define MODE1_NORMAL_MODE	(0 << 4)
++#define MODE1_SPEED_MODE	(1 << 4)
++
++#define TLC59116_REG_MODE2	0x01
++#define MODE2_DIM		(0 << 5)
++#define MODE2_BLINK		(1 << 5)
++#define MODE2_OCH_STOP		(0 << 3)
++#define MODE2_OCH_ACK		(1 << 3)
++
++#define TLC59116_REG_PWM(x)	(0x02 + (x))
++
++#define TLC59116_REG_GRPPWM	0x12
++#define TLC59116_REG_GRPFREQ	0x13
++
++/* LED Driver Output State, determine the source that drives LED outputs */
++#define TLC59116_REG_LEDOUT(x)	(0x14 + ((x) >> 2))
++#define TLC59116_LED_OFF	0x0	/* Output LOW */
++#define TLC59116_LED_ON		0x1	/* Output HI-Z */
++#define TLC59116_DIM		0x2	/* Dimming */
++#define TLC59116_BLINK		0x3	/* Blinking */
++#define LED_MASK		0x3
++
++#define ldev_to_led(c)		container_of(c, struct tlc59116_led, ldev)
++#define work_to_led(work)	container_of(work, struct tlc59116_led, work)
++
++struct tlc59116_led {
++	bool active;
++	struct regmap *regmap;
++	unsigned int led_no;
++	struct led_classdev ldev;
++	struct work_struct work;
++};
++
++struct tlc59116_priv {
++	struct tlc59116_led leds[TLC59116_LEDS];
++};
++
++static int
++tlc59116_set_mode(struct regmap *regmap, u8 mode)
++{
++	int err;
++	u8 val;
++
++	if ((mode != MODE2_DIM) && (mode != MODE2_BLINK))
++		mode = MODE2_DIM;
++
++	/* Configure MODE1 register */
++	err = regmap_write(regmap, TLC59116_REG_MODE1, MODE1_NORMAL_MODE);
++	if (err)
++		return err;
++
++	/* Configure MODE2 Reg */
++	val = MODE2_OCH_STOP | mode;
++
++	return regmap_write(regmap, TLC59116_REG_MODE2, val);
++}
++
++static int
++tlc59116_set_led(struct tlc59116_led *led, u8 val)
++{
++	struct regmap *regmap = led->regmap;
++	unsigned int i = (led->led_no % 4) * 2;
++	unsigned int addr = TLC59116_REG_LEDOUT(led->led_no);
++	unsigned int mask = LED_MASK << i;
++
++	val = val << i;
++
++	return regmap_update_bits(regmap, addr, mask, val);
++}
++
++static void
++tlc59116_led_work(struct work_struct *work)
++{
++	struct tlc59116_led *led = work_to_led(work);
++	struct regmap *regmap = led->regmap;
++	int err;
++	u8 pwm;
++
++	pwm = TLC59116_REG_PWM(led->led_no);
++	err = regmap_write(regmap, pwm, led->ldev.brightness);
++	if (err)
++		dev_err(led->ldev.dev, "Failed setting brightness\n");
++}
++
++static void
++tlc59116_led_set(struct led_classdev *led_cdev, enum led_brightness value)
++{
++	struct tlc59116_led *led = ldev_to_led(led_cdev);
++
++	led->ldev.brightness = value;
++	schedule_work(&led->work);
++}
++
++static void
++tlc59116_destroy_devices(struct tlc59116_priv *priv, unsigned int i)
++{
++	while (--i >= 0) {
++		if (priv->leds[i].active) {
++			led_classdev_unregister(&priv->leds[i].ldev);
++			cancel_work_sync(&priv->leds[i].work);
++		}
++	}
++}
++
++static int
++tlc59116_configure(struct device *dev,
++		   struct tlc59116_priv *priv,
++		   struct regmap *regmap)
++{
++	unsigned int i;
++	int err = 0;
++
++	tlc59116_set_mode(regmap, MODE2_DIM);
++	for (i = 0; i < TLC59116_LEDS; i++) {
++		struct tlc59116_led *led = &priv->leds[i];
++
++		if (!led->active)
++			continue;
++
++		led->regmap = regmap;
++		led->led_no = i;
++		led->ldev.brightness_set = tlc59116_led_set;
++		led->ldev.max_brightness = LED_FULL;
++		INIT_WORK(&led->work, tlc59116_led_work);
++		err = led_classdev_register(dev, &led->ldev);
++		if (err < 0) {
++			dev_err(dev, "couldn't register LED %s\n",
++				led->ldev.name);
++			goto exit;
++		}
++		tlc59116_set_led(led, TLC59116_DIM);
++	}
++
++	return 0;
++
++exit:
++	tlc59116_destroy_devices(priv, i);
++	return err;
++}
++
++static const struct regmap_config tlc59116_regmap = {
++	.reg_bits = 8,
++	.val_bits = 8,
++	.max_register = 0x1e,
++};
++
++static int
++tlc59116_probe(struct i2c_client *client,
++	       const struct i2c_device_id *id)
++{
++	struct tlc59116_priv *priv = i2c_get_clientdata(client);
++	struct device *dev = &client->dev;
++	struct device_node *np = client->dev.of_node, *child;
++	struct regmap *regmap;
++	int err, count, reg;
++
++	count = of_get_child_count(np);
++	if (!count || count > TLC59116_LEDS)
++		return -EINVAL;
++
++	if (!i2c_check_functionality(client->adapter,
++		I2C_FUNC_SMBUS_BYTE_DATA))
++		return -EIO;
++
++	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
++	if (!priv)
++		return -ENOMEM;
++
++	regmap = devm_regmap_init_i2c(client, &tlc59116_regmap);
++	if (IS_ERR(regmap)) {
++		err = PTR_ERR(regmap);
++		dev_err(dev, "Failed to allocate register map: %d\n", err);
++		return err;
++	}
++
++	i2c_set_clientdata(client, priv);
++
++	for_each_child_of_node(np, child) {
++		err = of_property_read_u32(child, "reg", &reg);
++		if (err)
++			return err;
++		if (reg < 0 || reg >= TLC59116_LEDS)
++			return -EINVAL;
++		if (priv->leds[reg].active)
++			return -EINVAL;
++		priv->leds[reg].active = true;
++		priv->leds[reg].ldev.name =
++			of_get_property(child, "label", NULL) ? : child->name;
++		priv->leds[reg].ldev.default_trigger =
++			of_get_property(child, "linux,default-trigger", NULL);
++	}
++	return tlc59116_configure(dev, priv, regmap);
++}
++
++static int
++tlc59116_remove(struct i2c_client *client)
++{
++	struct tlc59116_priv *priv = i2c_get_clientdata(client);
++
++	tlc59116_destroy_devices(priv, TLC59116_LEDS);
++
++	return 0;
++}
++
++static const struct of_device_id of_tlc59116_leds_match[] = {
++	{ .compatible = "ti,tlc59116", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, of_tlc59116_leds_match);
++
++static const struct i2c_device_id tlc59116_id[] = {
++	{ "tlc59116" },
++	{},
++};
++MODULE_DEVICE_TABLE(i2c, tlc59116_id);
++
++static struct i2c_driver tlc59116_driver = {
++	.driver = {
++		.name = "tlc59116",
++		.of_match_table = of_match_ptr(of_tlc59116_leds_match),
++	},
++	.probe = tlc59116_probe,
++	.remove = tlc59116_remove,
++	.id_table = tlc59116_id,
++};
++
++module_i2c_driver(tlc59116_driver);
++
++MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>");
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("TLC59116 LED driver");
diff --git a/target/linux/mvebu/patches-4.1/100-find_active_root.patch b/target/linux/mvebu/patches-4.1/100-find_active_root.patch
new file mode 100644
index 0000000..77afdb0
--- /dev/null
+++ b/target/linux/mvebu/patches-4.1/100-find_active_root.patch
@@ -0,0 +1,63 @@
+The WRT1900AC among other Linksys routers uses a dual-firmware layout.
+Dynamically rename the active partition to "ubi".
+
+Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
+
+Index: linux-4.1.6/drivers/mtd/ofpart.c
+===================================================================
+--- linux-4.1.6.orig/drivers/mtd/ofpart.c
++++ linux-4.1.6/drivers/mtd/ofpart.c
+@@ -25,12 +25,15 @@ static bool node_has_compatible(struct d
+ 	return of_get_property(pp, "compatible", NULL);
+ }
+ 
++static int mangled_rootblock;
++
+ static int parse_ofpart_partitions(struct mtd_info *master,
+ 				   struct mtd_partition **pparts,
+ 				   struct mtd_part_parser_data *data)
+ {
+ 	struct device_node *node;
+ 	const char *partname;
++	const char *owrtpart = "ubi";
+ 	struct device_node *pp;
+ 	int nr_parts, i;
+ 
+@@ -78,9 +81,15 @@ static int parse_ofpart_partitions(struc
+ 		(*pparts)[i].offset = of_read_number(reg, a_cells);
+ 		(*pparts)[i].size = of_read_number(reg + a_cells, s_cells);
+ 
+-		partname = of_get_property(pp, "label", &len);
+-		if (!partname)
+-			partname = of_get_property(pp, "name", &len);
++		if (mangled_rootblock && (i == mangled_rootblock)) {
++				partname = owrtpart;
++		} else {
++			partname = of_get_property(pp, "label", &len);
++
++			if (!partname)
++				partname = of_get_property(pp, "name", &len);
++		}
++
+ 		(*pparts)[i].name = partname;
+ 
+ 		if (of_get_property(pp, "read-only", &len))
+@@ -178,6 +187,18 @@ static int __init ofpart_parser_init(voi
+ 	return 0;
+ }
+ 
++static int __init active_root(char *str)
++{
++	get_option(&str, &mangled_rootblock);
++
++	if (!mangled_rootblock)
++		return 1;
++
++	return 1;
++}
++
++__setup("mangled_rootblock=", active_root);
++
+ static void __exit ofpart_parser_exit(void)
+ {
+ 	deregister_mtd_parser(&ofpart_parser);
diff --git a/target/linux/mvebu/patches-4.1/102-revert_i2c_delay.patch b/target/linux/mvebu/patches-4.1/102-revert_i2c_delay.patch
new file mode 100644
index 0000000..eb6924e
--- /dev/null
+++ b/target/linux/mvebu/patches-4.1/102-revert_i2c_delay.patch
@@ -0,0 +1,17 @@
+Index: linux-4.1.6/arch/arm/boot/dts/armada-xp.dtsi
+===================================================================
+--- linux-4.1.6.orig/arch/arm/boot/dts/armada-xp.dtsi
++++ linux-4.1.6/arch/arm/boot/dts/armada-xp.dtsi
+@@ -90,12 +90,10 @@
+ 			};
+ 
+ 			i2c0: i2c@11000 {
+-				compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
+ 				reg = <0x11000 0x100>;
+ 			};
+ 
+ 			i2c1: i2c@11100 {
+-				compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
+ 				reg = <0x11100 0x100>;
+ 			};
+ 
diff --git a/target/linux/mvebu/patches-4.1/202-gpio_mvebu_add_limited_pwm_support.patch b/target/linux/mvebu/patches-4.1/202-gpio_mvebu_add_limited_pwm_support.patch
new file mode 100644
index 0000000..02c2816
--- /dev/null
+++ b/target/linux/mvebu/patches-4.1/202-gpio_mvebu_add_limited_pwm_support.patch
@@ -0,0 +1,443 @@
+Armada 370/XP devices can 'blink' gpio lines with a configurable on
+and off period. This can be modelled as a PWM.
+
+However, there are only two sets of PWM configuration registers for
+all the gpio lines. This driver simply allows a single gpio line per
+gpio chip of 32 lines to be used as a PWM. Attempts to use more return
+EBUSY.
+
+Due to the interleaving of registers it is not simple to separate the
+PWM driver from the gpio driver. Thus the gpio driver has been
+extended with a PWM driver.
+
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+---
+ drivers/gpio/Kconfig          |   5 ++
+ drivers/gpio/Makefile         |   1 +
+ drivers/gpio/gpio-mvebu-pwm.c | 202 ++++++++++++++++++++++++++++++++++++++++++
+ drivers/gpio/gpio-mvebu.c     |  37 +++-----
+ drivers/gpio/gpio-mvebu.h     |  79 +++++++++++++++++
+ 5 files changed, 299 insertions(+), 25 deletions(-)
+ create mode 100644 drivers/gpio/gpio-mvebu-pwm.c
+ create mode 100644 drivers/gpio/gpio-mvebu.h
+
+Index: linux-4.1.6/drivers/gpio/Kconfig
+===================================================================
+--- linux-4.1.6.orig/drivers/gpio/Kconfig
++++ linux-4.1.6/drivers/gpio/Kconfig
+@@ -287,6 +287,11 @@ config GPIO_MVEBU
+ 	select GPIO_GENERIC
+ 	select GENERIC_IRQ_CHIP
+ 
++config GPIO_MVEBU_PWM
++	def_bool y
++	depends on GPIO_MVEBU
++	depends on PWM
++
+ config GPIO_MXC
+ 	def_bool y
+ 	depends on ARCH_MXC
+Index: linux-4.1.6/drivers/gpio/Makefile
+===================================================================
+--- linux-4.1.6.orig/drivers/gpio/Makefile
++++ linux-4.1.6/drivers/gpio/Makefile
+@@ -62,6 +62,7 @@ obj-$(CONFIG_GPIO_MPC8XXX)	+= gpio-mpc8x
+ obj-$(CONFIG_GPIO_MSIC)		+= gpio-msic.o
+ obj-$(CONFIG_GPIO_MSM_V2)	+= gpio-msm-v2.o
+ obj-$(CONFIG_GPIO_MVEBU)        += gpio-mvebu.o
++obj-$(CONFIG_GPIO_MVEBU_PWM)	+= gpio-mvebu-pwm.o
+ obj-$(CONFIG_GPIO_MXC)		+= gpio-mxc.o
+ obj-$(CONFIG_GPIO_MXS)		+= gpio-mxs.o
+ obj-$(CONFIG_GPIO_OCTEON)	+= gpio-octeon.o
+Index: linux-4.1.6/drivers/gpio/gpio-mvebu-pwm.c
+===================================================================
+--- /dev/null
++++ linux-4.1.6/drivers/gpio/gpio-mvebu-pwm.c
+@@ -0,0 +1,202 @@
++#include <linux/err.h>
++#include <linux/module.h>
++#include <linux/gpio.h>
++#include <linux/pwm.h>
++#include <linux/clk.h>
++#include <linux/platform_device.h>
++#include "gpio-mvebu.h"
++#include "gpiolib.h"
++
++static void __iomem *mvebu_gpioreg_blink_select(struct mvebu_gpio_chip *mvchip)
++{
++	return mvchip->membase + GPIO_BLINK_CNT_SELECT;
++}
++
++static inline struct mvebu_pwm *to_mvebu_pwm(struct pwm_chip *chip)
++{
++	return container_of(chip, struct mvebu_pwm, chip);
++}
++
++static inline struct mvebu_gpio_chip *to_mvchip(struct mvebu_pwm *pwm)
++{
++	return container_of(pwm, struct mvebu_gpio_chip, pwm);
++}
++
++static int mvebu_pwm_request(struct pwm_chip *chip, struct pwm_device *pwmd)
++{
++	struct mvebu_pwm *pwm = to_mvebu_pwm(chip);
++	struct mvebu_gpio_chip *mvchip = to_mvchip(pwm);
++	struct gpio_desc *desc = gpio_to_desc(pwmd->pwm);
++	unsigned long flags;
++	int ret = 0;
++
++	spin_lock_irqsave(&pwm->lock, flags);
++	if (pwm->used) {
++		ret = -EBUSY;
++	} else {
++		if (!desc) {
++			ret = -ENODEV;
++			goto out;
++		}
++		ret = gpiod_request(desc, "mvebu-pwm");
++		if (ret)
++			goto out;
++
++		ret = gpiod_direction_output(desc, 0);
++		if (ret) {
++			gpiod_free(desc);
++			goto out;
++		}
++
++		pwm->pin = pwmd->pwm - mvchip->chip.base;
++		pwm->used = true;
++	}
++
++out:
++	spin_unlock_irqrestore(&pwm->lock, flags);
++	return ret;
++}
++
++static void mvebu_pwm_free(struct pwm_chip *chip, struct pwm_device *pwmd)
++{
++	struct mvebu_pwm *pwm = to_mvebu_pwm(chip);
++	struct gpio_desc *desc = gpio_to_desc(pwmd->pwm);
++	unsigned long flags;
++
++	spin_lock_irqsave(&pwm->lock, flags);
++	gpiod_free(desc);
++	pwm->used = false;
++	spin_unlock_irqrestore(&pwm->lock, flags);
++}
++
++static int mvebu_pwm_config(struct pwm_chip *chip, struct pwm_device *pwmd,
++			    int duty_ns, int period_ns)
++{
++	struct mvebu_pwm *pwm = to_mvebu_pwm(chip);
++	struct mvebu_gpio_chip *mvchip = to_mvchip(pwm);
++	unsigned int on, off;
++	unsigned long long val;
++	u32 u;
++
++	val = (unsigned long long) pwm->clk_rate * duty_ns;
++	do_div(val, NSEC_PER_SEC);
++	if (val > UINT_MAX)
++		return -EINVAL;
++	if (val)
++		on = val;
++	else
++		on = 1;
++
++	val = (unsigned long long) pwm->clk_rate * (period_ns - duty_ns);
++	do_div(val, NSEC_PER_SEC);
++	if (val > UINT_MAX)
++		return -EINVAL;
++	if (val)
++		off = val;
++	else
++		off = 1;
++
++	u = readl_relaxed(mvebu_gpioreg_blink_select(mvchip));
++	u &= ~(1 << pwm->pin);
++	u |= (pwm->id << pwm->pin);
++	writel_relaxed(u, mvebu_gpioreg_blink_select(mvchip));
++
++	writel_relaxed(on, pwm->membase + BLINK_ON_DURATION);
++	writel_relaxed(off, pwm->membase + BLINK_OFF_DURATION);
++
++	return 0;
++}
++
++static int mvebu_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwmd)
++{
++	struct mvebu_pwm *pwm = to_mvebu_pwm(chip);
++	struct mvebu_gpio_chip *mvchip = to_mvchip(pwm);
++
++	mvebu_gpio_blink(&mvchip->chip, pwm->pin, 1);
++
++	return 0;
++}
++
++static void mvebu_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwmd)
++{
++	struct mvebu_pwm *pwm = to_mvebu_pwm(chip);
++	struct mvebu_gpio_chip *mvchip = to_mvchip(pwm);
++
++	mvebu_gpio_blink(&mvchip->chip, pwm->pin, 0);
++}
++
++static const struct pwm_ops mvebu_pwm_ops = {
++	.request = mvebu_pwm_request,
++	.free = mvebu_pwm_free,
++	.config = mvebu_pwm_config,
++	.enable = mvebu_pwm_enable,
++	.disable = mvebu_pwm_disable,
++	.owner = THIS_MODULE,
++};
++
++void mvebu_pwm_suspend(struct mvebu_gpio_chip *mvchip)
++{
++	struct mvebu_pwm *pwm = &mvchip->pwm;
++
++	pwm->blink_select = readl_relaxed(mvebu_gpioreg_blink_select(mvchip));
++	pwm->blink_on_duration =
++		readl_relaxed(pwm->membase + BLINK_ON_DURATION);
++	pwm->blink_off_duration =
++		readl_relaxed(pwm->membase + BLINK_OFF_DURATION);
++}
++
++void mvebu_pwm_resume(struct mvebu_gpio_chip *mvchip)
++{
++	struct mvebu_pwm *pwm = &mvchip->pwm;
++
++	writel_relaxed(pwm->blink_select, mvebu_gpioreg_blink_select(mvchip));
++	writel_relaxed(pwm->blink_on_duration,
++		       pwm->membase + BLINK_ON_DURATION);
++	writel_relaxed(pwm->blink_off_duration,
++		       pwm->membase + BLINK_OFF_DURATION);
++}
++
++/*
++ * Armada 370/XP has simple PWM support for gpio lines. Other SoCs
++ * don't have this hardware. So if we don't have the necessary
++ * resource, it is not an error.
++ */
++int mvebu_pwm_probe(struct platform_device *pdev,
++		    struct mvebu_gpio_chip *mvchip,
++		    int id)
++{
++	struct device *dev = &pdev->dev;
++	struct mvebu_pwm *pwm = &mvchip->pwm;
++	struct resource *res;
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwm");
++	if (!res)
++		return 0;
++
++	mvchip->pwm.membase = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(mvchip->pwm.membase))
++		return PTR_ERR(mvchip->percpu_membase);
++
++	if (id < 0 || id > 1)
++		return -EINVAL;
++	pwm->id = id;
++
++	if (IS_ERR(mvchip->clk))
++		return PTR_ERR(mvchip->clk);
++
++	pwm->clk_rate = clk_get_rate(mvchip->clk);
++	if (!pwm->clk_rate) {
++		dev_err(dev, "failed to get clock rate\n");
++		return -EINVAL;
++	}
++
++	pwm->chip.dev = dev;
++	pwm->chip.ops = &mvebu_pwm_ops;
++	pwm->chip.base = mvchip->chip.base;
++	pwm->chip.npwm = mvchip->chip.ngpio;
++	pwm->chip.can_sleep = false;
++
++	spin_lock_init(&pwm->lock);
++
++	return pwmchip_add(&pwm->chip);
++}
+Index: linux-4.1.6/drivers/gpio/gpio-mvebu.c
+===================================================================
+--- linux-4.1.6.orig/drivers/gpio/gpio-mvebu.c
++++ linux-4.1.6/drivers/gpio/gpio-mvebu.c
+@@ -42,10 +42,11 @@
+ #include <linux/io.h>
+ #include <linux/of_irq.h>
+ #include <linux/of_device.h>
++#include <linux/pwm.h>
+ #include <linux/clk.h>
+ #include <linux/pinctrl/consumer.h>
+ #include <linux/irqchip/chained_irq.h>
+-
++#include "gpio-mvebu.h"
+ /*
+  * GPIO unit register offsets.
+  */
+@@ -75,24 +76,6 @@
+ 
+ #define MVEBU_MAX_GPIO_PER_BANK		32
+ 
+-struct mvebu_gpio_chip {
+-	struct gpio_chip   chip;
+-	spinlock_t	   lock;
+-	void __iomem	  *membase;
+-	void __iomem	  *percpu_membase;
+-	int		   irqbase;
+-	struct irq_domain *domain;
+-	int		   soc_variant;
+-
+-	/* Used to preserve GPIO registers across suspend/resume */
+-	u32                out_reg;
+-	u32                io_conf_reg;
+-	u32                blink_en_reg;
+-	u32                in_pol_reg;
+-	u32                edge_mask_regs[4];
+-	u32                level_mask_regs[4];
+-};
+-
+ /*
+  * Functions returning addresses of individual registers for a given
+  * GPIO controller.
+@@ -228,7 +211,7 @@ static int mvebu_gpio_get(struct gpio_ch
+ 	return (u >> pin) & 1;
+ }
+ 
+-static void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value)
++void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value)
+ {
+ 	struct mvebu_gpio_chip *mvchip =
+ 		container_of(chip, struct mvebu_gpio_chip, chip);
+@@ -617,6 +600,8 @@ static int mvebu_gpio_suspend(struct pla
+ 		BUG();
+ 	}
+ 
++	mvebu_pwm_suspend(mvchip);
++
+ 	return 0;
+ }
+ 
+@@ -660,6 +645,8 @@ static int mvebu_gpio_resume(struct plat
+ 		BUG();
+ 	}
+ 
++	mvebu_pwm_resume(mvchip);
++
+ 	return 0;
+ }
+ 
+@@ -671,7 +658,6 @@ static int mvebu_gpio_probe(struct platf
+ 	struct resource *res;
+ 	struct irq_chip_generic *gc;
+ 	struct irq_chip_type *ct;
+-	struct clk *clk;
+ 	unsigned int ngpios;
+ 	int soc_variant;
+ 	int i, cpu, id;
+@@ -701,10 +687,10 @@ static int mvebu_gpio_probe(struct platf
+ 		return id;
+ 	}
+ 
+-	clk = devm_clk_get(&pdev->dev, NULL);
++	mvchip->clk = devm_clk_get(&pdev->dev, NULL);
+ 	/* Not all SoCs require a clock.*/
+-	if (!IS_ERR(clk))
+-		clk_prepare_enable(clk);
++	if (!IS_ERR(mvchip->clk))
++		clk_prepare_enable(mvchip->clk);
+ 
+ 	mvchip->soc_variant = soc_variant;
+ 	mvchip->chip.label = dev_name(&pdev->dev);
+@@ -838,7 +824,8 @@ static int mvebu_gpio_probe(struct platf
+ 		goto err_generic_chip;
+ 	}
+ 
+-	return 0;
++	/* Armada 370/XP has simple PWM support for gpio lines */
++	return mvebu_pwm_probe(pdev, mvchip, id);
+ 
+ err_generic_chip:
+ 	irq_remove_generic_chip(gc, IRQ_MSK(ngpios), IRQ_NOREQUEST,
+Index: linux-4.1.6/drivers/gpio/gpio-mvebu.h
+===================================================================
+--- /dev/null
++++ linux-4.1.6/drivers/gpio/gpio-mvebu.h
+@@ -0,0 +1,79 @@
++/*
++ * Interface between MVEBU GPIO driver and PWM driver for GPIO pins
++ *
++ * Copyright (C) 2015, Andrew Lunn <andrew@lunn.ch>
++ *
++ * This program 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.
++ */
++
++#ifndef MVEBU_GPIO_PWM_H
++#define MVEBU_GPIO_PWM_H
++
++#define BLINK_ON_DURATION	0x0
++#define BLINK_OFF_DURATION	0x4
++#define GPIO_BLINK_CNT_SELECT	0x0020
++
++struct mvebu_pwm {
++	void __iomem	*membase;
++	unsigned long	 clk_rate;
++	bool		 used;
++	unsigned	 pin;
++	struct pwm_chip	 chip;
++	int		 id;
++	spinlock_t	 lock;
++
++	/* Used to preserve GPIO/PWM registers across suspend /
++	 * resume */
++	u32		 blink_select;
++	u32		 blink_on_duration;
++	u32		 blink_off_duration;
++};
++
++struct mvebu_gpio_chip {
++	struct gpio_chip   chip;
++	spinlock_t	   lock;
++	void __iomem	  *membase;
++	void __iomem	  *percpu_membase;
++	int		   irqbase;
++	struct irq_domain *domain;
++	int		   soc_variant;
++	struct clk	  *clk;
++#ifdef CONFIG_PWM
++	struct mvebu_pwm pwm;
++#endif
++	/* Used to preserve GPIO registers across suspend/resume */
++	u32		   out_reg;
++	u32		   io_conf_reg;
++	u32		   blink_en_reg;
++	u32		   in_pol_reg;
++	u32		   edge_mask_regs[4];
++	u32		   level_mask_regs[4];
++};
++
++void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value);
++
++#ifdef CONFIG_PWM
++int mvebu_pwm_probe(struct platform_device *pdev,
++		    struct mvebu_gpio_chip *mvchip,
++		    int id);
++void mvebu_pwm_suspend(struct mvebu_gpio_chip *mvchip);
++void mvebu_pwm_resume(struct mvebu_gpio_chip *mvchip);
++#else
++int mvebu_pwm_probe(struct platform_device *pdev,
++		    struct mvebu_gpio_chip *mvchip,
++		    int id)
++{
++	return 0;
++}
++
++void mvebu_pwm_suspend(struct mvebu_gpio_chip *mvchip)
++{
++}
++
++void mvebu_pwm_resume(struct mvebu_gpio_chip *mvchip)
++{
++}
++#endif
++#endif
diff --git a/target/linux/mvebu/patches-4.1/203-dt_bindings_extend_mvebu_gpio_documentation_with_pwm.patch b/target/linux/mvebu/patches-4.1/203-dt_bindings_extend_mvebu_gpio_documentation_with_pwm.patch
new file mode 100644
index 0000000..235923d
--- /dev/null
+++ b/target/linux/mvebu/patches-4.1/203-dt_bindings_extend_mvebu_gpio_documentation_with_pwm.patch
@@ -0,0 +1,54 @@
+Document the optional parameters needed for PWM operation of gpio
+lines.
+
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+---
+ .../devicetree/bindings/gpio/gpio-mvebu.txt        | 31 ++++++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+
+Index: linux-4.1.6/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt
+===================================================================
+--- linux-4.1.6.orig/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt
++++ linux-4.1.6/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt
+@@ -38,6 +38,23 @@ Required properties:
+ - #gpio-cells: Should be two. The first cell is the pin number. The
+   second cell is reserved for flags, unused at the moment.
+ 
++Optional properties:
++
++In order to use the gpio lines in PWM mode, some additional optional
++properties are required. Only Armada 370 and XP supports these
++properties.
++
++- reg: an additional register set is needed, for the GPIO Blink
++  Counter on/off registers.
++
++- reg-names: Must contain an entry "pwm" corresponding to the
++  additional register range needed for pwm operation.
++
++- #pwm-cells: Should be two. The first cell is the pin number. The
++  second cell is reserved for flags, unused at the moment.
++
++- clocks: Must be a phandle to the clock for the gpio controller.
++
+ Example:
+ 
+ 		gpio0: gpio@d0018100 {
+@@ -51,3 +68,17 @@ Example:
+ 			#interrupt-cells = <2>;
+ 			interrupts = <16>, <17>, <18>, <19>;
+ 		};
++
++		gpio1: gpio@18140 {
++			compatible = "marvell,orion-gpio";
++			reg = <0x18140 0x40>, <0x181c8 0x08>;
++			reg-names = "gpio", "pwm";
++			ngpios = <17>;
++			gpio-controller;
++			#gpio-cells = <2>;
++			#pwm-cells = <2>;
++			interrupt-controller;
++			#interrupt-cells = <2>;
++			interrupts = <87>, <88>, <89>;
++			clocks = <&coreclk 0>;
++		};
diff --git a/target/linux/mvebu/patches-4.1/204-mvebu_xp_add_pwm_properties_to_dtsi_files.patch b/target/linux/mvebu/patches-4.1/204-mvebu_xp_add_pwm_properties_to_dtsi_files.patch
new file mode 100644
index 0000000..c5bc6d6
--- /dev/null
+++ b/target/linux/mvebu/patches-4.1/204-mvebu_xp_add_pwm_properties_to_dtsi_files.patch
@@ -0,0 +1,157 @@
+Add properties to the gpio nodes to allow them to be also used
+as pwm lines.
+
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+---
+ arch/arm/boot/dts/armada-370.dtsi        | 10 ++++++++--
+ arch/arm/boot/dts/armada-xp-mv78230.dtsi | 10 ++++++++--
+ arch/arm/boot/dts/armada-xp-mv78260.dtsi |  8 ++++++--
+ arch/arm/boot/dts/armada-xp-mv78460.dtsi | 10 ++++++++--
+ 4 files changed, 30 insertions(+), 8 deletions(-)
+
+Index: linux-4.1.6/arch/arm/boot/dts/armada-370.dtsi
+===================================================================
+--- linux-4.1.6.orig/arch/arm/boot/dts/armada-370.dtsi
++++ linux-4.1.6/arch/arm/boot/dts/armada-370.dtsi
+@@ -158,24 +158,30 @@
+ 
+ 			gpio0: gpio@18100 {
+ 				compatible = "marvell,orion-gpio";
+-				reg = <0x18100 0x40>;
++				reg = <0x18100 0x40>, <0x181c0 0x08>;
++				reg-names = "gpio", "pwm";
+ 				ngpios = <32>;
+ 				gpio-controller;
+ 				#gpio-cells = <2>;
++				#pwm-cells = <2>;
+ 				interrupt-controller;
+ 				#interrupt-cells = <2>;
+ 				interrupts = <82>, <83>, <84>, <85>;
++				clocks = <&coreclk 0>;
+ 			};
+ 
+ 			gpio1: gpio@18140 {
+ 				compatible = "marvell,orion-gpio";
+-				reg = <0x18140 0x40>;
++				reg = <0x18140 0x40>, <0x181c8 0x08>;
++				reg-names = "gpio", "pwm";
+ 				ngpios = <32>;
+ 				gpio-controller;
+ 				#gpio-cells = <2>;
++				#pwm-cells = <2>;
+ 				interrupt-controller;
+ 				#interrupt-cells = <2>;
+ 				interrupts = <87>, <88>, <89>, <90>;
++				clocks = <&coreclk 0>;
+ 			};
+ 
+ 			gpio2: gpio@18180 {
+Index: linux-4.1.6/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+===================================================================
+--- linux-4.1.6.orig/arch/arm/boot/dts/armada-xp-mv78230.dtsi
++++ linux-4.1.6/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+@@ -203,24 +203,30 @@
+ 		internal-regs {
+ 			gpio0: gpio@18100 {
+ 				compatible = "marvell,orion-gpio";
+-				reg = <0x18100 0x40>;
++				reg = <0x18100 0x40>, <0x181c0 0x08>;
++				reg-names = "gpio", "pwm";
+ 				ngpios = <32>;
+ 				gpio-controller;
+ 				#gpio-cells = <2>;
++				#pwm-cells = <2>;
+ 				interrupt-controller;
+ 				#interrupt-cells = <2>;
+ 				interrupts = <82>, <83>, <84>, <85>;
++				clocks = <&coreclk 0>;
+ 			};
+ 
+ 			gpio1: gpio@18140 {
+ 				compatible = "marvell,orion-gpio";
+-				reg = <0x18140 0x40>;
++				reg = <0x18140 0x40>, <0x181c8 0x08>;
++				reg-names = "gpio", "pwm";
+ 				ngpios = <17>;
+ 				gpio-controller;
+ 				#gpio-cells = <2>;
++				#pwm-cells = <2>;
+ 				interrupt-controller;
+ 				#interrupt-cells = <2>;
+ 				interrupts = <87>, <88>, <89>;
++				clocks = <&coreclk 0>;
+ 			};
+ 		};
+ 	};
+Index: linux-4.1.6/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+===================================================================
+--- linux-4.1.6.orig/arch/arm/boot/dts/armada-xp-mv78260.dtsi
++++ linux-4.1.6/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+@@ -286,24 +286,28 @@
+ 		internal-regs {
+ 			gpio0: gpio@18100 {
+ 				compatible = "marvell,orion-gpio";
+-				reg = <0x18100 0x40>;
++				reg = <0x18100 0x40>, <0x181c0 0x08>;
++				reg-names = "gpio", "pwm";
+ 				ngpios = <32>;
+ 				gpio-controller;
+ 				#gpio-cells = <2>;
++				#pwm-cells = <2>;
+ 				interrupt-controller;
+ 				#interrupt-cells = <2>;
+ 				interrupts = <82>, <83>, <84>, <85>;
++				clocks = <&coreclk 0>;
+ 			};
+ 
+ 			gpio1: gpio@18140 {
+ 				compatible = "marvell,orion-gpio";
+-				reg = <0x18140 0x40>;
++				reg = <0x18140 0x40>, <0x181c8 0x08>;
+ 				ngpios = <32>;
+ 				gpio-controller;
+ 				#gpio-cells = <2>;
+ 				interrupt-controller;
+ 				#interrupt-cells = <2>;
+ 				interrupts = <87>, <88>, <89>, <90>;
++				clocks = <&coreclk 0>;
+ 			};
+ 
+ 			gpio2: gpio@18180 {
+Index: linux-4.1.6/arch/arm/boot/dts/armada-xp-mv78460.dtsi
+===================================================================
+--- linux-4.1.6.orig/arch/arm/boot/dts/armada-xp-mv78460.dtsi
++++ linux-4.1.6/arch/arm/boot/dts/armada-xp-mv78460.dtsi
+@@ -324,24 +324,30 @@
+ 		internal-regs {
+ 			gpio0: gpio@18100 {
+ 				compatible = "marvell,orion-gpio";
+-				reg = <0x18100 0x40>;
++				reg = <0x18100 0x40>, <0x181c0 0x08>;
++				reg-names = "gpio", "pwm";
+ 				ngpios = <32>;
+ 				gpio-controller;
+ 				#gpio-cells = <2>;
++				#pwm-cells = <2>;
+ 				interrupt-controller;
+ 				#interrupt-cells = <2>;
+ 				interrupts = <82>, <83>, <84>, <85>;
++				clocks = <&coreclk 0>;
+ 			};
+ 
+ 			gpio1: gpio@18140 {
+ 				compatible = "marvell,orion-gpio";
+-				reg = <0x18140 0x40>;
++				reg = <0x18140 0x40>, <0x181c8 0x08>;
++				reg-names = "gpio", "pwm";
+ 				ngpios = <32>;
+ 				gpio-controller;
+ 				#gpio-cells = <2>;
++				#pwm-cells = <2>;
+ 				interrupt-controller;
+ 				#interrupt-cells = <2>;
+ 				interrupts = <87>, <88>, <89>, <90>;
++				clocks = <&coreclk 0>;
+ 			};
+ 
+ 			gpio2: gpio@18180 {
diff --git a/target/linux/mvebu/patches-4.1/205-arm_mvebu_enable_pwm_in_defconfig.patch b/target/linux/mvebu/patches-4.1/205-arm_mvebu_enable_pwm_in_defconfig.patch
new file mode 100644
index 0000000..7c39b79
--- /dev/null
+++ b/target/linux/mvebu/patches-4.1/205-arm_mvebu_enable_pwm_in_defconfig.patch
@@ -0,0 +1,20 @@
+Now that the gpio driver also supports PWM operation, enable
+the PWM framework in mvebu_v7_defconfig.
+
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+---
+ arch/arm/configs/mvebu_v7_defconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+Index: linux-4.1.6/arch/arm/configs/mvebu_v7_defconfig
+===================================================================
+--- linux-4.1.6.orig/arch/arm/configs/mvebu_v7_defconfig
++++ linux-4.1.6/arch/arm/configs/mvebu_v7_defconfig
+@@ -120,6 +120,7 @@ CONFIG_DMADEVICES=y
+ CONFIG_MV_XOR=y
+ # CONFIG_IOMMU_SUPPORT is not set
+ CONFIG_MEMORY=y
++CONFIG_PWM=y
+ CONFIG_EXT4_FS=y
+ CONFIG_ISO9660_FS=y
+ CONFIG_JOLIET=y
diff --git a/target/linux/mvebu/patches-4.1/206-mvebu_wrt1900ac_use_pwm-fan_rather_than_gpio-fan.patch b/target/linux/mvebu/patches-4.1/206-mvebu_wrt1900ac_use_pwm-fan_rather_than_gpio-fan.patch
new file mode 100644
index 0000000..2bc4781
--- /dev/null
+++ b/target/linux/mvebu/patches-4.1/206-mvebu_wrt1900ac_use_pwm-fan_rather_than_gpio-fan.patch
@@ -0,0 +1,30 @@
+The mvebu gpio driver can also perform PWM on some pins. Us the
+pwm-fan driver to control the fan of the WRT1900AC, giving us fine
+grain control over its speed and hence noise.
+
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+---
+ arch/arm/boot/dts/armada-xp-wrt1900ac.dts | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+Index: linux-4.1.6/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+===================================================================
+--- linux-4.1.6.orig/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
++++ linux-4.1.6/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+@@ -412,13 +412,11 @@
+ 		};
+ 	};
+ 
+-	gpio_fan {
++	pwm_fan {
+ 		/* SUNON HA4010V4-0000-C99 */
+-		compatible = "gpio-fan";
+-		gpios = <&gpio0 24 0>;
+ 
+-		gpio-fan,speed-map = <0    0
+-				      4500 1>;
++		compatible = "pwm-fan";
++		pwms = <&gpio0 24 4000 0>;
+ 	};
+ 
+ 	dsa@0 {
diff --git a/target/linux/mvebu/patches-4.1/207-armada-385-rd-mtd-partitions.patch b/target/linux/mvebu/patches-4.1/207-armada-385-rd-mtd-partitions.patch
new file mode 100644
index 0000000..b70acb9
--- /dev/null
+++ b/target/linux/mvebu/patches-4.1/207-armada-385-rd-mtd-partitions.patch
@@ -0,0 +1,21 @@
+Index: linux-4.1.6/arch/arm/boot/dts/armada-388-rd.dts
+===================================================================
+--- linux-4.1.6.orig/arch/arm/boot/dts/armada-388-rd.dts
++++ linux-4.1.6/arch/arm/boot/dts/armada-388-rd.dts
+@@ -77,6 +77,16 @@
+ 					compatible = "st,m25p128";
+ 					reg = <0>; /* Chip select 0 */
+ 					spi-max-frequency = <108000000>;
++
++					partition@0 {
++						label = "uboot";
++						reg = <0 0x400000>;
++					};
++
++					partition@1 {
++						label = "firmware";
++						reg = <0x400000 0xc00000>;
++					};
+ 				};
+ 			};
+ 
diff --git a/target/linux/mvebu/patches-4.1/208-ARM-mvebu-385-ap-Add-partitions.patch b/target/linux/mvebu/patches-4.1/208-ARM-mvebu-385-ap-Add-partitions.patch
new file mode 100644
index 0000000..55f538f
--- /dev/null
+++ b/target/linux/mvebu/patches-4.1/208-ARM-mvebu-385-ap-Add-partitions.patch
@@ -0,0 +1,36 @@
+From 9861f93a59142a3131870df2521eb2deb73026d7 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Tue, 13 Jan 2015 11:14:09 +0100
+Subject: [PATCH 2/2] ARM: mvebu: 385-ap: Add partitions
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ arch/arm/boot/dts/armada-385-db-ap.dts | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+Index: linux-4.1.6/arch/arm/boot/dts/armada-385-db-ap.dts
+===================================================================
+--- linux-4.1.6.orig/arch/arm/boot/dts/armada-385-db-ap.dts
++++ linux-4.1.6/arch/arm/boot/dts/armada-385-db-ap.dts
+@@ -186,6 +186,21 @@
+ 				marvell,nand-keep-config;
+ 				marvell,nand-enable-arbiter;
+ 				nand-on-flash-bbt;
++
++				mtd0@00000000 {
++					label = "u-boot";
++					reg = <0x00000000 0x00800000>;
++				};
++
++				mtd1@00800000 {
++					label = "kernel";
++					reg = <0x00800000 0x00800000>;
++				};
++
++				mtd2@01000000 {
++					label = "ubi";
++					reg = <0x01000000 0x3f000000>;
++				};
+ 			};
+ 		};
+ 
diff --git a/target/linux/mvebu/patches-4.1/300-add_missing_labels.patch b/target/linux/mvebu/patches-4.1/300-add_missing_labels.patch
new file mode 100644
index 0000000..6da2200
--- /dev/null
+++ b/target/linux/mvebu/patches-4.1/300-add_missing_labels.patch
@@ -0,0 +1,13 @@
+Index: linux-4.1.6/arch/arm/boot/dts/armada-38x.dtsi
+===================================================================
+--- linux-4.1.6.orig/arch/arm/boot/dts/armada-38x.dtsi
++++ linux-4.1.6/arch/arm/boot/dts/armada-38x.dtsi
+@@ -495,7 +495,7 @@
+ 				status = "disabled";
+ 			};
+ 
+-			mdio@72004 {
++			mdio: mdio@72004 {
+ 				#address-cells = <1>;
+ 				#size-cells = <0>;
+ 				compatible = "marvell,orion-mdio";
