aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/kernel-version.mk4
-rw-r--r--package/kernel/linux/modules/netsupport.mk2
-rw-r--r--package/kernel/linux/modules/other.mk38
-rw-r--r--target/linux/ar71xx/patches-4.4/608-MIPS-ath79-ubnt-xm-add-more-boards.patch2
-rw-r--r--target/linux/brcm2708/patches-4.4/0027-Main-bcm2708-bcm2709-linux-port.patch4
-rw-r--r--target/linux/brcm47xx/patches-4.4/159-cpu_fixes.patch16
-rw-r--r--target/linux/brcm47xx/patches-4.4/160-kmap_coherent.patch4
-rw-r--r--target/linux/generic/config-4.46
-rw-r--r--target/linux/generic/patches-4.4/046-ubifs-silence-error-output-if-MS_SILENT-is-set.patch37
-rw-r--r--target/linux/generic/patches-4.4/271-uapi-libc-compat.h-do-not-rely-on-__GLIBC__.patch2
-rw-r--r--target/linux/generic/patches-4.4/610-netfilter_match_bypass_default_checks.patch25
-rw-r--r--target/linux/ipq806x/patches-4.4/022-add-db149-dts.patch2
-rw-r--r--target/linux/ipq806x/patches-4.4/023-ARM-dts-ipq806x-Disable-i2c-device-on-gsbi4.patch6
-rw-r--r--target/linux/ipq806x/patches-4.4/037-mtd-add-SMEM-parser-for-QCOM-platforms.patch11
-rw-r--r--target/linux/ipq806x/patches-4.4/100-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch8
-rw-r--r--target/linux/ipq806x/patches-4.4/111-PCI-qcom-Add-Qualcomm-PCIe-controller-driver.patch6
-rw-r--r--target/linux/ipq806x/patches-4.4/133-ARM-Add-Krait-L2-register-accessor-functions.patch4
-rw-r--r--target/linux/ipq806x/patches-4.4/134-clk-mux-Split-out-register-accessors-for-reuse.patch19
-rw-r--r--target/linux/ipq806x/patches-4.4/135-clk-Avoid-sending-high-rates-to-downstream-clocks-du.patch15
-rw-r--r--target/linux/ipq806x/patches-4.4/136-clk-Add-safe-switch-hook.patch17
-rw-r--r--target/linux/ipq806x/patches-4.4/137-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch2
-rw-r--r--target/linux/ipq806x/patches-4.4/138-clk-qcom-Add-HFPLL-driver.patch4
-rw-r--r--target/linux/ipq806x/patches-4.4/139-clk-qcom-Add-IPQ806X-s-HFPLLs.patch4
-rw-r--r--target/linux/ipq806x/patches-4.4/140-clk-qcom-Add-support-for-Krait-clocks.patch5
-rw-r--r--target/linux/ipq806x/patches-4.4/141-clk-qcom-Add-KPSS-ACC-GCC-driver.patch6
-rw-r--r--target/linux/ipq806x/patches-4.4/142-clk-qcom-Add-Krait-clock-controller-driver.patch4
-rw-r--r--target/linux/ipq806x/patches-4.4/143-cpufreq-Add-module-to-register-cpufreq-on-Krait-CPUs.patch4
-rw-r--r--target/linux/ipq806x/patches-4.4/145-cpufreq-Add-a-cpufreq-krait-based-on-cpufre.patch6
-rw-r--r--target/linux/ipq806x/patches-4.4/156-dmaengine-Add-ADM-driver.patch4
-rw-r--r--target/linux/ipq806x/patches-4.4/161-mtd-nand-Create-a-BBT-flag-to-access-bad-block-markers-in-raw-mode.patch6
-rw-r--r--target/linux/ipq806x/patches-4.4/162-mtd-nand-Qualcomm-NAND-controller-driver.patch4
-rw-r--r--target/linux/ipq806x/patches-4.4/168-ARM-qcom-add-smb208-DT.patch49
-rw-r--r--target/linux/ipq806x/patches-4.4/300-arch-arm-force-ZRELADDR-on-arch-qcom.patch4
-rw-r--r--target/linux/ipq806x/patches-4.4/400-dsa-add-qca.patch1099
-rw-r--r--target/linux/ipq806x/patches-4.4/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch2
-rw-r--r--target/linux/ipq806x/patches-4.4/709-spi-qup-Fix-fifo-and-dma-support-for-IPQ806x.patch17
-rw-r--r--target/linux/ipq806x/patches-4.4/710-watchdog-qcom-set-WDT_BARK_TIME-register-offset-to-o.patch7
-rw-r--r--target/linux/ipq806x/patches-4.4/711-stmmac-fix-ipq806x-DMA-configuration.patch4
-rw-r--r--target/linux/ipq806x/patches-4.4/800-devicetree.patch2
-rw-r--r--target/linux/ipq806x/patches-4.4/996-ATAG_DTB_COMPAT_CMDLINE_MANGLE.patch10
-rw-r--r--target/linux/lantiq/patches-4.4/0028-NET-lantiq-various-etop-fixes.patch81
-rw-r--r--target/linux/lantiq/patches-4.4/0160-owrt-lantiq-multiple-flash.patch69
-rw-r--r--target/linux/mediatek/Makefile4
-rwxr-xr-xtarget/linux/mediatek/base-files/lib/upgrade/platform.sh14
-rw-r--r--target/linux/mediatek/config-4.4106
-rw-r--r--target/linux/mediatek/files/arch/arm/boot/dts/mt7623-NAND.dts3
-rw-r--r--target/linux/mediatek/image/Makefile11
-rw-r--r--target/linux/mediatek/patches-4.4/0072-mtd-backport-v4.7-0day-patches-from-Boris.patch177
-rw-r--r--target/linux/mediatek/patches-4.4/0103-nand_fixes.patch22
-rw-r--r--target/linux/octeon/patches-4.4/170-cisco-hack.patch2
-rw-r--r--target/linux/oxnas/patches-4.4/300-introduce-oxnas-platform.patch4
-rwxr-xr-xtarget/linux/ramips/base-files/etc/board.d/02_network4
-rw-r--r--target/linux/ramips/base-files/etc/uci-defaults/09_fix-seama-header6
-rw-r--r--target/linux/ramips/dts/WL-351.dts7
-rw-r--r--target/linux/ramips/dts/mt7620a.dtsi9
-rw-r--r--target/linux/ramips/dts/mt7621.dtsi54
-rw-r--r--target/linux/ramips/dts/mt7628an.dtsi11
-rw-r--r--target/linux/ramips/dts/rt2880.dtsi23
-rw-r--r--target/linux/ramips/dts/rt3050.dtsi41
-rw-r--r--target/linux/ramips/dts/rt3352.dtsi43
-rw-r--r--target/linux/ramips/dts/rt3883.dtsi43
-rw-r--r--target/linux/ramips/dts/rt5350.dtsi36
-rw-r--r--target/linux/ramips/image/rt305x.mk1
-rw-r--r--target/linux/ramips/patches-4.4/0048-asoc-add-mt7620-support.patch1203
-rw-r--r--target/linux/ramips/patches-4.4/0085-pinmux-util.patch77
-rw-r--r--target/linux/ramips/patches-4.4/0085-sdhci-no-wp.patch21
-rw-r--r--target/linux/ramips/patches-4.4/0520-esw-gmac.patch69
-rw-r--r--target/linux/ramips/patches-4.4/0720-arch-mips-ralink-add-i2c-clocks.patch67
-rw-r--r--target/linux/ramips/rt305x/profiles/sitecom.mk18
69 files changed, 1913 insertions, 1784 deletions
diff --git a/include/kernel-version.mk b/include/kernel-version.mk
index c1dbd2330e..a507b7db13 100644
--- a/include/kernel-version.mk
+++ b/include/kernel-version.mk
@@ -4,11 +4,11 @@ LINUX_RELEASE?=1
LINUX_VERSION-3.18 = .29
LINUX_VERSION-4.1 = .23
-LINUX_VERSION-4.4 = .13
+LINUX_VERSION-4.4 = .14
LINUX_KERNEL_MD5SUM-3.18.29 = b25737a0bc98e80d12200de93f239c28
LINUX_KERNEL_MD5SUM-4.1.23 = 5cb969fa874e110118722398b7c72c5d
-LINUX_KERNEL_MD5SUM-4.4.13 = d70b6959d8db61bcea7070c089aace9b
+LINUX_KERNEL_MD5SUM-4.4.14 = 59e99c3bf5d495f1f95d26257962ca3e
ifdef KERNEL_PATCHVER
LINUX_VERSION:=$(KERNEL_PATCHVER)$(strip $(LINUX_VERSION-$(KERNEL_PATCHVER)))
diff --git a/package/kernel/linux/modules/netsupport.mk b/package/kernel/linux/modules/netsupport.mk
index 919ddcf819..032e085c2f 100644
--- a/package/kernel/linux/modules/netsupport.mk
+++ b/package/kernel/linux/modules/netsupport.mk
@@ -1029,7 +1029,7 @@ $(eval $(call KernelPackage,mpls))
define KernelPackage/9pnet
SUBMENU:=$(NETWORK_SUPPORT_MENU)
TITLE:=Plan 9 Resource Sharing Support (9P2000)
- DEPENDS:=@PCI_SUPPORT
+ DEPENDS:=@PCI_SUPPORT +kmod-virtio-pci
KCONFIG:= \
CONFIG_NET_9P=m \
CONFIG_NET_9P_DEBUG=n \
diff --git a/package/kernel/linux/modules/other.mk b/package/kernel/linux/modules/other.mk
index 301460e416..503ca98be4 100644
--- a/package/kernel/linux/modules/other.mk
+++ b/package/kernel/linux/modules/other.mk
@@ -1064,7 +1064,7 @@ define KernelPackage/bmp085-spi
DEPENDS:= +kmod-bmp085
KCONFIG:= CONFIG_BMP085_SPI
FILES:= $(LINUX_DIR)/drivers/misc/bmp085-spi.ko
- AUTOLOAD:=$(call AutoProbe,bm085-spi)
+ AUTOLOAD:=$(call AutoProbe,bmp085-spi)
endef
define KernelPackage/bmp085-spi/description
This driver adds support for Bosch Sensortec's digital pressure
@@ -1072,3 +1072,39 @@ define KernelPackage/bmp085-spi/description
endef
$(eval $(call KernelPackage,bmp085-spi))
+
+
+define KernelPackage/virtio-pci
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Virtio PCI support
+ KCONFIG:= CONFIG_VIRTIO CONFIG_VIRTIO_PCI
+ FILES:=\
+ $(LINUX_DIR)/drivers/virtio/virtio_pci.ko \
+ $(LINUX_DIR)/drivers/virtio/virtio.ko \
+ $(LINUX_DIR)/drivers/virtio/virtio_ring.ko
+ AUTOLOAD:=$(call AutoProbe,virtio virtio_ring virtio_pci)
+endef
+define KernelPackage/virtio-pci/description
+ This driver adds virtio PCI support.
+endef
+
+$(eval $(call KernelPackage,virtio-pci))
+
+
+define KernelPackage/virtio-mmio
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=Virtio MMIO support
+ KCONFIG:= CONFIG_VIRTIO CONFIG_VIRTIO_MMIO
+ FILES:= \
+ $(LINUX_DIR)/drivers/virtio/virtio.ko \
+ $(LINUX_DIR)/drivers/virtio/virtio_ring.ko \
+ $(LINUX_DIR)/drivers/virtio/virtio_mmio.ko
+ AUTOLOAD:=$(call AutoProbe,virtio virtio_ring virtio_mmio)
+endef
+define KernelPackage/virtio-mmio/description
+ This driver adds virtio MMIO support.
+endef
+
+$(eval $(call KernelPackage,virtio-mmio))
+
+
diff --git a/target/linux/ar71xx/patches-4.4/608-MIPS-ath79-ubnt-xm-add-more-boards.patch b/target/linux/ar71xx/patches-4.4/608-MIPS-ath79-ubnt-xm-add-more-boards.patch
index 2bfd58d4e8..b33db4dd0d 100644
--- a/target/linux/ar71xx/patches-4.4/608-MIPS-ath79-ubnt-xm-add-more-boards.patch
+++ b/target/linux/ar71xx/patches-4.4/608-MIPS-ath79-ubnt-xm-add-more-boards.patch
@@ -2,7 +2,7 @@
+++ b/arch/mips/ath79/Kconfig
@@ -68,12 +68,16 @@ config ATH79_MACH_PB44
Atheros PB44 reference board.
-
+
config ATH79_MACH_UBNT_XM
- bool "Ubiquiti Networks XM (rev 1.0) board"
+ bool "Ubiquiti Networks XM/UniFi boards"
diff --git a/target/linux/brcm2708/patches-4.4/0027-Main-bcm2708-bcm2709-linux-port.patch b/target/linux/brcm2708/patches-4.4/0027-Main-bcm2708-bcm2709-linux-port.patch
index 249716c2b6..47bf84cb80 100644
--- a/target/linux/brcm2708/patches-4.4/0027-Main-bcm2708-bcm2709-linux-port.patch
+++ b/target/linux/brcm2708/patches-4.4/0027-Main-bcm2708-bcm2709-linux-port.patch
@@ -75,7 +75,7 @@ Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
-@@ -317,6 +317,52 @@ choice
+@@ -318,6 +318,52 @@ choice
default ARCH_VERSATILE if !MMU
default ARCH_MULTIPLATFORM if MMU
@@ -128,7 +128,7 @@ Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
config ARCH_MULTIPLATFORM
bool "Allow multiple platforms to be selected"
depends on MMU
-@@ -808,6 +854,9 @@ config ARCH_VIRT
+@@ -809,6 +855,9 @@ config ARCH_VIRT
# Kconfigs may be included either alphabetically (according to the
# plat- suffix) or along side the corresponding mach-* source.
#
diff --git a/target/linux/brcm47xx/patches-4.4/159-cpu_fixes.patch b/target/linux/brcm47xx/patches-4.4/159-cpu_fixes.patch
index 50df04f1e0..1a3e0a60f9 100644
--- a/target/linux/brcm47xx/patches-4.4/159-cpu_fixes.patch
+++ b/target/linux/brcm47xx/patches-4.4/159-cpu_fixes.patch
@@ -276,9 +276,9 @@
+int bcm4710 = 0;
+
/*
- * Special Variant of smp_call_function for use by cache functions:
+ * Bits describing what cache ops an IPI callback function may perform.
*
-@@ -157,6 +160,9 @@ static void r4k_blast_dcache_user_page_s
+@@ -202,6 +205,9 @@ static void r4k_blast_dcache_user_page_s
{
unsigned long dc_lsize = cpu_dcache_line_size();
@@ -288,7 +288,7 @@
if (dc_lsize == 0)
r4k_blast_dcache_user_page = (void *)cache_noop;
else if (dc_lsize == 16)
-@@ -175,6 +181,9 @@ static void r4k_blast_dcache_page_indexe
+@@ -220,6 +226,9 @@ static void r4k_blast_dcache_page_indexe
{
unsigned long dc_lsize = cpu_dcache_line_size();
@@ -298,7 +298,7 @@
if (dc_lsize == 0)
r4k_blast_dcache_page_indexed = (void *)cache_noop;
else if (dc_lsize == 16)
-@@ -194,6 +203,9 @@ static void r4k_blast_dcache_setup(void)
+@@ -239,6 +248,9 @@ static void r4k_blast_dcache_setup(void)
{
unsigned long dc_lsize = cpu_dcache_line_size();
@@ -308,7 +308,7 @@
if (dc_lsize == 0)
r4k_blast_dcache = (void *)cache_noop;
else if (dc_lsize == 16)
-@@ -793,6 +805,8 @@ static void local_r4k_flush_cache_sigtra
+@@ -880,6 +892,8 @@ static void local_r4k_flush_cache_sigtra
unsigned long addr = (unsigned long) arg;
R4600_HIT_CACHEOP_WAR_IMPL;
@@ -317,7 +317,7 @@
if (dc_lsize)
protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
if (!cpu_icache_snoops_remote_store && scache_size)
-@@ -1602,6 +1616,17 @@ static void coherency_setup(void)
+@@ -1704,6 +1718,17 @@ static void coherency_setup(void)
* silly idea of putting something else there ...
*/
switch (current_cpu_type()) {
@@ -335,7 +335,7 @@
case CPU_R4000PC:
case CPU_R4000SC:
case CPU_R4000MC:
-@@ -1648,6 +1673,15 @@ void r4k_cache_init(void)
+@@ -1750,6 +1775,15 @@ void r4k_cache_init(void)
extern void build_copy_page(void);
struct cpuinfo_mips *c = &current_cpu_data;
@@ -351,7 +351,7 @@
probe_pcache();
setup_scache();
-@@ -1717,7 +1751,15 @@ void r4k_cache_init(void)
+@@ -1819,7 +1853,15 @@ void r4k_cache_init(void)
*/
local_r4k___flush_cache_all(NULL);
diff --git a/target/linux/brcm47xx/patches-4.4/160-kmap_coherent.patch b/target/linux/brcm47xx/patches-4.4/160-kmap_coherent.patch
index 3d65fdfd62..af8c27a674 100644
--- a/target/linux/brcm47xx/patches-4.4/160-kmap_coherent.patch
+++ b/target/linux/brcm47xx/patches-4.4/160-kmap_coherent.patch
@@ -29,7 +29,7 @@ This fixes OpenWrt ticket #1485: https://dev.openwrt.org/ticket/1485
#endif /* __ASM_MACH_BCM47XX_CPU_FEATURE_OVERRIDES_H */
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
-@@ -600,7 +600,7 @@ static inline void local_r4k_flush_cache
+@@ -645,7 +645,7 @@ static inline void local_r4k_flush_cache
*/
map_coherent = (cpu_has_dc_aliases &&
page_mapped(page) && !Page_dcache_dirty(page));
@@ -38,7 +38,7 @@ This fixes OpenWrt ticket #1485: https://dev.openwrt.org/ticket/1485
vaddr = kmap_coherent(page, addr);
else
vaddr = kmap_atomic(page);
-@@ -625,7 +625,7 @@ static inline void local_r4k_flush_cache
+@@ -670,7 +670,7 @@ static inline void local_r4k_flush_cache
}
if (vaddr) {
diff --git a/target/linux/generic/config-4.4 b/target/linux/generic/config-4.4
index 17c6db9f6c..9bd304f692 100644
--- a/target/linux/generic/config-4.4
+++ b/target/linux/generic/config-4.4
@@ -1378,6 +1378,7 @@ CONFIG_HW_PERF_EVENTS=y
# CONFIG_HW_RANDOM_PPC4XX is not set
# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_HW_RANDOM_VIA is not set
+# CONFIG_HW_RANDOM_VIRTIO is not set
# CONFIG_HYPERV is not set
# CONFIG_HYSDN is not set
CONFIG_HZ=100
@@ -4669,9 +4670,14 @@ CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
# CONFIG_VIDEO_WM8775 is not set
# CONFIG_VIDEO_ZORAN is not set
# CONFIG_VIRTIO_BALLOON is not set
+# CONFIG_VIRTIO_BLK is not set
+# CONFIG_VIRTIO_CONSOLE is not set
# CONFIG_VIRTIO_INPUT is not set
# CONFIG_VIRTIO_MMIO is not set
+# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set
+# CONFIG_VIRTIO_NET is not set
# CONFIG_VIRTIO_PCI is not set
+# CONFIG_VIRTIO_PCI_LEGACY is not set
# CONFIG_VIRTUALIZATION is not set
# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
# CONFIG_VIRT_DRIVERS is not set
diff --git a/target/linux/generic/patches-4.4/046-ubifs-silence-error-output-if-MS_SILENT-is-set.patch b/target/linux/generic/patches-4.4/046-ubifs-silence-error-output-if-MS_SILENT-is-set.patch
new file mode 100644
index 0000000000..ee679fa755
--- /dev/null
+++ b/target/linux/generic/patches-4.4/046-ubifs-silence-error-output-if-MS_SILENT-is-set.patch
@@ -0,0 +1,37 @@
+From 6da56ec248e48c9c78721f51528c178adec3b35b Mon Sep 17 00:00:00 2001
+In-Reply-To: <5765615E.5010409@nod.at>
+References: <5765615E.5010409@nod.at>
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sat, 18 Jun 2016 11:42:52 +0200
+Subject: [PATCH] ubifs: silence error output if MS_SILENT is set
+X-Patchwork-Id: 637491
+X-Patchwork-Delegate: richard.weinberger@gmail.com
+To: linux-mtd@lists.infradead.org
+Cc: Artem Bityutskiy <dedekind1@gmail.com>,
+ Richard Weinberger <richard.weinberger@gmail.com>
+
+This change completes
+commit 90bea5a3f0bf680b87b90516f3c231997f4b8f3b
+which already implements support for MS_SILENT except for that one
+error message which is still being displayed despite MS_SILENT being
+set. Suppress that error message as well in case MS_SILENT is set.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ fs/ubifs/super.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/fs/ubifs/super.c
++++ b/fs/ubifs/super.c
+@@ -2107,8 +2107,9 @@ static struct dentry *ubifs_mount(struct
+ */
+ ubi = open_ubi(name, UBI_READONLY);
+ if (IS_ERR(ubi)) {
+- pr_err("UBIFS error (pid: %d): cannot open \"%s\", error %d",
+- current->pid, name, (int)PTR_ERR(ubi));
++ if (!(flags & MS_SILENT))
++ pr_err("UBIFS error (pid: %d): cannot open \"%s\", error %d",
++ current->pid, name, (int)PTR_ERR(ubi));
+ return ERR_CAST(ubi);
+ }
+
diff --git a/target/linux/generic/patches-4.4/271-uapi-libc-compat.h-do-not-rely-on-__GLIBC__.patch b/target/linux/generic/patches-4.4/271-uapi-libc-compat.h-do-not-rely-on-__GLIBC__.patch
index b8e6a3a882..2a29535eed 100644
--- a/target/linux/generic/patches-4.4/271-uapi-libc-compat.h-do-not-rely-on-__GLIBC__.patch
+++ b/target/linux/generic/patches-4.4/271-uapi-libc-compat.h-do-not-rely-on-__GLIBC__.patch
@@ -28,7 +28,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
-/* Coordinate with glibc net/if.h header. */
+/* Coordinate with libc net/if.h header. */
- #if defined(_NET_IF_H)
+ #if defined(_NET_IF_H) && defined(__USE_MISC)
-/* GLIBC headers included first so don't define anything
+/* LIBC headers included first so don't define anything
diff --git a/target/linux/generic/patches-4.4/610-netfilter_match_bypass_default_checks.patch b/target/linux/generic/patches-4.4/610-netfilter_match_bypass_default_checks.patch
index eccad944ea..ea9558fccf 100644
--- a/target/linux/generic/patches-4.4/610-netfilter_match_bypass_default_checks.patch
+++ b/target/linux/generic/patches-4.4/610-netfilter_match_bypass_default_checks.patch
@@ -50,25 +50,16 @@
static bool
ip_checkentry(const struct ipt_ip *ip)
{
-@@ -569,7 +595,7 @@ static void cleanup_match(struct xt_entr
- }
-
- static int
--check_entry(const struct ipt_entry *e, const char *name)
-+check_entry(struct ipt_entry *e, const char *name)
- {
- const struct xt_entry_target *t;
-
-@@ -578,6 +604,8 @@ check_entry(const struct ipt_entry *e, c
- return -EINVAL;
- }
+@@ -664,6 +690,8 @@ find_check_entry(struct ipt_entry *e, st
+ struct xt_mtchk_param mtpar;
+ struct xt_entry_match *ematch;
+ ip_checkdefault(&e->ip);
+
- if (e->target_offset + sizeof(struct xt_entry_target) >
- e->next_offset)
- return -EINVAL;
-@@ -944,6 +972,7 @@ copy_entries_to_user(unsigned int total_
+ e->counters.pcnt = xt_percpu_counter_alloc();
+ if (IS_ERR_VALUE(e->counters.pcnt))
+ return -ENOMEM;
+@@ -948,6 +976,7 @@ copy_entries_to_user(unsigned int total_
const struct xt_table_info *private = table->private;
int ret = 0;
const void *loc_cpu_entry;
@@ -76,7 +67,7 @@
counters = alloc_counters(table);
if (IS_ERR(counters))
-@@ -970,6 +999,14 @@ copy_entries_to_user(unsigned int total_
+@@ -974,6 +1003,14 @@ copy_entries_to_user(unsigned int total_
ret = -EFAULT;
goto free_counters;
}
diff --git a/target/linux/ipq806x/patches-4.4/022-add-db149-dts.patch b/target/linux/ipq806x/patches-4.4/022-add-db149-dts.patch
index 4d3e827b51..0845d3f213 100644
--- a/target/linux/ipq806x/patches-4.4/022-add-db149-dts.patch
+++ b/target/linux/ipq806x/patches-4.4/022-add-db149-dts.patch
@@ -15,7 +15,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
-@@ -506,6 +506,7 @@
+@@ -506,6 +506,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
qcom-apq8084-ifc6540.dtb \
qcom-apq8084-mtp.dtb \
qcom-ipq8064-ap148.dtb \
diff --git a/target/linux/ipq806x/patches-4.4/023-ARM-dts-ipq806x-Disable-i2c-device-on-gsbi4.patch b/target/linux/ipq806x/patches-4.4/023-ARM-dts-ipq806x-Disable-i2c-device-on-gsbi4.patch
index b8c527b6ae..705306d9f0 100644
--- a/target/linux/ipq806x/patches-4.4/023-ARM-dts-ipq806x-Disable-i2c-device-on-gsbi4.patch
+++ b/target/linux/ipq806x/patches-4.4/023-ARM-dts-ipq806x-Disable-i2c-device-on-gsbi4.patch
@@ -23,7 +23,7 @@
gsbi5: gsbi@1a200000 {
--- a/drivers/clk/qcom/gcc-ipq806x.c
+++ b/drivers/clk/qcom/gcc-ipq806x.c
-@@ -294,7 +294,7 @@
+@@ -294,7 +294,7 @@ static struct clk_rcg gsbi1_uart_src = {
.parent_names = gcc_pxo_pll8,
.num_parents = 2,
.ops = &clk_rcg_ops,
@@ -32,7 +32,7 @@
},
},
};
-@@ -312,7 +312,7 @@
+@@ -312,7 +312,7 @@ static struct clk_branch gsbi1_uart_clk
},
.num_parents = 1,
.ops = &clk_branch_ops,
@@ -41,7 +41,7 @@
},
},
};
-@@ -890,7 +890,7 @@
+@@ -890,7 +890,7 @@ static struct clk_branch gsbi1_h_clk = {
.hw.init = &(struct clk_init_data){
.name = "gsbi1_h_clk",
.ops = &clk_branch_ops,
diff --git a/target/linux/ipq806x/patches-4.4/037-mtd-add-SMEM-parser-for-QCOM-platforms.patch b/target/linux/ipq806x/patches-4.4/037-mtd-add-SMEM-parser-for-QCOM-platforms.patch
index d80eb86056..7c0c803565 100644
--- a/target/linux/ipq806x/patches-4.4/037-mtd-add-SMEM-parser-for-QCOM-platforms.patch
+++ b/target/linux/ipq806x/patches-4.4/037-mtd-add-SMEM-parser-for-QCOM-platforms.patch
@@ -16,11 +16,9 @@ Signed-off-by: Ram Chandra Jangir <rjangi@codeaurora.org>
3 files changed, 236 insertions(+)
create mode 100644 drivers/mtd/qcom_smem_part.c
-diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
-index a03ad29..debc887 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
-@@ -190,6 +190,13 @@
+@@ -190,6 +190,13 @@ config MTD_MYLOADER_PARTS
You will still need the parsing functions to be called by the driver
for your particular device. It won't happen automatically.
@@ -34,11 +32,9 @@ index a03ad29..debc887 100644
comment "User Modules And Translation Layers"
#
-diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
-index 99bb9a1..2a44a64 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
-@@ -16,6 +16,7 @@
+@@ -16,6 +16,7 @@ obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o
obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o
obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o
obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
@@ -46,9 +42,6 @@ index 99bb9a1..2a44a64 100644
# 'Users' - code which presents functionality to userspace.
obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o
-diff --git a/drivers/mtd/qcom_smem_part.c b/drivers/mtd/qcom_smem_part.c
-new file mode 100644
-index 0000000..f9c1bca
--- /dev/null
+++ b/drivers/mtd/qcom_smem_part.c
@@ -0,0 +1,228 @@
diff --git a/target/linux/ipq806x/patches-4.4/100-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch b/target/linux/ipq806x/patches-4.4/100-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch
index 68f2b39813..4bba0ac557 100644
--- a/target/linux/ipq806x/patches-4.4/100-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch
+++ b/target/linux/ipq806x/patches-4.4/100-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch
@@ -1,8 +1,8 @@
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
-@@ -390,4 +390,15 @@
- Enable this to support the Broadcom Cygnus PCIe PHY.
- If unsure, say N.
+@@ -390,4 +390,15 @@ config PHY_CYGNUS_PCIE
+ Enable this to support the Broadcom Cygnus PCIe PHY.
+ If unsure, say N.
+config PHY_QCOM_DWC3
+ tristate "QCOM DWC3 USB PHY support"
@@ -18,7 +18,7 @@
endmenu
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
-@@ -48,3 +48,4 @@ obj-$(CONFIG_PHY_TUSB1210) +=
+@@ -48,3 +48,4 @@ obj-$(CONFIG_PHY_TUSB1210) += phy-tusb1
obj-$(CONFIG_PHY_BRCMSTB_SATA) += phy-brcmstb-sata.o
obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o
obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o
diff --git a/target/linux/ipq806x/patches-4.4/111-PCI-qcom-Add-Qualcomm-PCIe-controller-driver.patch b/target/linux/ipq806x/patches-4.4/111-PCI-qcom-Add-Qualcomm-PCIe-controller-driver.patch
index ad1a1b9cb3..4d907988fb 100644
--- a/target/linux/ipq806x/patches-4.4/111-PCI-qcom-Add-Qualcomm-PCIe-controller-driver.patch
+++ b/target/linux/ipq806x/patches-4.4/111-PCI-qcom-Add-Qualcomm-PCIe-controller-driver.patch
@@ -34,7 +34,7 @@ MAINTAINERS | 7 +
--- a/MAINTAINERS
+++ b/MAINTAINERS
-@@ -8253,6 +8253,13 @@
+@@ -8253,6 +8253,13 @@ S: Maintained
F: Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
F: drivers/pci/host/pcie-hisi.c
@@ -50,7 +50,7 @@ MAINTAINERS | 7 +
L: linux-pcmcia@lists.infradead.org
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
-@@ -173,4 +173,13 @@
+@@ -173,4 +173,13 @@ config PCI_HISI
help
Say Y here if you want PCIe controller support on HiSilicon HIP05 SoC
@@ -745,7 +745,7 @@ MAINTAINERS | 7 +
+MODULE_ALIAS("platform:qcom-pcie");
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
-@@ -20,3 +20,4 @@
+@@ -20,3 +20,4 @@ obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-ip
obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
obj-$(CONFIG_PCI_HISI) += pcie-hisi.o
diff --git a/target/linux/ipq806x/patches-4.4/133-ARM-Add-Krait-L2-register-accessor-functions.patch b/target/linux/ipq806x/patches-4.4/133-ARM-Add-Krait-L2-register-accessor-functions.patch
index 01bd7497d1..36a92c858a 100644
--- a/target/linux/ipq806x/patches-4.4/133-ARM-Add-Krait-L2-register-accessor-functions.patch
+++ b/target/linux/ipq806x/patches-4.4/133-ARM-Add-Krait-L2-register-accessor-functions.patch
@@ -38,7 +38,7 @@ arch/arm/common/Kconfig | 3 ++
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
-@@ -9,6 +9,9 @@
+@@ -9,6 +9,9 @@ config DMABOUNCE
bool
select ZONE_DMA
@@ -50,7 +50,7 @@ arch/arm/common/Kconfig | 3 ++
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
-@@ -7,6 +7,7 @@
+@@ -7,6 +7,7 @@ obj-y += firmware.o
obj-$(CONFIG_ICST) += icst.o
obj-$(CONFIG_SA1111) += sa1111.o
obj-$(CONFIG_DMABOUNCE) += dmabounce.o
diff --git a/target/linux/ipq806x/patches-4.4/134-clk-mux-Split-out-register-accessors-for-reuse.patch b/target/linux/ipq806x/patches-4.4/134-clk-mux-Split-out-register-accessors-for-reuse.patch
index acf5820e6c..6efa5d8045 100644
--- a/target/linux/ipq806x/patches-4.4/134-clk-mux-Split-out-register-accessors-for-reuse.patch
+++ b/target/linux/ipq806x/patches-4.4/134-clk-mux-Split-out-register-accessors-for-reuse.patch
@@ -18,8 +18,6 @@ Signed-off-by: Ram Chandra Jangir <rjangi@codeaurora.org>
include/linux/clk-provider.h | 9 ++++--
2 files changed, 53 insertions(+), 30 deletions(-)
-diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
-index 7129c86..b03a34d 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -28,35 +28,24 @@
@@ -64,7 +62,7 @@ index 7129c86..b03a34d 100644
val--;
if (val >= num_parents)
-@@ -64,24 +53,53 @@ static u8 clk_mux_get_parent(struct clk_hw *hw)
+@@ -64,24 +53,53 @@ static u8 clk_mux_get_parent(struct clk_
return val;
}
@@ -127,7 +125,7 @@ index 7129c86..b03a34d 100644
if (mux->lock)
spin_lock_irqsave(mux->lock, flags);
else
-@@ -105,7 +123,7 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
+@@ -105,7 +123,7 @@ static int clk_mux_set_parent(struct clk
}
const struct clk_ops clk_mux_ops = {
@@ -136,7 +134,7 @@ index 7129c86..b03a34d 100644
.set_parent = clk_mux_set_parent,
.determine_rate = __clk_mux_determine_rate,
};
-@@ -120,7 +138,7 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,
+@@ -120,7 +138,7 @@ struct clk *clk_register_mux_table(struc
const char * const *parent_names, u8 num_parents,
unsigned long flags,
void __iomem *reg, u8 shift, u32 mask,
@@ -145,11 +143,9 @@ index 7129c86..b03a34d 100644
{
struct clk_mux *mux;
struct clk *clk;
-diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
-index c56988a..b6b17b5 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
-@@ -432,7 +432,7 @@ void clk_unregister_divider(struct clk *clk);
+@@ -433,7 +433,7 @@ void clk_unregister_divider(struct clk *
struct clk_mux {
struct clk_hw hw;
void __iomem *reg;
@@ -158,7 +154,7 @@ index c56988a..b6b17b5 100644
u32 mask;
u8 shift;
u8 flags;
-@@ -448,6 +448,11 @@ struct clk_mux {
+@@ -449,6 +449,11 @@ struct clk_mux {
extern const struct clk_ops clk_mux_ops;
extern const struct clk_ops clk_mux_ro_ops;
@@ -170,7 +166,7 @@ index c56988a..b6b17b5 100644
struct clk *clk_register_mux(struct device *dev, const char *name,
const char * const *parent_names, u8 num_parents,
unsigned long flags,
-@@ -458,7 +463,7 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,
+@@ -459,7 +464,7 @@ struct clk *clk_register_mux_table(struc
const char * const *parent_names, u8 num_parents,
unsigned long flags,
void __iomem *reg, u8 shift, u32 mask,
@@ -179,6 +175,3 @@ index c56988a..b6b17b5 100644
void clk_unregister_mux(struct clk *clk);
---
-2.7.2
-
diff --git a/target/linux/ipq806x/patches-4.4/135-clk-Avoid-sending-high-rates-to-downstream-clocks-du.patch b/target/linux/ipq806x/patches-4.4/135-clk-Avoid-sending-high-rates-to-downstream-clocks-du.patch
index 5df0a5613e..5015d32d86 100644
--- a/target/linux/ipq806x/patches-4.4/135-clk-Avoid-sending-high-rates-to-downstream-clocks-du.patch
+++ b/target/linux/ipq806x/patches-4.4/135-clk-Avoid-sending-high-rates-to-downstream-clocks-du.patch
@@ -37,11 +37,9 @@ Signed-off-by: Ram Chandra Jangir <rjangi@codeaurora.org>
drivers/clk/clk.c | 34 ++++++++++++++++++++++------------
1 file changed, 22 insertions(+), 12 deletions(-)
-diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
-index f13c3f4..8404c3c 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
-@@ -1427,21 +1427,24 @@ static struct clk_core *clk_propagate_rate_change(struct clk_core *core,
+@@ -1427,21 +1427,24 @@ static struct clk_core *clk_propagate_ra
* walk down a subtree and set the new rates notifying the rate
* change on the way
*/
@@ -73,7 +71,7 @@ index f13c3f4..8404c3c 100644
if (core->new_parent && core->new_parent != core->parent) {
old_parent = __clk_set_parent_before(core, core->new_parent);
-@@ -1467,7 +1470,7 @@ static void clk_change_rate(struct clk_core *core)
+@@ -1467,7 +1470,7 @@ static void clk_change_rate(struct clk_c
trace_clk_set_rate_complete(core, core->new_rate);
@@ -82,7 +80,7 @@ index f13c3f4..8404c3c 100644
if (core->notifier_count && old_rate != core->rate)
__clk_notify(core, POST_RATE_CHANGE, old_rate, core->rate);
-@@ -1483,12 +1486,13 @@ static void clk_change_rate(struct clk_core *core)
+@@ -1483,12 +1486,13 @@ static void clk_change_rate(struct clk_c
/* Skip children who will be reparented to another clock */
if (child->new_parent && child->new_parent != core)
continue;
@@ -99,7 +97,7 @@ index f13c3f4..8404c3c 100644
}
static int clk_core_set_rate_nolock(struct clk_core *core,
-@@ -1497,6 +1501,7 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
+@@ -1497,6 +1501,7 @@ static int clk_core_set_rate_nolock(stru
struct clk_core *top, *fail_clk;
unsigned long rate = req_rate;
int ret = 0;
@@ -107,7 +105,7 @@ index f13c3f4..8404c3c 100644
if (!core)
return 0;
-@@ -1522,8 +1527,13 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
+@@ -1522,8 +1527,13 @@ static int clk_core_set_rate_nolock(stru
return -EBUSY;
}
@@ -122,6 +120,3 @@ index f13c3f4..8404c3c 100644
core->req_rate = req_rate;
---
-2.7.2
-
diff --git a/target/linux/ipq806x/patches-4.4/136-clk-Add-safe-switch-hook.patch b/target/linux/ipq806x/patches-4.4/136-clk-Add-safe-switch-hook.patch
index e969f6bca4..de3ac7d14c 100644
--- a/target/linux/ipq806x/patches-4.4/136-clk-Add-safe-switch-hook.patch
+++ b/target/linux/ipq806x/patches-4.4/136-clk-Add-safe-switch-hook.patch
@@ -19,8 +19,6 @@ Signed-off-by: Ram Chandra Jangir <rjangi@codeaurora.org>
include/linux/clk-provider.h | 1 +
2 files changed, 54 insertions(+), 8 deletions(-)
-diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
-index 8404c3c..a29319a 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -51,9 +51,12 @@ struct clk_core {
@@ -46,7 +44,7 @@ index 8404c3c..a29319a 100644
core->new_rate = new_rate;
core->new_parent = new_parent;
-@@ -1281,6 +1285,18 @@ static void clk_calc_subtree(struct clk_core *core, unsigned long new_rate,
+@@ -1281,6 +1285,18 @@ static void clk_calc_subtree(struct clk_
if (new_parent && new_parent != core->parent)
new_parent->new_child = core;
@@ -65,7 +63,7 @@ index 8404c3c..a29319a 100644
hlist_for_each_entry(child, &core->children, child_node) {
child->new_rate = clk_recalc(child, new_rate);
clk_calc_subtree(child, child->new_rate, NULL, 0);
-@@ -1393,14 +1409,43 @@ static struct clk_core *clk_propagate_rate_change(struct clk_core *core,
+@@ -1393,14 +1409,43 @@ static struct clk_core *clk_propagate_ra
unsigned long event)
{
struct clk_core *child, *tmp_clk, *fail_clk = NULL;
@@ -112,7 +110,7 @@ index 8404c3c..a29319a 100644
fail_clk = core;
}
-@@ -1446,7 +1491,8 @@ clk_change_rate(struct clk_core *core, unsigned long best_parent_rate)
+@@ -1446,7 +1491,8 @@ clk_change_rate(struct clk_core *core, u
old_rate = core->rate;
@@ -122,7 +120,7 @@ index 8404c3c..a29319a 100644
old_parent = __clk_set_parent_before(core, core->new_parent);
trace_clk_set_parent(core, core->new_parent);
-@@ -1472,9 +1518,6 @@ clk_change_rate(struct clk_core *core, unsigned long best_parent_rate)
+@@ -1472,9 +1518,6 @@ clk_change_rate(struct clk_core *core, u
core->rate = core->new_rate;
@@ -132,7 +130,7 @@ index 8404c3c..a29319a 100644
if (core->flags & CLK_RECALC_NEW_RATES)
(void)clk_calc_new_rates(core, core->new_rate);
-@@ -1537,6 +1580,8 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
+@@ -1537,6 +1580,8 @@ static int clk_core_set_rate_nolock(stru
core->req_rate = req_rate;
@@ -141,8 +139,6 @@ index 8404c3c..a29319a 100644
return ret;
}
-diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
-index b6b17b5..5d49262 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -202,6 +202,7 @@ struct clk_ops {
@@ -153,6 +149,3 @@ index b6b17b5..5d49262 100644
int (*set_rate)(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate);
int (*set_rate_and_parent)(struct clk_hw *hw,
---
-2.7.2
-
diff --git a/target/linux/ipq806x/patches-4.4/137-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch b/target/linux/ipq806x/patches-4.4/137-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch
index a1b1f4b1f7..4924e5ff4b 100644
--- a/target/linux/ipq806x/patches-4.4/137-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch
+++ b/target/linux/ipq806x/patches-4.4/137-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch
@@ -28,7 +28,7 @@ I'd really like to get rid of __clk_hfpll_init_once() if possible...
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
-@@ -8,6 +8,7 @@
+@@ -8,6 +8,7 @@ clk-qcom-y += clk-rcg2.o
clk-qcom-y += clk-branch.o
clk-qcom-y += clk-regmap-divider.o
clk-qcom-y += clk-regmap-mux.o
diff --git a/target/linux/ipq806x/patches-4.4/138-clk-qcom-Add-HFPLL-driver.patch b/target/linux/ipq806x/patches-4.4/138-clk-qcom-Add-HFPLL-driver.patch
index 5a452dbcbc..cc7c4cd177 100644
--- a/target/linux/ipq806x/patches-4.4/138-clk-qcom-Add-HFPLL-driver.patch
+++ b/target/linux/ipq806x/patches-4.4/138-clk-qcom-Add-HFPLL-driver.patch
@@ -73,7 +73,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+ };
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
-@@ -106,3 +106,11 @@
+@@ -106,3 +106,11 @@ config MSM_MMCC_8974
Support for the multimedia clock controller on msm8974 devices.
Say Y if you want to support multimedia devices such as display,
graphics, video encode/decode, camera, etc.
@@ -87,7 +87,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+ such as MSM8974, APQ8084, etc.
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
-@@ -23,3 +23,4 @@
+@@ -23,3 +23,4 @@ obj-$(CONFIG_MSM_LCC_8960) += lcc-msm896
obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
diff --git a/target/linux/ipq806x/patches-4.4/139-clk-qcom-Add-IPQ806X-s-HFPLLs.patch b/target/linux/ipq806x/patches-4.4/139-clk-qcom-Add-IPQ806X-s-HFPLLs.patch
index 5b191b5597..a01decfd8b 100644
--- a/target/linux/ipq806x/patches-4.4/139-clk-qcom-Add-IPQ806X-s-HFPLLs.patch
+++ b/target/linux/ipq806x/patches-4.4/139-clk-qcom-Add-IPQ806X-s-HFPLLs.patch
@@ -29,7 +29,7 @@ drivers/clk/qcom/gcc-ipq806x.c | 83 ++++++++++++++++++++++++++++++++++++++++++
#include "reset.h"
static struct clk_pll pll0 = {
-@@ -113,6 +114,85 @@
+@@ -113,6 +114,85 @@ static struct clk_regmap pll8_vote = {
},
};
@@ -115,7 +115,7 @@ drivers/clk/qcom/gcc-ipq806x.c | 83 ++++++++++++++++++++++++++++++++++++++++++
static struct clk_pll pll14 = {
.l_reg = 0x31c4,
.m_reg = 0x31c8,
-@@ -2837,6 +2917,9 @@
+@@ -2837,6 +2917,9 @@ static struct clk_regmap *gcc_ipq806x_cl
[UBI32_CORE2_CLK_SRC] = &ubi32_core2_src_clk.clkr,
[NSSTCM_CLK_SRC] = &nss_tcm_src.clkr,
[NSSTCM_CLK] = &nss_tcm_clk.clkr,
diff --git a/target/linux/ipq806x/patches-4.4/140-clk-qcom-Add-support-for-Krait-clocks.patch b/target/linux/ipq806x/patches-4.4/140-clk-qcom-Add-support-for-Krait-clocks.patch
index 522482d841..ecf1ef589c 100644
--- a/target/linux/ipq806x/patches-4.4/140-clk-qcom-Add-support-for-Krait-clocks.patch
+++ b/target/linux/ipq806x/patches-4.4/140-clk-qcom-Add-support-for-Krait-clocks.patch
@@ -30,7 +30,7 @@ drivers/clk/qcom/Kconfig | 4 ++
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
-@@ -114,3 +114,7 @@
+@@ -114,3 +114,7 @@ config QCOM_HFPLL
Support for the high-frequency PLLs present on Qualcomm devices.
Say Y if you want to support CPU frequency scaling on devices
such as MSM8974, APQ8084, etc.
@@ -40,7 +40,7 @@ drivers/clk/qcom/Kconfig | 4 ++
+ select KRAIT_L2_ACCESSORS
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
-@@ -8,6 +8,7 @@
+@@ -8,6 +8,7 @@ clk-qcom-y += clk-rcg2.o
clk-qcom-y += clk-branch.o
clk-qcom-y += clk-regmap-divider.o
clk-qcom-y += clk-regmap-mux.o
@@ -48,7 +48,6 @@ drivers/clk/qcom/Kconfig | 4 ++
clk-qcom-y += clk-hfpll.o
clk-qcom-y += reset.o
clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
-
--- /dev/null
+++ b/drivers/clk/qcom/clk-krait.c
@@ -0,0 +1,166 @@
diff --git a/target/linux/ipq806x/patches-4.4/141-clk-qcom-Add-KPSS-ACC-GCC-driver.patch b/target/linux/ipq806x/patches-4.4/141-clk-qcom-Add-KPSS-ACC-GCC-driver.patch
index b2ddbc8a68..2b0bbb01a3 100644
--- a/target/linux/ipq806x/patches-4.4/141-clk-qcom-Add-KPSS-ACC-GCC-driver.patch
+++ b/target/linux/ipq806x/patches-4.4/141-clk-qcom-Add-KPSS-ACC-GCC-driver.patch
@@ -31,7 +31,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
--- a/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt
-@@ -21,10 +21,17 @@
+@@ -21,10 +21,17 @@ PROPERTIES
the register region. An optional second element specifies
the base address and size of the alias register region.
@@ -82,7 +82,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+ };
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
-@@ -115,6 +115,14 @@
+@@ -115,6 +115,14 @@ config QCOM_HFPLL
Say Y if you want to support CPU frequency scaling on devices
such as MSM8974, APQ8084, etc.
@@ -99,7 +99,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
select KRAIT_L2_ACCESSORS
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
-@@ -9,6 +9,7 @@
+@@ -9,6 +9,7 @@ clk-qcom-y += clk-branch.o
clk-qcom-y += clk-regmap-divider.o
clk-qcom-y += clk-regmap-mux.o
clk-qcom-$(CONFIG_KRAIT_CLOCKS) += clk-krait.o
diff --git a/target/linux/ipq806x/patches-4.4/142-clk-qcom-Add-Krait-clock-controller-driver.patch b/target/linux/ipq806x/patches-4.4/142-clk-qcom-Add-Krait-clock-controller-driver.patch
index f0e946781b..813366fdca 100644
--- a/target/linux/ipq806x/patches-4.4/142-clk-qcom-Add-Krait-clock-controller-driver.patch
+++ b/target/linux/ipq806x/patches-4.4/142-clk-qcom-Add-Krait-clock-controller-driver.patch
@@ -56,7 +56,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+ };
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
-@@ -123,6 +123,14 @@
+@@ -123,6 +123,14 @@ config KPSS_XCC
if you want to support CPU frequency scaling on devices such
as MSM8960, APQ8064, etc.
@@ -73,7 +73,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
select KRAIT_L2_ACCESSORS
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
-@@ -26,3 +26,4 @@
+@@ -26,3 +26,4 @@ obj-$(CONFIG_MSM_GCC_8974) += gcc-msm897
obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
obj-$(CONFIG_QCOM_HFPLL) += hfpll.o
diff --git a/target/linux/ipq806x/patches-4.4/143-cpufreq-Add-module-to-register-cpufreq-on-Krait-CPUs.patch b/target/linux/ipq806x/patches-4.4/143-cpufreq-Add-module-to-register-cpufreq-on-Krait-CPUs.patch
index d4c43f412a..e8d8ddf674 100644
--- a/target/linux/ipq806x/patches-4.4/143-cpufreq-Add-module-to-register-cpufreq-on-Krait-CPUs.patch
+++ b/target/linux/ipq806x/patches-4.4/143-cpufreq-Add-module-to-register-cpufreq-on-Krait-CPUs.patch
@@ -69,7 +69,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+ };
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
-@@ -95,6 +95,15 @@
+@@ -95,6 +95,15 @@ config ARM_OMAP2PLUS_CPUFREQ
depends on ARCH_OMAP2PLUS
default ARCH_OMAP2PLUS
@@ -87,7 +87,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
help
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
-@@ -61,6 +61,7 @@
+@@ -61,6 +61,7 @@ obj-$(CONFIG_ARM_MT8173_CPUFREQ) += mt81
obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o
obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o
diff --git a/target/linux/ipq806x/patches-4.4/145-cpufreq-Add-a-cpufreq-krait-based-on-cpufre.patch b/target/linux/ipq806x/patches-4.4/145-cpufreq-Add-a-cpufreq-krait-based-on-cpufre.patch
index f33c9e0d8c..67770e8ce9 100644
--- a/target/linux/ipq806x/patches-4.4/145-cpufreq-Add-a-cpufreq-krait-based-on-cpufre.patch
+++ b/target/linux/ipq806x/patches-4.4/145-cpufreq-Add-a-cpufreq-krait-based-on-cpufre.patch
@@ -21,7 +21,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
-@@ -198,6 +198,19 @@
+@@ -198,6 +198,19 @@ config CPUFREQ_DT
If in doubt, say N.
@@ -43,7 +43,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
endif
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
-@@ -13,6 +13,7 @@
+@@ -13,6 +13,7 @@ obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)
obj-$(CONFIG_CPU_FREQ_GOV_COMMON) += cpufreq_governor.o
obj-$(CONFIG_CPUFREQ_DT) += cpufreq-dt.o
@@ -446,7 +446,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+MODULE_LICENSE("GPL v2");
--- a/drivers/cpufreq/qcom-cpufreq.c
+++ b/drivers/cpufreq/qcom-cpufreq.c
-@@ -168,11 +168,8 @@
+@@ -168,11 +168,8 @@ static int __init qcom_cpufreq_populate_
static int __init qcom_cpufreq_driver_init(void)
{
diff --git a/target/linux/ipq806x/patches-4.4/156-dmaengine-Add-ADM-driver.patch b/target/linux/ipq806x/patches-4.4/156-dmaengine-Add-ADM-driver.patch
index 805f28f323..02038aa942 100644
--- a/target/linux/ipq806x/patches-4.4/156-dmaengine-Add-ADM-driver.patch
+++ b/target/linux/ipq806x/patches-4.4/156-dmaengine-Add-ADM-driver.patch
@@ -35,7 +35,7 @@ drivers/dma/Kconfig | 10 +
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
-@@ -558,4 +558,14 @@
+@@ -558,4 +558,14 @@ config DMATEST
config DMA_ENGINE_RAID
bool
@@ -955,7 +955,7 @@ drivers/dma/Kconfig | 10 +
+MODULE_LICENSE("GPL v2");
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
-@@ -65,5 +65,6 @@
+@@ -65,5 +65,6 @@ obj-$(CONFIG_TI_DMA_CROSSBAR) += ti-dma-
obj-$(CONFIG_TI_EDMA) += edma.o
obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
obj-$(CONFIG_ZX_DMA) += zx296702_dma.o
diff --git a/target/linux/ipq806x/patches-4.4/161-mtd-nand-Create-a-BBT-flag-to-access-bad-block-markers-in-raw-mode.patch b/target/linux/ipq806x/patches-4.4/161-mtd-nand-Create-a-BBT-flag-to-access-bad-block-markers-in-raw-mode.patch
index 21fe405b90..154649dca6 100644
--- a/target/linux/ipq806x/patches-4.4/161-mtd-nand-Create-a-BBT-flag-to-access-bad-block-markers-in-raw-mode.patch
+++ b/target/linux/ipq806x/patches-4.4/161-mtd-nand-Create-a-BBT-flag-to-access-bad-block-markers-in-raw-mode.patch
@@ -38,7 +38,7 @@ drivers/mtd/nand/nand_base.c | 6 +++++-
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
-@@ -394,7 +394,11 @@
+@@ -394,7 +394,11 @@ static int nand_default_block_markbad(st
} else {
ops.len = ops.ooblen = 1;
}
@@ -53,7 +53,7 @@ drivers/mtd/nand/nand_base.c | 6 +++++-
if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
-@@ -420,7 +420,11 @@
+@@ -420,7 +420,11 @@ static int scan_block_fast(struct mtd_in
ops.oobbuf = buf;
ops.ooboffs = 0;
ops.datbuf = NULL;
@@ -68,7 +68,7 @@ drivers/mtd/nand/nand_base.c | 6 +++++-
/*
--- a/include/linux/mtd/bbm.h
+++ b/include/linux/mtd/bbm.h
-@@ -116,6 +116,12 @@
+@@ -116,6 +116,12 @@ struct nand_bbt_descr {
#define NAND_BBT_NO_OOB_BBM 0x00080000
/*
diff --git a/target/linux/ipq806x/patches-4.4/162-mtd-nand-Qualcomm-NAND-controller-driver.patch b/target/linux/ipq806x/patches-4.4/162-mtd-nand-Qualcomm-NAND-controller-driver.patch
index 19e5f91812..84ff6e74e0 100644
--- a/target/linux/ipq806x/patches-4.4/162-mtd-nand-Qualcomm-NAND-controller-driver.patch
+++ b/target/linux/ipq806x/patches-4.4/162-mtd-nand-Qualcomm-NAND-controller-driver.patch
@@ -80,7 +80,7 @@ drivers/mtd/nand/Kconfig | 7 +
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
-@@ -546,4 +546,11 @@
+@@ -546,4 +546,11 @@ config MTD_NAND_HISI504
help
Enables support for NAND controller on Hisilicon SoC Hip04.
@@ -2015,7 +2015,7 @@ drivers/mtd/nand/Kconfig | 7 +
+MODULE_LICENSE("GPL v2");
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
-@@ -55,5 +55,6 @@
+@@ -55,5 +55,6 @@ obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) +=
obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_nand.o
obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o
obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/
diff --git a/target/linux/ipq806x/patches-4.4/168-ARM-qcom-add-smb208-DT.patch b/target/linux/ipq806x/patches-4.4/168-ARM-qcom-add-smb208-DT.patch
index ef81ed2e55..0ad0508a9d 100644
--- a/target/linux/ipq806x/patches-4.4/168-ARM-qcom-add-smb208-DT.patch
+++ b/target/linux/ipq806x/patches-4.4/168-ARM-qcom-add-smb208-DT.patch
@@ -11,31 +11,31 @@ Signed-off-by: Adrian Panella <ianchi74@outlook.com>
- smb208_s1a: smb208-s1a {
- compatible = "qcom,rpm-smb208";
- reg = <QCOM_RPM_SMB208_S1a>;
--
-- regulator-min-microvolt = <1050000>;
-- regulator-max-microvolt = <1150000>;
+ regulators {
+ compatible = "qcom,rpm-smb208-regulators";
-- qcom,switch-mode-frequency = <1200000>;
--
-- };
+- regulator-min-microvolt = <1050000>;
+- regulator-max-microvolt = <1150000>;
+ smb208_s1a: s1a {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1150000>;
+- qcom,switch-mode-frequency = <1200000>;
++ qcom,switch-mode-frequency = <1200000>;
+
+- };
+-
- smb208_s1b: smb208-s1b {
- compatible = "qcom,rpm-smb208";
- reg = <QCOM_RPM_SMB208_S1b>;
-+ qcom,switch-mode-frequency = <1200000>;
-
+-
- regulator-min-microvolt = <1050000>;
- regulator-max-microvolt = <1150000>;
--
-- qcom,switch-mode-frequency = <1200000>;
-- };
+ };
+- qcom,switch-mode-frequency = <1200000>;
+- };
+-
- smb208_s2a: smb208-s2a {
- compatible = "qcom,rpm-smb208";
- reg = <QCOM_RPM_SMB208_S2a>;
@@ -71,7 +71,7 @@ Signed-off-by: Adrian Panella <ianchi74@outlook.com>
+ };
};
};
-
+
--- a/arch/arm/boot/dts/qcom-ipq8065.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8065.dtsi
@@ -311,45 +311,37 @@
@@ -81,31 +81,31 @@ Signed-off-by: Adrian Panella <ianchi74@outlook.com>
- smb208_s1a: smb208-s1a {
- compatible = "qcom,rpm-smb208";
- reg = <QCOM_RPM_SMB208_S1a>;
--
-- regulator-min-microvolt = <1050000>;
-- regulator-max-microvolt = <1150000>;
+ regulators {
+ compatible = "qcom,rpm-smb208-regulators";
-- qcom,switch-mode-frequency = <1200000>;
--
-- };
+- regulator-min-microvolt = <1050000>;
+- regulator-max-microvolt = <1150000>;
+ smb208_s1a: s1a {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1150000>;
+- qcom,switch-mode-frequency = <1200000>;
++ qcom,switch-mode-frequency = <1200000>;
+
+- };
+-
- smb208_s1b: smb208-s1b {
- compatible = "qcom,rpm-smb208";
- reg = <QCOM_RPM_SMB208_S1b>;
-+ qcom,switch-mode-frequency = <1200000>;
-
+-
- regulator-min-microvolt = <1050000>;
- regulator-max-microvolt = <1150000>;
--
-- qcom,switch-mode-frequency = <1200000>;
-- };
+ };
+- qcom,switch-mode-frequency = <1200000>;
+- };
+-
- smb208_s2a: smb208-s2a {
- compatible = "qcom,rpm-smb208";
- reg = <QCOM_RPM_SMB208_S2a>;
@@ -140,4 +140,5 @@ Signed-off-by: Adrian Panella <ianchi74@outlook.com>
+ qcom,switch-mode-frequency = <1400000>;
+ };
};
- };
+
+ cxo_clk: cxo-clk {
diff --git a/target/linux/ipq806x/patches-4.4/300-arch-arm-force-ZRELADDR-on-arch-qcom.patch b/target/linux/ipq806x/patches-4.4/300-arch-arm-force-ZRELADDR-on-arch-qcom.patch
index c0281ff070..35ba6fbb22 100644
--- a/target/linux/ipq806x/patches-4.4/300-arch-arm-force-ZRELADDR-on-arch-qcom.patch
+++ b/target/linux/ipq806x/patches-4.4/300-arch-arm-force-ZRELADDR-on-arch-qcom.patch
@@ -33,7 +33,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
-@@ -323,7 +323,7 @@
+@@ -324,7 +324,7 @@ config ARCH_MULTIPLATFORM
select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_HAS_SG_CHAIN
select ARM_PATCH_PHYS_VIRT
@@ -44,7 +44,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
select GENERIC_CLOCKEVENTS
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
-@@ -256,9 +256,11 @@
+@@ -256,9 +256,11 @@ MACHINE := arch/arm/mach-$(word 1,$(mac
else
MACHINE :=
endif
diff --git a/target/linux/ipq806x/patches-4.4/400-dsa-add-qca.patch b/target/linux/ipq806x/patches-4.4/400-dsa-add-qca.patch
index f1bdf1aa6f..00659c104b 100644
--- a/target/linux/ipq806x/patches-4.4/400-dsa-add-qca.patch
+++ b/target/linux/ipq806x/patches-4.4/400-dsa-add-qca.patch
@@ -40,24 +40,22 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
create mode 100644 drivers/net/dsa/ar8xxx.c
create mode 100644 drivers/net/dsa/ar8xxx.h
-diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
-index 7ad0a4d..2aae541 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
-@@ -65,4 +65,11 @@ config NET_DSA_BCM_SF2
+@@ -65,4 +65,13 @@ config NET_DSA_BCM_SF2
This enables support for the Broadcom Starfighter 2 Ethernet
switch chips.
+config NET_DSA_AR8XXX
+ tristate "Qualcomm Atheros AR8XXX Ethernet switch family support"
+ depends on NET_DSA
++ select NET_DSA_TAG_QCA
++ select REGMAP
+ ---help---
+ This enables support for the Qualcomm Atheros AR8XXX Ethernet
+ switch chips.
+
endmenu
-diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile
-index e2d51c4..7647687 100644
--- a/drivers/net/dsa/Makefile
+++ b/drivers/net/dsa/Makefile
@@ -14,3 +14,4 @@ ifdef CONFIG_NET_DSA_MV88E6171
@@ -65,12 +63,9 @@ index e2d51c4..7647687 100644
endif
obj-$(CONFIG_NET_DSA_BCM_SF2) += bcm_sf2.o
+obj-$(CONFIG_NET_DSA_AR8XXX) += ar8xxx.o
-diff --git a/drivers/net/dsa/ar8xxx.c b/drivers/net/dsa/ar8xxx.c
-new file mode 100644
-index 0000000..4ce3ffc
--- /dev/null
+++ b/drivers/net/dsa/ar8xxx.c
-@@ -0,0 +1,303 @@
+@@ -0,0 +1,529 @@
+/*
+ * Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
@@ -92,9 +87,59 @@ index 0000000..4ce3ffc
+#include <net/dsa.h>
+#include <linux/phy.h>
+#include <linux/of_net.h>
++#include <linux/of_platform.h>
+
+#include "ar8xxx.h"
+
++#define MIB_DESC(_s, _o, _n) \
++ { \
++ .size = (_s), \
++ .offset = (_o), \
++ .name = (_n), \
++ }
++
++static const struct ar8xxx_mib_desc ar8327_mib[] = {
++ MIB_DESC(1, 0x00, "RxBroad"),
++ MIB_DESC(1, 0x04, "RxPause"),
++ MIB_DESC(1, 0x08, "RxMulti"),
++ MIB_DESC(1, 0x0c, "RxFcsErr"),
++ MIB_DESC(1, 0x10, "RxAlignErr"),
++ MIB_DESC(1, 0x14, "RxRunt"),
++ MIB_DESC(1, 0x18, "RxFragment"),
++ MIB_DESC(1, 0x1c, "Rx64Byte"),
++ MIB_DESC(1, 0x20, "Rx128Byte"),
++ MIB_DESC(1, 0x24, "Rx256Byte"),
++ MIB_DESC(1, 0x28, "Rx512Byte"),
++ MIB_DESC(1, 0x2c, "Rx1024Byte"),
++ MIB_DESC(1, 0x30, "Rx1518Byte"),
++ MIB_DESC(1, 0x34, "RxMaxByte"),
++ MIB_DESC(1, 0x38, "RxTooLong"),
++ MIB_DESC(2, 0x3c, "RxGoodByte"),
++ MIB_DESC(2, 0x44, "RxBadByte"),
++ MIB_DESC(1, 0x4c, "RxOverFlow"),
++ MIB_DESC(1, 0x50, "Filtered"),
++ MIB_DESC(1, 0x54, "TxBroad"),
++ MIB_DESC(1, 0x58, "TxPause"),
++ MIB_DESC(1, 0x5c, "TxMulti"),
++ MIB_DESC(1, 0x60, "TxUnderRun"),
++ MIB_DESC(1, 0x64, "Tx64Byte"),
++ MIB_DESC(1, 0x68, "Tx128Byte"),
++ MIB_DESC(1, 0x6c, "Tx256Byte"),
++ MIB_DESC(1, 0x70, "Tx512Byte"),
++ MIB_DESC(1, 0x74, "Tx1024Byte"),
++ MIB_DESC(1, 0x78, "Tx1518Byte"),
++ MIB_DESC(1, 0x7c, "TxMaxByte"),
++ MIB_DESC(1, 0x80, "TxOverSize"),
++ MIB_DESC(2, 0x84, "TxByte"),
++ MIB_DESC(1, 0x8c, "TxCollision"),
++ MIB_DESC(1, 0x90, "TxAbortCol"),
++ MIB_DESC(1, 0x94, "TxMultiCol"),
++ MIB_DESC(1, 0x98, "TxSingleCol"),
++ MIB_DESC(1, 0x9c, "TxExcDefer"),
++ MIB_DESC(1, 0xa0, "TxDefer"),
++ MIB_DESC(1, 0xa4, "TxLateCol"),
++};
++
+u32
+ar8xxx_mii_read32(struct mii_bus *bus, int phy_id, int regnum)
+{
@@ -200,6 +245,57 @@ index 0000000..4ce3ffc
+ }
+}
+
++static int ar8xxx_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
++{
++ struct dsa_switch *ds = (struct dsa_switch *)ctx;
++
++ *val = ar8xxx_read(ds, reg);
++
++ return 0;
++}
++
++static int ar8xxx_regmap_write(void *ctx, uint32_t reg, uint32_t val)
++{
++ struct dsa_switch *ds = (struct dsa_switch *)ctx;
++
++ ar8xxx_write(ds, reg, val);
++
++ return 0;
++}
++
++static const struct regmap_range ar8xxx_readable_ranges[] = {
++ regmap_reg_range(0x0000, 0x00e4), /* Global control */
++ regmap_reg_range(0x0100, 0x0168), /* EEE control */
++ regmap_reg_range(0x0200, 0x0270), /* Parser control */
++ regmap_reg_range(0x0400, 0x0454), /* ACL */
++ regmap_reg_range(0x0600, 0x0718), /* Lookup */
++ regmap_reg_range(0x0800, 0x0b70), /* QM */
++ regmap_reg_range(0x0C00, 0x0c80), /* PKT */
++ regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */
++ regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */
++ regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */
++ regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */
++ regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */
++ regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */
++ regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */
++
++};
++
++static struct regmap_access_table ar8xxx_readable_table = {
++ .yes_ranges = ar8xxx_readable_ranges,
++ .n_yes_ranges = ARRAY_SIZE(ar8xxx_readable_ranges),
++};
++
++struct regmap_config ar8xxx_regmap_config = {
++ .reg_bits = 16,
++ .val_bits = 32,
++ .reg_stride = 4,
++ .max_register = 0x16ac, /* end MIB - Port6 range */
++ .reg_read = ar8xxx_regmap_read,
++ .reg_write = ar8xxx_regmap_write,
++ .rd_table = &ar8xxx_readable_table,
++};
++
+static int ar8xxx_set_pad_ctrl(struct dsa_switch *ds, int port, int mode)
+{
+ int reg;
@@ -233,6 +329,9 @@ index 0000000..4ce3ffc
+ ar8xxx_write(ds, AR8327_REG_PORT5_PAD_CTRL,
+ AR8327_PORT_PAD_RGMII_RX_DELAY_EN);
+ break;
++ case PHY_INTERFACE_MODE_SGMII:
++ ar8xxx_write(ds, reg, AR8327_PORT_PAD_SGMII_EN);
++ break;
+ default:
+ pr_err("xMII mode %d not supported\n", mode);
+ return -EINVAL;
@@ -241,11 +340,61 @@ index 0000000..4ce3ffc
+ return 0;
+}
+
++static int ar8xxx_of_setup(struct dsa_switch *ds)
++{
++ struct device_node *dn = ds->pd->of_node;
++ const char *s_phymode;
++ int ret, mode;
++ u32 phy_id, ctrl;
++
++ /* If port6-phy-mode property exists, configure it accordingly */
++ if (!of_property_read_string(dn, "qca,port6-phy-mode", &s_phymode)) {
++ for (mode = 0; mode < PHY_INTERFACE_MODE_MAX; mode++)
++ if (!strcasecmp(s_phymode, phy_modes(mode)))
++ break;
++
++ if (mode == PHY_INTERFACE_MODE_MAX)
++ pr_err("Unknown phy-mode: \"%s\"\n", s_phymode);
++
++ ret = ar8xxx_set_pad_ctrl(ds, 6, mode);
++ if (ret < 0)
++ return ret;
++ }
++
++ /* If a phy ID is specified for PORT6 mac, connect them together */
++ if (!of_property_read_u32(dn, "qca,port6-phy-id", &phy_id)) {
++ ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(6),
++ AR8327_PORT_LOOKUP_MEMBER, BIT(phy_to_port(phy_id)));
++ ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(phy_to_port(phy_id)),
++ AR8327_PORT_LOOKUP_MEMBER, BIT(6));
++
++ /* We want the switch to be pass-through and act like a PHY on
++ * these ports. So BC/MC/UC & IGMP frames need to be accepted
++ */
++ ctrl = BIT(phy_to_port(phy_id)) | BIT(6);
++ ar8xxx_reg_set(ds, AR8327_REG_GLOBAL_FW_CTRL1,
++ ctrl << AR8327_GLOBAL_FW_CTRL1_IGMP_DP_S |
++ ctrl << AR8327_GLOBAL_FW_CTRL1_BC_DP_S |
++ ctrl << AR8327_GLOBAL_FW_CTRL1_MC_DP_S |
++ ctrl << AR8327_GLOBAL_FW_CTRL1_UC_DP_S);
++ }
++
++ return 0;
++}
++
+static int ar8xxx_setup(struct dsa_switch *ds)
+{
++ struct ar8xxx_priv *priv = ds_to_priv(ds);
+ struct net_device *netdev = ds->dst->pd->of_netdev;
+ int ret, i, phy_mode;
+
++ /* Start by setting up the register mapping */
++ priv->regmap = devm_regmap_init(ds->master_dev, NULL, ds,
++ &ar8xxx_regmap_config);
++
++ if (IS_ERR(priv->regmap))
++ pr_warn("regmap initialization failed");
++
+ /* Initialize CPU port pad mode (xMII type, delays...) */
+ phy_mode = of_get_phy_mode(netdev->dev.parent->of_node);
+ if (phy_mode < 0) {
@@ -257,11 +406,31 @@ index 0000000..4ce3ffc
+ if (ret < 0)
+ return ret;
+
++ /* Enable CPU Port */
++ ar8xxx_reg_set(ds, AR8327_REG_GLOBAL_FW_CTRL0,
++ AR8327_GLOBAL_FW_CTRL0_CPU_PORT_EN);
++
++ /* Enable MIB counters */
++ ar8xxx_reg_set(ds, AR8327_REG_MIB, AR8327_MIB_CPU_KEEP);
++ ar8xxx_write(ds, AR8327_REG_MODULE_EN, AR8327_MODULE_EN_MIB);
++
++ /* Enable QCA header mode on Port 0 */
++ ar8xxx_write(ds, AR8327_REG_PORT_HDR_CTRL(0),
++ AR8327_PORT_HDR_CTRL_ALL << AR8327_PORT_HDR_CTRL_TX_S |
++ AR8327_PORT_HDR_CTRL_ALL << AR8327_PORT_HDR_CTRL_RX_S);
++
+ /* Disable forwarding by default on all ports */
+ for (i = 0; i < AR8327_NUM_PORTS; i++)
+ ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(i),
+ AR8327_PORT_LOOKUP_MEMBER, 0);
+
++ /* Forward all unknown frames to CPU port for Linux processing */
++ ar8xxx_write(ds, AR8327_REG_GLOBAL_FW_CTRL1,
++ BIT(0) << AR8327_GLOBAL_FW_CTRL1_IGMP_DP_S |
++ BIT(0) << AR8327_GLOBAL_FW_CTRL1_BC_DP_S |
++ BIT(0) << AR8327_GLOBAL_FW_CTRL1_MC_DP_S |
++ BIT(0) << AR8327_GLOBAL_FW_CTRL1_UC_DP_S);
++
+ /* Setup connection between CPU ports & PHYs */
+ for (i = 0; i < DSA_MAX_PORTS; i++) {
+ /* CPU port gets connected to all PHYs in the switch */
@@ -273,11 +442,23 @@ index 0000000..4ce3ffc
+
+ /* Invividual PHYs gets connected to CPU port only */
+ if (ds->phys_port_mask & BIT(i)) {
-+ ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(phy_to_port(i)),
++ int phy = phy_to_port(i);
++
++ ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(phy),
+ AR8327_PORT_LOOKUP_MEMBER, BIT(0));
++
++ /* Disable Auto-learning by default so the switch
++ * doesn't try to forward the frame to another port
++ */
++ ar8xxx_reg_clear(ds, AR8327_PORT_LOOKUP_CTRL(phy),
++ AR8327_PORT_LOOKUP_LEARN);
+ }
+ }
+
++ ret = ar8xxx_of_setup(ds);
++ if (ret < 0)
++ return ret;
++
+ return 0;
+}
+
@@ -301,6 +482,42 @@ index 0000000..4ce3ffc
+ return mdiobus_write(bus, phy, regnum, val);
+}
+
++static void ar8xxx_get_strings(struct dsa_switch *ds, int phy, uint8_t *data)
++{
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) {
++ strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name,
++ ETH_GSTRING_LEN);
++ }
++}
++
++static void ar8xxx_get_ethtool_stats(struct dsa_switch *ds, int phy,
++ uint64_t *data)
++{
++ const struct ar8xxx_mib_desc *mib;
++ uint32_t reg, i, port;
++ u64 hi;
++
++ port = phy_to_port(phy);
++
++ for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) {
++ mib = &ar8327_mib[i];
++ reg = AR8327_PORT_MIB_COUNTER(port) + mib->offset;
++
++ data[i] = ar8xxx_read(ds, reg);
++ if (mib->size == 2) {
++ hi = ar8xxx_read(ds, reg + 4);
++ data[i] |= hi << 32;
++ }
++ }
++}
++
++static int ar8xxx_get_sset_count(struct dsa_switch *ds)
++{
++ return ARRAY_SIZE(ar8327_mib);
++}
++
+static void ar8xxx_poll_link(struct dsa_switch *ds)
+{
+ int i = 0;
@@ -348,13 +565,17 @@ index 0000000..4ce3ffc
+}
+
+static struct dsa_switch_driver ar8xxx_switch_driver = {
-+ .tag_protocol = DSA_TAG_PROTO_NONE,
-+ .probe = ar8xxx_probe,
-+ .setup = ar8xxx_setup,
-+ .set_addr = ar8xxx_set_addr,
-+ .poll_link = ar8xxx_poll_link,
-+ .phy_read = ar8xxx_phy_read,
-+ .phy_write = ar8xxx_phy_write,
++ .tag_protocol = DSA_TAG_PROTO_QCA,
++ .priv_size = sizeof(struct ar8xxx_priv),
++ .probe = ar8xxx_probe,
++ .setup = ar8xxx_setup,
++ .set_addr = ar8xxx_set_addr,
++ .poll_link = ar8xxx_poll_link,
++ .phy_read = ar8xxx_phy_read,
++ .phy_write = ar8xxx_phy_write,
++ .get_strings = ar8xxx_get_strings,
++ .get_ethtool_stats = ar8xxx_get_ethtool_stats,
++ .get_sset_count = ar8xxx_get_sset_count,
+};
+
+static int __init ar8xxx_init(void)
@@ -374,12 +595,9 @@ index 0000000..4ce3ffc
+MODULE_DESCRIPTION("Driver for AR8XXX ethernet switch family");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ar8xxx");
-diff --git a/drivers/net/dsa/ar8xxx.h b/drivers/net/dsa/ar8xxx.h
-new file mode 100644
-index 0000000..a29b6d3
--- /dev/null
+++ b/drivers/net/dsa/ar8xxx.h
-@@ -0,0 +1,82 @@
+@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
@@ -399,6 +617,17 @@ index 0000000..a29b6d3
+#define __AR8XXX_H
+
+#include <linux/delay.h>
++#include <linux/regmap.h>
++
++struct ar8xxx_priv {
++ struct regmap *regmap;
++};
++
++struct ar8xxx_mib_desc {
++ unsigned int size;
++ unsigned int offset;
++ const char *name;
++};
+
+#define AR8327_NUM_PORTS 7
+
@@ -413,6 +642,14 @@ index 0000000..a29b6d3
+#define AR8327_PORT_PAD_RGMII_RX_DELAY_EN BIT(24)
+#define AR8327_PORT_PAD_SGMII_EN BIT(7)
+
++#define AR8327_REG_MODULE_EN 0x030
++#define AR8327_MODULE_EN_MIB BIT(0)
++#define AR8327_MODULE_EN_ACL BIT(1)
++#define AR8327_MODULE_EN_L3 BIT(2)
++
++#define AR8327_REG_MIB 0x034
++#define AR8327_MIB_CPU_KEEP BIT(20)
++
+#define AR8327_REG_PORT_STATUS(_i) (0x07c + (_i) * 4)
+#define AR8XXX_PORT_STATUS_SPEED GENMASK(2, 0)
+#define AR8XXX_PORT_STATUS_SPEED_S 0
@@ -425,6 +662,28 @@ index 0000000..a29b6d3
+#define AR8XXX_PORT_STATUS_LINK_AUTO BIT(9)
+#define AR8XXX_PORT_STATUS_LINK_PAUSE BIT(10)
+
++#define AR8327_REG_PORT_HDR_CTRL(_i) (0x9c + (_i * 4))
++#define AR8327_PORT_HDR_CTRL_RX_MASK GENMASK(3, 2)
++#define AR8327_PORT_HDR_CTRL_RX_S 2
++#define AR8327_PORT_HDR_CTRL_TX_MASK GENMASK(1, 0)
++#define AR8327_PORT_HDR_CTRL_TX_S 0
++#define AR8327_PORT_HDR_CTRL_ALL 2
++#define AR8327_PORT_HDR_CTRL_MGMT 1
++#define AR8327_PORT_HDR_CTRL_NONE 0
++
++#define AR8327_REG_GLOBAL_FW_CTRL0 0x620
++#define AR8327_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10)
++
++#define AR8327_REG_GLOBAL_FW_CTRL1 0x624
++#define AR8327_GLOBAL_FW_CTRL1_IGMP_DP_MASK GENMASK(30, 24)
++#define AR8327_GLOBAL_FW_CTRL1_IGMP_DP_S 24
++#define AR8327_GLOBAL_FW_CTRL1_BC_DP_MASK GENMASK(22, 16)
++#define AR8327_GLOBAL_FW_CTRL1_BC_DP_S 16
++#define AR8327_GLOBAL_FW_CTRL1_MC_DP_MASK GENMASK(14, 8)
++#define AR8327_GLOBAL_FW_CTRL1_MC_DP_S 8
++#define AR8327_GLOBAL_FW_CTRL1_UC_DP_MASK GENMASK(6, 0)
++#define AR8327_GLOBAL_FW_CTRL1_UC_DP_S 0
++
+#define AR8327_PORT_LOOKUP_CTRL(_i) (0x660 + (_i) * 0xc)
+#define AR8327_PORT_LOOKUP_MEMBER GENMASK(6, 0)
+#define AR8327_PORT_LOOKUP_IN_MODE GENMASK(9, 8)
@@ -434,6 +693,8 @@ index 0000000..a29b6d3
+#define AR8327_PORT_LOOKUP_LEARN BIT(20)
+#define AR8327_PORT_LOOKUP_ING_MIRROR_EN BIT(25)
+
++#define AR8327_PORT_MIB_COUNTER(_i) (0x1000 + (_i) * 0x100)
++
+/* port speed */
+enum {
+ AR8XXX_PORT_SPEED_10M = 0,
@@ -442,251 +703,6 @@ index 0000000..a29b6d3
+ AR8XXX_PORT_SPEED_ERR = 3,
+};
+
-+static inline void
-+split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
-+{
-+ regaddr >>= 1;
-+ *r1 = regaddr & 0x1e;
-+
-+ regaddr >>= 5;
-+ *r2 = regaddr & 0x7;
-+
-+ regaddr >>= 3;
-+ *page = regaddr & 0x1ff;
-+}
-+
-+static inline void
-+wait_for_page_switch(void)
-+{
-+ udelay(5);
-+}
-+
-+#endif /* __AR8XXX_H */
-diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
-index e6f6cc3..fffb9aa 100644
---- a/net/dsa/dsa.c
-+++ b/net/dsa/dsa.c
-@@ -893,6 +893,7 @@ static SIMPLE_DEV_PM_OPS(dsa_pm_ops, dsa_suspend, dsa_resume);
-
- static const struct of_device_id dsa_of_match_table[] = {
- { .compatible = "brcm,bcm7445-switch-v4.0" },
-+ { .compatible = "qca,ar8xxx", },
- { .compatible = "marvell,dsa", },
- {}
- };
-
-From patchwork Fri May 29 01:42:17 2015
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [2/7] net: dsa: ar8xxx: add ethtool hw statistics support
-From: Mathieu Olivari <mathieu@codeaurora.org>
-X-Patchwork-Id: 477524
-X-Patchwork-Delegate: davem@davemloft.net
-Message-Id: <1432863742-18427-3-git-send-email-mathieu@codeaurora.org>
-To: robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com,
- ijc+devicetree@hellion.org.uk, galak@codeaurora.org,
- davem@davemloft.net, mathieu@codeaurora.org, andrew@lunn.ch,
- f.fainelli@gmail.com, linux@roeck-us.net, gang.chen.5i5j@gmail.com,
- jiri@resnulli.us, leitec@staticky.com, fabf@skynet.be,
- alexander.h.duyck@intel.com, pavel.nakonechny@skitlab.ru,
- joe@perches.com, sfeldma@gmail.com, nbd@openwrt.org, juhosg@openwrt.org
-Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
- netdev@vger.kernel.org
-Date: Thu, 28 May 2015 18:42:17 -0700
-
-MIB counters can now be reported through each switch port by using
-"ethtool -S".
-
-Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
----
- drivers/net/dsa/ar8xxx.c | 106 +++++++++++++++++++++++++++++++++++++++++++----
- drivers/net/dsa/ar8xxx.h | 47 +++++++++++++++++++++
- 2 files changed, 146 insertions(+), 7 deletions(-)
-
-diff --git a/drivers/net/dsa/ar8xxx.c b/drivers/net/dsa/ar8xxx.c
-index 4ce3ffc..2f0fa4d 100644
---- a/drivers/net/dsa/ar8xxx.c
-+++ b/drivers/net/dsa/ar8xxx.c
-@@ -22,6 +22,55 @@
-
- #include "ar8xxx.h"
-
-+#define MIB_DESC(_s, _o, _n) \
-+ { \
-+ .size = (_s), \
-+ .offset = (_o), \
-+ .name = (_n), \
-+ }
-+
-+static const struct ar8xxx_mib_desc ar8327_mib[] = {
-+ MIB_DESC(1, 0x00, "RxBroad"),
-+ MIB_DESC(1, 0x04, "RxPause"),
-+ MIB_DESC(1, 0x08, "RxMulti"),
-+ MIB_DESC(1, 0x0c, "RxFcsErr"),
-+ MIB_DESC(1, 0x10, "RxAlignErr"),
-+ MIB_DESC(1, 0x14, "RxRunt"),
-+ MIB_DESC(1, 0x18, "RxFragment"),
-+ MIB_DESC(1, 0x1c, "Rx64Byte"),
-+ MIB_DESC(1, 0x20, "Rx128Byte"),
-+ MIB_DESC(1, 0x24, "Rx256Byte"),
-+ MIB_DESC(1, 0x28, "Rx512Byte"),
-+ MIB_DESC(1, 0x2c, "Rx1024Byte"),
-+ MIB_DESC(1, 0x30, "Rx1518Byte"),
-+ MIB_DESC(1, 0x34, "RxMaxByte"),
-+ MIB_DESC(1, 0x38, "RxTooLong"),
-+ MIB_DESC(2, 0x3c, "RxGoodByte"),
-+ MIB_DESC(2, 0x44, "RxBadByte"),
-+ MIB_DESC(1, 0x4c, "RxOverFlow"),
-+ MIB_DESC(1, 0x50, "Filtered"),
-+ MIB_DESC(1, 0x54, "TxBroad"),
-+ MIB_DESC(1, 0x58, "TxPause"),
-+ MIB_DESC(1, 0x5c, "TxMulti"),
-+ MIB_DESC(1, 0x60, "TxUnderRun"),
-+ MIB_DESC(1, 0x64, "Tx64Byte"),
-+ MIB_DESC(1, 0x68, "Tx128Byte"),
-+ MIB_DESC(1, 0x6c, "Tx256Byte"),
-+ MIB_DESC(1, 0x70, "Tx512Byte"),
-+ MIB_DESC(1, 0x74, "Tx1024Byte"),
-+ MIB_DESC(1, 0x78, "Tx1518Byte"),
-+ MIB_DESC(1, 0x7c, "TxMaxByte"),
-+ MIB_DESC(1, 0x80, "TxOverSize"),
-+ MIB_DESC(2, 0x84, "TxByte"),
-+ MIB_DESC(1, 0x8c, "TxCollision"),
-+ MIB_DESC(1, 0x90, "TxAbortCol"),
-+ MIB_DESC(1, 0x94, "TxMultiCol"),
-+ MIB_DESC(1, 0x98, "TxSingleCol"),
-+ MIB_DESC(1, 0x9c, "TxExcDefer"),
-+ MIB_DESC(1, 0xa0, "TxDefer"),
-+ MIB_DESC(1, 0xa4, "TxLateCol"),
-+};
-+
- u32
- ar8xxx_mii_read32(struct mii_bus *bus, int phy_id, int regnum)
- {
-@@ -184,6 +233,10 @@ static int ar8xxx_setup(struct dsa_switch *ds)
- if (ret < 0)
- return ret;
-
-+ /* Enable MIB counters */
-+ ar8xxx_reg_set(ds, AR8327_REG_MIB, AR8327_MIB_CPU_KEEP);
-+ ar8xxx_write(ds, AR8327_REG_MODULE_EN, AR8327_MODULE_EN_MIB);
-+
- /* Disable forwarding by default on all ports */
- for (i = 0; i < AR8327_NUM_PORTS; i++)
- ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(i),
-@@ -228,6 +281,42 @@ ar8xxx_phy_write(struct dsa_switch *ds, int phy, int regnum, u16 val)
- return mdiobus_write(bus, phy, regnum, val);
- }
-
-+static void ar8xxx_get_strings(struct dsa_switch *ds, int phy, uint8_t *data)
-+{
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) {
-+ strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name,
-+ ETH_GSTRING_LEN);
-+ }
-+}
-+
-+static void ar8xxx_get_ethtool_stats(struct dsa_switch *ds, int phy,
-+ uint64_t *data)
-+{
-+ const struct ar8xxx_mib_desc *mib;
-+ uint32_t reg, i, port;
-+ u64 hi;
-+
-+ port = phy_to_port(phy);
-+
-+ for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) {
-+ mib = &ar8327_mib[i];
-+ reg = AR8327_PORT_MIB_COUNTER(port) + mib->offset;
-+
-+ data[i] = ar8xxx_read(ds, reg);
-+ if (mib->size == 2) {
-+ hi = ar8xxx_read(ds, reg + 4);
-+ data[i] |= hi << 32;
-+ }
-+ }
-+}
-+
-+static int ar8xxx_get_sset_count(struct dsa_switch *ds)
-+{
-+ return ARRAY_SIZE(ar8327_mib);
-+}
-+
- static void ar8xxx_poll_link(struct dsa_switch *ds)
- {
- int i = 0;
-@@ -275,13 +364,16 @@ static void ar8xxx_poll_link(struct dsa_switch *ds)
- }
-
- static struct dsa_switch_driver ar8xxx_switch_driver = {
-- .tag_protocol = DSA_TAG_PROTO_NONE,
-- .probe = ar8xxx_probe,
-- .setup = ar8xxx_setup,
-- .set_addr = ar8xxx_set_addr,
-- .poll_link = ar8xxx_poll_link,
-- .phy_read = ar8xxx_phy_read,
-- .phy_write = ar8xxx_phy_write,
-+ .tag_protocol = DSA_TAG_PROTO_NONE,
-+ .probe = ar8xxx_probe,
-+ .setup = ar8xxx_setup,
-+ .set_addr = ar8xxx_set_addr,
-+ .poll_link = ar8xxx_poll_link,
-+ .phy_read = ar8xxx_phy_read,
-+ .phy_write = ar8xxx_phy_write,
-+ .get_strings = ar8xxx_get_strings,
-+ .get_ethtool_stats = ar8xxx_get_ethtool_stats,
-+ .get_sset_count = ar8xxx_get_sset_count,
- };
-
- static int __init ar8xxx_init(void)
-diff --git a/drivers/net/dsa/ar8xxx.h b/drivers/net/dsa/ar8xxx.h
-index a29b6d3..7c7a125 100644
---- a/drivers/net/dsa/ar8xxx.h
-+++ b/drivers/net/dsa/ar8xxx.h
-@@ -18,6 +18,12 @@
-
- #include <linux/delay.h>
-
-+struct ar8xxx_mib_desc {
-+ unsigned int size;
-+ unsigned int offset;
-+ const char *name;
-+};
-+
- #define AR8327_NUM_PORTS 7
-
- #define PHY_ID_QCA8337 0x004dd036
-@@ -31,6 +37,14 @@
- #define AR8327_PORT_PAD_RGMII_RX_DELAY_EN BIT(24)
- #define AR8327_PORT_PAD_SGMII_EN BIT(7)
-
-+#define AR8327_REG_MODULE_EN 0x030
-+#define AR8327_MODULE_EN_MIB BIT(0)
-+#define AR8327_MODULE_EN_ACL BIT(1)
-+#define AR8327_MODULE_EN_L3 BIT(2)
-+
-+#define AR8327_REG_MIB 0x034
-+#define AR8327_MIB_CPU_KEEP BIT(20)
-+
- #define AR8327_REG_PORT_STATUS(_i) (0x07c + (_i) * 4)
- #define AR8XXX_PORT_STATUS_SPEED GENMASK(2, 0)
- #define AR8XXX_PORT_STATUS_SPEED_S 0
-@@ -52,6 +66,8 @@
- #define AR8327_PORT_LOOKUP_LEARN BIT(20)
- #define AR8327_PORT_LOOKUP_ING_MIRROR_EN BIT(25)
-
-+#define AR8327_PORT_MIB_COUNTER(_i) (0x1000 + (_i) * 0x100)
-+
- /* port speed */
- enum {
- AR8XXX_PORT_SPEED_10M = 0,
-@@ -60,6 +76,25 @@ enum {
- AR8XXX_PORT_SPEED_ERR = 3,
- };
-
+static inline int port_to_phy(int port)
+{
+ if (port >= 1 && port <= 6)
@@ -706,215 +722,60 @@ index a29b6d3..7c7a125 100644
+u32
+ar8xxx_rmw(struct dsa_switch *ds, int reg, u32 mask, u32 val);
+
- static inline void
- split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
- {
-@@ -79,4 +114,16 @@ wait_for_page_switch(void)
- udelay(5);
- }
-
+static inline void
-+ar8xxx_reg_set(struct dsa_switch *ds, int reg, u32 val)
++split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
+{
-+ ar8xxx_rmw(ds, reg, 0, val);
++ regaddr >>= 1;
++ *r1 = regaddr & 0x1e;
++
++ regaddr >>= 5;
++ *r2 = regaddr & 0x7;
++
++ regaddr >>= 3;
++ *page = regaddr & 0x1ff;
+}
+
+static inline void
-+ar8xxx_reg_clear(struct dsa_switch *ds, int reg, u32 val)
++wait_for_page_switch(void)
+{
-+ ar8xxx_rmw(ds, reg, val, 0);
++ udelay(5);
+}
+
- #endif /* __AR8XXX_H */
-
-From patchwork Fri May 29 01:42:18 2015
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [3/7] net: dsa: ar8xxx: add regmap support
-From: Mathieu Olivari <mathieu@codeaurora.org>
-X-Patchwork-Id: 477522
-X-Patchwork-Delegate: davem@davemloft.net
-Message-Id: <1432863742-18427-4-git-send-email-mathieu@codeaurora.org>
-To: robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com,
- ijc+devicetree@hellion.org.uk, galak@codeaurora.org,
- davem@davemloft.net, mathieu@codeaurora.org, andrew@lunn.ch,
- f.fainelli@gmail.com, linux@roeck-us.net, gang.chen.5i5j@gmail.com,
- jiri@resnulli.us, leitec@staticky.com, fabf@skynet.be,
- alexander.h.duyck@intel.com, pavel.nakonechny@skitlab.ru,
- joe@perches.com, sfeldma@gmail.com, nbd@openwrt.org, juhosg@openwrt.org
-Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
- netdev@vger.kernel.org
-Date: Thu, 28 May 2015 18:42:18 -0700
-
-All switch registers can now be dumped using regmap/debugfs.
-
-\# cat /sys/kernel/debug/regmap/<mdiobus>/registers
-0000: 00001302
-0004: ...
-...
-
-Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
----
- drivers/net/dsa/Kconfig | 1 +
- drivers/net/dsa/ar8xxx.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
- drivers/net/dsa/ar8xxx.h | 5 ++++
- 3 files changed, 66 insertions(+)
-
-diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
-index 2aae541..17fb296 100644
---- a/drivers/net/dsa/Kconfig
-+++ b/drivers/net/dsa/Kconfig
-@@ -68,6 +68,7 @@ config NET_DSA_BCM_SF2
- config NET_DSA_AR8XXX
- tristate "Qualcomm Atheros AR8XXX Ethernet switch family support"
- depends on NET_DSA
-+ select REGMAP
- ---help---
- This enables support for the Qualcomm Atheros AR8XXX Ethernet
- switch chips.
-diff --git a/drivers/net/dsa/ar8xxx.c b/drivers/net/dsa/ar8xxx.c
-index 2f0fa4d..327abd4 100644
---- a/drivers/net/dsa/ar8xxx.c
-+++ b/drivers/net/dsa/ar8xxx.c
-@@ -176,6 +176,57 @@ static char *ar8xxx_probe(struct device *host_dev, int sw_addr)
- }
- }
-
-+static int ar8xxx_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
++static inline void
++ar8xxx_reg_set(struct dsa_switch *ds, int reg, u32 val)
+{
-+ struct dsa_switch *ds = (struct dsa_switch *)ctx;
-+
-+ *val = ar8xxx_read(ds, reg);
-+
-+ return 0;
++ ar8xxx_rmw(ds, reg, 0, val);
+}
+
-+static int ar8xxx_regmap_write(void *ctx, uint32_t reg, uint32_t val)
++static inline void
++ar8xxx_reg_clear(struct dsa_switch *ds, int reg, u32 val)
+{
-+ struct dsa_switch *ds = (struct dsa_switch *)ctx;
-+
-+ ar8xxx_write(ds, reg, val);
-+
-+ return 0;
++ ar8xxx_rmw(ds, reg, val, 0);
+}
+
-+static const struct regmap_range ar8xxx_readable_ranges[] = {
-+ regmap_reg_range(0x0000, 0x00e4), /* Global control */
-+ regmap_reg_range(0x0100, 0x0168), /* EEE control */
-+ regmap_reg_range(0x0200, 0x0270), /* Parser control */
-+ regmap_reg_range(0x0400, 0x0454), /* ACL */
-+ regmap_reg_range(0x0600, 0x0718), /* Lookup */
-+ regmap_reg_range(0x0800, 0x0b70), /* QM */
-+ regmap_reg_range(0x0C00, 0x0c80), /* PKT */
-+ regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */
-+ regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */
-+ regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */
-+ regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */
-+ regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */
-+ regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */
-+ regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */
-+
-+};
-+
-+static struct regmap_access_table ar8xxx_readable_table = {
-+ .yes_ranges = ar8xxx_readable_ranges,
-+ .n_yes_ranges = ARRAY_SIZE(ar8xxx_readable_ranges),
-+};
-+
-+struct regmap_config ar8xxx_regmap_config = {
-+ .reg_bits = 16,
-+ .val_bits = 32,
-+ .reg_stride = 4,
-+ .max_register = 0x16ac, /* end MIB - Port6 range */
-+ .reg_read = ar8xxx_regmap_read,
-+ .reg_write = ar8xxx_regmap_write,
-+ .rd_table = &ar8xxx_readable_table,
-+};
-+
- static int ar8xxx_set_pad_ctrl(struct dsa_switch *ds, int port, int mode)
- {
- int reg;
-@@ -219,9 +270,17 @@ static int ar8xxx_set_pad_ctrl(struct dsa_switch *ds, int port, int mode)
-
- static int ar8xxx_setup(struct dsa_switch *ds)
- {
-+ struct ar8xxx_priv *priv = ds_to_priv(ds);
- struct net_device *netdev = ds->dst->pd->of_netdev;
- int ret, i, phy_mode;
-
-+ /* Start by setting up the register mapping */
-+ priv->regmap = devm_regmap_init(ds->master_dev, NULL, ds,
-+ &ar8xxx_regmap_config);
-+
-+ if (IS_ERR(priv->regmap))
-+ pr_warn("regmap initialization failed");
-+
- /* Initialize CPU port pad mode (xMII type, delays...) */
- phy_mode = of_get_phy_mode(netdev->dev.parent->of_node);
- if (phy_mode < 0) {
-@@ -365,6 +424,7 @@ static void ar8xxx_poll_link(struct dsa_switch *ds)
-
- static struct dsa_switch_driver ar8xxx_switch_driver = {
- .tag_protocol = DSA_TAG_PROTO_NONE,
-+ .priv_size = sizeof(struct ar8xxx_priv),
- .probe = ar8xxx_probe,
- .setup = ar8xxx_setup,
- .set_addr = ar8xxx_set_addr,
-diff --git a/drivers/net/dsa/ar8xxx.h b/drivers/net/dsa/ar8xxx.h
-index 7c7a125..98cc7ed 100644
---- a/drivers/net/dsa/ar8xxx.h
-+++ b/drivers/net/dsa/ar8xxx.h
-@@ -17,6 +17,11 @@
- #define __AR8XXX_H
-
- #include <linux/delay.h>
-+#include <linux/regmap.h>
-+
-+struct ar8xxx_priv {
-+ struct regmap *regmap;
-+};
++#endif /* __AR8XXX_H */
+--- a/net/dsa/dsa.c
++++ b/net/dsa/dsa.c
+@@ -285,6 +285,11 @@ static int dsa_switch_setup_one(struct d
+ dst->rcv = brcm_netdev_ops.rcv;
+ break;
+ #endif
++#ifdef CONFIG_NET_DSA_TAG_QCA
++ case DSA_TAG_PROTO_QCA:
++ dst->rcv = qca_netdev_ops.rcv;
++ break;
++#endif
+ case DSA_TAG_PROTO_NONE:
+ break;
+ default:
+@@ -1041,6 +1046,7 @@ static SIMPLE_DEV_PM_OPS(dsa_pm_ops, dsa
- struct ar8xxx_mib_desc {
- unsigned int size;
-
-From patchwork Fri May 29 01:42:19 2015
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [4/7] net: dsa: add QCA tag support
-From: Mathieu Olivari <mathieu@codeaurora.org>
-X-Patchwork-Id: 477521
-X-Patchwork-Delegate: davem@davemloft.net
-Message-Id: <1432863742-18427-5-git-send-email-mathieu@codeaurora.org>
-To: robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com,
- ijc+devicetree@hellion.org.uk, galak@codeaurora.org,
- davem@davemloft.net, mathieu@codeaurora.org, andrew@lunn.ch,
- f.fainelli@gmail.com, linux@roeck-us.net, gang.chen.5i5j@gmail.com,
- jiri@resnulli.us, leitec@staticky.com, fabf@skynet.be,
- alexander.h.duyck@intel.com, pavel.nakonechny@skitlab.ru,
- joe@perches.com, sfeldma@gmail.com, nbd@openwrt.org, juhosg@openwrt.org
-Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
- netdev@vger.kernel.org
-Date: Thu, 28 May 2015 18:42:19 -0700
-
-QCA tags are used on QCA ar8xxx switch family. This change adds support
-for encap/decap using 2 bytes header mode.
-
-Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
----
- include/net/dsa.h | 1 +
- net/dsa/Kconfig | 3 +
- net/dsa/Makefile | 1 +
- net/dsa/dsa.c | 5 ++
- net/dsa/dsa_priv.h | 2 +
- net/dsa/slave.c | 5 ++
- net/dsa/tag_qca.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++
- 7 files changed, 175 insertions(+)
- create mode 100644 net/dsa/tag_qca.c
-
-diff --git a/include/net/dsa.h b/include/net/dsa.h
-index fbca63b..64ddf6f 100644
+ static const struct of_device_id dsa_of_match_table[] = {
+ { .compatible = "brcm,bcm7445-switch-v4.0" },
++ { .compatible = "qca,ar8xxx", },
+ { .compatible = "marvell,dsa", },
+ {}
+ };
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -26,6 +26,7 @@ enum dsa_tag_protocol {
@@ -925,8 +786,6 @@ index fbca63b..64ddf6f 100644
};
#define DSA_MAX_SWITCHES 4
-diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig
-index ff7736f..4f3cce1 100644
--- a/net/dsa/Kconfig
+++ b/net/dsa/Kconfig
@@ -26,6 +26,9 @@ config NET_DSA_HWMON
@@ -939,8 +798,6 @@ index ff7736f..4f3cce1 100644
config NET_DSA_TAG_BRCM
bool
-diff --git a/net/dsa/Makefile b/net/dsa/Makefile
-index da06ed1..9feb86c 100644
--- a/net/dsa/Makefile
+++ b/net/dsa/Makefile
@@ -3,6 +3,7 @@ obj-$(CONFIG_NET_DSA) += dsa_core.o
@@ -951,27 +808,9 @@ index da06ed1..9feb86c 100644
dsa_core-$(CONFIG_NET_DSA_TAG_BRCM) += tag_brcm.o
dsa_core-$(CONFIG_NET_DSA_TAG_DSA) += tag_dsa.o
dsa_core-$(CONFIG_NET_DSA_TAG_EDSA) += tag_edsa.o
-diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
-index fffb9aa..6010a7d 100644
---- a/net/dsa/dsa.c
-+++ b/net/dsa/dsa.c
-@@ -249,6 +249,11 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
- dst->rcv = brcm_netdev_ops.rcv;
- break;
- #endif
-+#ifdef CONFIG_NET_DSA_TAG_QCA
-+ case DSA_TAG_PROTO_QCA:
-+ dst->rcv = qca_netdev_ops.rcv;
-+ break;
-+#endif
- case DSA_TAG_PROTO_NONE:
- break;
- default:
-diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
-index d5f1f9b..350c94b 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
-@@ -74,5 +74,7 @@ extern const struct dsa_device_ops trailer_netdev_ops;
+@@ -78,5 +78,7 @@ extern const struct dsa_device_ops trail
/* tag_brcm.c */
extern const struct dsa_device_ops brcm_netdev_ops;
@@ -979,11 +818,9 @@ index d5f1f9b..350c94b 100644
+extern const struct dsa_device_ops qca_netdev_ops;
#endif
-diff --git a/net/dsa/slave.c b/net/dsa/slave.c
-index 04ffad3..cd8f552 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
-@@ -925,6 +925,11 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent,
+@@ -1180,6 +1180,11 @@ int dsa_slave_create(struct dsa_switch *
p->xmit = brcm_netdev_ops.xmit;
break;
#endif
@@ -995,9 +832,6 @@ index 04ffad3..cd8f552 100644
default:
p->xmit = dsa_slave_notag_xmit;
break;
-diff --git a/net/dsa/tag_qca.c b/net/dsa/tag_qca.c
-new file mode 100644
-index 0000000..8f02196
--- /dev/null
+++ b/net/dsa/tag_qca.c
@@ -0,0 +1,158 @@
@@ -1159,293 +993,6 @@ index 0000000..8f02196
+ .xmit = qca_tag_xmit,
+ .rcv = qca_tag_rcv,
+};
-
-From patchwork Fri May 29 01:42:20 2015
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [5/7] net: dsa: ar8xxx: enable QCA header support on AR8xxx
-From: Mathieu Olivari <mathieu@codeaurora.org>
-X-Patchwork-Id: 477527
-X-Patchwork-Delegate: davem@davemloft.net
-Message-Id: <1432863742-18427-6-git-send-email-mathieu@codeaurora.org>
-To: robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com,
- ijc+devicetree@hellion.org.uk, galak@codeaurora.org,
- davem@davemloft.net, mathieu@codeaurora.org, andrew@lunn.ch,
- f.fainelli@gmail.com, linux@roeck-us.net, gang.chen.5i5j@gmail.com,
- jiri@resnulli.us, leitec@staticky.com, fabf@skynet.be,
- alexander.h.duyck@intel.com, pavel.nakonechny@skitlab.ru,
- joe@perches.com, sfeldma@gmail.com, nbd@openwrt.org, juhosg@openwrt.org
-Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
- netdev@vger.kernel.org
-Date: Thu, 28 May 2015 18:42:20 -0700
-
-This change enable support for the QCA headers in QCA83337 driver.
-A 2 bytes header will be added by the switch on every incoming packet
-to identify the ingress port, and the DSA tagging code will add a
-similar 2 bytes header to control which port is used to send a
-particular packet.
-
-Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
----
- drivers/net/dsa/Kconfig | 1 +
- drivers/net/dsa/ar8xxx.c | 28 ++++++++++++++++++++++++++--
- drivers/net/dsa/ar8xxx.h | 22 ++++++++++++++++++++++
- 3 files changed, 49 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
-index 17fb296..fa8b484 100644
---- a/drivers/net/dsa/Kconfig
-+++ b/drivers/net/dsa/Kconfig
-@@ -68,6 +68,7 @@ config NET_DSA_BCM_SF2
- config NET_DSA_AR8XXX
- tristate "Qualcomm Atheros AR8XXX Ethernet switch family support"
- depends on NET_DSA
-+ select NET_DSA_TAG_QCA
- select REGMAP
- ---help---
- This enables support for the Qualcomm Atheros AR8XXX Ethernet
-diff --git a/drivers/net/dsa/ar8xxx.c b/drivers/net/dsa/ar8xxx.c
-index 327abd4..4044614 100644
---- a/drivers/net/dsa/ar8xxx.c
-+++ b/drivers/net/dsa/ar8xxx.c
-@@ -292,15 +292,31 @@ static int ar8xxx_setup(struct dsa_switch *ds)
- if (ret < 0)
- return ret;
-
-+ /* Enable CPU Port */
-+ ar8xxx_reg_set(ds, AR8327_REG_GLOBAL_FW_CTRL0,
-+ AR8327_GLOBAL_FW_CTRL0_CPU_PORT_EN);
-+
- /* Enable MIB counters */
- ar8xxx_reg_set(ds, AR8327_REG_MIB, AR8327_MIB_CPU_KEEP);
- ar8xxx_write(ds, AR8327_REG_MODULE_EN, AR8327_MODULE_EN_MIB);
-
-+ /* Enable QCA header mode on Port 0 */
-+ ar8xxx_write(ds, AR8327_REG_PORT_HDR_CTRL(0),
-+ AR8327_PORT_HDR_CTRL_ALL << AR8327_PORT_HDR_CTRL_TX_S |
-+ AR8327_PORT_HDR_CTRL_ALL << AR8327_PORT_HDR_CTRL_RX_S);
-+
- /* Disable forwarding by default on all ports */
- for (i = 0; i < AR8327_NUM_PORTS; i++)
- ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(i),
- AR8327_PORT_LOOKUP_MEMBER, 0);
-
-+ /* Forward all unknown frames to CPU port for Linux processing */
-+ ar8xxx_write(ds, AR8327_REG_GLOBAL_FW_CTRL1,
-+ BIT(0) << AR8327_GLOBAL_FW_CTRL1_IGMP_DP_S |
-+ BIT(0) << AR8327_GLOBAL_FW_CTRL1_BC_DP_S |
-+ BIT(0) << AR8327_GLOBAL_FW_CTRL1_MC_DP_S |
-+ BIT(0) << AR8327_GLOBAL_FW_CTRL1_UC_DP_S);
-+
- /* Setup connection between CPU ports & PHYs */
- for (i = 0; i < DSA_MAX_PORTS; i++) {
- /* CPU port gets connected to all PHYs in the switch */
-@@ -312,8 +328,16 @@ static int ar8xxx_setup(struct dsa_switch *ds)
-
- /* Invividual PHYs gets connected to CPU port only */
- if (ds->phys_port_mask & BIT(i)) {
-- ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(phy_to_port(i)),
-+ int phy = phy_to_port(i);
-+
-+ ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(phy),
- AR8327_PORT_LOOKUP_MEMBER, BIT(0));
-+
-+ /* Disable Auto-learning by default so the switch
-+ * doesn't try to forward the frame to another port
-+ */
-+ ar8xxx_reg_clear(ds, AR8327_PORT_LOOKUP_CTRL(phy),
-+ AR8327_PORT_LOOKUP_LEARN);
- }
- }
-
-@@ -423,7 +447,7 @@ static void ar8xxx_poll_link(struct dsa_switch *ds)
- }
-
- static struct dsa_switch_driver ar8xxx_switch_driver = {
-- .tag_protocol = DSA_TAG_PROTO_NONE,
-+ .tag_protocol = DSA_TAG_PROTO_QCA,
- .priv_size = sizeof(struct ar8xxx_priv),
- .probe = ar8xxx_probe,
- .setup = ar8xxx_setup,
-diff --git a/drivers/net/dsa/ar8xxx.h b/drivers/net/dsa/ar8xxx.h
-index 98cc7ed..e68b92a 100644
---- a/drivers/net/dsa/ar8xxx.h
-+++ b/drivers/net/dsa/ar8xxx.h
-@@ -62,6 +62,28 @@ struct ar8xxx_mib_desc {
- #define AR8XXX_PORT_STATUS_LINK_AUTO BIT(9)
- #define AR8XXX_PORT_STATUS_LINK_PAUSE BIT(10)
-
-+#define AR8327_REG_PORT_HDR_CTRL(_i) (0x9c + (_i * 4))
-+#define AR8327_PORT_HDR_CTRL_RX_MASK GENMASK(3, 2)
-+#define AR8327_PORT_HDR_CTRL_RX_S 2
-+#define AR8327_PORT_HDR_CTRL_TX_MASK GENMASK(1, 0)
-+#define AR8327_PORT_HDR_CTRL_TX_S 0
-+#define AR8327_PORT_HDR_CTRL_ALL 2
-+#define AR8327_PORT_HDR_CTRL_MGMT 1
-+#define AR8327_PORT_HDR_CTRL_NONE 0
-+
-+#define AR8327_REG_GLOBAL_FW_CTRL0 0x620
-+#define AR8327_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10)
-+
-+#define AR8327_REG_GLOBAL_FW_CTRL1 0x624
-+#define AR8327_GLOBAL_FW_CTRL1_IGMP_DP_MASK GENMASK(30, 24)
-+#define AR8327_GLOBAL_FW_CTRL1_IGMP_DP_S 24
-+#define AR8327_GLOBAL_FW_CTRL1_BC_DP_MASK GENMASK(22, 16)
-+#define AR8327_GLOBAL_FW_CTRL1_BC_DP_S 16
-+#define AR8327_GLOBAL_FW_CTRL1_MC_DP_MASK GENMASK(14, 8)
-+#define AR8327_GLOBAL_FW_CTRL1_MC_DP_S 8
-+#define AR8327_GLOBAL_FW_CTRL1_UC_DP_MASK GENMASK(6, 0)
-+#define AR8327_GLOBAL_FW_CTRL1_UC_DP_S 0
-+
- #define AR8327_PORT_LOOKUP_CTRL(_i) (0x660 + (_i) * 0xc)
- #define AR8327_PORT_LOOKUP_MEMBER GENMASK(6, 0)
- #define AR8327_PORT_LOOKUP_IN_MODE GENMASK(9, 8)
-
-From patchwork Fri May 29 01:42:21 2015
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [6/7] net: dsa: ar8xxx: add support for second xMII interfaces
- through DT
-From: Mathieu Olivari <mathieu@codeaurora.org>
-X-Patchwork-Id: 477525
-X-Patchwork-Delegate: davem@davemloft.net
-Message-Id: <1432863742-18427-7-git-send-email-mathieu@codeaurora.org>
-To: robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com,
- ijc+devicetree@hellion.org.uk, galak@codeaurora.org,
- davem@davemloft.net, mathieu@codeaurora.org, andrew@lunn.ch,
- f.fainelli@gmail.com, linux@roeck-us.net, gang.chen.5i5j@gmail.com,
- jiri@resnulli.us, leitec@staticky.com, fabf@skynet.be,
- alexander.h.duyck@intel.com, pavel.nakonechny@skitlab.ru,
- joe@perches.com, sfeldma@gmail.com, nbd@openwrt.org, juhosg@openwrt.org
-Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
- netdev@vger.kernel.org
-Date: Thu, 28 May 2015 18:42:21 -0700
-
-This patch is adding support for port6 specific options to device tree.
-They can be used to setup the second xMII interface, and connect it to
-one of the switch port.
-
-Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
----
- drivers/net/dsa/ar8xxx.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 50 insertions(+)
-
-diff --git a/drivers/net/dsa/ar8xxx.c b/drivers/net/dsa/ar8xxx.c
-index 4044614..7559249 100644
---- a/drivers/net/dsa/ar8xxx.c
-+++ b/drivers/net/dsa/ar8xxx.c
-@@ -19,6 +19,7 @@
- #include <net/dsa.h>
- #include <linux/phy.h>
- #include <linux/of_net.h>
-+#include <linux/of_platform.h>
-
- #include "ar8xxx.h"
-
-@@ -260,6 +261,9 @@ static int ar8xxx_set_pad_ctrl(struct dsa_switch *ds, int port, int mode)
- ar8xxx_write(ds, AR8327_REG_PORT5_PAD_CTRL,
- AR8327_PORT_PAD_RGMII_RX_DELAY_EN);
- break;
-+ case PHY_INTERFACE_MODE_SGMII:
-+ ar8xxx_write(ds, reg, AR8327_PORT_PAD_SGMII_EN);
-+ break;
- default:
- pr_err("xMII mode %d not supported\n", mode);
- return -EINVAL;
-@@ -268,6 +272,48 @@ static int ar8xxx_set_pad_ctrl(struct dsa_switch *ds, int port, int mode)
- return 0;
- }
-
-+static int ar8xxx_of_setup(struct dsa_switch *ds)
-+{
-+ struct device_node *dn = ds->pd->of_node;
-+ const char *s_phymode;
-+ int ret, mode;
-+ u32 phy_id, ctrl;
-+
-+ /* If port6-phy-mode property exists, configure it accordingly */
-+ if (!of_property_read_string(dn, "qca,port6-phy-mode", &s_phymode)) {
-+ for (mode = 0; mode < PHY_INTERFACE_MODE_MAX; mode++)
-+ if (!strcasecmp(s_phymode, phy_modes(mode)))
-+ break;
-+
-+ if (mode == PHY_INTERFACE_MODE_MAX)
-+ pr_err("Unknown phy-mode: \"%s\"\n", s_phymode);
-+
-+ ret = ar8xxx_set_pad_ctrl(ds, 6, mode);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ /* If a phy ID is specified for PORT6 mac, connect them together */
-+ if (!of_property_read_u32(dn, "qca,port6-phy-id", &phy_id)) {
-+ ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(6),
-+ AR8327_PORT_LOOKUP_MEMBER, BIT(phy_to_port(phy_id)));
-+ ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(phy_to_port(phy_id)),
-+ AR8327_PORT_LOOKUP_MEMBER, BIT(6));
-+
-+ /* We want the switch to be pass-through and act like a PHY on
-+ * these ports. So BC/MC/UC & IGMP frames need to be accepted
-+ */
-+ ctrl = BIT(phy_to_port(phy_id)) | BIT(6);
-+ ar8xxx_reg_set(ds, AR8327_REG_GLOBAL_FW_CTRL1,
-+ ctrl << AR8327_GLOBAL_FW_CTRL1_IGMP_DP_S |
-+ ctrl << AR8327_GLOBAL_FW_CTRL1_BC_DP_S |
-+ ctrl << AR8327_GLOBAL_FW_CTRL1_MC_DP_S |
-+ ctrl << AR8327_GLOBAL_FW_CTRL1_UC_DP_S);
-+ }
-+
-+ return 0;
-+}
-+
- static int ar8xxx_setup(struct dsa_switch *ds)
- {
- struct ar8xxx_priv *priv = ds_to_priv(ds);
-@@ -341,6 +387,10 @@ static int ar8xxx_setup(struct dsa_switch *ds)
- }
- }
-
-+ ret = ar8xxx_of_setup(ds);
-+ if (ret < 0)
-+ return ret;
-+
- return 0;
- }
-
-
-From patchwork Fri May 29 01:42:22 2015
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [7/7] Documentation: devicetree: add ar8xxx binding
-From: Mathieu Olivari <mathieu@codeaurora.org>
-X-Patchwork-Id: 477528
-X-Patchwork-Delegate: davem@davemloft.net
-Message-Id: <1432863742-18427-8-git-send-email-mathieu@codeaurora.org>
-To: robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com,
- ijc+devicetree@hellion.org.uk, galak@codeaurora.org,
- davem@davemloft.net, mathieu@codeaurora.org, andrew@lunn.ch,
- f.fainelli@gmail.com, linux@roeck-us.net, gang.chen.5i5j@gmail.com,
- jiri@resnulli.us, leitec@staticky.com, fabf@skynet.be,
- alexander.h.duyck@intel.com, pavel.nakonechny@skitlab.ru,
- joe@perches.com, sfeldma@gmail.com, nbd@openwrt.org, juhosg@openwrt.org
-Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
- netdev@vger.kernel.org
-Date: Thu, 28 May 2015 18:42:22 -0700
-
-Add device-tree binding for ar8xxx switch families.
-
-Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
----
- .../devicetree/bindings/net/dsa/qca-ar8xxx.txt | 70 ++++++++++++++++++++++
- 1 file changed, 70 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/net/dsa/qca-ar8xxx.txt
-
-diff --git a/Documentation/devicetree/bindings/net/dsa/qca-ar8xxx.txt b/Documentation/devicetree/bindings/net/dsa/qca-ar8xxx.txt
-new file mode 100644
-index 0000000..f4fd3f1
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/dsa/qca-ar8xxx.txt
@@ -0,0 +1,70 @@
diff --git a/target/linux/ipq806x/patches-4.4/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch b/target/linux/ipq806x/patches-4.4/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch
index 691ebb66ba..d85d8b02aa 100644
--- a/target/linux/ipq806x/patches-4.4/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch
+++ b/target/linux/ipq806x/patches-4.4/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch
@@ -121,7 +121,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
};
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -763,6 +763,92 @@
+@@ -755,6 +755,92 @@
status = "disabled";
};
diff --git a/target/linux/ipq806x/patches-4.4/709-spi-qup-Fix-fifo-and-dma-support-for-IPQ806x.patch b/target/linux/ipq806x/patches-4.4/709-spi-qup-Fix-fifo-and-dma-support-for-IPQ806x.patch
index 8c4718e2a6..fa78a0aeda 100644
--- a/target/linux/ipq806x/patches-4.4/709-spi-qup-Fix-fifo-and-dma-support-for-IPQ806x.patch
+++ b/target/linux/ipq806x/patches-4.4/709-spi-qup-Fix-fifo-and-dma-support-for-IPQ806x.patch
@@ -8,8 +8,6 @@ Signed-off-by: Ram Chandra Jangir <rjangi@codeaurora.org>
drivers/spi/spi-qup.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 52 insertions(+), 2 deletions(-)
-diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c
-index 810a7fa..0808017 100644
--- a/drivers/spi/spi-qup.c
+++ b/drivers/spi/spi-qup.c
@@ -24,6 +24,7 @@
@@ -28,7 +26,7 @@ index 810a7fa..0808017 100644
};
-@@ -370,7 +372,8 @@ static int spi_qup_do_pio(struct spi_master *master, struct spi_transfer *xfer)
+@@ -370,7 +372,8 @@ static int spi_qup_do_pio(struct spi_mas
return ret;
}
@@ -38,7 +36,7 @@ index 810a7fa..0808017 100644
return 0;
}
-@@ -448,6 +451,7 @@ spi_qup_get_mode(struct spi_master *master, struct spi_transfer *xfer)
+@@ -448,6 +451,7 @@ spi_qup_get_mode(struct spi_master *mast
{
struct spi_qup *qup = spi_master_get_devdata(master);
u32 mode;
@@ -46,7 +44,7 @@ index 810a7fa..0808017 100644
qup->w_size = 4;
-@@ -458,6 +462,14 @@ spi_qup_get_mode(struct spi_master *master, struct spi_transfer *xfer)
+@@ -458,6 +462,14 @@ spi_qup_get_mode(struct spi_master *mast
qup->n_words = xfer->len / qup->w_size;
@@ -61,7 +59,7 @@ index 810a7fa..0808017 100644
if (qup->n_words <= (qup->in_fifo_sz / sizeof(u32)))
mode = QUP_IO_M_MODE_FIFO;
else
-@@ -491,7 +503,7 @@ static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer)
+@@ -491,7 +503,7 @@ static int spi_qup_io_config(struct spi_
return -EIO;
}
@@ -70,7 +68,7 @@ index 810a7fa..0808017 100644
n_words = controller->n_words;
if (mode == QUP_IO_M_MODE_FIFO) {
-@@ -500,6 +512,7 @@ static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer)
+@@ -500,6 +512,7 @@ static int spi_qup_io_config(struct spi_
/* must be zero for FIFO */
writel_relaxed(0, controller->base + QUP_MX_INPUT_CNT);
writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT);
@@ -117,7 +115,7 @@ index 810a7fa..0808017 100644
static int spi_qup_probe(struct platform_device *pdev)
{
struct spi_master *master;
-@@ -846,6 +891,11 @@ static int spi_qup_probe(struct platform_device *pdev)
+@@ -846,6 +891,11 @@ static int spi_qup_probe(struct platform
if (of_device_is_compatible(dev->of_node, "qcom,spi-qup-v1.1.1"))
controller->qup_v1 = 1;
@@ -129,6 +127,3 @@ index 810a7fa..0808017 100644
spin_lock_init(&controller->lock);
init_completion(&controller->done);
---
-2.7.2
-
diff --git a/target/linux/ipq806x/patches-4.4/710-watchdog-qcom-set-WDT_BARK_TIME-register-offset-to-o.patch b/target/linux/ipq806x/patches-4.4/710-watchdog-qcom-set-WDT_BARK_TIME-register-offset-to-o.patch
index 7573c963a7..dde5822f16 100644
--- a/target/linux/ipq806x/patches-4.4/710-watchdog-qcom-set-WDT_BARK_TIME-register-offset-to-o.patch
+++ b/target/linux/ipq806x/patches-4.4/710-watchdog-qcom-set-WDT_BARK_TIME-register-offset-to-o.patch
@@ -18,8 +18,6 @@ Signed-off-by: Ram Chandra Jangir <rjangi@codeaurora.org>
drivers/watchdog/qcom-wdt.c | 2 ++
1 file changed, 2 insertions(+)
-diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
-index 773dcfa..002274a 100644
--- a/drivers/watchdog/qcom-wdt.c
+++ b/drivers/watchdog/qcom-wdt.c
@@ -22,6 +22,7 @@
@@ -30,7 +28,7 @@ index 773dcfa..002274a 100644
#define WDT_BITE_TIME 0x5C
struct qcom_wdt {
-@@ -44,6 +45,7 @@ static int qcom_wdt_start(struct watchdog_device *wdd)
+@@ -44,6 +45,7 @@ static int qcom_wdt_start(struct watchdo
writel(0, wdt->base + WDT_EN);
writel(1, wdt->base + WDT_RST);
@@ -38,6 +36,3 @@ index 773dcfa..002274a 100644
writel(wdd->timeout * wdt->rate, wdt->base + WDT_BITE_TIME);
writel(1, wdt->base + WDT_EN);
return 0;
---
-2.7.2
-
diff --git a/target/linux/ipq806x/patches-4.4/711-stmmac-fix-ipq806x-DMA-configuration.patch b/target/linux/ipq806x/patches-4.4/711-stmmac-fix-ipq806x-DMA-configuration.patch
index c99f60768f..58400314c7 100644
--- a/target/linux/ipq806x/patches-4.4/711-stmmac-fix-ipq806x-DMA-configuration.patch
+++ b/target/linux/ipq806x/patches-4.4/711-stmmac-fix-ipq806x-DMA-configuration.patch
@@ -94,7 +94,7 @@
int limit;
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -1639,9 +1639,11 @@ static int stmmac_init_dma_engine(struct
+@@ -1641,9 +1641,11 @@ static int stmmac_init_dma_engine(struct
int pbl = DEFAULT_DMA_PBL, fixed_burst = 0, burst_len = 0;
int mixed_burst = 0;
int atds = 0;
@@ -106,7 +106,7 @@
fixed_burst = priv->plat->dma_cfg->fixed_burst;
mixed_burst = priv->plat->dma_cfg->mixed_burst;
burst_len = priv->plat->dma_cfg->burst_len;
-@@ -1652,7 +1654,7 @@ static int stmmac_init_dma_engine(struct
+@@ -1654,7 +1656,7 @@ static int stmmac_init_dma_engine(struct
return priv->hw->dma->init(priv->ioaddr, pbl, fixed_burst, mixed_burst,
burst_len, priv->dma_tx_phy,
diff --git a/target/linux/ipq806x/patches-4.4/800-devicetree.patch b/target/linux/ipq806x/patches-4.4/800-devicetree.patch
index 0081a28885..39f59d36c8 100644
--- a/target/linux/ipq806x/patches-4.4/800-devicetree.patch
+++ b/target/linux/ipq806x/patches-4.4/800-devicetree.patch
@@ -12,7 +12,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
-@@ -506,7 +506,12 @@
+@@ -506,7 +506,12 @@ dtb-$(CONFIG_ARCH_QCOM) += \
qcom-apq8084-ifc6540.dtb \
qcom-apq8084-mtp.dtb \
qcom-ipq8064-ap148.dtb \
diff --git a/target/linux/ipq806x/patches-4.4/996-ATAG_DTB_COMPAT_CMDLINE_MANGLE.patch b/target/linux/ipq806x/patches-4.4/996-ATAG_DTB_COMPAT_CMDLINE_MANGLE.patch
index 490886ee44..8d5cbf9102 100644
--- a/target/linux/ipq806x/patches-4.4/996-ATAG_DTB_COMPAT_CMDLINE_MANGLE.patch
+++ b/target/linux/ipq806x/patches-4.4/996-ATAG_DTB_COMPAT_CMDLINE_MANGLE.patch
@@ -18,7 +18,7 @@ Signed-off-by: Adrian Panella <ianchi74@outlook.com>
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
-@@ -1927,6 +1927,17 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN
+@@ -1928,6 +1928,17 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN
The command-line arguments provided by the boot loader will be
appended to the the device tree bootargs property.
@@ -107,7 +107,7 @@ Signed-off-by: Adrian Panella <ianchi74@outlook.com>
static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
{
char cmdline[COMMAND_LINE_SIZE];
-@@ -85,12 +134,21 @@ static void merge_fdt_bootargs(void *fdt
+@@ -85,12 +140,21 @@ static void merge_fdt_bootargs(void *fdt
/* and append the ATAG_CMDLINE */
if (fdt_cmdline) {
@@ -129,7 +129,7 @@ Signed-off-by: Adrian Panella <ianchi74@outlook.com>
}
*ptr = '\0';
-@@ -147,7 +205,9 @@ int atags_to_fdt(void *atag_list, void *
+@@ -147,7 +211,9 @@ int atags_to_fdt(void *atag_list, void *
else
setprop_string(fdt, "/chosen", "bootargs",
atag->u.cmdline.cmdline);
@@ -140,7 +140,7 @@ Signed-off-by: Adrian Panella <ianchi74@outlook.com>
if (memcount >= sizeof(mem_reg_property)/4)
continue;
if (!atag->u.mem.size)
-@@ -186,6 +246,10 @@ int atags_to_fdt(void *atag_list, void *
+@@ -186,6 +252,10 @@ int atags_to_fdt(void *atag_list, void *
setprop(fdt, "/memory", "reg", mem_reg_property,
4 * memcount * memsize);
}
@@ -164,7 +164,7 @@ Signed-off-by: Adrian Panella <ianchi74@outlook.com>
static int kernel_init(void *);
extern void init_IRQ(void);
-@@ -585,6 +589,18 @@ asmlinkage __visible void __init start_k
+@@ -560,6 +564,18 @@ asmlinkage __visible void __init start_k
page_alloc_init();
pr_notice("Kernel command line: %s\n", boot_command_line);
diff --git a/target/linux/lantiq/patches-4.4/0028-NET-lantiq-various-etop-fixes.patch b/target/linux/lantiq/patches-4.4/0028-NET-lantiq-various-etop-fixes.patch
index a236da1efa..81eccf24bc 100644
--- a/target/linux/lantiq/patches-4.4/0028-NET-lantiq-various-etop-fixes.patch
+++ b/target/linux/lantiq/patches-4.4/0028-NET-lantiq-various-etop-fixes.patch
@@ -104,7 +104,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+
+#define PMAC_HD_CTL_AS (1 << 19)
+#define PMAC_HD_CTL_RXSH (1 << 22)
-
++
+/* Switch Enable (0=disable, 1=enable) */
+#define GCTL0_SE 0x80000000
+/* Disable MDIO auto polling (0=disable, 1=enable) */
@@ -124,7 +124,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+#define MDIO_XR9_REG_OFFSET 0
+#define MDIO_XR9_ADDR_OFFSET 5
+#define MDIO_XR9_WR_OFFSET 16
-+
+
+#define LTQ_DMA_ETOP ((of_machine_is_compatible("lantiq,ase")) ? \
+ (INT_NUM_IM3_IRL0) : (INT_NUM_IM2_IRL0))
+
@@ -333,8 +333,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
- ltq_pmu_enable(PMU_PPE);
+ clk_enable(priv->clk_ppe);
-
-- switch (priv->pldata->mii_mode) {
++
+ if (of_machine_is_compatible("lantiq,ar9")) {
+ ltq_etop_gbit_init(dev);
+ /* force the etops link to the gbit to MII */
@@ -343,7 +342,8 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ ltq_etop_w32_mask(MDIO_CFG_MASK, 0, LTQ_ETOP_MDIO_CFG);
+ ltq_etop_w32_mask(MAC_CFG_MASK, MAC_CFG_CGEN | MAC_CFG_DUPLEX |
+ MAC_CFG_SPEED | MAC_CFG_LINK, LTQ_ETOP_MAC_CFG);
-+
+
+- switch (priv->pldata->mii_mode) {
+ switch (mii_mode) {
case PHY_INTERFACE_MODE_RMII:
- ltq_etop_w32_mask(ETOP_MII_MASK,
@@ -382,8 +382,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
- ltq_etop_w32(PPE32_CGEN, LQ_PPE32_ENET_MAC_CFG);
+ return 0;
+}
-
-- ltq_dma_init_port(DMA_PORT_ETOP);
++
+static int
+ltq_etop_dma_init(struct net_device *dev)
+{
@@ -392,21 +391,14 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ int rx = priv->rx_irq - LTQ_DMA_ETOP;
+ int err;
+ ltq_dma_init_port(DMA_PORT_ETOP);
+
- for (i = 0; i < MAX_DMA_CHAN; i++) {
- int irq = LTQ_DMA_CH0_INT + i;
- struct ltq_etop_chan *ch = &priv->ch[i];
-+ ltq_dma_init_port(DMA_PORT_ETOP);
-
+-
- ch->idx = ch->dma.nr = i;
-+ priv->txch.dma.nr = tx;
-+ ltq_dma_alloc_tx(&priv->txch.dma);
-+ err = request_irq(priv->tx_irq, ltq_etop_dma_irq, 0, "eth_tx", priv);
-+ if (err) {
-+ netdev_err(dev, "failed to allocate tx irq\n");
-+ goto err_out;
-+ }
-+ priv->txch.dma.irq = priv->tx_irq;
-
+-
- if (IS_TX(i)) {
- ltq_dma_alloc_tx(&ch->dma);
- request_irq(irq, ltq_etop_dma_irq, 0, "etop_tx", priv);
@@ -418,6 +410,15 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
- return -ENOMEM;
- ch->dma.desc = 0;
- request_irq(irq, ltq_etop_dma_irq, 0, "etop_rx", priv);
++ priv->txch.dma.nr = tx;
++ ltq_dma_alloc_tx(&priv->txch.dma);
++ err = request_irq(priv->tx_irq, ltq_etop_dma_irq, 0, "eth_tx", priv);
++ if (err) {
++ netdev_err(dev, "failed to allocate tx irq\n");
++ goto err_out;
++ }
++ priv->txch.dma.irq = priv->tx_irq;
++
+ priv->rxch.dma.nr = rx;
+ ltq_dma_alloc_rx(&priv->rxch.dma);
+ for (priv->rxch.dma.desc = 0; priv->rxch.dma.desc < LTQ_DESC_NUM;
@@ -655,6 +656,12 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
- phy_stop(priv->phydev);
- for (i = 0; i < MAX_DMA_CHAN; i++) {
- struct ltq_etop_chan *ch = &priv->ch[i];
+-
+- if (!IS_RX(i) && !IS_TX(i))
+- continue;
+- napi_disable(&ch->napi);
+- ltq_dma_close(&ch->dma);
+- }
+ if (priv->phydev)
+ phy_stop(priv->phydev);
+ napi_disable(&priv->txch.napi);
@@ -664,12 +671,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ ltq_dma_close(&priv->txch.dma);
+ ltq_dma_close(&priv->rxch.dma);
+ spin_unlock_irqrestore(&priv->lock, flags);
-
-- if (!IS_RX(i) && !IS_TX(i))
-- continue;
-- napi_disable(&ch->napi);
-- ltq_dma_close(&ch->dma);
-- }
++
return 0;
}
@@ -789,7 +791,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
-@@ -733,31 +943,62 @@ ltq_etop_probe(struct platform_device *p
+@@ -733,30 +943,61 @@ ltq_etop_probe(struct platform_device *p
goto err_out;
}
@@ -823,19 +825,10 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
priv->pdev = pdev;
- priv->pldata = dev_get_platdata(&pdev->dev);
priv->netdev = dev;
-- spin_lock_init(&priv->lock);
+ priv->tx_irq = irqres[0].start;
+ priv->rx_irq = irqres[1].start;
+ priv->mii_mode = of_get_phy_mode(pdev->dev.of_node);
-
-- for (i = 0; i < MAX_DMA_CHAN; i++) {
-- if (IS_TX(i))
-- netif_napi_add(dev, &priv->ch[i].napi,
-- ltq_etop_poll_tx, 8);
-- else if (IS_RX(i))
-- netif_napi_add(dev, &priv->ch[i].napi,
-- ltq_etop_poll_rx, 32);
-- priv->ch[i].netdev = dev;
++
+ mac = of_get_mac_address(pdev->dev.of_node);
+ if (mac)
+ memcpy(priv->mac, mac, ETH_ALEN);
@@ -855,18 +848,26 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ priv->clk_ephycgu = clk_get(&pdev->dev, "ephycgu");
+ if (IS_ERR(priv->clk_ephycgu))
+ return PTR_ERR(priv->clk_ephycgu);
- }
-
-+ spin_lock_init(&priv->lock);
++ }
+
+ spin_lock_init(&priv->lock);
+
+- for (i = 0; i < MAX_DMA_CHAN; i++) {
+- if (IS_TX(i))
+- netif_napi_add(dev, &priv->ch[i].napi,
+- ltq_etop_poll_tx, 8);
+- else if (IS_RX(i))
+- netif_napi_add(dev, &priv->ch[i].napi,
+- ltq_etop_poll_rx, 32);
+- priv->ch[i].netdev = dev;
+- }
+ netif_napi_add(dev, &priv->txch.napi, ltq_etop_poll_tx, 8);
+ netif_napi_add(dev, &priv->rxch.napi, ltq_etop_poll_rx, 32);
+ priv->txch.netdev = dev;
+ priv->rxch.netdev = dev;
-+
+
err = register_netdev(dev);
if (err)
- goto err_free;
@@ -785,31 +1026,22 @@ ltq_etop_remove(struct platform_device *
return 0;
}
diff --git a/target/linux/lantiq/patches-4.4/0160-owrt-lantiq-multiple-flash.patch b/target/linux/lantiq/patches-4.4/0160-owrt-lantiq-multiple-flash.patch
index 4c45e4f8a1..087d923f7d 100644
--- a/target/linux/lantiq/patches-4.4/0160-owrt-lantiq-multiple-flash.patch
+++ b/target/linux/lantiq/patches-4.4/0160-owrt-lantiq-multiple-flash.patch
@@ -82,7 +82,6 @@
- if (!ltq_mtd->res) {
- dev_err(&pdev->dev, "failed to get memory resource\n");
- return -ENOENT;
-- }
+ for (i = 0; i < pdev->num_resources; i++) {
+ printk(KERN_NOTICE "lantiq nor flash device: %.8llx at %.8llx\n",
+ (unsigned long long)resource_size(&pdev->resource[i]),
@@ -95,27 +94,14 @@
+ dev_err(&pdev->dev, "Could not reserve memory region\n");
+ return -ENOMEM;
+ }
-
-- ltq_mtd->map = devm_kzalloc(&pdev->dev, sizeof(struct map_info),
-- GFP_KERNEL);
-- if (!ltq_mtd->map)
-- return -ENOMEM;
++
+ ltq_mtd->map[i].name = ltq_map_name;
+ ltq_mtd->map[i].bankwidth = 2;
+ ltq_mtd->map[i].read = ltq_read16;
+ ltq_mtd->map[i].write = ltq_write16;
+ ltq_mtd->map[i].copy_from = ltq_copy_from;
+ ltq_mtd->map[i].copy_to = ltq_copy_to;
-
-- if (of_find_property(pdev->dev.of_node, "lantiq,noxip", NULL))
-- ltq_mtd->map->phys = NO_XIP;
-- else
-- ltq_mtd->map->phys = ltq_mtd->res->start;
-- ltq_mtd->res->start;
-- ltq_mtd->map->size = resource_size(ltq_mtd->res);
-- ltq_mtd->map->virt = devm_ioremap_resource(&pdev->dev, ltq_mtd->res);
-- if (IS_ERR(ltq_mtd->map->virt))
-- return PTR_ERR(ltq_mtd->map->virt);
++
+ if (of_find_property(pdev->dev.of_node, "lantiq,noxip", NULL))
+ ltq_mtd->map[i].phys = NO_XIP;
+ else
@@ -125,30 +111,18 @@
+ ltq_mtd->map[i].size);
+ if (IS_ERR(ltq_mtd->map[i].virt))
+ return PTR_ERR(ltq_mtd->map[i].virt);
-
-- ltq_mtd->map->name = ltq_map_name;
-- ltq_mtd->map->bankwidth = 2;
-- ltq_mtd->map->read = ltq_read16;
-- ltq_mtd->map->write = ltq_write16;
-- ltq_mtd->map->copy_from = ltq_copy_from;
-- ltq_mtd->map->copy_to = ltq_copy_to;
++
+ if (ltq_mtd->map[i].virt == NULL) {
+ dev_err(&pdev->dev, "Failed to ioremap flash region\n");
+ err = PTR_ERR(ltq_mtd->map[i].virt);
+ goto err_out;
+ }
-
-- ltq_mtd->map->map_priv_1 = LTQ_NOR_PROBING;
-- ltq_mtd->mtd = do_map_probe("cfi_probe", ltq_mtd->map);
-- ltq_mtd->map->map_priv_1 = LTQ_NOR_NORMAL;
++
+ ltq_mtd->map[i].map_priv_1 = LTQ_NOR_PROBING;
+ for (type = rom_probe_types; !ltq_mtd->mtd[i] && *type; type++)
+ ltq_mtd->mtd[i] = do_map_probe(*type, &ltq_mtd->map[i]);
+ ltq_mtd->map[i].map_priv_1 = LTQ_NOR_NORMAL;
-
-- if (!ltq_mtd->mtd) {
-- dev_err(&pdev->dev, "probing failed\n");
-- return -ENXIO;
++
+ if (!ltq_mtd->mtd[i]) {
+ dev_err(&pdev->dev, "probing failed\n");
+ return -ENXIO;
@@ -164,7 +138,10 @@
+ cfi->addr_unlock2 ^= 1;
}
-- ltq_mtd->mtd->dev.parent = &pdev->dev;
+- ltq_mtd->map = devm_kzalloc(&pdev->dev, sizeof(struct map_info),
+- GFP_KERNEL);
+- if (!ltq_mtd->map)
+- return -ENOMEM;
+ if (devices_found == 1) {
+ ltq_mtd->cmtd = ltq_mtd->mtd[0];
+ } else if (devices_found > 1) {
@@ -176,6 +153,34 @@
+ err = -ENXIO;
+ }
+- if (of_find_property(pdev->dev.of_node, "lantiq,noxip", NULL))
+- ltq_mtd->map->phys = NO_XIP;
+- else
+- ltq_mtd->map->phys = ltq_mtd->res->start;
+- ltq_mtd->res->start;
+- ltq_mtd->map->size = resource_size(ltq_mtd->res);
+- ltq_mtd->map->virt = devm_ioremap_resource(&pdev->dev, ltq_mtd->res);
+- if (IS_ERR(ltq_mtd->map->virt))
+- return PTR_ERR(ltq_mtd->map->virt);
+-
+- ltq_mtd->map->name = ltq_map_name;
+- ltq_mtd->map->bankwidth = 2;
+- ltq_mtd->map->read = ltq_read16;
+- ltq_mtd->map->write = ltq_write16;
+- ltq_mtd->map->copy_from = ltq_copy_from;
+- ltq_mtd->map->copy_to = ltq_copy_to;
+-
+- ltq_mtd->map->map_priv_1 = LTQ_NOR_PROBING;
+- ltq_mtd->mtd = do_map_probe("cfi_probe", ltq_mtd->map);
+- ltq_mtd->map->map_priv_1 = LTQ_NOR_NORMAL;
+-
+- if (!ltq_mtd->mtd) {
+- dev_err(&pdev->dev, "probing failed\n");
+- return -ENXIO;
+- }
+-
+- ltq_mtd->mtd->dev.parent = &pdev->dev;
+-
- cfi = ltq_mtd->map->fldrv_priv;
- cfi->addr_unlock1 ^= 1;
- cfi->addr_unlock2 ^= 1;
diff --git a/target/linux/mediatek/Makefile b/target/linux/mediatek/Makefile
index 17deab16a3..689ba31b02 100644
--- a/target/linux/mediatek/Makefile
+++ b/target/linux/mediatek/Makefile
@@ -4,8 +4,8 @@ include $(TOPDIR)/rules.mk
ARCH:=arm
BOARD:=mediatek
-BOARDNAME:=Mediatek Ralink ARM
-FEATURES:=squashfs jffs2
+BOARDNAME:=MediaTek Ralink ARM
+FEATURES:=squashfs nand ubifs
CPU_TYPE:=cortex-a7
MAINTAINER:=John Crispin <john@phrozen.org>
diff --git a/target/linux/mediatek/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/base-files/lib/upgrade/platform.sh
index be72114adb..f2dd453a11 100755
--- a/target/linux/mediatek/base-files/lib/upgrade/platform.sh
+++ b/target/linux/mediatek/base-files/lib/upgrade/platform.sh
@@ -20,7 +20,10 @@ platform_check_image() {
local board=$(cat /tmp/sysinfo/board_name)
case "$board" in
- NAND | \
+ NAND)
+ nand_do_platform_check $board $1
+ return $?
+ ;;
eMMC)
local kernel_length=`(tar xf $tar_file sysupgrade-$board/kernel -O | wc -c) 2> /dev/null`
local rootfs_length=`(tar xf $tar_file sysupgrade-$board/root -O | wc -c) 2> /dev/null`
@@ -39,3 +42,12 @@ platform_check_image() {
return 0
}
+
+platform_pre_upgrade() {
+ local board=$(cat /tmp/sysinfo/board_name)
+ case "$board" in
+ NAND)
+ nand_do_upgrade $1
+ ;;
+ esac
+}
diff --git a/target/linux/mediatek/config-4.4 b/target/linux/mediatek/config-4.4
index b20ae5d6a9..45fd2dc92b 100644
--- a/target/linux/mediatek/config-4.4
+++ b/target/linux/mediatek/config-4.4
@@ -97,28 +97,12 @@ CONFIG_CPU_V7=y
CONFIG_CRC16=y
# CONFIG_CRC32_SARWATE is not set
CONFIG_CRC32_SLICEBY8=y
-CONFIG_CRC_CCITT=m
CONFIG_CROSS_MEMORY_ATTACH=y
-CONFIG_CRYPTO_AEAD=m
-CONFIG_CRYPTO_AEAD2=m
-CONFIG_CRYPTO_DRBG=m
-CONFIG_CRYPTO_DRBG_HMAC=y
-CONFIG_CRYPTO_DRBG_MENU=m
-CONFIG_CRYPTO_ECHAINIV=m
-CONFIG_CRYPTO_HASH=m
-CONFIG_CRYPTO_HASH2=m
-CONFIG_CRYPTO_HMAC=m
-CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_JITTERENTROPY=m
-CONFIG_CRYPTO_MANAGER=m
-CONFIG_CRYPTO_MANAGER2=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_NULL2=m
-CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_RNG_DEFAULT=m
-CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_WORKQUEUE=y
+CONFIG_CRYPTO_XZ=y
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_GPIO=y
@@ -202,11 +186,6 @@ 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_MOD_ARCH_SPECIFIC=y
CONFIG_HAVE_NET_DSA=y
@@ -237,32 +216,12 @@ CONFIG_INITRAMFS_SOURCE="/openwrt/trunk/build_dir/target-arm_cortex-a7_musl-1.1.
CONFIG_IOMMU_HELPER=y
# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
CONFIG_IOMMU_SUPPORT=y
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_RAW=m
-CONFIG_IP6_NF_TARGET_REJECT=m
-CONFIG_IPV6=y
-# CONFIG_IPV6_GRE is not set
-CONFIG_IPV6_MROUTE=y
-CONFIG_IPV6_MULTIPLE_TABLES=y
-# CONFIG_IPV6_PIMSM_V2 is not set
-CONFIG_IPV6_SUBTREES=y
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IRQCHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_WORK=y
CONFIG_KALLSYMS=y
-CONFIG_LEDS_GPIO=m
CONFIG_LIBFDT=y
CONFIG_LOCKUP_DETECTOR=y
CONFIG_LOCK_SPIN_ON_OWNER=y
@@ -301,6 +260,12 @@ CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_NAND_MTK=y
CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+CONFIG_MTD_UBI_BLOCK=y
+# CONFIG_MTD_UBI_FASTMAP is not set
+# CONFIG_MTD_UBI_GLUEBI is not set
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MTK_INFRACFG=y
CONFIG_MTK_PMIC_WRAP=y
CONFIG_MTK_SCPSYS=y
@@ -311,46 +276,11 @@ CONFIG_MULTI_IRQ_HANDLER=y
CONFIG_MUTEX_SPIN_ON_OWNER=y
CONFIG_NEED_DMA_MAP_STATE=y
# CONFIG_NEON is not set
-CONFIG_NETFILTER=y
-CONFIG_NETFILTER_ADVANCED=y
-CONFIG_NETFILTER_INGRESS=y
-CONFIG_NETFILTER_XTABLES=m
-CONFIG_NETFILTER_XT_MARK=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
-# CONFIG_NETFILTER_XT_MATCH_ID is not set
-CONFIG_NETFILTER_XT_MATCH_LIMIT=m
-CONFIG_NETFILTER_XT_MATCH_MAC=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_STATE=m
-CONFIG_NETFILTER_XT_MATCH_TIME=m
-CONFIG_NETFILTER_XT_NAT=m
-CONFIG_NETFILTER_XT_TARGET_CT=m
-CONFIG_NETFILTER_XT_TARGET_LOG=m
-CONFIG_NETFILTER_XT_TARGET_REDIRECT=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_INGRESS=y
CONFIG_NET_MEDIATEK_SOC=y
# CONFIG_NET_VENDOR_AURORA is not set
CONFIG_NET_VENDOR_MEDIATEK=y
# CONFIG_NET_VENDOR_WIZNET is not set
-CONFIG_NF_CONNTRACK=m
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_NF_CONNTRACK_IPV6=m
-# CONFIG_NF_CONNTRACK_RTCACHE is not set
-CONFIG_NF_DEFRAG_IPV4=m
-CONFIG_NF_DEFRAG_IPV6=m
-CONFIG_NF_LOG_COMMON=m
-CONFIG_NF_LOG_IPV4=m
-CONFIG_NF_LOG_IPV6=m
-CONFIG_NF_NAT=m
-CONFIG_NF_NAT_IPV4=m
-CONFIG_NF_NAT_MASQUERADE_IPV4=m
-CONFIG_NF_NAT_NEEDED=y
-CONFIG_NF_NAT_REDIRECT=m
-CONFIG_NF_REJECT_IPV4=m
-CONFIG_NF_REJECT_IPV6=m
CONFIG_NLS=y
CONFIG_NO_BOOTMEM=y
CONFIG_NO_HZ=y
@@ -399,9 +329,6 @@ CONFIG_PM_SLEEP=y
CONFIG_PM_SLEEP_SMP=y
CONFIG_POWER_RESET=y
CONFIG_POWER_SUPPLY=y
-CONFIG_PPP=m
-CONFIG_PPPOE=m
-CONFIG_PPP_ASYNC=m
CONFIG_PREEMPT=y
CONFIG_PREEMPT_COUNT=y
# CONFIG_PREEMPT_NONE is not set
@@ -415,7 +342,6 @@ CONFIG_RATIONAL=y
CONFIG_RCU_CPU_STALL_TIMEOUT=21
# CONFIG_RCU_EXPERT is not set
CONFIG_RCU_STALL_COMMON=y
-CONFIG_REALTEK_PHY=m
CONFIG_REGMAP=y
CONFIG_REGMAP_MMIO=y
CONFIG_REGULATOR=y
@@ -440,7 +366,6 @@ CONFIG_SERIAL_8250_FSL=y
CONFIG_SERIAL_8250_MT6577=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SLHC=m
CONFIG_SMP=y
# CONFIG_SMP_ON_UP is not set
CONFIG_SPARSE_IRQ=y
@@ -460,16 +385,17 @@ CONFIG_SYS_SUPPORTS_APM_EMULATION=y
# CONFIG_THUMB2_KERNEL is not set
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_STATS=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_UEVENT_HELPER_PATH=""
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
CONFIG_UNINLINE_SPIN_UNLOCK=y
CONFIG_USB=y
CONFIG_USB_COMMON=y
-CONFIG_USB_EHCI_HCD=m
-CONFIG_USB_EHCI_HCD_PLATFORM=m
-CONFIG_USB_EHCI_PCI=m
-CONFIG_USB_OHCI_HCD=m
-CONFIG_USB_OHCI_HCD_PLATFORM=m
+# CONFIG_USB_EHCI_HCD is not set
CONFIG_USB_SUPPORT=y
# CONFIG_USB_UHCI_HCD is not set
CONFIG_USB_XHCI_HCD=y
@@ -487,4 +413,6 @@ CONFIG_XZ_DEC_ARM=y
CONFIG_XZ_DEC_BCJ=y
CONFIG_ZBOOT_ROM_BSS=0
CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
CONFIG_ZONE_DMA_FLAG=0
diff --git a/target/linux/mediatek/files/arch/arm/boot/dts/mt7623-NAND.dts b/target/linux/mediatek/files/arch/arm/boot/dts/mt7623-NAND.dts
index 43551f7a07..15b7da9a76 100644
--- a/target/linux/mediatek/files/arch/arm/boot/dts/mt7623-NAND.dts
+++ b/target/linux/mediatek/files/arch/arm/boot/dts/mt7623-NAND.dts
@@ -360,7 +360,6 @@
nand@0 {
reg = <0>;
spare_per_sector = <64>;
- nand-on-flash-bbt;
nand-ecc-mode = "hw";
nand-ecc-strength = <12>;
nand-ecc-step-size = <1024>;
@@ -390,7 +389,7 @@
};
partition@4140000 {
- label = "rootfs";
+ label = "ubi";
reg = <0x4140000 0x1000000>;
};
};
diff --git a/target/linux/mediatek/image/Makefile b/target/linux/mediatek/image/Makefile
index b88d2dce2f..3139197dd3 100644
--- a/target/linux/mediatek/image/Makefile
+++ b/target/linux/mediatek/image/Makefile
@@ -30,12 +30,13 @@ define Image/Build/squashfs
$(CP) $(KDIR)/root.squashfs $(BIN_DIR)/$(IMG_PREFIX)-root.squashfs
$(call Image/Build/SysupgradeCombined,eMMC,squashfs)
-endef
-
-define Image/Build/jffs2-128k
- $(CP) $(KDIR)/root.jffs2-128k $(BIN_DIR)/$(IMG_PREFIX)-root.jffs2
- $(call Image/Build/SysupgradeCombined,NAND,jffs2-128k)
+ $(call Image/BuilduImage,NAND)
+ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),)
+ $(call Image/BuilduImage,NAND,-initramfs)
+ $(CP) $(KDIR)/uImage-NAND-initramfs $(BIN_DIR)/$(IMG_PREFIX)-uImage-NAND-initramfs
+endif
+ $(call Image/Build/SysupgradeNAND,NAND,$(1),$(KDIR)/uImage-NAND)
endef
define Image/Build
diff --git a/target/linux/mediatek/patches-4.4/0072-mtd-backport-v4.7-0day-patches-from-Boris.patch b/target/linux/mediatek/patches-4.4/0072-mtd-backport-v4.7-0day-patches-from-Boris.patch
index ccbf8d0fb2..7e7a5de1c8 100644
--- a/target/linux/mediatek/patches-4.4/0072-mtd-backport-v4.7-0day-patches-from-Boris.patch
+++ b/target/linux/mediatek/patches-4.4/0072-mtd-backport-v4.7-0day-patches-from-Boris.patch
@@ -31,11 +31,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
drivers/mtd/tests/mtd_nandecctest.c | 2 +-
drivers/mtd/tests/oobtest.c | 49 ++-
drivers/mtd/tests/pagetest.c | 3 +-
- drivers/mtd/ubi/cdev.c | 4 +-
- drivers/mtd/ubi/misc.c | 49 +++
- drivers/mtd/ubi/ubi.h | 16 +-
- drivers/mtd/ubi/upd.c | 2 +-
- drivers/mtd/ubi/wl.c | 21 +-
include/linux/mtd/bbm.h | 1 -
include/linux/mtd/fsmc.h | 18 --
include/linux/mtd/inftl.h | 1 -
@@ -4654,178 +4649,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
addr0 = 0;
for (i = 0; i < ebcnt && bbt[i]; ++i)
---- a/drivers/mtd/ubi/cdev.c
-+++ b/drivers/mtd/ubi/cdev.c
-@@ -174,9 +174,9 @@ static int vol_cdev_fsync(struct file *f
- struct ubi_device *ubi = desc->vol->ubi;
- struct inode *inode = file_inode(file);
- int err;
-- mutex_lock(&inode->i_mutex);
-+ inode_lock(inode);
- err = ubi_sync(ubi->ubi_num);
-- mutex_unlock(&inode->i_mutex);
-+ inode_unlock(inode);
- return err;
- }
-
---- a/drivers/mtd/ubi/misc.c
-+++ b/drivers/mtd/ubi/misc.c
-@@ -153,3 +153,52 @@ int ubi_check_pattern(const void *buf, u
- return 0;
- return 1;
- }
-+
-+/* Normal UBI messages */
-+void ubi_msg(const struct ubi_device *ubi, const char *fmt, ...)
-+{
-+ struct va_format vaf;
-+ va_list args;
-+
-+ va_start(args, fmt);
-+
-+ vaf.fmt = fmt;
-+ vaf.va = &args;
-+
-+ pr_notice(UBI_NAME_STR "%d: %pV\n", ubi->ubi_num, &vaf);
-+
-+ va_end(args);
-+}
-+
-+/* UBI warning messages */
-+void ubi_warn(const struct ubi_device *ubi, const char *fmt, ...)
-+{
-+ struct va_format vaf;
-+ va_list args;
-+
-+ va_start(args, fmt);
-+
-+ vaf.fmt = fmt;
-+ vaf.va = &args;
-+
-+ pr_warn(UBI_NAME_STR "%d warning: %ps: %pV\n",
-+ ubi->ubi_num, __builtin_return_address(0), &vaf);
-+
-+ va_end(args);
-+}
-+
-+/* UBI error messages */
-+void ubi_err(const struct ubi_device *ubi, const char *fmt, ...)
-+{
-+ struct va_format vaf;
-+ va_list args;
-+
-+ va_start(args, fmt);
-+
-+ vaf.fmt = fmt;
-+ vaf.va = &args;
-+
-+ pr_err(UBI_NAME_STR "%d error: %ps: %pV\n",
-+ ubi->ubi_num, __builtin_return_address(0), &vaf);
-+ va_end(args);
-+}
---- a/drivers/mtd/ubi/ubi.h
-+++ b/drivers/mtd/ubi/ubi.h
-@@ -49,15 +49,19 @@
- /* UBI name used for character devices, sysfs, etc */
- #define UBI_NAME_STR "ubi"
-
-+struct ubi_device;
-+
- /* Normal UBI messages */
--#define ubi_msg(ubi, fmt, ...) pr_notice(UBI_NAME_STR "%d: " fmt "\n", \
-- ubi->ubi_num, ##__VA_ARGS__)
-+__printf(2, 3)
-+void ubi_msg(const struct ubi_device *ubi, const char *fmt, ...);
-+
- /* UBI warning messages */
--#define ubi_warn(ubi, fmt, ...) pr_warn(UBI_NAME_STR "%d warning: %s: " fmt "\n", \
-- ubi->ubi_num, __func__, ##__VA_ARGS__)
-+__printf(2, 3)
-+void ubi_warn(const struct ubi_device *ubi, const char *fmt, ...);
-+
- /* UBI error messages */
--#define ubi_err(ubi, fmt, ...) pr_err(UBI_NAME_STR "%d error: %s: " fmt "\n", \
-- ubi->ubi_num, __func__, ##__VA_ARGS__)
-+__printf(2, 3)
-+void ubi_err(const struct ubi_device *ubi, const char *fmt, ...);
-
- /* Background thread name pattern */
- #define UBI_BGT_NAME_PATTERN "ubi_bgt%dd"
---- a/drivers/mtd/ubi/wl.c
-+++ b/drivers/mtd/ubi/wl.c
-@@ -628,6 +628,7 @@ static int do_sync_erase(struct ubi_devi
- return __erase_worker(ubi, &wl_wrk);
- }
-
-+static int ensure_wear_leveling(struct ubi_device *ubi, int nested);
- /**
- * wear_leveling_worker - wear-leveling worker function.
- * @ubi: UBI device description object
-@@ -649,6 +650,7 @@ static int wear_leveling_worker(struct u
- #endif
- struct ubi_wl_entry *e1, *e2;
- struct ubi_vid_hdr *vid_hdr;
-+ int dst_leb_clean = 0;
-
- kfree(wrk);
- if (shutdown)
-@@ -753,6 +755,7 @@ static int wear_leveling_worker(struct u
-
- err = ubi_io_read_vid_hdr(ubi, e1->pnum, vid_hdr, 0);
- if (err && err != UBI_IO_BITFLIPS) {
-+ dst_leb_clean = 1;
- if (err == UBI_IO_FF) {
- /*
- * We are trying to move PEB without a VID header. UBI
-@@ -798,10 +801,12 @@ static int wear_leveling_worker(struct u
- * protection queue.
- */
- protect = 1;
-+ dst_leb_clean = 1;
- goto out_not_moved;
- }
- if (err == MOVE_RETRY) {
- scrubbing = 1;
-+ dst_leb_clean = 1;
- goto out_not_moved;
- }
- if (err == MOVE_TARGET_BITFLIPS || err == MOVE_TARGET_WR_ERR ||
-@@ -827,6 +832,7 @@ static int wear_leveling_worker(struct u
- ubi->erroneous_peb_count);
- goto out_error;
- }
-+ dst_leb_clean = 1;
- erroneous = 1;
- goto out_not_moved;
- }
-@@ -897,15 +903,24 @@ out_not_moved:
- wl_tree_add(e1, &ubi->scrub);
- else
- wl_tree_add(e1, &ubi->used);
-+ if (dst_leb_clean) {
-+ wl_tree_add(e2, &ubi->free);
-+ ubi->free_count++;
-+ }
-+
- ubi_assert(!ubi->move_to_put);
- ubi->move_from = ubi->move_to = NULL;
- ubi->wl_scheduled = 0;
- spin_unlock(&ubi->wl_lock);
-
- ubi_free_vid_hdr(ubi, vid_hdr);
-- err = do_sync_erase(ubi, e2, vol_id, lnum, torture);
-- if (err)
-- goto out_ro;
-+ if (dst_leb_clean) {
-+ ensure_wear_leveling(ubi, 1);
-+ } else {
-+ err = do_sync_erase(ubi, e2, vol_id, lnum, torture);
-+ if (err)
-+ goto out_ro;
-+ }
-
- mutex_unlock(&ubi->move_mutex);
- return 0;
--- a/include/linux/mtd/bbm.h
+++ b/include/linux/mtd/bbm.h
@@ -166,7 +166,6 @@ struct bbm_info {
diff --git a/target/linux/mediatek/patches-4.4/0103-nand_fixes.patch b/target/linux/mediatek/patches-4.4/0103-nand_fixes.patch
new file mode 100644
index 0000000000..92f34c5fc2
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0103-nand_fixes.patch
@@ -0,0 +1,22 @@
+--- a/drivers/mtd/nand/mtk_nand.c
++++ b/drivers/mtd/nand/mtk_nand.c
+@@ -1017,8 +1017,8 @@ static int mtk_nfc_ooblayout_free(struct
+ if (section >= eccsteps)
+ return -ERANGE;
+
+- oob_region->length = fdm->reg_size - fdm->ecc_size;
+- oob_region->offset = section * fdm->reg_size + fdm->ecc_size;
++ oob_region->length = fdm->reg_size - 1;
++ oob_region->offset = section * fdm->reg_size + 1;
+
+ return 0;
+ }
+@@ -1058,7 +1058,7 @@ static void mtk_nfc_set_fdm(struct mtk_n
+ fdm->reg_size = NFI_FDM_MAX_SIZE;
+
+ /* bad block mark storage */
+- fdm->ecc_size = 1;
++ fdm->ecc_size = fdm->reg_size;
+ }
+
+ static void mtk_nfc_set_bad_mark_ctl(struct mtk_nfc_bad_mark_ctl *bm_ctl,
diff --git a/target/linux/octeon/patches-4.4/170-cisco-hack.patch b/target/linux/octeon/patches-4.4/170-cisco-hack.patch
index 2311e351eb..591b51caef 100644
--- a/target/linux/octeon/patches-4.4/170-cisco-hack.patch
+++ b/target/linux/octeon/patches-4.4/170-cisco-hack.patch
@@ -18,7 +18,7 @@ Signed-off-by: Michał Osowiecki <michal.osowiecki@gmail.com>
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
-@@ -944,6 +944,10 @@
+@@ -944,6 +944,10 @@ void __init plat_mem_setup(void)
if (mem_alloc_size > MAX_MEMORY)
mem_alloc_size = MAX_MEMORY;
diff --git a/target/linux/oxnas/patches-4.4/300-introduce-oxnas-platform.patch b/target/linux/oxnas/patches-4.4/300-introduce-oxnas-platform.patch
index b3a8dc0f90..a88d5d94b5 100644
--- a/target/linux/oxnas/patches-4.4/300-introduce-oxnas-platform.patch
+++ b/target/linux/oxnas/patches-4.4/300-introduce-oxnas-platform.patch
@@ -1,6 +1,6 @@
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
-@@ -602,6 +602,19 @@ config ARCH_LPC32XX
+@@ -603,6 +603,19 @@ config ARCH_LPC32XX
help
Support for the NXP LPC32XX family of processors
@@ -20,7 +20,7 @@
config ARCH_PXA
bool "PXA2xx/PXA3xx-based"
depends on MMU
-@@ -882,6 +895,8 @@ source "arch/arm/mach-omap2/Kconfig"
+@@ -883,6 +896,8 @@ source "arch/arm/mach-omap2/Kconfig"
source "arch/arm/mach-orion5x/Kconfig"
diff --git a/target/linux/ramips/base-files/etc/board.d/02_network b/target/linux/ramips/base-files/etc/board.d/02_network
index dbb5fb43e0..6157d87763 100755
--- a/target/linux/ramips/base-files/etc/board.d/02_network
+++ b/target/linux/ramips/base-files/etc/board.d/02_network
@@ -286,6 +286,10 @@ ramips_setup_macs()
lan_mac=$(mtd_get_mac_ascii nvram lanmac)
wan_mac=$(mtd_get_mac_ascii nvram wanmac)
;;
+ dir-860l-b1)
+ lan_mac=$(mtd_get_mac_ascii factory lanmac)
+ wan_mac=$(mtd_get_mac_ascii factory wanmac)
+ ;;
e1700)
wan_mac=$(mtd_get_mac_ascii config WAN_MAC_ADDR)
;;
diff --git a/target/linux/ramips/base-files/etc/uci-defaults/09_fix-seama-header b/target/linux/ramips/base-files/etc/uci-defaults/09_fix-seama-header
index 35167f1adc..7a0a325d4b 100644
--- a/target/linux/ramips/base-files/etc/uci-defaults/09_fix-seama-header
+++ b/target/linux/ramips/base-files/etc/uci-defaults/09_fix-seama-header
@@ -6,9 +6,9 @@
. /lib/ramips.sh
fix_seama_header() {
- local part=$1
+ local kernel_size=$(sed -n 's/mtd[0-9]*: \([0-9a-f]*\).*"kernel".*/\1/p' /proc/mtd)
- mtd fixseama $part
+ [ "$kernel_size" ] && mtd -c 0x$kernel_size fixseama firmware
}
board=$(ramips_board_name)
@@ -17,6 +17,6 @@ case "$board" in
cy-swr1100 | \
dir-645 | \
dir-860l-b1)
- fix_seama_header kernel
+ fix_seama_header
;;
esac
diff --git a/target/linux/ramips/dts/WL-351.dts b/target/linux/ramips/dts/WL-351.dts
index ecda696732..541f8cef99 100644
--- a/target/linux/ramips/dts/WL-351.dts
+++ b/target/linux/ramips/dts/WL-351.dts
@@ -86,9 +86,13 @@
&pinctrl {
state_default: pinctrl0 {
gpio {
- ralink,group = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+ ralink,group = "spi", "i2c", "jtag", "mdio", "uartf";
ralink,function = "gpio";
};
+ rgmii {
+ ralink,group = "rgmii";
+ ralink,function = "rgmii";
+ };
};
};
@@ -97,6 +101,7 @@
};
&esw {
+ ralink,rgmii = <1>;
mediatek,portmap = <0x3f>;
ralink,fct2 = <0x0002500c>;
/*
diff --git a/target/linux/ramips/dts/mt7620a.dtsi b/target/linux/ramips/dts/mt7620a.dtsi
index ccadbe40db..641d248e60 100644
--- a/target/linux/ramips/dts/mt7620a.dtsi
+++ b/target/linux/ramips/dts/mt7620a.dtsi
@@ -176,7 +176,7 @@
};
i2c: i2c@900 {
- compatible = "link,mt7620a-i2c", "ralink,rt2880-i2c";
+ compatible = "ralink,rt2880-i2c";
reg = <0x900 0x100>;
resets = <&rstctrl 16>;
@@ -192,7 +192,7 @@
};
i2s: i2s@a00 {
- compatible = "ralink,mt7620a-i2s";
+ compatible = "mediatek,mt7620-i2s";
reg = <0xa00 0x100>;
resets = <&rstctrl 17>;
@@ -201,8 +201,11 @@
interrupt-parent = <&intc>;
interrupts = <10>;
+ txdma-req = <2>;
+ rxdma-req = <3>;
+
dmas = <&gdma 4>,
- <&gdma 5>;
+ <&gdma 6>;
dma-names = "tx", "rx";
status = "disabled";
diff --git a/target/linux/ramips/dts/mt7621.dtsi b/target/linux/ramips/dts/mt7621.dtsi
index 7a9d79a88b..a8b98ed8c6 100644
--- a/target/linux/ramips/dts/mt7621.dtsi
+++ b/target/linux/ramips/dts/mt7621.dtsi
@@ -89,6 +89,46 @@
};
};
+ i2c: i2c@900 {
+ compatible = "mediatek,mt7621-i2c";
+ reg = <0x900 0x100>;
+
+ clocks = <&sysclock>;
+
+ resets = <&rstctrl 16>;
+ reset-names = "i2c";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c_pins>;
+ };
+
+ i2s: i2s@a00 {
+ compatible = "mediatek,mt7621-i2s";
+ reg = <0xa00 0x100>;
+
+ clocks = <&sysclock>;
+
+ resets = <&rstctrl 17>;
+ reset-names = "i2s";
+
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SHARED 16 IRQ_TYPE_LEVEL_HIGH>;
+
+ txdma-req = <2>;
+ rxdma-req = <3>;
+
+ dmas = <&gdma 4>,
+ <&gdma 6>;
+ dma-names = "tx", "rx";
+
+ status = "disabled";
+ };
+
memc: memc@5000 {
compatible = "mtk,mt7621-memc";
reg = <0x300 0x100>;
@@ -188,13 +228,6 @@
state_default: pinctrl0 {
};
- spi_pins: spi {
- spi {
- ralink,group = "spi";
- ralink,function = "spi";
- };
- };
-
i2c_pins: i2c {
i2c {
ralink,group = "i2c";
@@ -202,6 +235,13 @@
};
};
+ spi_pins: spi {
+ spi {
+ ralink,group = "spi";
+ ralink,function = "spi";
+ };
+ };
+
uart1_pins: uart1 {
uart1 {
ralink,group = "uart1";
diff --git a/target/linux/ramips/dts/mt7628an.dtsi b/target/linux/ramips/dts/mt7628an.dtsi
index 6d5ed95e49..671aaef386 100644
--- a/target/linux/ramips/dts/mt7628an.dtsi
+++ b/target/linux/ramips/dts/mt7628an.dtsi
@@ -110,7 +110,7 @@
};
i2c: i2c@900 {
- compatible = "mediatek,mt7628-i2c";
+ compatible = "mediatek,mt7621-i2c";
reg = <0x900 0x100>;
resets = <&rstctrl 16>;
@@ -126,7 +126,7 @@
};
i2s: i2s@a00 {
- compatible = "ralink,mt7620a-i2s";
+ compatible = "mediatek,mt7628-i2s";
reg = <0xa00 0x100>;
resets = <&rstctrl 17>;
@@ -135,8 +135,11 @@
interrupt-parent = <&intc>;
interrupts = <10>;
- dmas = <&gdma 2>,
- <&gdma 3>;
+ txdma-req = <2>;
+ rxdma-req = <3>;
+
+ dmas = <&gdma 4>,
+ <&gdma 6>;
dma-names = "tx", "rx";
status = "disabled";
diff --git a/target/linux/ramips/dts/rt2880.dtsi b/target/linux/ramips/dts/rt2880.dtsi
index ad882547f7..c2ead2c975 100644
--- a/target/linux/ramips/dts/rt2880.dtsi
+++ b/target/linux/ramips/dts/rt2880.dtsi
@@ -114,6 +114,22 @@
status = "disabled";
};
+ i2c: i2c@900 {
+ compatible = "ralink,rt2880-i2c";
+ reg = <0x900 0x100>;
+
+ resets = <&rstctrl 9>;
+ reset-names = "i2c";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c_pins>;
+ };
+
uartlite: uartlite@c00 {
compatible = "ralink,rt2880-uart", "ns16550a";
reg = <0xc00 0x100>;
@@ -138,6 +154,13 @@
};
};
+ i2c_pins: i2c {
+ i2c {
+ ralink,group = "i2c";
+ ralink,function = "i2c";
+ };
+ };
+
spi_pins: spi {
spi {
ralink,group = "spi";
diff --git a/target/linux/ramips/dts/rt3050.dtsi b/target/linux/ramips/dts/rt3050.dtsi
index ed88ac12ec..23da1c43ef 100644
--- a/target/linux/ramips/dts/rt3050.dtsi
+++ b/target/linux/ramips/dts/rt3050.dtsi
@@ -166,6 +166,40 @@
status = "disabled";
};
+ i2c@900 {
+ compatible = "ralink,rt2880-i2c";
+ reg = <0x900 0x100>;
+
+ resets = <&rstctrl 16>;
+ reset-names = "i2c";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c_pins>;
+ };
+
+ i2s@a00 {
+ compatible = "ralink,rt3050-i2s";
+ reg = <0xa00 0x100>;
+
+ resets = <&rstctrl 17>;
+ reset-names = "i2s";
+
+ interrupt-parent = <&intc>;
+ interrupts = <10>;
+
+ txdma-req = <2>;
+
+ dmas = <&gdma 4>;
+ dma-names = "tx";
+
+ status = "disabled";
+ };
+
spi0: spi@b00 {
compatible = "ralink,rt3050-spi", "ralink,rt2880-spi";
reg = <0xb00 0x100>;
@@ -212,6 +246,13 @@
};
};
+ i2c_pins: i2c {
+ i2c {
+ ralink,group = "i2c";
+ ralink,function = "i2c";
+ };
+ };
+
spi_pins: spi {
spi {
ralink,group = "spi";
diff --git a/target/linux/ramips/dts/rt3352.dtsi b/target/linux/ramips/dts/rt3352.dtsi
index 0bb28ec833..a617281b75 100644
--- a/target/linux/ramips/dts/rt3352.dtsi
+++ b/target/linux/ramips/dts/rt3352.dtsi
@@ -146,6 +146,42 @@
status = "disabled";
};
+ i2c@900 {
+ compatible = "ralink,rt2880-i2c";
+ reg = <0x900 0x100>;
+
+ resets = <&rstctrl 16>;
+ reset-names = "i2c";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c_pins>;
+ };
+
+ i2s@a00 {
+ compatible = "ralink,rt3352-i2s";
+ reg = <0xa00 0x100>;
+
+ resets = <&rstctrl 17>;
+ reset-names = "i2s";
+
+ interrupt-parent = <&intc>;
+ interrupts = <10>;
+
+ txdma-req = <2>;
+ rxdma-req = <3>;
+
+ dmas = <&gdma 4>,
+ <&gdma 6>;
+ dma-names = "tx", "rx";
+
+ status = "disabled";
+ };
+
spi0: spi@b00 {
compatible = "ralink,rt3352-spi", "ralink,rt2880-spi";
reg = <0xb00 0x40>;
@@ -219,6 +255,13 @@
state_default: pinctrl0 {
};
+ i2c_pins: i2c {
+ i2c {
+ ralink,group = "i2c";
+ ralink,function = "i2c";
+ };
+ };
+
spi_pins: spi {
spi {
ralink,group = "spi";
diff --git a/target/linux/ramips/dts/rt3883.dtsi b/target/linux/ramips/dts/rt3883.dtsi
index 041b0633d3..20fe7bfab9 100644
--- a/target/linux/ramips/dts/rt3883.dtsi
+++ b/target/linux/ramips/dts/rt3883.dtsi
@@ -166,6 +166,42 @@
status = "disabled";
};
+ i2c@900 {
+ compatible = "ralink,rt2880-i2c";
+ reg = <0x900 0x100>;
+
+ resets = <&rstctrl 16>;
+ reset-names = "i2c";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c_pins>;
+ };
+
+ i2s@a00 {
+ compatible = "ralink,rt3883-i2s";
+ reg = <0xa00 0x100>;
+
+ resets = <&rstctrl 17>;
+ reset-names = "i2s";
+
+ interrupt-parent = <&intc>;
+ interrupts = <10>;
+
+ txdma-req = <2>;
+ rxdma-req = <3>;
+
+ dmas = <&gdma 4>,
+ <&gdma 6>;
+ dma-names = "tx", "rx";
+
+ status = "disabled";
+ };
+
spi0: spi@b00 {
compatible = "ralink,rt3883-spi", "ralink,rt2880-spi";
reg = <0xb00 0x40>;
@@ -239,6 +275,13 @@
state_default: pinctrl0 {
};
+ i2c_pins: i2c {
+ i2c {
+ ralink,group = "i2c";
+ ralink,function = "i2c";
+ };
+ };
+
spi_pins: spi {
spi {
ralink,group = "spi";
diff --git a/target/linux/ramips/dts/rt5350.dtsi b/target/linux/ramips/dts/rt5350.dtsi
index 1027519c98..99959bfa35 100644
--- a/target/linux/ramips/dts/rt5350.dtsi
+++ b/target/linux/ramips/dts/rt5350.dtsi
@@ -138,7 +138,7 @@
};
i2c: i2c@900 {
- compatible = "link,rt5350-i2c", "ralink,rt2880-i2c";
+ compatible = "ralink,rt2880-i2c";
reg = <0x900 0x100>;
resets = <&rstctrl 16>;
@@ -153,6 +153,26 @@
status = "disabled";
};
+ i2s@a00 {
+ compatible = "ralink,rt3352-i2s";
+ reg = <0xa00 0x100>;
+
+ resets = <&rstctrl 17>;
+ reset-names = "i2s";
+
+ interrupt-parent = <&intc>;
+ interrupts = <10>;
+
+ txdma-req = <2>;
+ rxdma-req = <3>;
+
+ dmas = <&gdma 4>,
+ <&gdma 6>;
+ dma-names = "tx", "rx";
+
+ status = "disabled";
+ };
+
spi0: spi@b00 {
compatible = "ralink,rt5350-spi", "ralink,rt2880-spi";
reg = <0xb00 0x40>;
@@ -236,13 +256,6 @@
state_default: pinctrl0 {
};
- spi_pins: spi {
- spi {
- ralink,group = "spi";
- ralink,function = "spi";
- };
- };
-
i2c_pins: i2c {
i2c {
ralink,group = "i2c";
@@ -250,6 +263,13 @@
};
};
+ spi_pins: spi {
+ spi {
+ ralink,group = "spi";
+ ralink,function = "spi";
+ };
+ };
+
phy_led_pins: phy_led {
phy_led {
ralink,group = "led";
diff --git a/target/linux/ramips/image/rt305x.mk b/target/linux/ramips/image/rt305x.mk
index da7fc463f4..96175747d7 100644
--- a/target/linux/ramips/image/rt305x.mk
+++ b/target/linux/ramips/image/rt305x.mk
@@ -379,7 +379,6 @@ define Image/Build/Profile/Default
$(call Image/Build/Profile/WL-330N,$(1))
$(call Image/Build/Profile/WL-330N3G,$(1))
$(call Image/Build/Profile/WL-341V3,$(1))
- $(call Image/Build/Profile/WL-351,$(1))
$(call Image/Build/Profile/WNCE2001,$(1))
$(call Image/Build/Profile/WR512-3GN,$(1))
$(call Image/Build/Profile/WR6202,$(1))
diff --git a/target/linux/ramips/patches-4.4/0048-asoc-add-mt7620-support.patch b/target/linux/ramips/patches-4.4/0048-asoc-add-mt7620-support.patch
index 41ef41c022..bc1800efe4 100644
--- a/target/linux/ramips/patches-4.4/0048-asoc-add-mt7620-support.patch
+++ b/target/linux/ramips/patches-4.4/0048-asoc-add-mt7620-support.patch
@@ -58,41 +58,30 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
obj-$(CONFIG_SND_SOC) += sirf/
--- /dev/null
+++ b/sound/soc/ralink/Kconfig
-@@ -0,0 +1,15 @@
-+config SND_MT7620_SOC_I2S
-+ depends on SOC_MT7620 && SND_SOC
+@@ -0,0 +1,8 @@
++config SND_RALINK_SOC_I2S
++ depends on RALINK && SND_SOC && !SOC_RT288X
+ select SND_SOC_GENERIC_DMAENGINE_PCM
-+ tristate "SoC Audio (I2S protocol) for Ralink MT7620 SoC"
++ select REGMAP_MMIO
++ tristate "SoC Audio (I2S protocol) for Ralink SoC"
+ help
-+ Say Y if you want to use I2S protocol and I2S codec on Ingenic MT7620
++ Say Y if you want to use I2S protocol and I2S codec on Ralink/MediaTek
+ based boards.
-+
-+config SND_MT7620_SOC_WM8960
-+ tristate "SoC Audio support for Ralink WM8960"
-+ select SND_MT7620_SOC_I2S
-+ select SND_SOC_WM8960
-+ help
-+ Say Y if you want to add support for ASoC audio on the Qi LB60 board
-+ a.k.a Qi Ben NanoNote.
--- /dev/null
+++ b/sound/soc/ralink/Makefile
-@@ -0,0 +1,11 @@
+@@ -0,0 +1,6 @@
+#
-+# Jz4740 Platform Support
++# Ralink/MediaTek Platform Support
+#
-+snd-soc-mt7620-i2s-objs := mt7620-i2s.o
-+
-+obj-$(CONFIG_SND_MT7620_SOC_I2S) += snd-soc-mt7620-i2s.o
-+
-+# Jz4740 Machine Support
-+snd-soc-mt7620-wm8960-objs := mt7620-wm8960.o
++snd-soc-ralink-i2s-objs := ralink-i2s.o
+
-+obj-$(CONFIG_SND_MT7620_SOC_WM8960) += snd-soc-mt7620-wm8960.o
++obj-$(CONFIG_SND_RALINK_SOC_I2S) += snd-soc-ralink-i2s.o
--- /dev/null
-+++ b/sound/soc/ralink/mt7620-i2s.c
-@@ -0,0 +1,436 @@
++++ b/sound/soc/ralink/ralink-i2s.c
+@@ -0,0 +1,965 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
++ * Copyright (C) 2016 Michael Lee <igvtee@gmail.com>
+ *
+ * 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
@@ -105,27 +94,31 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ *
+ */
+
-+#include <linux/init.h>
-+#include <linux/io.h>
-+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+
-+#include <linux/delay.h>
-+
-+#include <linux/dma-mapping.h>
-+
-+#include <sound/core.h>
-+#include <sound/pcm.h>
++#include <linux/clk.h>
++#include <linux/regmap.h>
++#include <linux/reset.h>
++#include <linux/debugfs.h>
++#include <linux/of_device.h>
+#include <sound/pcm_params.h>
-+#include <sound/soc.h>
-+#include <sound/initval.h>
+#include <sound/dmaengine_pcm.h>
+
-+#include <ralink_regs.h>
++#include <asm/mach-ralink/ralink_regs.h>
++
++#define DRV_NAME "ralink-i2s"
+
+#define I2S_REG_CFG0 0x00
++#define I2S_REG_INT_STATUS 0x04
++#define I2S_REG_INT_EN 0x08
++#define I2S_REG_FF_STATUS 0x0c
++#define I2S_REG_WREG 0x10
++#define I2S_REG_RREG 0x14
++#define I2S_REG_CFG1 0x18
++#define I2S_REG_DIVCMP 0x20
++#define I2S_REG_DIVINT 0x24
++
++/* I2S_REG_CFG0 */
+#define I2S_REG_CFG0_EN BIT(31)
+#define I2S_REG_CFG0_DMA_EN BIT(30)
+#define I2S_REG_CFG0_BYTE_SWAP BIT(28)
@@ -134,143 +127,235 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+#define I2S_REG_CFG0_SLAVE BIT(16)
+#define I2S_REG_CFG0_RX_THRES 12
+#define I2S_REG_CFG0_TX_THRES 4
++#define I2S_REG_CFG0_THRES_MASK (0xf << I2S_REG_CFG0_RX_THRES) | \
++ (4 << I2S_REG_CFG0_TX_THRES)
+#define I2S_REG_CFG0_DFT_THRES (4 << I2S_REG_CFG0_RX_THRES) | \
-+ (4 << I2S_REG_CFG0_TX_THRES)
-+
-+#define I2S_REG_INT_STATUS 0x04
-+#define I2S_REG_INT_EN 0x08
-+#define I2S_REG_FF_STATUS 0x0c
-+#define I2S_REG_WREG 0x10
-+#define I2S_REG_RREG 0x14
-+#define I2S_REG_CFG1 0x18
-+
-+#define I2S_REG_DIVCMP 0x20
-+#define I2S_REG_DIVINT 0x24
-+#define I2S_REG_CLK_EN BIT(31)
++ (4 << I2S_REG_CFG0_TX_THRES)
++/* RT305x */
++#define I2S_REG_CFG0_CLK_DIS BIT(8)
++#define I2S_REG_CFG0_TXCH_SWAP BIT(3)
++#define I2S_REG_CFG0_TXCH1_OFF BIT(2)
++#define I2S_REG_CFG0_TXCH0_OFF BIT(1)
++#define I2S_REG_CFG0_SLAVE_EN BIT(0)
++/* RT3883 */
++#define I2S_REG_CFG0_RXCH_SWAP BIT(11)
++#define I2S_REG_CFG0_RXCH1_OFF BIT(10)
++#define I2S_REG_CFG0_RXCH0_OFF BIT(9)
++#define I2S_REG_CFG0_WS_INV BIT(0)
++/* MT7628 */
++#define I2S_REG_CFG0_FMT_LE BIT(29)
++#define I2S_REG_CFG0_SYS_BE BIT(28)
++#define I2S_REG_CFG0_NORM_24 BIT(18)
++#define I2S_REG_CFG0_DATA_24 BIT(17)
++
++/* I2S_REG_INT_STATUS */
++#define I2S_REG_INT_RX_FAULT BIT(7)
++#define I2S_REG_INT_RX_OVRUN BIT(6)
++#define I2S_REG_INT_RX_UNRUN BIT(5)
++#define I2S_REG_INT_RX_THRES BIT(4)
++#define I2S_REG_INT_TX_FAULT BIT(3)
++#define I2S_REG_INT_TX_OVRUN BIT(2)
++#define I2S_REG_INT_TX_UNRUN BIT(1)
++#define I2S_REG_INT_TX_THRES BIT(0)
++#define I2S_REG_INT_TX_MASK 0xf
++#define I2S_REG_INT_RX_MASK 0xf0
++
++/* I2S_REG_INT_STATUS */
++#define I2S_RX_AVCNT(x) ((x >> 4) & 0xf)
++#define I2S_TX_AVCNT(x) (x & 0xf)
++/* MT7628 */
++#define MT7628_I2S_RX_AVCNT(x) ((x >> 8) & 0x1f)
++#define MT7628_I2S_TX_AVCNT(x) (x & 0x1f)
++
++/* I2S_REG_CFG1 */
++#define I2S_REG_CFG1_LBK BIT(31)
++#define I2S_REG_CFG1_EXTLBK BIT(30)
++/* RT3883 */
++#define I2S_REG_CFG1_LEFT_J BIT(0)
++#define I2S_REG_CFG1_RIGHT_J BIT(1)
++#define I2S_REG_CFG1_FMT_MASK 0x3
++
++/* I2S_REG_DIVCMP */
++#define I2S_REG_DIVCMP_CLKEN BIT(31)
++#define I2S_REG_DIVCMP_DIVCOMP_MASK 0x1ff
++
++/* I2S_REG_DIVINT */
++#define I2S_REG_DIVINT_MASK 0x3ff
++
++/* BCLK dividers */
++#define RALINK_I2S_DIVCMP 0
++#define RALINK_I2S_DIVINT 1
++
++/* FIFO */
++#define RALINK_I2S_FIFO_SIZE 32
++
++/* feature flags */
++#define RALINK_FLAGS_TXONLY BIT(0)
++#define RALINK_FLAGS_LEFT_J BIT(1)
++#define RALINK_FLAGS_RIGHT_J BIT(2)
++#define RALINK_FLAGS_ENDIAN BIT(3)
++#define RALINK_FLAGS_24BIT BIT(4)
++
++#define RALINK_I2S_INT_EN 0
++
++struct ralink_i2s_stats {
++ u32 dmafault;
++ u32 overrun;
++ u32 underrun;
++ u32 belowthres;
++};
+
-+struct mt7620_i2s {
-+ struct resource *mem;
-+ void __iomem *base;
-+ dma_addr_t phys_base;
++struct ralink_i2s {
++ struct device *dev;
++ void __iomem *regs;
++ struct clk *clk;
++ struct regmap *regmap;
++ u32 flags;
++ unsigned int fmt;
++ u16 txdma_req;
++ u16 rxdma_req;
+
+ struct snd_dmaengine_dai_dma_data playback_dma_data;
+ struct snd_dmaengine_dai_dma_data capture_dma_data;
++
++ struct dentry *dbg_dir;
++ struct dentry *dbg_stats;
++ struct ralink_i2s_stats txstats;
++ struct ralink_i2s_stats rxstats;
+};
+
-+static inline uint32_t mt7620_i2s_read(const struct mt7620_i2s *i2s,
-+ unsigned int reg)
++static void ralink_i2s_dump_regs(struct ralink_i2s *i2s)
+{
-+ return readl(i2s->base + reg);
++ u32 buf[10];
++ int ret;
++
++ ret = regmap_bulk_read(i2s->regmap, I2S_REG_CFG0,
++ buf, ARRAY_SIZE(buf));
++
++ dev_dbg(i2s->dev, "CFG0: %08x, INTSTAT: %08x, INTEN: %08x, " \
++ "FFSTAT: %08x, WREG: %08x, RREG: %08x, " \
++ "CFG1: %08x, DIVCMP: %08x, DIVINT: %08x\n",
++ buf[0], buf[1], buf[2], buf[3], buf[4],
++ buf[5], buf[6], buf[8], buf[9]);
+}
+
-+static inline void mt7620_i2s_write(const struct mt7620_i2s *i2s,
-+ unsigned int reg, uint32_t value)
++static int ralink_i2s_set_sysclk(struct snd_soc_dai *dai,
++ int clk_id, unsigned int freq, int dir)
+{
-+ //printk("i2s --> %p = 0x%08X\n", i2s->base + reg, value);
-+ writel(value, i2s->base + reg);
++ return 0;
+}
+
-+static int mt7620_i2s_startup(struct snd_pcm_substream *substream,
-+ struct snd_soc_dai *dai)
++static int ralink_i2s_set_sys_bclk(struct snd_soc_dai *dai, int width, int rate)
+{
-+ struct mt7620_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+ uint32_t cfg;
++ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
++ unsigned long clk = clk_get_rate(i2s->clk);
++ int div;
++ uint32_t data;
+
-+ if (dai->active)
++ /* disable clock at slave mode */
++ if ((i2s->fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
++ SND_SOC_DAIFMT_CBM_CFM) {
++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++ I2S_REG_CFG0_CLK_DIS,
++ I2S_REG_CFG0_CLK_DIS);
+ return 0;
++ }
+
-+ cfg = mt7620_i2s_read(i2s, I2S_REG_CFG0);
-+ cfg |= I2S_REG_CFG0_EN;
-+ mt7620_i2s_write(i2s, I2S_REG_CFG0, cfg);
++ /* FREQOUT = FREQIN / (I2S_CLK_DIV + 1) */
++ div = (clk / rate ) - 1;
+
-+ return 0;
-+}
++ data = rt_sysc_r32(0x30);
++ data &= (0xff << 8);
++ data |= (0x1 << 15) | (div << 8);
++ rt_sysc_w32(data, 0x30);
+
-+static void mt7620_i2s_shutdown(struct snd_pcm_substream *substream,
-+ struct snd_soc_dai *dai)
-+{
-+ struct mt7620_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+ uint32_t cfg;
++ /* enable clock */
++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, I2S_REG_CFG0_CLK_DIS, 0);
+
-+ if (dai->active)
-+ return;
++ dev_dbg(i2s->dev, "clk: %lu, rate: %u, div: %d\n",
++ clk, rate, div);
+
-+ cfg = mt7620_i2s_read(i2s, I2S_REG_CFG0);
-+ cfg &= ~I2S_REG_CFG0_EN;
-+ mt7620_i2s_write(i2s, I2S_REG_CFG0, cfg);
++ return 0;
+}
+
-+static int mt7620_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
-+ struct snd_soc_dai *dai)
++static int ralink_i2s_set_bclk(struct snd_soc_dai *dai, int width, int rate)
+{
-+ struct mt7620_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+
-+ uint32_t cfg;
-+ uint32_t mask;
-+
-+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-+ mask = I2S_REG_CFG0_TX_EN;
-+ else
-+ mask = I2S_REG_CFG0_RX_EN;
++ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
++ unsigned long clk = clk_get_rate(i2s->clk);
++ int divint, divcomp;
++
++ /* disable clock at slave mode */
++ if ((i2s->fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
++ SND_SOC_DAIFMT_CBM_CFM) {
++ regmap_update_bits(i2s->regmap, I2S_REG_DIVCMP,
++ I2S_REG_DIVCMP_CLKEN, 0);
++ return 0;
++ }
+
-+ cfg = mt7620_i2s_read(i2s, I2S_REG_CFG0);
++ /* FREQOUT = FREQIN * (1/2) * (1/(DIVINT + DIVCOMP/512)) */
++ clk = clk / (2 * 2 * width);
++ divint = clk / rate;
++ divcomp = ((clk % rate) * 512) / rate;
+
-+ switch (cmd) {
-+ case SNDRV_PCM_TRIGGER_START:
-+ case SNDRV_PCM_TRIGGER_RESUME:
-+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-+ cfg |= mask;
-+ break;
-+ case SNDRV_PCM_TRIGGER_STOP:
-+ case SNDRV_PCM_TRIGGER_SUSPEND:
-+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-+ cfg &= ~mask;
-+ break;
-+ default:
++ if ((divint > I2S_REG_DIVINT_MASK) ||
++ (divcomp > I2S_REG_DIVCMP_DIVCOMP_MASK))
+ return -EINVAL;
-+ }
+
-+ if (cfg & (I2S_REG_CFG0_TX_EN | I2S_REG_CFG0_RX_EN))
-+ cfg |= I2S_REG_CFG0_DMA_EN;
-+ else
-+ cfg &= ~I2S_REG_CFG0_DMA_EN;
++ regmap_update_bits(i2s->regmap, I2S_REG_DIVINT,
++ I2S_REG_DIVINT_MASK, divint);
++ regmap_update_bits(i2s->regmap, I2S_REG_DIVCMP,
++ I2S_REG_DIVCMP_DIVCOMP_MASK, divcomp);
++
++ /* enable clock */
++ regmap_update_bits(i2s->regmap, I2S_REG_DIVCMP, I2S_REG_DIVCMP_CLKEN,
++ I2S_REG_DIVCMP_CLKEN);
+
-+ mt7620_i2s_write(i2s, I2S_REG_CFG0, cfg);
++ dev_dbg(i2s->dev, "clk: %lu, rate: %u, int: %d, comp: %d\n",
++ clk_get_rate(i2s->clk), rate, divint, divcomp);
+
+ return 0;
+}
+
-+static int mt7620_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
++static int ralink_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
-+ struct mt7620_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+ uint32_t cfg;
-+
-+ cfg = mt7620_i2s_read(i2s, I2S_REG_CFG0);
++ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
++ unsigned int cfg0 = 0, cfg1 = 0;
+
++ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
-+ case SND_SOC_DAIFMT_CBS_CFS:
-+ cfg |= I2S_REG_CFG0_SLAVE;
-+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
-+ cfg &= ~I2S_REG_CFG0_SLAVE;
++ if (i2s->flags & RALINK_FLAGS_TXONLY)
++ cfg0 |= I2S_REG_CFG0_SLAVE_EN;
++ else
++ cfg0 |= I2S_REG_CFG0_SLAVE;
++ break;
++ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
-+ case SND_SOC_DAIFMT_CBM_CFS:
+ default:
+ return -EINVAL;
+ }
+
++ /* interface format */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
-+ case SND_SOC_DAIFMT_MSB:
-+ cfg &= ~I2S_REG_CFG0_BYTE_SWAP;
-+ break;
-+ case SND_SOC_DAIFMT_LSB:
-+ cfg |= I2S_REG_CFG0_BYTE_SWAP;
+ break;
++ case SND_SOC_DAIFMT_RIGHT_J:
++ if (i2s->flags & RALINK_FLAGS_RIGHT_J) {
++ cfg1 |= I2S_REG_CFG1_RIGHT_J;
++ break;
++ }
++ return -EINVAL;
++ case SND_SOC_DAIFMT_LEFT_J:
++ if (i2s->flags & RALINK_FLAGS_LEFT_J) {
++ cfg1 |= I2S_REG_CFG1_LEFT_J;
++ break;
++ }
++ return -EINVAL;
+ default:
+ return -EINVAL;
+ }
+
++ /* clock inversion */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
@@ -278,488 +363,684 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ return -EINVAL;
+ }
+
-+ mt7620_i2s_write(i2s, I2S_REG_CFG0, cfg);
++ if (i2s->flags & RALINK_FLAGS_TXONLY) {
++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++ I2S_REG_CFG0_SLAVE_EN, cfg0);
++ } else {
++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++ I2S_REG_CFG0_SLAVE, cfg0);
++ }
++ regmap_update_bits(i2s->regmap, I2S_REG_CFG1,
++ I2S_REG_CFG1_FMT_MASK, cfg1);
++ i2s->fmt = fmt;
+
+ return 0;
+}
+
-+static int mt7620_i2s_hw_params(struct snd_pcm_substream *substream,
-+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
++static int ralink_i2s_startup(struct snd_pcm_substream *substream,
++ struct snd_soc_dai *dai)
+{
++ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
++
++ if (dai->active)
++ return 0;
++
++ /* setup status interrupt */
++#if (RALINK_I2S_INT_EN)
++ regmap_write(i2s->regmap, I2S_REG_INT_EN, 0xff);
++#else
++ regmap_write(i2s->regmap, I2S_REG_INT_EN, 0x0);
++#endif
++
++ /* enable */
++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++ I2S_REG_CFG0_EN | I2S_REG_CFG0_DMA_EN |
++ I2S_REG_CFG0_THRES_MASK,
++ I2S_REG_CFG0_EN | I2S_REG_CFG0_DMA_EN |
++ I2S_REG_CFG0_DFT_THRES);
+
+ return 0;
+}
+
-+unsigned long i2sMaster_inclk_int[11] = {
-+ 78, 56, 52, 39, 28, 26, 19, 14, 13, 9, 6};
-+unsigned long i2sMaster_inclk_comp[11] = {
-+ 64, 352, 42, 32, 176, 21, 272, 88, 10, 455, 261};
++static void ralink_i2s_shutdown(struct snd_pcm_substream *substream,
++ struct snd_soc_dai *dai)
++{
++ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
++
++ /* If both streams are stopped, disable module and clock */
++ if (dai->active)
++ return;
+
++ /*
++ * datasheet mention when disable all control regs are cleared
++ * to initial values. need reinit at startup.
++ */
++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, I2S_REG_CFG0_EN, 0);
++}
+
-+static int mt7620_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
-+ unsigned int freq, int dir)
++static int ralink_i2s_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
-+ struct mt7620_i2s *i2s = snd_soc_dai_get_drvdata(dai);
++ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
++ int width;
++ int ret;
++
++ width = params_width(params);
++ switch (width) {
++ case 16:
++ if (i2s->flags & RALINK_FLAGS_24BIT)
++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++ I2S_REG_CFG0_DATA_24, 0);
++ break;
++ case 24:
++ if (i2s->flags & RALINK_FLAGS_24BIT) {
++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++ I2S_REG_CFG0_DATA_24,
++ I2S_REG_CFG0_DATA_24);
++ break;
++ }
++ return -EINVAL;
++ default:
++ return -EINVAL;
++ }
+
-+ printk("Internal REFCLK with fractional division\n");
++ switch (params_channels(params)) {
++ case 2:
++ break;
++ default:
++ return -EINVAL;
++ }
+
-+ mt7620_i2s_write(i2s, I2S_REG_DIVINT, i2sMaster_inclk_int[7]);
-+ mt7620_i2s_write(i2s, I2S_REG_DIVCMP,
-+ i2sMaster_inclk_comp[7] | I2S_REG_CLK_EN);
++ if (i2s->flags & RALINK_FLAGS_ENDIAN) {
++ /* system endian */
++#ifdef SNDRV_LITTLE_ENDIAN
++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++ I2S_REG_CFG0_SYS_BE, 0);
++#else
++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++ I2S_REG_CFG0_SYS_BE,
++ I2S_REG_CFG0_SYS_BE);
++#endif
++
++ /* data endian */
++ switch (params_format(params)) {
++ case SNDRV_PCM_FORMAT_S16_LE:
++ case SNDRV_PCM_FORMAT_S24_LE:
++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++ I2S_REG_CFG0_FMT_LE,
++ I2S_REG_CFG0_FMT_LE);
++ break;
++ case SNDRV_PCM_FORMAT_S16_BE:
++ case SNDRV_PCM_FORMAT_S24_BE:
++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++ I2S_REG_CFG0_FMT_LE, 0);
++ break;
++ default:
++ return -EINVAL;
++ }
++ }
+
-+/* struct mt7620_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+ struct clk *parent;
-+ int ret = 0;
++ /* setup bclk rate */
++ if (i2s->flags & RALINK_FLAGS_TXONLY)
++ ret = ralink_i2s_set_sys_bclk(dai, width, params_rate(params));
++ else
++ ret = ralink_i2s_set_bclk(dai, width, params_rate(params));
++
++ return ret;
++}
++
++static int ralink_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
++ struct snd_soc_dai *dai)
++{
++ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
++ unsigned int mask, val;
++
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++ mask = I2S_REG_CFG0_TX_EN;
++ else
++ mask = I2S_REG_CFG0_RX_EN;
+
-+ switch (clk_id) {
-+ case JZ4740_I2S_CLKSRC_EXT:
-+ parent = clk_get(NULL, "ext");
-+ clk_set_parent(i2s->clk_i2s, parent);
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ case SNDRV_PCM_TRIGGER_RESUME:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ val = mask;
+ break;
-+ case JZ4740_I2S_CLKSRC_PLL:
-+ parent = clk_get(NULL, "pll half");
-+ clk_set_parent(i2s->clk_i2s, parent);
-+ ret = clk_set_rate(i2s->clk_i2s, freq);
++ case SNDRV_PCM_TRIGGER_STOP:
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ val = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
-+ clk_put(parent);
+
-+ return ret;*/
++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, mask, val);
++
+ return 0;
+}
+
-+static void mt7620_i2c_init_pcm_config(struct mt7620_i2s *i2s)
++static void ralink_i2s_init_dma_data(struct ralink_i2s *i2s,
++ struct resource *res)
+{
+ struct snd_dmaengine_dai_dma_data *dma_data;
+
+ /* Playback */
+ dma_data = &i2s->playback_dma_data;
-+ dma_data->maxburst = 16;
-+ dma_data->slave_id = 2; //JZ4740_DMA_TYPE_AIC_TRANSMIT;
-+ dma_data->addr = i2s->phys_base + I2S_REG_WREG;
++ dma_data->addr = res->start + I2S_REG_WREG;
++ dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
++ dma_data->maxburst = 1;
++ dma_data->slave_id = i2s->txdma_req;
++
++ if (i2s->flags & RALINK_FLAGS_TXONLY)
++ return;
+
+ /* Capture */
+ dma_data = &i2s->capture_dma_data;
-+ dma_data->maxburst = 16;
-+ dma_data->slave_id = 3; //JZ4740_DMA_TYPE_AIC_RECEIVE;
-+ dma_data->addr = i2s->phys_base + I2S_REG_RREG;
++ dma_data->addr = res->start + I2S_REG_RREG;
++ dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
++ dma_data->maxburst = 1;
++ dma_data->slave_id = i2s->rxdma_req;
+}
+
-+static int mt7620_i2s_dai_probe(struct snd_soc_dai *dai)
++static int ralink_i2s_dai_probe(struct snd_soc_dai *dai)
+{
-+ struct mt7620_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+ uint32_t data;
-+
-+ mt7620_i2c_init_pcm_config(i2s);
-+ dai->playback_dma_data = &i2s->playback_dma_data;
-+ dai->capture_dma_data = &i2s->capture_dma_data;
++ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+
-+ /* set share pins to i2s/gpio mode and i2c mode */
-+ data = rt_sysc_r32(0x60);
-+ data &= 0xFFFFFFE2;
-+ data |= 0x00000018;
-+ rt_sysc_w32(data, 0x60);
-+
-+ printk("Internal REFCLK with fractional division\n");
-+
-+ mt7620_i2s_write(i2s, I2S_REG_CFG0, I2S_REG_CFG0_DFT_THRES);
-+ mt7620_i2s_write(i2s, I2S_REG_CFG1, 0);
-+ mt7620_i2s_write(i2s, I2S_REG_INT_EN, 0);
-+
-+ mt7620_i2s_write(i2s, I2S_REG_DIVINT, i2sMaster_inclk_int[7]);
-+ mt7620_i2s_write(i2s, I2S_REG_DIVCMP,
-+ i2sMaster_inclk_comp[7] | I2S_REG_CLK_EN);
++ snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
++ &i2s->capture_dma_data);
+
+ return 0;
+}
+
-+static int mt7620_i2s_dai_remove(struct snd_soc_dai *dai)
++static int ralink_i2s_dai_remove(struct snd_soc_dai *dai)
+{
+ return 0;
+}
+
-+static const struct snd_soc_dai_ops mt7620_i2s_dai_ops = {
-+ .startup = mt7620_i2s_startup,
-+ .shutdown = mt7620_i2s_shutdown,
-+ .trigger = mt7620_i2s_trigger,
-+ .hw_params = mt7620_i2s_hw_params,
-+ .set_fmt = mt7620_i2s_set_fmt,
-+ .set_sysclk = mt7620_i2s_set_sysclk,
++static const struct snd_soc_dai_ops ralink_i2s_dai_ops = {
++ .set_sysclk = ralink_i2s_set_sysclk,
++ .set_fmt = ralink_i2s_set_fmt,
++ .startup = ralink_i2s_startup,
++ .shutdown = ralink_i2s_shutdown,
++ .hw_params = ralink_i2s_hw_params,
++ .trigger = ralink_i2s_trigger,
+};
+
-+#define JZ4740_I2S_FMTS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
-+ SNDRV_PCM_FMTBIT_S24_LE)
-+
-+static struct snd_soc_dai_driver mt7620_i2s_dai = {
-+ .probe = mt7620_i2s_dai_probe,
-+ .remove = mt7620_i2s_dai_remove,
-+ .playback = {
-+ .channels_min = 1,
++static struct snd_soc_dai_driver ralink_i2s_dai = {
++ .name = DRV_NAME,
++ .probe = ralink_i2s_dai_probe,
++ .remove = ralink_i2s_dai_remove,
++ .ops = &ralink_i2s_dai_ops,
++ .capture = {
++ .stream_name = "I2S Capture",
++ .channels_min = 2,
+ .channels_max = 2,
-+ .rates = SNDRV_PCM_RATE_8000_48000,
-+ .formats = JZ4740_I2S_FMTS,
++ .rate_min = 5512,
++ .rate_max = 192000,
++ .rates = SNDRV_PCM_RATE_CONTINUOUS,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ },
-+ .capture = {
++ .playback = {
++ .stream_name = "I2S Playback",
+ .channels_min = 2,
+ .channels_max = 2,
-+ .rates = SNDRV_PCM_RATE_8000_48000,
-+ .formats = JZ4740_I2S_FMTS,
++ .rate_min = 5512,
++ .rate_max = 192000,
++ .rates = SNDRV_PCM_RATE_CONTINUOUS,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ },
+ .symmetric_rates = 1,
-+ .ops = &mt7620_i2s_dai_ops,
+};
+
-+static const struct snd_pcm_hardware mt7620_pcm_hardware = {
++static struct snd_pcm_hardware ralink_pcm_hardware = {
+ .info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER,
-+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,
++ .channels_min = 2,
++ .channels_max = 2,
+ .period_bytes_min = PAGE_SIZE,
-+ .period_bytes_max = 64 * 1024,
++ .period_bytes_max = PAGE_SIZE * 2,
+ .periods_min = 2,
+ .periods_max = 128,
+ .buffer_bytes_max = 128 * 1024,
-+ .fifo_size = 32,
++ .fifo_size = RALINK_I2S_FIFO_SIZE,
+};
+
-+static const struct snd_dmaengine_pcm_config mt7620_dmaengine_pcm_config = {
++static const struct snd_dmaengine_pcm_config ralink_dmaengine_pcm_config = {
+ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
-+ .pcm_hardware = &mt7620_pcm_hardware,
++ .pcm_hardware = &ralink_pcm_hardware,
+ .prealloc_buffer_size = 256 * PAGE_SIZE,
+};
+
-+static const struct snd_soc_component_driver mt7620_i2s_component = {
-+ .name = "mt7620-i2s",
++static const struct snd_soc_component_driver ralink_i2s_component = {
++ .name = DRV_NAME,
+};
+
-+static int mt7620_i2s_dev_probe(struct platform_device *pdev)
++static bool ralink_i2s_readable_reg(struct device *dev, unsigned int reg)
+{
-+ struct mt7620_i2s *i2s;
-+ int ret;
-+
-+ snd_dmaengine_pcm_register(&pdev->dev,
-+ &mt7620_dmaengine_pcm_config,
-+ SND_DMAENGINE_PCM_FLAG_COMPAT);
-+
-+ i2s = kzalloc(sizeof(*i2s), GFP_KERNEL);
-+ if (!i2s)
-+ return -ENOMEM;
-+
-+ i2s->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ if (!i2s->mem) {
-+ ret = -ENOENT;
-+ goto err_free;
-+ }
++ return true;
++}
+
-+ i2s->mem = request_mem_region(i2s->mem->start, resource_size(i2s->mem),
-+ pdev->name);
-+ if (!i2s->mem) {
-+ ret = -EBUSY;
-+ goto err_free;
++static bool ralink_i2s_volatile_reg(struct device *dev, unsigned int reg)
++{
++ switch (reg) {
++ case I2S_REG_INT_STATUS:
++ case I2S_REG_FF_STATUS:
++ return true;
+ }
++ return false;
++}
+
-+ i2s->base = ioremap_nocache(i2s->mem->start, resource_size(i2s->mem));
-+ if (!i2s->base) {
-+ ret = -EBUSY;
-+ goto err_release_mem_region;
++static bool ralink_i2s_writeable_reg(struct device *dev, unsigned int reg)
++{
++ switch (reg) {
++ case I2S_REG_FF_STATUS:
++ case I2S_REG_RREG:
++ return false;
+ }
++ return true;
++}
+
-+ i2s->phys_base = i2s->mem->start;
-+
-+ platform_set_drvdata(pdev, i2s);
-+ ret = snd_soc_register_component(&pdev->dev, &mt7620_i2s_component,
-+ &mt7620_i2s_dai, 1);
++static const struct regmap_config ralink_i2s_regmap_config = {
++ .reg_bits = 32,
++ .reg_stride = 4,
++ .val_bits = 32,
++ .writeable_reg = ralink_i2s_writeable_reg,
++ .readable_reg = ralink_i2s_readable_reg,
++ .volatile_reg = ralink_i2s_volatile_reg,
++ .max_register = I2S_REG_DIVINT,
++};
+
-+ if (!ret) {
-+ dev_err(&pdev->dev, "loaded\n");
-+ return ret;
++#if (RALINK_I2S_INT_EN)
++static irqreturn_t ralink_i2s_irq(int irq, void *devid)
++{
++ struct ralink_i2s *i2s = devid;
++ u32 status;
++
++ regmap_read(i2s->regmap, I2S_REG_INT_STATUS, &status);
++ if (unlikely(!status))
++ return IRQ_NONE;
++
++ /* tx stats */
++ if (status & I2S_REG_INT_TX_MASK) {
++ if (status & I2S_REG_INT_TX_THRES)
++ i2s->txstats.belowthres++;
++ if (status & I2S_REG_INT_TX_UNRUN)
++ i2s->txstats.underrun++;
++ if (status & I2S_REG_INT_TX_OVRUN)
++ i2s->txstats.overrun++;
++ if (status & I2S_REG_INT_TX_FAULT)
++ i2s->txstats.dmafault++;
+ }
+
-+ dev_err(&pdev->dev, "Failed to register DAI\n");
-+ iounmap(i2s->base);
++ /* rx stats */
++ if (status & I2S_REG_INT_RX_MASK) {
++ if (status & I2S_REG_INT_RX_THRES)
++ i2s->rxstats.belowthres++;
++ if (status & I2S_REG_INT_RX_UNRUN)
++ i2s->rxstats.underrun++;
++ if (status & I2S_REG_INT_RX_OVRUN)
++ i2s->rxstats.overrun++;
++ if (status & I2S_REG_INT_RX_FAULT)
++ i2s->rxstats.dmafault++;
++ }
+
-+err_release_mem_region:
-+ release_mem_region(i2s->mem->start, resource_size(i2s->mem));
-+err_free:
-+ kfree(i2s);
++ /* clean status bits */
++ regmap_write(i2s->regmap, I2S_REG_INT_STATUS, status);
+
-+ return ret;
++ return IRQ_HANDLED;
+}
++#endif
+
-+static int mt7620_i2s_dev_remove(struct platform_device *pdev)
++#if IS_ENABLED(CONFIG_DEBUG_FS)
++static int ralink_i2s_stats_show(struct seq_file *s, void *unused)
+{
-+ struct mt7620_i2s *i2s = platform_get_drvdata(pdev);
++ struct ralink_i2s *i2s = s->private;
+
-+ snd_soc_unregister_component(&pdev->dev);
++ seq_printf(s, "tx stats\n");
++ seq_printf(s, "\tbelow threshold\t%u\n", i2s->txstats.belowthres);
++ seq_printf(s, "\tunder run\t%u\n", i2s->txstats.underrun);
++ seq_printf(s, "\tover run\t%u\n", i2s->txstats.overrun);
++ seq_printf(s, "\tdma fault\t%u\n", i2s->txstats.dmafault);
+
-+ iounmap(i2s->base);
-+ release_mem_region(i2s->mem->start, resource_size(i2s->mem));
++ seq_printf(s, "rx stats\n");
++ seq_printf(s, "\tbelow threshold\t%u\n", i2s->rxstats.belowthres);
++ seq_printf(s, "\tunder run\t%u\n", i2s->rxstats.underrun);
++ seq_printf(s, "\tover run\t%u\n", i2s->rxstats.overrun);
++ seq_printf(s, "\tdma fault\t%u\n", i2s->rxstats.dmafault);
+
-+ kfree(i2s);
-+
-+ snd_dmaengine_pcm_unregister(&pdev->dev);
++ ralink_i2s_dump_regs(i2s);
+
+ return 0;
+}
+
-+static const struct of_device_id mt7620_i2s_match[] = {
-+ { .compatible = "ralink,mt7620a-i2s" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, mt7620_i2s_match);
++static int ralink_i2s_stats_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, ralink_i2s_stats_show, inode->i_private);
++}
+
-+static struct platform_driver mt7620_i2s_driver = {
-+ .probe = mt7620_i2s_dev_probe,
-+ .remove = mt7620_i2s_dev_remove,
-+ .driver = {
-+ .name = "mt7620-i2s",
-+ .owner = THIS_MODULE,
-+ .of_match_table = mt7620_i2s_match,
-+ },
++static const struct file_operations ralink_i2s_stats_ops = {
++ .open = ralink_i2s_stats_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
+};
+
-+module_platform_driver(mt7620_i2s_driver);
++static inline int ralink_i2s_debugfs_create(struct ralink_i2s *i2s)
++{
++ i2s->dbg_dir = debugfs_create_dir(dev_name(i2s->dev), NULL);
++ if (!i2s->dbg_dir)
++ return -ENOMEM;
++
++ i2s->dbg_stats = debugfs_create_file("stats", S_IRUGO,
++ i2s->dbg_dir, i2s, &ralink_i2s_stats_ops);
++ if (!i2s->dbg_stats) {
++ debugfs_remove(i2s->dbg_dir);
++ return -ENOMEM;
++ }
++
++ return 0;
++}
++
++static inline void ralink_i2s_debugfs_remove(struct ralink_i2s *i2s)
++{
++ debugfs_remove(i2s->dbg_stats);
++ debugfs_remove(i2s->dbg_dir);
++}
++#else
++static inline int ralink_i2s_debugfs_create(struct ralink_i2s *i2s)
++{
++ return 0;
++}
++
++static inline void ralink_i2s_debugfs_remove(struct fsl_ssi_dbg *ssi_dbg)
++{
++}
++#endif
+
-+MODULE_AUTHOR("Lars-Peter Clausen, <lars@metafoo.de>");
-+MODULE_DESCRIPTION("Ingenic JZ4740 SoC I2S driver");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("platform:mt7620-i2s");
---- /dev/null
-+++ b/sound/soc/ralink/mt7620-wm8960.c
-@@ -0,0 +1,233 @@
+/*
-+ * Copyright 2013 Freescale Semiconductor, Inc.
-+ *
-+ * Based on mt7620-sgtl5000.c
-+ * Copyright 2012 Freescale Semiconductor, Inc.
-+ * Copyright 2012 Linaro Ltd.
-+ *
-+ * The code contained herein is licensed under the GNU General Public
-+ * License. You may obtain a copy of the GNU General Public License
-+ * Version 2 or later at the following locations:
-+ *
-+ * http://www.opensource.org/licenses/gpl-license.html
-+ * http://www.gnu.org/copyleft/gpl.html
++ * TODO: these refclk setup functions should use
++ * clock framework instead. hardcode it now.
+ */
++static void rt3350_refclk_setup(void)
++{
++ uint32_t data;
+
-+#include <linux/module.h>
-+#include <linux/of_platform.h>
-+#include <linux/i2c.h>
-+#include <linux/slab.h>
-+#include <sound/soc.h>
-+#include <sound/pcm_params.h>
-+#include <sound/soc-dapm.h>
-+#include <linux/pinctrl/consumer.h>
++ /* set refclk output 12Mhz clock */
++ data = rt_sysc_r32(0x2c);
++ data |= (0x1 << 8);
++ rt_sysc_w32(data, 0x2c);
++}
+
-+#include "../codecs/wm8960.h"
++static void rt3883_refclk_setup(void)
++{
++ uint32_t data;
+
-+#define DAI_NAME_SIZE 32
++ /* set refclk output 12Mhz clock */
++ data = rt_sysc_r32(0x2c);
++ data &= ~(0x3 << 13);
++ data |= (0x1 << 13);
++ rt_sysc_w32(data, 0x2c);
++}
+
-+struct mt7620_wm8960_data {
-+ struct snd_soc_dai_link dai;
-+ struct snd_soc_card card;
-+ char codec_dai_name[DAI_NAME_SIZE];
-+ char platform_name[DAI_NAME_SIZE];
-+ unsigned int clk_frequency;
-+};
++static void rt3552_refclk_setup(void)
++{
++ uint32_t data;
+
-+struct mt7620_priv {
-+ struct platform_device *pdev;
-+};
-+static struct mt7620_priv card_priv;
++ /* set refclk output 12Mhz clock */
++ data = rt_sysc_r32(0x2c);
++ data &= ~(0xf << 8);
++ data |= (0x3 << 8);
++ rt_sysc_w32(data, 0x2c);
++}
+
-+static const struct snd_soc_dapm_widget mt7620_wm8960_dapm_widgets[] = {
-+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
-+ SND_SOC_DAPM_SPK("Ext Spk", NULL),
-+ SND_SOC_DAPM_MIC("AMIC", NULL),
-+ SND_SOC_DAPM_MIC("DMIC", NULL),
-+};
++static void mt7620_refclk_setup(void)
++{
++ uint32_t data;
+
-+static int sample_rate = 44100;
-+static snd_pcm_format_t sample_format = SNDRV_PCM_FORMAT_S16_LE;
++ /* set refclk output 12Mhz clock */
++ data = rt_sysc_r32(0x2c);
++ data &= ~(0x7 << 9);
++ data |= 0x1 << 9;
++ rt_sysc_w32(data, 0x2c);
++}
+
-+static int mt7620_hifi_hw_params(struct snd_pcm_substream *substream,
-+ struct snd_pcm_hw_params *params)
++static void mt7621_refclk_setup(void)
+{
-+ sample_rate = params_rate(params);
-+ sample_format = params_format(params);
++ uint32_t data;
+
-+ return 0;
++ /* set refclk output 12Mhz clock */
++ data = rt_sysc_r32(0x2c);
++ data &= ~(0x1f << 18);
++ data |= (0x19 << 18);
++ data &= ~(0x1f << 12);
++ data |= (0x1 << 12);
++ data &= ~(0x7 << 9);
++ data |= (0x5 << 9);
++ rt_sysc_w32(data, 0x2c);
+}
+
-+static struct snd_soc_ops mt7620_hifi_ops = {
-+ .hw_params = mt7620_hifi_hw_params,
++static void mt7628_refclk_setup(void)
++{
++ uint32_t data;
++
++ /* set i2s and refclk digital pad */
++ data = rt_sysc_r32(0x3c);
++ data |= 0x1f;
++ rt_sysc_w32(data, 0x3c);
++
++ /* Adjust REFCLK0's driving strength */
++ data = rt_sysc_r32(0x1354);
++ data &= ~(0x1 << 5);
++ rt_sysc_w32(data, 0x1354);
++ data = rt_sysc_r32(0x1364);
++ data |= ~(0x1 << 5);
++ rt_sysc_w32(data, 0x1364);
++
++ /* set refclk output 12Mhz clock */
++ data = rt_sysc_r32(0x2c);
++ data &= ~(0x7 << 9);
++ data |= 0x1 << 9;
++ rt_sysc_w32(data, 0x2c);
++}
++
++struct rt_i2s_data {
++ u32 flags;
++ void (*refclk_setup)(void);
++};
++
++struct rt_i2s_data rt3050_i2s_data = { .flags = RALINK_FLAGS_TXONLY };
++struct rt_i2s_data rt3350_i2s_data = { .flags = RALINK_FLAGS_TXONLY,
++ .refclk_setup = rt3350_refclk_setup };
++struct rt_i2s_data rt3883_i2s_data = {
++ .flags = (RALINK_FLAGS_LEFT_J | RALINK_FLAGS_RIGHT_J),
++ .refclk_setup = rt3883_refclk_setup };
++struct rt_i2s_data rt3352_i2s_data = { .refclk_setup = rt3552_refclk_setup};
++struct rt_i2s_data mt7620_i2s_data = { .refclk_setup = mt7620_refclk_setup};
++struct rt_i2s_data mt7621_i2s_data = { .refclk_setup = mt7621_refclk_setup};
++struct rt_i2s_data mt7628_i2s_data = {
++ .flags = (RALINK_FLAGS_ENDIAN | RALINK_FLAGS_24BIT |
++ RALINK_FLAGS_LEFT_J),
++ .refclk_setup = mt7628_refclk_setup};
++
++static const struct of_device_id ralink_i2s_match_table[] = {
++ { .compatible = "ralink,rt3050-i2s",
++ .data = (void *)&rt3050_i2s_data },
++ { .compatible = "ralink,rt3350-i2s",
++ .data = (void *)&rt3350_i2s_data },
++ { .compatible = "ralink,rt3883-i2s",
++ .data = (void *)&rt3883_i2s_data },
++ { .compatible = "ralink,rt3352-i2s",
++ .data = (void *)&rt3352_i2s_data },
++ { .compatible = "mediatek,mt7620-i2s",
++ .data = (void *)&mt7620_i2s_data },
++ { .compatible = "mediatek,mt7621-i2s",
++ .data = (void *)&mt7621_i2s_data },
++ { .compatible = "mediatek,mt7628-i2s",
++ .data = (void *)&mt7628_i2s_data },
+};
++MODULE_DEVICE_TABLE(of, ralink_i2s_match_table);
+
-+static int mt7620_wm8960_set_bias_level(struct snd_soc_card *card,
-+ struct snd_soc_dapm_context *dapm,
-+ enum snd_soc_bias_level level)
++static int ralink_i2s_probe(struct platform_device *pdev)
+{
-+ struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
-+ struct mt7620_priv *priv = &card_priv;
-+ struct mt7620_wm8960_data *data = snd_soc_card_get_drvdata(card);
-+ struct device *dev = &priv->pdev->dev;
-+ int ret;
++ const struct of_device_id *match;
++ struct device_node *np = pdev->dev.of_node;
++ struct ralink_i2s *i2s;
++ struct resource *res;
++ int irq, ret;
++ u32 dma_req;
++ struct rt_i2s_data *data;
++
++ i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
++ if (!i2s)
++ return -ENOMEM;
+
-+ if (dapm->dev != codec_dai->dev)
-+ return 0;
++ platform_set_drvdata(pdev, i2s);
++ i2s->dev = &pdev->dev;
+
-+ switch (level) {
-+ case SND_SOC_BIAS_PREPARE:
-+ if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
++ match = of_match_device(ralink_i2s_match_table, &pdev->dev);
++ if (!match)
++ return -EINVAL;
++ data = (struct rt_i2s_data *)match->data;
++ i2s->flags = data->flags;
++ /* setup out 12Mhz refclk to codec as mclk */
++ if (data->refclk_setup)
++ data->refclk_setup();
++
++ if (of_property_read_u32(np, "txdma-req", &dma_req)) {
++ dev_err(&pdev->dev, "no txdma-req define\n");
++ return -EINVAL;
++ }
++ i2s->txdma_req = (u16)dma_req;
++ if (!(i2s->flags & RALINK_FLAGS_TXONLY)) {
++ if (of_property_read_u32(np, "rxdma-req", &dma_req)) {
++ dev_err(&pdev->dev, "no rxdma-req define\n");
++ return -EINVAL;
+ }
-+ break;
++ i2s->rxdma_req = (u16)dma_req;
++ }
+
-+ case SND_SOC_BIAS_STANDBY:
-+ if (dapm->bias_level == SND_SOC_BIAS_PREPARE) {
-+ ret = snd_soc_dai_set_sysclk(codec_dai,
-+ WM8960_SYSCLK_MCLK, data->clk_frequency,
-+ SND_SOC_CLOCK_IN);
-+ if (ret < 0) {
-+ dev_err(dev,
-+ "failed to switch away from FLL: %d\n",
-+ ret);
-+ return ret;
-+ }
-+ }
-+ break;
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ i2s->regs = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(i2s->regs))
++ return PTR_ERR(i2s->regs);
+
-+ default:
-+ break;
++ i2s->regmap = devm_regmap_init_mmio(&pdev->dev, i2s->regs,
++ &ralink_i2s_regmap_config);
++ if (IS_ERR(i2s->regmap)) {
++ dev_err(&pdev->dev, "regmap init failed\n");
++ return PTR_ERR(i2s->regmap);
+ }
+
-+ return 0;
-+}
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0) {
++ dev_err(&pdev->dev, "failed to get irq\n");
++ return -EINVAL;
++ }
+
-+static int mt7620_wm8960_late_probe(struct snd_soc_card *card)
-+{
-+ struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
-+ struct mt7620_priv *priv = &card_priv;
-+ struct mt7620_wm8960_data *data = snd_soc_card_get_drvdata(card);
-+ struct device *dev = &priv->pdev->dev;
-+ int ret;
++#if (RALINK_I2S_INT_EN)
++ ret = devm_request_irq(&pdev->dev, irq, ralink_i2s_irq,
++ 0, dev_name(&pdev->dev), i2s);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to request irq\n");
++ return ret;
++ }
++#endif
+
-+ ret = snd_soc_dai_set_sysclk(codec_dai, WM8960_SYSCLK_MCLK,
-+ data->clk_frequency, SND_SOC_CLOCK_IN);
-+ if (ret < 0)
-+ dev_err(dev, "failed to set sysclk in %s\n", __func__);
++ i2s->clk = devm_clk_get(&pdev->dev, NULL);
++ if (IS_ERR(i2s->clk)) {
++ dev_err(&pdev->dev, "no clock defined\n");
++ return PTR_ERR(i2s->clk);
++ }
+
-+ return ret;
-+}
++ ret = clk_prepare_enable(i2s->clk);
++ if (ret)
++ return ret;
+
-+static int mt7620_wm8960_probe(struct platform_device *pdev)
-+{
-+ struct device_node *i2s_np, *codec_np;
-+ struct platform_device *i2s_pdev;
-+ struct mt7620_priv *priv = &card_priv;
-+ struct i2c_client *codec_dev;
-+ struct mt7620_wm8960_data *data;
-+ int ret;
++ ralink_i2s_init_dma_data(i2s, res);
+
-+ priv->pdev = pdev;
++ device_reset(&pdev->dev);
+
-+ i2s_np = of_parse_phandle(pdev->dev.of_node, "i2s-controller", 0);
-+ codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
-+ if (!i2s_np || !codec_np) {
-+ dev_err(&pdev->dev, "phandle missing or invalid\n");
-+ ret = -EINVAL;
-+ goto fail;
++ ret = ralink_i2s_debugfs_create(i2s);
++ if (ret) {
++ dev_err(&pdev->dev, "create debugfs failed\n");
++ goto err_clk_disable;
+ }
+
-+ i2s_pdev = of_find_device_by_node(i2s_np);
-+ if (!i2s_pdev) {
-+ dev_err(&pdev->dev, "failed to find SSI platform device\n");
-+ ret = -EINVAL;
-+ goto fail;
-+ }
-+ codec_dev = of_find_i2c_device_by_node(codec_np);
-+ if (!codec_dev || !codec_dev->dev.driver) {
-+ dev_err(&pdev->dev, "failed to find codec platform device\n");
-+ ret = -EINVAL;
-+ goto fail;
++ /* enable 24bits support */
++ if (i2s->flags & RALINK_FLAGS_24BIT) {
++ ralink_i2s_dai.capture.formats |= SNDRV_PCM_FMTBIT_S24_LE;
++ ralink_i2s_dai.playback.formats |= SNDRV_PCM_FMTBIT_S24_LE;
+ }
+
-+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
-+ if (!data) {
-+ ret = -ENOMEM;
-+ goto fail;
++ /* enable big endian support */
++ if (i2s->flags & RALINK_FLAGS_ENDIAN) {
++ ralink_i2s_dai.capture.formats |= SNDRV_PCM_FMTBIT_S16_BE;
++ ralink_i2s_dai.playback.formats |= SNDRV_PCM_FMTBIT_S16_BE;
++ ralink_pcm_hardware.formats |= SNDRV_PCM_FMTBIT_S16_BE;
++ if (i2s->flags & RALINK_FLAGS_24BIT) {
++ ralink_i2s_dai.capture.formats |=
++ SNDRV_PCM_FMTBIT_S24_BE;
++ ralink_i2s_dai.playback.formats |=
++ SNDRV_PCM_FMTBIT_S24_BE;
++ ralink_pcm_hardware.formats |=
++ SNDRV_PCM_FMTBIT_S24_BE;
++ }
+ }
+
-+ data->clk_frequency = 12000000;
-+ data->dai.name = "HiFi";
-+ data->dai.stream_name = "HiFi";
-+ data->dai.codec_dai_name = "wm8960-hifi";
-+ data->dai.codec_of_node = codec_np;
-+ data->dai.cpu_dai_name = dev_name(&i2s_pdev->dev);
-+ data->dai.platform_of_node = i2s_np;
-+ data->dai.ops = &mt7620_hifi_ops;
-+ data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-+ SND_SOC_DAIFMT_CBM_CFM;
-+
-+ data->card.dev = &pdev->dev;
-+ ret = snd_soc_of_parse_card_name(&data->card, "model");
++ /* disable capture support */
++ if (i2s->flags & RALINK_FLAGS_TXONLY)
++ memset(&ralink_i2s_dai.capture, sizeof(ralink_i2s_dai.capture),
++ 0);
++
++ ret = devm_snd_soc_register_component(&pdev->dev, &ralink_i2s_component,
++ &ralink_i2s_dai, 1);
+ if (ret)
-+ goto fail;
-+ ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
++ goto err_debugfs;
++
++ ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
++ &ralink_dmaengine_pcm_config,
++ SND_DMAENGINE_PCM_FLAG_COMPAT);
+ if (ret)
-+ goto fail;
-+ data->card.num_links = 1;
-+ data->card.dai_link = &data->dai;
-+ data->card.dapm_widgets = mt7620_wm8960_dapm_widgets;
-+ data->card.num_dapm_widgets = ARRAY_SIZE(mt7620_wm8960_dapm_widgets);
++ goto err_debugfs;
+
-+ data->card.late_probe = mt7620_wm8960_late_probe;
-+ data->card.set_bias_level = mt7620_wm8960_set_bias_level;
++ dev_info(i2s->dev, "mclk %luKHz\n", clk_get_rate(i2s->clk) / 1000000);
+
-+ platform_set_drvdata(pdev, &data->card);
-+ snd_soc_card_set_drvdata(&data->card, data);
++ return 0;
+
-+ ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
-+ if (ret) {
-+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
-+ goto fail;
-+ }
++err_debugfs:
++ ralink_i2s_debugfs_remove(i2s);
+
-+ of_node_put(i2s_np);
-+ of_node_put(codec_np);
-+
-+ return 0;
-+fail:
-+ if (i2s_np)
-+ of_node_put(i2s_np);
-+ if (codec_np)
-+ of_node_put(codec_np);
++err_clk_disable:
++ clk_disable_unprepare(i2s->clk);
+
+ return ret;
+}
+
-+static int mt7620_wm8960_remove(struct platform_device *pdev)
++static int ralink_i2s_remove(struct platform_device *pdev)
+{
++ struct ralink_i2s *i2s = platform_get_drvdata(pdev);
++
++ ralink_i2s_debugfs_remove(i2s);
++ clk_disable_unprepare(i2s->clk);
++
+ return 0;
+}
+
-+static const struct of_device_id mt7620_wm8960_dt_ids[] = {
-+ { .compatible = "mediatek,mt7620-audio-wm8960", },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, mt7620_wm8960_dt_ids);
-+
-+static struct platform_driver mt7620_wm8960_driver = {
++static struct platform_driver ralink_i2s_driver = {
++ .probe = ralink_i2s_probe,
++ .remove = ralink_i2s_remove,
+ .driver = {
-+ .name = "mt7620-wm8960",
-+ .owner = THIS_MODULE,
-+ .pm = &snd_soc_pm_ops,
-+ .of_match_table = mt7620_wm8960_dt_ids,
++ .name = DRV_NAME,
++ .of_match_table = ralink_i2s_match_table,
+ },
-+ .probe = mt7620_wm8960_probe,
-+ .remove = mt7620_wm8960_remove,
+};
-+module_platform_driver(mt7620_wm8960_driver);
++module_platform_driver(ralink_i2s_driver);
+
-+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
-+MODULE_DESCRIPTION("Freescale i.MX WM8962 ASoC machine driver");
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:mt7620-wm8962");
++MODULE_AUTHOR("Lars-Peter Clausen, <lars@metafoo.de>");
++MODULE_DESCRIPTION("Ralink/MediaTek I2S driver");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/target/linux/ramips/patches-4.4/0085-pinmux-util.patch b/target/linux/ramips/patches-4.4/0085-pinmux-util.patch
new file mode 100644
index 0000000000..4acbc3311f
--- /dev/null
+++ b/target/linux/ramips/patches-4.4/0085-pinmux-util.patch
@@ -0,0 +1,77 @@
+--- a/arch/mips/ralink/mt7620.c
++++ b/arch/mips/ralink/mt7620.c
+@@ -176,7 +176,7 @@
+
+ static struct rt2880_pmx_func spis_grp_mt7628[] = {
+ FUNC("pwm", 3, 14, 4),
+- FUNC("util", 2, 14, 4),
++ FUNC("utif", 2, 14, 4),
+ FUNC("gpio", 1, 14, 4),
+ FUNC("spis", 0, 14, 4),
+ };
+@@ -190,28 +190,28 @@
+
+ static struct rt2880_pmx_func p4led_kn_grp_mt7628[] = {
+ FUNC("jtag", 3, 30, 1),
+- FUNC("util", 2, 30, 1),
++ FUNC("utif", 2, 30, 1),
+ FUNC("gpio", 1, 30, 1),
+ FUNC("p4led_kn", 0, 30, 1),
+ };
+
+ static struct rt2880_pmx_func p3led_kn_grp_mt7628[] = {
+ FUNC("jtag", 3, 31, 1),
+- FUNC("util", 2, 31, 1),
++ FUNC("utif", 2, 31, 1),
+ FUNC("gpio", 1, 31, 1),
+ FUNC("p3led_kn", 0, 31, 1),
+ };
+
+ static struct rt2880_pmx_func p2led_kn_grp_mt7628[] = {
+ FUNC("jtag", 3, 32, 1),
+- FUNC("util", 2, 32, 1),
++ FUNC("utif", 2, 32, 1),
+ FUNC("gpio", 1, 32, 1),
+ FUNC("p2led_kn", 0, 32, 1),
+ };
+
+ static struct rt2880_pmx_func p1led_kn_grp_mt7628[] = {
+ FUNC("jtag", 3, 33, 1),
+- FUNC("util", 2, 33, 1),
++ FUNC("utif", 2, 33, 1),
+ FUNC("gpio", 1, 33, 1),
+ FUNC("p1led_kn", 0, 33, 1),
+ };
+@@ -232,28 +232,28 @@
+
+ static struct rt2880_pmx_func p4led_an_grp_mt7628[] = {
+ FUNC("jtag", 3, 39, 1),
+- FUNC("util", 2, 39, 1),
++ FUNC("utif", 2, 39, 1),
+ FUNC("gpio", 1, 39, 1),
+ FUNC("p4led_an", 0, 39, 1),
+ };
+
+ static struct rt2880_pmx_func p3led_an_grp_mt7628[] = {
+ FUNC("jtag", 3, 40, 1),
+- FUNC("util", 2, 40, 1),
++ FUNC("utif", 2, 40, 1),
+ FUNC("gpio", 1, 40, 1),
+ FUNC("p3led_an", 0, 40, 1),
+ };
+
+ static struct rt2880_pmx_func p2led_an_grp_mt7628[] = {
+ FUNC("jtag", 3, 41, 1),
+- FUNC("util", 2, 41, 1),
++ FUNC("utif", 2, 41, 1),
+ FUNC("gpio", 1, 41, 1),
+ FUNC("p2led_an", 0, 41, 1),
+ };
+
+ static struct rt2880_pmx_func p1led_an_grp_mt7628[] = {
+ FUNC("jtag", 3, 42, 1),
+- FUNC("util", 2, 42, 1),
++ FUNC("utif", 2, 42, 1),
+ FUNC("gpio", 1, 42, 1),
+ FUNC("p1led_an", 0, 42, 1),
+ };
diff --git a/target/linux/ramips/patches-4.4/0085-sdhci-no-wp.patch b/target/linux/ramips/patches-4.4/0085-sdhci-no-wp.patch
new file mode 100644
index 0000000000..46b1a6c04c
--- /dev/null
+++ b/target/linux/ramips/patches-4.4/0085-sdhci-no-wp.patch
@@ -0,0 +1,21 @@
+--- a/drivers/mmc/host/mtk-mmc/sd.c
++++ b/drivers/mmc/host/mtk-mmc/sd.c
+@@ -195,7 +195,7 @@
+ .dat_drv = 4,
+ .data_pins = 4,
+ .data_offset = 0,
+- .flags = MSDC_SYS_SUSPEND | MSDC_WP_PIN_EN | MSDC_CD_PIN_EN | MSDC_REMOVABLE | MSDC_HIGHSPEED,
++ .flags = MSDC_SYS_SUSPEND | MSDC_CD_PIN_EN | MSDC_REMOVABLE | MSDC_HIGHSPEED,
+ // .flags = MSDC_SYS_SUSPEND | MSDC_WP_PIN_EN | MSDC_CD_PIN_EN | MSDC_REMOVABLE,
+ };
+
+@@ -2746,6 +2746,9 @@
+ int ret, irq;
+
+ pdev->dev.platform_data = &msdc0_hw;
++
++ if (of_property_read_bool(pdev->dev.of_node, "mtk,wp-en"))
++ msdc0_hw.flags |= MSDC_WP_PIN_EN;
+
+ /* Allocate MMC host for this device */
+ mmc = mmc_alloc_host(sizeof(struct msdc_host), &pdev->dev);
diff --git a/target/linux/ramips/patches-4.4/0520-esw-gmac.patch b/target/linux/ramips/patches-4.4/0520-esw-gmac.patch
new file mode 100644
index 0000000000..9d4cd3f4c1
--- /dev/null
+++ b/target/linux/ramips/patches-4.4/0520-esw-gmac.patch
@@ -0,0 +1,69 @@
+--- a/drivers/net/ethernet/mediatek/esw_rt3050.c
++++ b/drivers/net/ethernet/mediatek/esw_rt3050.c
+@@ -221,6 +221,8 @@
+
+ unsigned char port_map;
+ unsigned char port_disable;
++ unsigned int reg_initval_fct2;
++ unsigned int reg_initval_fpa2;
+ unsigned int reg_led_polarity;
+
+ struct switch_dev swdev;
+@@ -452,7 +454,10 @@
+ (RT305X_ESW_PORTS_NOCPU << RT305X_ESW_POC2_UNTAG_EN_S)),
+ RT305X_ESW_REG_POC2);
+
+- esw_w32(esw, 0x0002500c, RT305X_ESW_REG_FCT2);
++ if (esw->reg_initval_fct2)
++ esw_w32(esw, esw->reg_initval_fct2, RT305X_ESW_REG_FCT2);
++ else
++ esw_w32(esw, 0x0002500c, RT305X_ESW_REG_FCT2);
+
+ /* 300s aging timer, max packet len 1536, broadcast storm prevention
+ * disabled, disable collision abort, mac xor48 hash, 10 packet back
+@@ -475,7 +480,10 @@
+ * port5: disabled
+ * port6: enabled, gige, full-duplex, rx/tx-flow-control
+ */
+- esw_w32(esw, 0x3f502b28, RT305X_ESW_REG_FPA2);
++ if (esw->reg_initval_fpa2)
++ esw_w32(esw, esw->reg_initval_fpa2, RT305X_ESW_REG_FPA2);
++ else
++ esw_w32(esw, 0x3f502b28, RT305X_ESW_REG_FPA2);
+ esw_w32(esw, 0x00000000, RT305X_ESW_REG_FPA);
+
+ /* Force Link/Activity on ports */
+@@ -1361,6 +1369,14 @@
+ if (port_disable)
+ esw->port_disable = be32_to_cpu(*port_disable);
+
++ reg_init = of_get_property(np, "ralink,fct2", NULL);
++ if (reg_init)
++ esw->reg_initval_fct2 = be32_to_cpu(*reg_init);
++
++ reg_init = of_get_property(np, "ralink,fpa2", NULL);
++ if (reg_init)
++ esw->reg_initval_fpa2 = be32_to_cpu(*reg_init);
++
+ reg_init = of_get_property(np, "mediatek,led_polarity", NULL);
+ if (reg_init)
+ esw->reg_led_polarity = be32_to_cpu(*reg_init);
+@@ -1386,6 +1402,18 @@
+
+ esw_hw_init(esw);
+
++ reg_init = of_get_property(np, "ralink,rgmii", NULL);
++ if (reg_init && be32_to_cpu(*reg_init) == 1) {
++ /*
++ * External switch connected to RGMII interface.
++ * Unregister the switch device after initialization.
++ */
++ dev_err(&pdev->dev, "RGMII mode, not exporting switch device.\n");
++ unregister_switch(&esw->swdev);
++ platform_set_drvdata(pdev, NULL);
++ return -ENODEV;
++ }
++
+ ret = devm_request_irq(&pdev->dev, esw->irq, esw_interrupt, 0, "esw",
+ esw);
+
diff --git a/target/linux/ramips/patches-4.4/0720-arch-mips-ralink-add-i2c-clocks.patch b/target/linux/ramips/patches-4.4/0720-arch-mips-ralink-add-i2c-clocks.patch
new file mode 100644
index 0000000000..500625b4e5
--- /dev/null
+++ b/target/linux/ramips/patches-4.4/0720-arch-mips-ralink-add-i2c-clocks.patch
@@ -0,0 +1,67 @@
+--- a/arch/mips/ralink/mt7620.c
++++ b/arch/mips/ralink/mt7620.c
+@@ -509,6 +509,7 @@ void __init ralink_clk_init(void)
+ unsigned long sys_rate;
+ unsigned long dram_rate;
+ unsigned long periph_rate;
++ unsigned long pcmi2s_rate;
+
+ xtal_rate = mt7620_get_xtal_rate();
+
+@@ -523,6 +524,7 @@ void __init ralink_clk_init(void)
+ cpu_rate = MHZ(575);
+ dram_rate = sys_rate = cpu_rate / 3;
+ periph_rate = MHZ(40);
++ pcmi2s_rate = MHZ(480);
+
+ ralink_clk_add("10000d00.uartlite", periph_rate);
+ ralink_clk_add("10000e00.uartlite", periph_rate);
+@@ -534,6 +536,7 @@ void __init ralink_clk_init(void)
+ dram_rate = mt7620_get_dram_rate(pll_rate);
+ sys_rate = mt7620_get_sys_rate(cpu_rate);
+ periph_rate = mt7620_get_periph_rate(xtal_rate);
++ pcmi2s_rate = periph_rate;
+
+ pr_debug(RFMT("XTAL") RFMT("CPU_PLL") RFMT("PLL"),
+ RINT(xtal_rate), RFRAC(xtal_rate),
+@@ -555,6 +558,8 @@ void __init ralink_clk_init(void)
+ ralink_clk_add("cpu", cpu_rate);
+ ralink_clk_add("10000100.timer", periph_rate);
+ ralink_clk_add("10000120.watchdog", periph_rate);
++ ralink_clk_add("10000900.i2c", periph_rate);
++ ralink_clk_add("10000a00.i2s", pcmi2s_rate);
+ ralink_clk_add("10000b00.spi", sys_rate);
+ ralink_clk_add("10000b40.spi", sys_rate);
+ ralink_clk_add("10000c00.uartlite", periph_rate);
+--- a/arch/mips/ralink/rt288x.c
++++ b/arch/mips/ralink/rt288x.c
+@@ -75,6 +75,7 @@ void __init ralink_clk_init(void)
+ ralink_clk_add("300100.timer", cpu_rate / 2);
+ ralink_clk_add("300120.watchdog", cpu_rate / 2);
+ ralink_clk_add("300500.uart", cpu_rate / 2);
++ ralink_clk_add("300900.i2c", cpu_rate / 2);
+ ralink_clk_add("300c00.uartlite", cpu_rate / 2);
+ ralink_clk_add("400000.ethernet", cpu_rate / 2);
+ ralink_clk_add("480000.wmac", wmac_rate);
+--- a/arch/mips/ralink/rt305x.c
++++ b/arch/mips/ralink/rt305x.c
+@@ -200,6 +200,8 @@ void __init ralink_clk_init(void)
+
+ ralink_clk_add("cpu", cpu_rate);
+ ralink_clk_add("sys", sys_rate);
++ ralink_clk_add("10000900.i2c", uart_rate);
++ ralink_clk_add("10000a00.i2s", uart_rate);
+ ralink_clk_add("10000b00.spi", sys_rate);
+ ralink_clk_add("10000b40.spi", sys_rate);
+ ralink_clk_add("10000100.timer", wdt_rate);
+--- a/arch/mips/ralink/rt3883.c
++++ b/arch/mips/ralink/rt3883.c
+@@ -108,6 +108,8 @@ void __init ralink_clk_init(void)
+ ralink_clk_add("10000100.timer", sys_rate);
+ ralink_clk_add("10000120.watchdog", sys_rate);
+ ralink_clk_add("10000500.uart", 40000000);
++ ralink_clk_add("10000900.i2c", 40000000);
++ ralink_clk_add("10000a00.i2s", 40000000);
+ ralink_clk_add("10000b00.spi", sys_rate);
+ ralink_clk_add("10000b40.spi", sys_rate);
+ ralink_clk_add("10000c00.uartlite", 40000000);
diff --git a/target/linux/ramips/rt305x/profiles/sitecom.mk b/target/linux/ramips/rt305x/profiles/sitecom.mk
new file mode 100644
index 0000000000..16d9feff43
--- /dev/null
+++ b/target/linux/ramips/rt305x/profiles/sitecom.mk
@@ -0,0 +1,18 @@
+#
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+define Profile/WL-351
+ NAME:=Sitecom WL-351 v1
+ PACKAGES:=\
+ kmod-switch-rtl8366rb kmod-swconfig swconfig
+endef
+
+define Profile/WL-351/Description
+ Package set for Sitecom WL-351 v1
+endef
+
+$(eval $(call Profile,WL-351))