aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mediatek/patches-4.9
diff options
context:
space:
mode:
authorJohn Crispin <john@phrozen.org>2018-01-08 15:06:24 +0100
committerJohn Crispin <john@phrozen.org>2018-02-14 11:27:50 +0100
commit7762c07c88980cff85ec20c12f18cd172260e9d9 (patch)
treed5e9e1f28c1aa9b47eadcf6b8d063b394a34ed17 /target/linux/mediatek/patches-4.9
parent04d3308b6248ef21a6f0bc3378b342906c2d2865 (diff)
downloadupstream-7762c07c88980cff85ec20c12f18cd172260e9d9.tar.gz
upstream-7762c07c88980cff85ec20c12f18cd172260e9d9.tar.bz2
upstream-7762c07c88980cff85ec20c12f18cd172260e9d9.zip
mediatek: bump to v4.14
This drops support for all the !emmc EVB and adds banannaPi-R2 Also drop mtkhnat until the nftables offoad driver is ready Signed-off-by: John Crispin <john@phrozen.org>
Diffstat (limited to 'target/linux/mediatek/patches-4.9')
-rw-r--r--target/linux/mediatek/patches-4.9/0001-arch-arm-add-dts-build-code.patch23
-rw-r--r--target/linux/mediatek/patches-4.9/0002-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch154
-rw-r--r--target/linux/mediatek/patches-4.9/0003-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch698
-rw-r--r--target/linux/mediatek/patches-4.9/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch75
-rw-r--r--target/linux/mediatek/patches-4.9/0005-clk-mediatek-Add-MT2701-clock-support.patch1431
-rw-r--r--target/linux/mediatek/patches-4.9/0006-reset-mediatek-mt2701-reset-driver.patch36
-rw-r--r--target/linux/mediatek/patches-4.9/0007-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch29
-rw-r--r--target/linux/mediatek/patches-4.9/0008-soc-mediatek-Refine-scpsys-to-support-multiple-platf.patch487
-rw-r--r--target/linux/mediatek/patches-4.9/0009-soc-mediatek-Add-MT2701-scpsys-driver.patch194
-rw-r--r--target/linux/mediatek/patches-4.9/0010-clk-add-hifsys-reset.patch30
-rw-r--r--target/linux/mediatek/patches-4.9/0011-scpsys-various-fixes.patch20
-rw-r--r--target/linux/mediatek/patches-4.9/0012-clk-dont-disable-unused-clocks.patch21
-rw-r--r--target/linux/mediatek/patches-4.9/0013-clk-mediatek-enable-critical-clocks.patch69
-rw-r--r--target/linux/mediatek/patches-4.9/0014-clk-mediatek-Export-CPU-mux-clocks-for-CPU-frequency.patch287
-rw-r--r--target/linux/mediatek/patches-4.9/0015-cpufreq-mediatek-add-driver.patch433
-rw-r--r--target/linux/mediatek/patches-4.9/0016-pwm-add-pwm-mediatek.patch274
-rw-r--r--target/linux/mediatek/patches-4.9/0017-mfd-mt6397-Add-MT6323-LED-support-into-MT6397-driver.patch27
-rw-r--r--target/linux/mediatek/patches-4.9/0018-dt-bindings-leds-Add-document-bindings-for-leds-mt63.patch78
-rw-r--r--target/linux/mediatek/patches-4.9/0019-dt-bindings-mfd-Add-the-description-for-LED-as-the-s.patch24
-rw-r--r--target/linux/mediatek/patches-4.9/0020-leds-Add-LED-support-for-MT6323-PMIC.patch539
-rw-r--r--target/linux/mediatek/patches-4.9/0021-mfd-mt6397-Align-the-placement-at-which-the-mfd_cell.patch27
-rw-r--r--target/linux/mediatek/patches-4.9/0022-nand-make-bootrom-work-with-upstream-driver.patch32
-rw-r--r--target/linux/mediatek/patches-4.9/0023-rng-add-mediatek-hw-rng.patch81
-rw-r--r--target/linux/mediatek/patches-4.9/0024-media-rc-add-driver-for-IR-remote-receiver-on-MT7623.patch1034
-rw-r--r--target/linux/mediatek/patches-4.9/0025-dt-bindings-net-dsa-add-Mediatek-MT7530-binding.patch110
-rw-r--r--target/linux/mediatek/patches-4.9/0026-net-mediatek-backport-v4.10-driver.patch1788
-rw-r--r--target/linux/mediatek/patches-4.9/0027-net-next-mediatek-fix-DQL-support.patch93
-rw-r--r--target/linux/mediatek/patches-4.9/0028-net-next-dsa-add-Mediatek-tag-RX-TX-handler.patch192
-rw-r--r--target/linux/mediatek/patches-4.9/0029-net-next-ethernet-mediatek-add-CDM-able-to-recognize.patch48
-rw-r--r--target/linux/mediatek/patches-4.9/0030-net-next-dsa-add-dsa-support-for-Mediatek-MT7530-swi.patch1584
-rw-r--r--target/linux/mediatek/patches-4.9/0031-net-dsa-dsa-api-compat.patch106
-rw-r--r--target/linux/mediatek/patches-4.9/0032-net-dsa-mediatek-add-support-for-GMAC2-wired-to-ext-.patch38
-rw-r--r--target/linux/mediatek/patches-4.9/0033-net-dsa-add-multi-gmac-support.patch272
-rw-r--r--target/linux/mediatek/patches-4.9/0034-net-dsa-mediatek-add-dual-gmac-support.patch91
-rw-r--r--target/linux/mediatek/patches-4.9/0035-net-mediatek-disable-RX-VLan-offloading.patch47
-rw-r--r--target/linux/mediatek/patches-4.9/0036-net-next-mediatek-fix-typos-inside-the-header-file.patch25
-rw-r--r--target/linux/mediatek/patches-4.9/0037-net-next-mediatek-bring-up-QDMA-RX-ring-0.patch128
-rw-r--r--target/linux/mediatek/patches-4.9/0038-net-next-dsa-move-struct-dsa_device_ops-to-the-globa.patch46
-rw-r--r--target/linux/mediatek/patches-4.9/0039-net-next-dsa-add-flow_dissect-callback-to-struct-dsa.patch32
-rw-r--r--target/linux/mediatek/patches-4.9/0040-net-next-tag_mtk-add-flow_dissect-callback-to-the-op.patch39
-rw-r--r--target/linux/mediatek/patches-4.9/0041-net-next-dsa-fix-flow-dissection.patch65
-rw-r--r--target/linux/mediatek/patches-4.9/0042-net-next-mediatek-honour-special-tag-bit-inside-RX-D.patch50
-rw-r--r--target/linux/mediatek/patches-4.9/0043-net-next-mediatek-enable-special-tag-indication-for-.patch41
-rw-r--r--target/linux/mediatek/patches-4.9/0044-net-next-dsa-mediatek-tell-GDMA-when-we-are-turning-.patch43
-rw-r--r--target/linux/mediatek/patches-4.9/0045-net-dsa-mediatek-turn-into-platform-driver.patch79
-rw-r--r--target/linux/mediatek/patches-4.9/0046-net-mediatek-add-irq-delay.patch56
-rw-r--r--target/linux/mediatek/patches-4.9/0047-net-next-mediatek-split-IRQ-register-locking-into-TX.patch208
-rw-r--r--target/linux/mediatek/patches-4.9/0048-net-core-add-RPS-balancer.patch90
-rw-r--r--target/linux/mediatek/patches-4.9/0049-net-mediatek-add-rx-queue.patch20
-rw-r--r--target/linux/mediatek/patches-4.9/0050-net-mediatek-add-trgmii-clock.patch21
-rw-r--r--target/linux/mediatek/patches-4.9/0051-net-mediatek-increase-tx_timeout.patch21
-rw-r--r--target/linux/mediatek/patches-4.9/0052-net-phy-add-FC.patch21
-rw-r--r--target/linux/mediatek/patches-4.9/0053-net-dsa-mediatek-add-software-phy-polling.patch68
-rw-r--r--target/linux/mediatek/patches-4.9/0054-net-ethernet-mediatek-fixed-deadlock-captured-by-loc.patch105
-rw-r--r--target/linux/mediatek/patches-4.9/0055-net-ethernet-mediatek-avoid-potential-invalid-memory.patch31
-rw-r--r--target/linux/mediatek/patches-4.9/0056-net-mediatek-add-hw-nat-support.patch119
-rw-r--r--target/linux/mediatek/patches-4.9/0057-net-mediatek-add-HW-QoS-support.patch121
-rw-r--r--target/linux/mediatek/patches-4.9/0058-pinctrl-update.patch470
-rw-r--r--target/linux/mediatek/patches-4.9/0059-eth-fixes.patch511
-rw-r--r--target/linux/mediatek/patches-4.9/0060-eth-debug.patch69
-rw-r--r--target/linux/mediatek/patches-4.9/0061-eth-up_down_lock.patch72
-rw-r--r--target/linux/mediatek/patches-4.9/0062-mdio-atomic.patch14
-rw-r--r--target/linux/mediatek/patches-4.9/0063-atomic-sleep.patch38
63 files changed, 0 insertions, 13075 deletions
diff --git a/target/linux/mediatek/patches-4.9/0001-arch-arm-add-dts-build-code.patch b/target/linux/mediatek/patches-4.9/0001-arch-arm-add-dts-build-code.patch
deleted file mode 100644
index ff04a9f1e5..0000000000
--- a/target/linux/mediatek/patches-4.9/0001-arch-arm-add-dts-build-code.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 9fdcf63545855f3a6f82dee109510f4735e861c8 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 15:54:13 +0200
-Subject: [PATCH 01/57] arch: arm: add dts build code
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- arch/arm/boot/dts/Makefile | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -950,6 +950,10 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
- mt6589-aquaris5.dtb \
- mt6592-evb.dtb \
- mt7623-evb.dtb \
-+ mt7623-eMMC.dtb \
-+ mt7623-NAND.dtb \
-+ mt7623-NAND-ePHY.dtb \
-+ mt7623n-bananapi-bpi-r2.dtb \
- mt8127-moose.dtb \
- mt8135-evbp1.dtb
- dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb
diff --git a/target/linux/mediatek/patches-4.9/0002-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch b/target/linux/mediatek/patches-4.9/0002-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch
deleted file mode 100644
index 9dd6fcd01d..0000000000
--- a/target/linux/mediatek/patches-4.9/0002-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch
+++ /dev/null
@@ -1,154 +0,0 @@
-From ad2d4df46d8ef6a7aab20f0b668fa7db5257cbea Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 6 Jan 2016 21:55:10 +0100
-Subject: [PATCH 02/57] dt-bindings: add MediaTek PCIe binding documentation
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- .../devicetree/bindings/pci/mediatek-pcie.txt | 140 +++++++++++++++++++++
- 1 file changed, 140 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/pci/mediatek-pcie.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt
-@@ -0,0 +1,140 @@
-+Mediatek PCIe controller
-+
-+Required properties:
-+- compatible: Should be one of:
-+ - "mediatek,mt2701-pcie"
-+ - "mediatek,mt7623-pcie"
-+- device_type: Must be "pci"
-+- reg: A list of physical base address and length for each set of controller
-+ registers. A list of register ranges to use. Must contain an
-+ entry for each entry in the reg-names property.
-+- reg-names: Must include the following entries:
-+ "pcie": PCIe registers
-+ "pcie phy0": PCIe PHY0 registers
-+ "pcie phy1": PCIe PHY0 registers
-+ "pcie phy2": PCIe PHY0 registers
-+- interrupts: A list of interrupt outputs of the controller. Must contain an
-+ entry for each entry in the interrupt-names property.
-+- interrupt-names: Must include the following entries:
-+ "pcie0": The interrupt that is asserted for port0
-+ "pcie1": The interrupt that is asserted for port1
-+ "pcie2": The interrupt that is asserted for port2
-+- bus-range: Range of bus numbers associated with this controller
-+- #address-cells: Address representation for root ports (must be 3)
-+- #size-cells: Size representation for root ports (must be 2)
-+- ranges: Describes the translation of addresses for root ports and standard
-+ PCI regions. The entries must be 6 cells each.
-+ Please refer to the standard PCI bus binding document for a more detailed
-+ explanation.
-+- #interrupt-cells: Size representation for interrupts (must be 1)
-+- clocks: Must contain an entry for each entry in clock-names.
-+ See ../clocks/clock-bindings.txt for details.
-+- clock-names: Must include the following entries:
-+ - pcie0
-+ - pcie1
-+ - pcie2
-+- resets: Must contain an entry for each entry in reset-names.
-+ See ../reset/reset.txt for details.
-+- reset-names: Must include the following entries:
-+ - pcie0
-+ - pcie1
-+ - pcie2
-+- mediatek,hifsys: Must contain a phandle to the HIFSYS syscon range.
-+Root ports are defined as subnodes of the PCIe controller node.
-+
-+Required properties:
-+- device_type: Must be "pci"
-+- assigned-addresses: Address and size of the port configuration registers
-+- reg: PCI bus address of the root port
-+- #address-cells: Must be 3
-+- #size-cells: Must be 2
-+- ranges: Sub-ranges distributed from the PCIe controller node. An empty
-+ property is sufficient.
-+
-+Example:
-+
-+SoC DTSI:
-+
-+ hifsys: clock-controller@1a000000 {
-+ compatible = "mediatek,mt7623-hifsys",
-+ "mediatek,mt2701-hifsys",
-+ "syscon";
-+ reg = <0 0x1a000000 0 0x1000>;
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
-+
-+ pcie-controller@1a140000 {
-+ compatible = "mediatek,mt7623-pcie";
-+ device_type = "pci";
-+ reg = <0 0x1a140000 0 0x8000>, /* PCI-Express registers */
-+ <0 0x1a149000 0 0x1000>, /* PCI-Express PHY0 */
-+ <0 0x1a14a000 0 0x1000>, /* PCI-Express PHY1 */
-+ <0 0x1a244000 0 0x1000>; /* PCI-Express PHY2 */
-+ reg-names = "pcie", "pcie phy0", "pcie phy1", "pcie phy2";
-+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>,
-+ <GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>,
-+ <GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>;
-+ interrupt-names = "pcie0", "pcie1", "pcie2";
-+ clocks = <&topckgen CLK_TOP_ETHIF_SEL>;
-+ clock-names = "pcie";
-+ power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>;
-+ resets = <&hifsys MT2701_HIFSYS_PCIE0_RST>,
-+ <&hifsys MT2701_HIFSYS_PCIE1_RST>,
-+ <&hifsys MT2701_HIFSYS_PCIE2_RST>;
-+ reset-names = "pcie0", "pice1", "pcie2";
-+
-+ bus-range = <0x00 0xff>;
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ mediatek,hifsys = <&hifsys>;
-+
-+ ranges = <0x81000000 0 0x1a160000 0 0x1a160000 0 0x00010000 /* io space */
-+ 0x83000000 0 0x60000000 0 0x60000000 0 0x10000000>; /* pci memory */
-+
-+ status = "disabled";
-+
-+ pcie@1,0 {
-+ device_type = "pci";
-+ reg = <0x0800 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ ranges;
-+
-+ status = "disabled";
-+ };
-+
-+ pcie@2,0{
-+ device_type = "pci";
-+ reg = <0x1000 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ ranges;
-+
-+ status = "disabled";
-+ };
-+
-+ pcie@3,0{
-+ device_type = "pci";
-+ reg = <0x1800 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ ranges;
-+
-+ status = "disabled";
-+ };
-+ };
-+
-+Board DTS:
-+
-+ pcie-controller {
-+ status = "okay";
-+
-+ pci@1,0 {
-+ status = "okay";
-+ };
-+ };
diff --git a/target/linux/mediatek/patches-4.9/0003-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch b/target/linux/mediatek/patches-4.9/0003-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch
deleted file mode 100644
index 43f51ef6b3..0000000000
--- a/target/linux/mediatek/patches-4.9/0003-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch
+++ /dev/null
@@ -1,698 +0,0 @@
-From 950bd9b0691dd10209c333086a6bdda0108ed3a8 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 5 Jan 2016 20:20:04 +0100
-Subject: [PATCH 03/57] PCI: mediatek: add support for PCIe found on
- MT7623/MT2701
-
-Add PCIe controller support on MediaTek MT2701/MT7623. The driver supports
-a single Root complex (RC) with 3 Root Ports. The SoCs supports a Gen2
-1-lan Link on each port.
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/arm/mach-mediatek/Kconfig | 1 +
- drivers/pci/host/Kconfig | 11 +
- drivers/pci/host/Makefile | 1 +
- drivers/pci/host/pcie-mediatek.c | 641 +++++++++++++++++++++++++++++++++++++++
- 4 files changed, 654 insertions(+)
- create mode 100644 drivers/pci/host/pcie-mediatek.c
-
---- a/arch/arm/mach-mediatek/Kconfig
-+++ b/arch/arm/mach-mediatek/Kconfig
-@@ -25,6 +25,7 @@ config MACH_MT6592
- config MACH_MT7623
- bool "MediaTek MT7623 SoCs support"
- default ARCH_MEDIATEK
-+ select MIGHT_HAVE_PCI
-
- config MACH_MT8127
- bool "MediaTek MT8127 SoCs support"
---- a/drivers/pci/host/Kconfig
-+++ b/drivers/pci/host/Kconfig
-@@ -301,4 +301,15 @@ config VMD
- To compile this driver as a module, choose M here: the
- module will be called vmd.
-
-+config PCIE_MTK
-+ bool "Mediatek PCIe Controller"
-+ depends on MACH_MT2701 || MACH_MT7623
-+ depends on OF
-+ depends on PCI
-+ help
-+ Say Y here if you want to enable PCI controller support on Mediatek MT7623.
-+ MT7623 PCIe supports single Root complex (RC) with 3 Root Ports.
-+ Each port supports a Gen2 1-lan Link.
-+ PCIe include one Host/PCI bridge and 3 PCIe MAC.
-+
- endmenu
---- a/drivers/pci/host/Makefile
-+++ b/drivers/pci/host/Makefile
-@@ -33,3 +33,4 @@ obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-arm
- obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
- obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o
- obj-$(CONFIG_VMD) += vmd.o
-+obj-$(CONFIG_PCIE_MTK) += pcie-mediatek.o
---- /dev/null
-+++ b/drivers/pci/host/pcie-mediatek.c
-@@ -0,0 +1,641 @@
-+/*
-+ * Mediatek MT2701/MT7623 SoC PCIE support
-+ *
-+ * Copyright (C) 2015 Mediatek
-+ * Copyright (C) 2015 Ziv Huang <ziv.huang@mediatek.com>
-+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/pci.h>
-+#include <linux/ioport.h>
-+#include <linux/interrupt.h>
-+#include <linux/spinlock.h>
-+#include <linux/init.h>
-+#include <linux/device.h>
-+#include <linux/io.h>
-+#include <linux/delay.h>
-+#include <asm/irq.h>
-+#include <asm/mach/pci.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_pci.h>
-+#include <linux/of_platform.h>
-+#include <linux/of_irq.h>
-+#include <linux/reset.h>
-+#include <linux/platform_device.h>
-+#include <linux/regulator/consumer.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/clk.h>
-+#include <linux/regmap.h>
-+#include <linux/mfd/syscon.h>
-+
-+#define MEMORY_BASE 0x80000000
-+
-+/* PCIE Registers */
-+#define PCICFG 0x00
-+#define PCIINT 0x08
-+#define PCIENA 0x0c
-+#define CFGADDR 0x20
-+#define CFGDATA 0x24
-+#define MEMBASE 0x28
-+#define IOBASE 0x2c
-+
-+/* per Port Registers */
-+#define BAR0SETUP 0x10
-+#define IMBASEBAR0 0x18
-+#define PCIE_CLASS 0x34
-+#define PCIE_SISTAT 0x50
-+
-+#define MTK_PCIE_HIGH_PERF BIT(14)
-+#define PCIEP0_BASE 0x2000
-+#define PCIEP1_BASE 0x3000
-+#define PCIEP2_BASE 0x4000
-+
-+#define PHY_P0_CTL 0x9000
-+#define PHY_P1_CTL 0xa000
-+#define PHY_P2_CTL 0x4000
-+
-+#define RSTCTL_PCIE0_RST BIT(24)
-+#define RSTCTL_PCIE1_RST BIT(25)
-+#define RSTCTL_PCIE2_RST BIT(26)
-+
-+#define HIFSYS_SYSCFG1 0x14
-+#define HIFSYS_SYSCFG1_PHY2_MASK (0x3 << 20)
-+
-+#define MTK_PHY_CLK 0xb00
-+#define MTK_PHY_CLKDRV_OFFSET BIT(2)
-+#define MTK_PHY_CLKDRV_OFFSET_MASK 0xe
-+#define MTK_PHY_PLL 0xb04
-+#define MTK_PHY_CLKDRV_AMP BIT(30)
-+#define MTK_PHY_CLKDRV_AMP_MASK 0xe0000000
-+#define MTK_PHY_REFCLK_SEL 0xc00
-+#define MTK_PHY_XTAL_EXT_EN (BIT(17) | BIT(12))
-+#define MTK_PHY_XTAL_EXT_EN_MASK 0x33000
-+#define MTK_PHY_PLL_BC 0xc08
-+#define MTK_PHY_PLL_BC_PE2H 0xc0
-+#define MTK_PHY_PLL_BC_PE2H_MASK 0x380000
-+#define MTK_PHY_PLL_IC 0xc0c
-+#define MTK_PHY_PLL_IC_BR_PE2H BIT(28)
-+#define MTK_PHY_PLL_IC_BR_PE2H_MASK 0x30000000
-+#define MTK_PHY_PLL_IC_PE2H BIT(12)
-+#define MTK_PHY_PLL_IC_PE2H_MASK 0xf000
-+#define MTK_PHY_PLL_IR 0xc10
-+#define MTK_PHY_PLL_IR_PE2H BIT(17)
-+#define MTK_PHY_PLL_IR_PE2H_MASK 0xf0000
-+#define MTK_PHY_PLL_BP 0xc14
-+#define MTK_PHY_PLL_BP_PE2H (BIT(19) | BIT(17))
-+#define MTK_PHY_PLL_BP_PE2H_MASK 0xf0000
-+#define MTK_PHY_SSC_DELTA1 0xc3c
-+#define MTK_PHY_SSC_DELTA1_PE2H (0x3c << 16)
-+#define MTK_PHY_SSC_DELTA1_PE2H_MASK 0xffff0000
-+#define MTK_PHY_SSC_DELTA 0xc48
-+#define MTK_PHY_SSC_DELTA_PE2H 0x36
-+#define MTK_PHY_SSC_DELTA_PE2H_MASK 0xffff
-+
-+#define MAX_PORT_NUM 3
-+
-+struct mtk_pcie_port {
-+ int id;
-+ int enable;
-+ int irq;
-+ u32 link;
-+ void __iomem *phy_base;
-+ struct reset_control *rstc;
-+};
-+
-+#define mtk_foreach_port(pcie, p) \
-+ for ((p) = pcie->port; \
-+ (p) != &pcie->port[MAX_PORT_NUM]; (p)++)
-+
-+struct mtk_pcie {
-+ struct device *dev;
-+ void __iomem *pcie_base;
-+ struct regmap *hifsys;
-+
-+ struct resource io;
-+ struct resource pio;
-+ struct resource mem;
-+ struct resource prefetch;
-+ struct resource busn;
-+
-+ u32 io_bus_addr;
-+ u32 mem_bus_addr;
-+
-+ struct clk *clk;
-+
-+ struct mtk_pcie_port port[MAX_PORT_NUM];
-+ int pcie_card_link;
-+};
-+
-+static struct mtk_pcie_port_data {
-+ u32 base;
-+ u32 perst_n;
-+ u32 interrupt_en;
-+} mtk_pcie_port_data[MAX_PORT_NUM] = {
-+ { PCIEP0_BASE, BIT(1), BIT(20) },
-+ { PCIEP1_BASE, BIT(2), BIT(21) },
-+ { PCIEP2_BASE, BIT(3), BIT(22) },
-+};
-+
-+static const struct mtk_phy_init {
-+ uint32_t reg;
-+ uint32_t mask;
-+ uint32_t val;
-+} mtk_phy_init[] = {
-+ { MTK_PHY_REFCLK_SEL, MTK_PHY_XTAL_EXT_EN_MASK, MTK_PHY_XTAL_EXT_EN },
-+ { MTK_PHY_PLL, MTK_PHY_CLKDRV_AMP_MASK, MTK_PHY_CLKDRV_AMP },
-+ { MTK_PHY_CLK, MTK_PHY_CLKDRV_OFFSET_MASK, MTK_PHY_CLKDRV_OFFSET },
-+ { MTK_PHY_SSC_DELTA1, MTK_PHY_SSC_DELTA1_PE2H_MASK, MTK_PHY_SSC_DELTA1_PE2H },
-+ { MTK_PHY_SSC_DELTA, MTK_PHY_SSC_DELTA_PE2H_MASK, MTK_PHY_SSC_DELTA_PE2H },
-+ { MTK_PHY_PLL_IC, MTK_PHY_PLL_IC_BR_PE2H_MASK, MTK_PHY_PLL_IC_BR_PE2H },
-+ { MTK_PHY_PLL_BC, MTK_PHY_PLL_BC_PE2H_MASK, MTK_PHY_PLL_BC_PE2H },
-+ { MTK_PHY_PLL_IR, MTK_PHY_PLL_IR_PE2H_MASK, MTK_PHY_PLL_IR_PE2H },
-+ { MTK_PHY_PLL_IC, MTK_PHY_PLL_IC_PE2H_MASK, MTK_PHY_PLL_IC_PE2H },
-+ { MTK_PHY_PLL_BP, MTK_PHY_PLL_BP_PE2H_MASK, MTK_PHY_PLL_BP_PE2H },
-+};
-+
-+static struct mtk_pcie *sys_to_pcie(struct pci_sys_data *sys)
-+{
-+ return sys->private_data;
-+}
-+
-+static void pcie_w32(struct mtk_pcie *pcie, u32 val, unsigned reg)
-+{
-+ iowrite32(val, pcie->pcie_base + reg);
-+}
-+
-+static u32 pcie_r32(struct mtk_pcie *pcie, unsigned reg)
-+{
-+ return ioread32(pcie->pcie_base + reg);
-+}
-+
-+static void pcie_m32(struct mtk_pcie *pcie, u32 mask, u32 val, unsigned reg)
-+{
-+ u32 v = pcie_r32(pcie, reg);
-+
-+ v &= mask;
-+ v |= val;
-+ pcie_w32(pcie, v, reg);
-+}
-+
-+static int pcie_config_read(struct pci_bus *bus, unsigned int devfn, int where,
-+ int size, u32 *val)
-+{
-+ struct mtk_pcie *pcie = sys_to_pcie(bus->sysdata);
-+ unsigned int slot = PCI_SLOT(devfn);
-+ u8 func = PCI_FUNC(devfn);
-+ u32 address;
-+ u32 data;
-+ u32 num = 0;
-+
-+ if (bus)
-+ num = bus->number;
-+
-+ address = (((where & 0xf00) >> 8) << 24) |
-+ (num << 16) |
-+ (slot << 11) |
-+ (func << 8) |
-+ (where & 0xfc);
-+
-+ pcie_w32(pcie, address, CFGADDR);
-+ data = pcie_r32(pcie, CFGDATA);
-+
-+ switch (size) {
-+ case 1:
-+ *val = (data >> ((where & 3) << 3)) & 0xff;
-+ break;
-+ case 2:
-+ *val = (data >> ((where & 3) << 3)) & 0xffff;
-+ break;
-+ case 4:
-+ *val = data;
-+ break;
-+ }
-+
-+ return PCIBIOS_SUCCESSFUL;
-+}
-+
-+static int pcie_config_write(struct pci_bus *bus, unsigned int devfn, int where,
-+ int size, u32 val)
-+{
-+ struct mtk_pcie *pcie = sys_to_pcie(bus->sysdata);
-+ unsigned int slot = PCI_SLOT(devfn);
-+ u8 func = PCI_FUNC(devfn);
-+ u32 address;
-+ u32 data;
-+ u32 num = 0;
-+
-+ if (bus)
-+ num = bus->number;
-+
-+ address = (((where & 0xf00) >> 8) << 24) |
-+ (num << 16) | (slot << 11) | (func << 8) | (where & 0xfc);
-+ pcie_w32(pcie, address, CFGADDR);
-+ data = pcie_r32(pcie, CFGDATA);
-+
-+ switch (size) {
-+ case 1:
-+ data = (data & ~(0xff << ((where & 3) << 3))) |
-+ (val << ((where & 3) << 3));
-+ break;
-+ case 2:
-+ data = (data & ~(0xffff << ((where & 3) << 3))) |
-+ (val << ((where & 3) << 3));
-+ break;
-+ case 4:
-+ data = val;
-+ break;
-+ }
-+ pcie_w32(pcie, data, CFGDATA);
-+
-+ return PCIBIOS_SUCCESSFUL;
-+}
-+
-+static struct pci_ops mtk_pcie_ops = {
-+ .read = pcie_config_read,
-+ .write = pcie_config_write,
-+};
-+
-+static int __init mtk_pcie_setup(int nr, struct pci_sys_data *sys)
-+{
-+ struct mtk_pcie *pcie = sys_to_pcie(sys);
-+
-+ request_resource(&ioport_resource, &pcie->pio);
-+ request_resource(&iomem_resource, &pcie->mem);
-+
-+ pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
-+ pci_add_resource_offset(&sys->resources, &pcie->pio, sys->io_offset);
-+ pci_add_resource(&sys->resources, &pcie->busn);
-+
-+ return 1;
-+}
-+
-+static struct pci_bus * __init mtk_pcie_scan_bus(int nr,
-+ struct pci_sys_data *sys)
-+{
-+ struct mtk_pcie *pcie = sys_to_pcie(sys);
-+ struct pci_bus *bus;
-+
-+ bus = pci_create_root_bus(pcie->dev, sys->busnr, &mtk_pcie_ops, sys,
-+ &sys->resources);
-+ if (!bus)
-+ return NULL;
-+
-+ pci_scan_child_bus(bus);
-+
-+ return bus;
-+}
-+
-+static int __init mtk_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-+{
-+ struct mtk_pcie *pcie = sys_to_pcie(dev->bus->sysdata);
-+ struct mtk_pcie_port *port;
-+ int irq = -1;
-+
-+ mtk_foreach_port(pcie, port)
-+ if (port->id == slot)
-+ irq = port->irq;
-+
-+ return irq;
-+}
-+
-+static void mtk_pcie_configure_phy(struct mtk_pcie *pcie,
-+ struct mtk_pcie_port *port)
-+{
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(mtk_phy_init); i++) {
-+ void __iomem *phy_addr = port->phy_base + mtk_phy_init[i].reg;
-+ u32 val = ioread32(phy_addr);
-+
-+ val &= ~mtk_phy_init[i].mask;
-+ val |= mtk_phy_init[i].val;
-+ iowrite32(val, phy_addr);
-+ }
-+ usleep_range(5000, 6000);
-+}
-+
-+static void mtk_pcie_configure_rc(struct mtk_pcie *pcie,
-+ struct mtk_pcie_port *port,
-+ struct pci_bus *bus)
-+{
-+ u32 val = 0;
-+
-+ pcie_config_write(bus,
-+ port->id << 3,
-+ PCI_BASE_ADDRESS_0, 4, MEMORY_BASE);
-+
-+ pcie_config_read(bus,
-+ port->id << 3, PCI_BASE_ADDRESS_0, 4, &val);
-+
-+ /* Configure RC Credit */
-+ pcie_config_read(bus, port->id << 3, 0x73c, 4, &val);
-+ val &= ~(0x9fff) << 16;
-+ val |= 0x806c << 16;
-+ pcie_config_write(bus, port->id << 3, 0x73c, 4, val);
-+
-+ /* Configure RC FTS number */
-+ pcie_config_read(bus, port->id << 3, 0x70c, 4, &val);
-+ val &= ~(0xff3) << 8;
-+ val |= 0x50 << 8;
-+ pcie_config_write(bus, port->id << 3, 0x70c, 4, val);
-+}
-+
-+static int mtk_pcie_preinit(struct mtk_pcie *pcie)
-+{
-+ struct mtk_pcie_port *port;
-+ u32 val = 0;
-+ struct pci_bus bus;
-+ struct pci_sys_data sys;
-+
-+ memset(&bus, 0, sizeof(bus));
-+ memset(&sys, 0, sizeof(sys));
-+ bus.sysdata = (void *)&sys;
-+ sys.private_data = (void *)pcie;
-+
-+ pcibios_min_io = 0;
-+ pcibios_min_mem = 0;
-+
-+ /* The PHY on Port 2 is shared with USB */
-+ if (pcie->port[2].enable)
-+ regmap_update_bits(pcie->hifsys, HIFSYS_SYSCFG1,
-+ HIFSYS_SYSCFG1_PHY2_MASK, 0x0);
-+
-+ /* PCIe RC Reset */
-+ mtk_foreach_port(pcie, port)
-+ if (port->enable)
-+ reset_control_assert(port->rstc);
-+ usleep_range(1000, 2000);
-+ mtk_foreach_port(pcie, port)
-+ if (port->enable)
-+ reset_control_deassert(port->rstc);
-+ usleep_range(1000, 2000);
-+
-+ /* Configure PCIe PHY */
-+ mtk_foreach_port(pcie, port)
-+ if (port->enable)
-+ mtk_pcie_configure_phy(pcie, port);
-+
-+ /* PCIe EP reset */
-+ val = 0;
-+ mtk_foreach_port(pcie, port)
-+ if (port->enable)
-+ val |= mtk_pcie_port_data[port->id].perst_n;
-+ pcie_w32(pcie, pcie_r32(pcie, PCICFG) | val, PCICFG);
-+ usleep_range(1000, 2000);
-+ pcie_w32(pcie, pcie_r32(pcie, PCICFG) & ~val, PCICFG);
-+ usleep_range(1000, 2000);
-+ msleep(100);
-+
-+ /* check the link status */
-+ val = 0;
-+ mtk_foreach_port(pcie, port) {
-+ if (port->enable) {
-+ u32 base = mtk_pcie_port_data[port->id].base;
-+
-+ if ((pcie_r32(pcie, base + PCIE_SISTAT) & 0x1))
-+ port->link = 1;
-+ else
-+ reset_control_assert(port->rstc);
-+ }
-+ }
-+
-+ mtk_foreach_port(pcie, port)
-+ if (port->link)
-+ pcie->pcie_card_link++;
-+
-+ if (!pcie->pcie_card_link)
-+ return -ENODEV;
-+
-+ pcie_w32(pcie, pcie->mem_bus_addr, MEMBASE);
-+ pcie_w32(pcie, pcie->io_bus_addr, IOBASE);
-+
-+ mtk_foreach_port(pcie, port) {
-+ if (port->link) {
-+ u32 base = mtk_pcie_port_data[port->id].base;
-+ u32 inte = mtk_pcie_port_data[port->id].interrupt_en;
-+
-+ pcie_m32(pcie, 0, inte, PCIENA);
-+ pcie_w32(pcie, 0x7fff0001, base + BAR0SETUP);
-+ pcie_w32(pcie, MEMORY_BASE, base + IMBASEBAR0);
-+ pcie_w32(pcie, 0x06040001, base + PCIE_CLASS);
-+ }
-+ }
-+
-+ mtk_foreach_port(pcie, port)
-+ if (port->link)
-+ mtk_pcie_configure_rc(pcie, port, &bus);
-+
-+ return 0;
-+}
-+
-+static int mtk_pcie_parse_dt(struct mtk_pcie *pcie)
-+{
-+ struct device_node *np = pcie->dev->of_node, *port;
-+ struct of_pci_range_parser parser;
-+ struct of_pci_range range;
-+ struct resource res;
-+ int err;
-+
-+ pcie->hifsys = syscon_regmap_lookup_by_phandle(np, "mediatek,hifsys");
-+ if (IS_ERR(pcie->hifsys)) {
-+ dev_err(pcie->dev, "missing \"mediatek,hifsys\" phandle\n");
-+ return PTR_ERR(pcie->hifsys);
-+ }
-+
-+ if (of_pci_range_parser_init(&parser, np)) {
-+ dev_err(pcie->dev, "missing \"ranges\" property\n");
-+ return -EINVAL;
-+ }
-+
-+ for_each_of_pci_range(&parser, &range) {
-+ err = of_pci_range_to_resource(&range, np, &res);
-+ if (err < 0) {
-+ dev_err(pcie->dev, "failed to read resource range\n");
-+ return err;
-+ }
-+
-+ switch (res.flags & IORESOURCE_TYPE_BITS) {
-+ case IORESOURCE_IO:
-+ memcpy(&pcie->pio, &res, sizeof(res));
-+ pcie->pio.start = (resource_size_t)range.pci_addr;
-+ pcie->pio.end = (resource_size_t)
-+ (range.pci_addr + range.size - 1);
-+ pcie->io_bus_addr = (resource_size_t)range.cpu_addr;
-+ break;
-+
-+ case IORESOURCE_MEM:
-+ if (res.flags & IORESOURCE_PREFETCH) {
-+ memcpy(&pcie->prefetch, &res, sizeof(res));
-+ pcie->prefetch.name = "prefetchable";
-+ pcie->prefetch.start =
-+ (resource_size_t)range.pci_addr;
-+ pcie->prefetch.end = (resource_size_t)
-+ (range.pci_addr + range.size - 1);
-+ } else {
-+ memcpy(&pcie->mem, &res, sizeof(res));
-+ pcie->mem.name = "non-prefetchable";
-+ pcie->mem.start = (resource_size_t)
-+ range.pci_addr;
-+ pcie->prefetch.end = (resource_size_t)
-+ (range.pci_addr + range.size - 1);
-+ pcie->mem_bus_addr = (resource_size_t)
-+ range.cpu_addr;
-+ }
-+ break;
-+ }
-+ }
-+
-+ err = of_pci_parse_bus_range(np, &pcie->busn);
-+ if (err < 0) {
-+ dev_err(pcie->dev, "failed to parse ranges property: %d\n",
-+ err);
-+ pcie->busn.name = np->name;
-+ pcie->busn.start = 0;
-+ pcie->busn.end = 0xff;
-+ pcie->busn.flags = IORESOURCE_BUS;
-+ }
-+
-+ /* parse root ports */
-+ for_each_child_of_node(np, port) {
-+ unsigned int index;
-+ char rst[] = "pcie0";
-+
-+ err = of_pci_get_devfn(port);
-+ if (err < 0) {
-+ dev_err(pcie->dev, "failed to parse address: %d\n",
-+ err);
-+ return err;
-+ }
-+
-+ index = PCI_SLOT(err);
-+ if (index > MAX_PORT_NUM) {
-+ dev_err(pcie->dev, "invalid port number: %d\n", index);
-+ continue;
-+ }
-+ index--;
-+ pcie->port[index].id = index;
-+
-+ if (!of_device_is_available(port))
-+ continue;
-+
-+ rst[4] += index;
-+ pcie->port[index].rstc = devm_reset_control_get(pcie->dev,
-+ rst);
-+ if (!IS_ERR(pcie->port[index].rstc))
-+ pcie->port[index].enable = 1;
-+ }
-+ return 0;
-+}
-+
-+static int mtk_pcie_get_resources(struct mtk_pcie *pcie)
-+{
-+ struct platform_device *pdev = to_platform_device(pcie->dev);
-+ struct mtk_pcie_port *port;
-+ struct resource *res;
-+
-+ pcie->clk = devm_clk_get(&pdev->dev, "pcie");
-+ if (IS_ERR(pcie->clk)) {
-+ dev_err(&pdev->dev, "Failed to get pcie clk\n");
-+ return PTR_ERR(pcie->clk);
-+ }
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ pcie->pcie_base = devm_ioremap_resource(&pdev->dev, res);
-+ if (IS_ERR(pcie->pcie_base)) {
-+ dev_err(&pdev->dev, "Failed to get pcie range\n");
-+ return PTR_ERR(pcie->pcie_base);
-+ }
-+
-+ mtk_foreach_port(pcie, port) {
-+ if (!port->enable)
-+ continue;
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, port->id + 1);
-+ port->phy_base = devm_ioremap_resource(&pdev->dev, res);
-+ if (IS_ERR(port->phy_base)) {
-+ dev_err(&pdev->dev, "Failed to get pcie phy%d range %p\n",
-+ port->id, port->phy_base);
-+ return PTR_ERR(port->phy_base);
-+ }
-+ port->irq = platform_get_irq(pdev, port->id);
-+ }
-+
-+ return clk_prepare_enable(pcie->clk);
-+}
-+
-+static int mtk_pcie_probe(struct platform_device *pdev)
-+{
-+ struct mtk_pcie *pcie;
-+ struct hw_pci hw;
-+ int ret;
-+
-+ pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
-+ if (!pcie)
-+ return -ENOMEM;
-+
-+ pcie->dev = &pdev->dev;
-+ ret = mtk_pcie_parse_dt(pcie);
-+ if (ret < 0)
-+ return ret;
-+
-+ pm_runtime_enable(&pdev->dev);
-+ pm_runtime_get_sync(&pdev->dev);
-+
-+ ret = mtk_pcie_get_resources(pcie);
-+ if (ret < 0) {
-+ dev_err(&pdev->dev, "failed to request resources: %d\n", ret);
-+ goto err_out;
-+ }
-+
-+ ret = mtk_pcie_preinit(pcie);
-+ if (ret)
-+ return ret;
-+
-+ memset(&hw, 0, sizeof(hw));
-+ hw.nr_controllers = 1;
-+ hw.private_data = (void **)&pcie;
-+ hw.setup = mtk_pcie_setup;
-+ hw.map_irq = mtk_pcie_map_irq;
-+ hw.scan = mtk_pcie_scan_bus;
-+
-+ pci_common_init_dev(pcie->dev, &hw);
-+ platform_set_drvdata(pdev, pcie);
-+
-+ return 0;
-+
-+err_out:
-+ clk_disable_unprepare(pcie->clk);
-+ pm_runtime_put_sync(&pdev->dev);
-+ pm_runtime_disable(&pdev->dev);
-+
-+ return ret;
-+}
-+
-+static const struct of_device_id mtk_pcie_ids[] = {
-+ { .compatible = "mediatek,mt2701-pcie" },
-+ { .compatible = "mediatek,mt7623-pcie" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, mtk_pcie_ids);
-+
-+static struct platform_driver mtk_pcie_driver = {
-+ .probe = mtk_pcie_probe,
-+ .driver = {
-+ .name = "mediatek-pcie",
-+ .owner = THIS_MODULE,
-+ .of_match_table = of_match_ptr(mtk_pcie_ids),
-+ },
-+};
-+
-+static int __init mtk_pcie_init(void)
-+{
-+ return platform_driver_register(&mtk_pcie_driver);
-+}
-+
-+module_init(mtk_pcie_init);
diff --git a/target/linux/mediatek/patches-4.9/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch b/target/linux/mediatek/patches-4.9/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch
deleted file mode 100644
index 8d91b121d7..0000000000
--- a/target/linux/mediatek/patches-4.9/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 2f47c01fe3015f4c649849ddffe04f12a122abe2 Mon Sep 17 00:00:00 2001
-From: Shunli Wang <shunli.wang@mediatek.com>
-Date: Thu, 20 Oct 2016 16:56:37 +0800
-Subject: [PATCH 04/57] soc: mediatek: Add MT2701 power dt-bindings
-
-Add power dt-bindings for MT2701.
-
-Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
-Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
-Acked-by: Rob Herring <robh@kernel.org>
-Reviewed-by: Kevin Hilman <khilman@baylibre.com>
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- .../devicetree/bindings/soc/mediatek/scpsys.txt | 13 ++++++-----
- include/dt-bindings/power/mt2701-power.h | 26 ++++++++++++++++++++++
- 2 files changed, 34 insertions(+), 5 deletions(-)
- create mode 100644 include/dt-bindings/power/mt2701-power.h
-
---- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
-+++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
-@@ -9,17 +9,20 @@ domain control.
-
- The driver implements the Generic PM domain bindings described in
- power/power_domain.txt. It provides the power domains defined in
--include/dt-bindings/power/mt8173-power.h.
-+include/dt-bindings/power/mt8173-power.h and mt2701-power.h.
-
- Required properties:
--- compatible: Must be "mediatek,mt8173-scpsys"
-+- compatible: Should be one of:
-+ - "mediatek,mt2701-scpsys"
-+ - "mediatek,mt8173-scpsys"
- - #power-domain-cells: Must be 1
- - reg: Address range of the SCPSYS unit
- - infracfg: must contain a phandle to the infracfg controller
- - clock, clock-names: clocks according to the common clock binding.
-- The clocks needed "mm", "mfg", "venc" and "venc_lt".
-- These are the clocks which hardware needs to be enabled
-- before enabling certain power domains.
-+ These are clocks which hardware needs to be
-+ enabled before enabling certain power domains.
-+ Required clocks for MT2701: "mm", "mfg", "ethif"
-+ Required clocks for MT8173: "mm", "mfg", "venc", "venc_lt"
-
- Optional properties:
- - vdec-supply: Power supply for the vdec power domain
---- /dev/null
-+++ b/include/dt-bindings/power/mt2701-power.h
-@@ -0,0 +1,26 @@
-+/*
-+ * Copyright (C) 2015 MediaTek Inc.
-+ *
-+ * This program is free software: you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#ifndef _DT_BINDINGS_POWER_MT2701_POWER_H
-+#define _DT_BINDINGS_POWER_MT2701_POWER_H
-+
-+#define MT2701_POWER_DOMAIN_CONN 0
-+#define MT2701_POWER_DOMAIN_DISP 1
-+#define MT2701_POWER_DOMAIN_IFR_MSC 2
-+#define MT2701_POWER_DOMAIN_VDEC 3
-+#define MT2701_POWER_DOMAIN_ISP 4
-+#define MT2701_POWER_DOMAIN_BDP 5
-+#define MT2701_POWER_DOMAIN_ETH 6
-+#define MT2701_POWER_DOMAIN_HIF 7
-+
-+#endif /* _DT_BINDINGS_POWER_MT2701_POWER_H */
diff --git a/target/linux/mediatek/patches-4.9/0005-clk-mediatek-Add-MT2701-clock-support.patch b/target/linux/mediatek/patches-4.9/0005-clk-mediatek-Add-MT2701-clock-support.patch
deleted file mode 100644
index ef40ba2345..0000000000
--- a/target/linux/mediatek/patches-4.9/0005-clk-mediatek-Add-MT2701-clock-support.patch
+++ /dev/null
@@ -1,1431 +0,0 @@
-From f76b34c799d87ab241432b1241f6fc6d9db3ecb6 Mon Sep 17 00:00:00 2001
-From: Shunli Wang <shunli.wang@mediatek.com>
-Date: Tue, 5 Jan 2016 14:30:20 +0800
-Subject: [PATCH 05/57] clk: mediatek: Add MT2701 clock support
-
-Add MT2701 clock support, include topckgen, apmixedsys,
-infracfg, pericfg and subsystem clocks.
-
-Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
-Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
----
- drivers/clk/mediatek/Kconfig | 8 +
- drivers/clk/mediatek/Makefile | 1 +
- drivers/clk/mediatek/clk-gate.c | 56 ++
- drivers/clk/mediatek/clk-gate.h | 2 +
- drivers/clk/mediatek/clk-mt2701.c | 1210 +++++++++++++++++++++++++++++++++++++
- drivers/clk/mediatek/clk-mtk.c | 25 +
- drivers/clk/mediatek/clk-mtk.h | 35 +-
- 7 files changed, 1334 insertions(+), 3 deletions(-)
- create mode 100644 drivers/clk/mediatek/clk-mt2701.c
-
---- a/drivers/clk/mediatek/Kconfig
-+++ b/drivers/clk/mediatek/Kconfig
-@@ -6,6 +6,14 @@ config COMMON_CLK_MEDIATEK
- ---help---
- Mediatek SoCs' clock support.
-
-+config COMMON_CLK_MT2701
-+ bool "Clock driver for Mediatek MT2701 and MT7623"
-+ depends on COMMON_CLK
-+ select COMMON_CLK_MEDIATEK
-+ default ARCH_MEDIATEK
-+ ---help---
-+ This driver supports Mediatek MT2701 and MT7623 clocks.
-+
- config COMMON_CLK_MT8135
- bool "Clock driver for Mediatek MT8135"
- depends on ARCH_MEDIATEK || COMPILE_TEST
---- a/drivers/clk/mediatek/Makefile
-+++ b/drivers/clk/mediatek/Makefile
-@@ -1,4 +1,5 @@
- obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o
- obj-$(CONFIG_RESET_CONTROLLER) += reset.o
-+obj-$(CONFIG_COMMON_CLK_MT2701) += clk-mt2701.o
- obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
- obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o
---- a/drivers/clk/mediatek/clk-gate.c
-+++ b/drivers/clk/mediatek/clk-gate.c
-@@ -61,6 +61,26 @@ static void mtk_cg_clr_bit(struct clk_hw
- regmap_write(cg->regmap, cg->clr_ofs, BIT(cg->bit));
- }
-
-+static void mtk_cg_set_bit_no_setclr(struct clk_hw *hw)
-+{
-+ struct mtk_clk_gate *cg = to_mtk_clk_gate(hw);
-+ u32 val;
-+
-+ regmap_read(cg->regmap, cg->sta_ofs, &val);
-+ val |= BIT(cg->bit);
-+ regmap_write(cg->regmap, cg->sta_ofs, val);
-+}
-+
-+static void mtk_cg_clr_bit_no_setclr(struct clk_hw *hw)
-+{
-+ struct mtk_clk_gate *cg = to_mtk_clk_gate(hw);
-+ u32 val;
-+
-+ regmap_read(cg->regmap, cg->sta_ofs, &val);
-+ val &= ~(BIT(cg->bit));
-+ regmap_write(cg->regmap, cg->sta_ofs, val);
-+}
-+
- static int mtk_cg_enable(struct clk_hw *hw)
- {
- mtk_cg_clr_bit(hw);
-@@ -85,6 +105,30 @@ static void mtk_cg_disable_inv(struct cl
- mtk_cg_clr_bit(hw);
- }
-
-+static int mtk_cg_enable_no_setclr(struct clk_hw *hw)
-+{
-+ mtk_cg_clr_bit_no_setclr(hw);
-+
-+ return 0;
-+}
-+
-+static void mtk_cg_disable_no_setclr(struct clk_hw *hw)
-+{
-+ mtk_cg_set_bit_no_setclr(hw);
-+}
-+
-+static int mtk_cg_enable_inv_no_setclr(struct clk_hw *hw)
-+{
-+ mtk_cg_set_bit_no_setclr(hw);
-+
-+ return 0;
-+}
-+
-+static void mtk_cg_disable_inv_no_setclr(struct clk_hw *hw)
-+{
-+ mtk_cg_clr_bit_no_setclr(hw);
-+}
-+
- const struct clk_ops mtk_clk_gate_ops_setclr = {
- .is_enabled = mtk_cg_bit_is_cleared,
- .enable = mtk_cg_enable,
-@@ -97,6 +141,18 @@ const struct clk_ops mtk_clk_gate_ops_se
- .disable = mtk_cg_disable_inv,
- };
-
-+const struct clk_ops mtk_clk_gate_ops_no_setclr = {
-+ .is_enabled = mtk_cg_bit_is_cleared,
-+ .enable = mtk_cg_enable_no_setclr,
-+ .disable = mtk_cg_disable_no_setclr,
-+};
-+
-+const struct clk_ops mtk_clk_gate_ops_no_setclr_inv = {
-+ .is_enabled = mtk_cg_bit_is_set,
-+ .enable = mtk_cg_enable_inv_no_setclr,
-+ .disable = mtk_cg_disable_inv_no_setclr,
-+};
-+
- struct clk *mtk_clk_register_gate(
- const char *name,
- const char *parent_name,
---- a/drivers/clk/mediatek/clk-gate.h
-+++ b/drivers/clk/mediatek/clk-gate.h
-@@ -36,6 +36,8 @@ static inline struct mtk_clk_gate *to_mt
-
- extern const struct clk_ops mtk_clk_gate_ops_setclr;
- extern const struct clk_ops mtk_clk_gate_ops_setclr_inv;
-+extern const struct clk_ops mtk_clk_gate_ops_no_setclr;
-+extern const struct clk_ops mtk_clk_gate_ops_no_setclr_inv;
-
- struct clk *mtk_clk_register_gate(
- const char *name,
---- /dev/null
-+++ b/drivers/clk/mediatek/clk-mt2701.c
-@@ -0,0 +1,1210 @@
-+/*
-+ * Copyright (c) 2014 MediaTek Inc.
-+ * Author: Shunli Wang <shunli.wang@mediatek.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+
-+#include "clk-mtk.h"
-+#include "clk-gate.h"
-+
-+#include <dt-bindings/clock/mt2701-clk.h>
-+
-+static DEFINE_SPINLOCK(lock);
-+
-+static const struct mtk_fixed_clk top_fixed_clks[] __initconst = {
-+ FIXED_CLK(CLK_TOP_DPI, "dpi_ck", "clk26m", 108 * MHZ),
-+ FIXED_CLK(CLK_TOP_DMPLL, "dmpll_ck", "clk26m", 400 * MHZ),
-+ FIXED_CLK(CLK_TOP_VENCPLL, "vencpll_ck", "clk26m", 295750000),
-+ FIXED_CLK(CLK_TOP_HDMI_0_PIX340M, "hdmi_0_pix340m", "clk26m", 340 * MHZ),
-+ FIXED_CLK(CLK_TOP_HDMI_0_DEEP340M, "hdmi_0_deep340m", "clk26m", 340 * MHZ),
-+ FIXED_CLK(CLK_TOP_HDMI_0_PLL340M, "hdmi_0_pll340m", "clk26m", 340 * MHZ),
-+ FIXED_CLK(CLK_TOP_HDMITX_CLKDIG_CTS, "hdmitx_dig_cts", "clk26m", 300 * MHZ),
-+ FIXED_CLK(CLK_TOP_HADDS2_FB, "hadds2_fbclk", "clk26m", 27 * MHZ),
-+ FIXED_CLK(CLK_TOP_WBG_DIG_416M, "wbg_dig_ck_416m", "clk26m", 416 * MHZ),
-+};
-+
-+static const struct mtk_fixed_factor top_fixed_divs[] __initconst = {
-+ FACTOR(CLK_TOP_SYSPLL, "syspll_ck", "mainpll", 1, 1),
-+ FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2),
-+ FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll", 1, 3),
-+ FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5),
-+ FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll", 1, 7),
-+ FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "syspll_d2", 1, 2),
-+ FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "syspll_d2", 1, 4),
-+ FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "syspll_d2", 1, 8),
-+ FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "syspll_d2", 1, 16),
-+ FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "syspll_d3", 1, 2),
-+ FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "syspll_d3", 1, 4),
-+ FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "syspll_d3", 1, 8),
-+ FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "syspll_d5", 1, 2),
-+ FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "syspll_d5", 1, 4),
-+ FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "syspll_d7", 1, 2),
-+ FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "syspll_d7", 1, 4),
-+
-+ FACTOR(CLK_TOP_UNIVPLL, "univpll_ck", "univpll", 1, 1),
-+ FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2),
-+ FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3),
-+ FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
-+ FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7),
-+ FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll", 1, 26),
-+ FACTOR(CLK_TOP_UNIVPLL_D52, "univpll_d52", "univpll", 1, 52),
-+ FACTOR(CLK_TOP_UNIVPLL_D108, "univpll_d108", "univpll", 1, 108),
-+ FACTOR(CLK_TOP_USB_PHY48M, "USB_PHY48M_CK", "univpll", 1, 26),
-+ FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_d2", 1, 2),
-+ FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_d2", 1, 4),
-+ FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_d2", 1, 8),
-+ FACTOR(CLK_TOP_8BDAC, "8bdac_ck", "univpll_d2", 1, 1),
-+ FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_d3", 1, 2),
-+ FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_d3", 1, 4),
-+ FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_d3", 1, 8),
-+ FACTOR(CLK_TOP_UNIVPLL2_D16, "univpll2_d16", "univpll_d3", 1, 16),
-+ FACTOR(CLK_TOP_UNIVPLL2_D32, "univpll2_d32", "univpll_d3", 1, 32),
-+ FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll_d5", 1, 2),
-+ FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll_d5", 1, 4),
-+ FACTOR(CLK_TOP_UNIVPLL3_D8, "univpll3_d8", "univpll_d5", 1, 8),
-+
-+ FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1, 1),
-+ FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2),
-+ FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4),
-+ FACTOR(CLK_TOP_MSDCPLL_D8, "msdcpll_d8", "msdcpll", 1, 8),
-+
-+ FACTOR(CLK_TOP_MMPLL, "mmpll_ck", "mmpll", 1, 1),
-+ FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
-+
-+ FACTOR(CLK_TOP_DMPLL_D2, "dmpll_d2", "dmpll_ck", 1, 2),
-+ FACTOR(CLK_TOP_DMPLL_D4, "dmpll_d4", "dmpll_ck", 1, 4),
-+ FACTOR(CLK_TOP_DMPLL_X2, "dmpll_x2", "dmpll_ck", 1, 1),
-+
-+ FACTOR(CLK_TOP_TVDPLL, "tvdpll_ck", "tvdpll", 1, 1),
-+ FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll", 1, 2),
-+ FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1, 4),
-+
-+ FACTOR(CLK_TOP_VDECPLL, "vdecpll_ck", "vdecpll", 1, 1),
-+ FACTOR(CLK_TOP_TVD2PLL, "tvd2pll_ck", "tvd2pll", 1, 1),
-+ FACTOR(CLK_TOP_TVD2PLL_D2, "tvd2pll_d2", "tvd2pll", 1, 2),
-+
-+ FACTOR(CLK_TOP_MIPIPLL, "mipipll", "dpi_ck", 1, 1),
-+ FACTOR(CLK_TOP_MIPIPLL_D2, "mipipll_d2", "dpi_ck", 1, 2),
-+ FACTOR(CLK_TOP_MIPIPLL_D4, "mipipll_d4", "dpi_ck", 1, 4),
-+
-+ FACTOR(CLK_TOP_HDMIPLL, "hdmipll_ck", "hdmitx_dig_cts", 1, 1),
-+ FACTOR(CLK_TOP_HDMIPLL_D2, "hdmipll_d2", "hdmitx_dig_cts", 1, 2),
-+ FACTOR(CLK_TOP_HDMIPLL_D3, "hdmipll_d3", "hdmitx_dig_cts", 1, 3),
-+
-+ FACTOR(CLK_TOP_ARMPLL_1P3G, "armpll_1p3g_ck", "armpll", 1, 1),
-+
-+ FACTOR(CLK_TOP_AUDPLL, "audpll", "audpll_sel", 1, 1),
-+ FACTOR(CLK_TOP_AUDPLL_D4, "audpll_d4", "audpll_sel", 1, 4),
-+ FACTOR(CLK_TOP_AUDPLL_D8, "audpll_d8", "audpll_sel", 1, 8),
-+ FACTOR(CLK_TOP_AUDPLL_D16, "audpll_d16", "audpll_sel", 1, 16),
-+ FACTOR(CLK_TOP_AUDPLL_D24, "audpll_d24", "audpll_sel", 1, 24),
-+
-+ FACTOR(CLK_TOP_AUD1PLL_98M, "aud1pll_98m_ck", "aud1pll", 1, 3),
-+ FACTOR(CLK_TOP_AUD2PLL_90M, "aud2pll_90m_ck", "aud2pll", 1, 3),
-+ FACTOR(CLK_TOP_HADDS2PLL_98M, "hadds2pll_98m", "hadds2pll", 1, 3),
-+ FACTOR(CLK_TOP_HADDS2PLL_294M, "hadds2pll_294m", "hadds2pll", 1, 1),
-+ FACTOR(CLK_TOP_ETHPLL_500M, "ethpll_500m_ck", "ethpll", 1, 1),
-+ FACTOR(CLK_TOP_CLK26M_D8, "clk26m_d8", "clk26m", 1, 8),
-+ FACTOR(CLK_TOP_32K_INTERNAL, "32k_internal", "clk26m", 1, 793),
-+ FACTOR(CLK_TOP_32K_EXTERNAL, "32k_external", "rtc32k", 1, 1),
-+};
-+
-+static const char * const axi_parents[] __initconst = {
-+ "clk26m",
-+ "syspll1_d2",
-+ "syspll_d5",
-+ "syspll1_d4",
-+ "univpll_d5",
-+ "univpll2_d2",
-+ "mmpll_d2",
-+ "dmpll_d2"
-+};
-+
-+static const char * const mem_parents[] __initconst = {
-+ "clk26m",
-+ "dmpll_ck"
-+};
-+
-+static const char * const ddrphycfg_parents[] __initconst = {
-+ "clk26m",
-+ "syspll1_d8"
-+};
-+
-+static const char * const mm_parents[] __initconst = {
-+ "clk26m",
-+ "vencpll_ck",
-+ "syspll1_d2",
-+ "syspll1_d4",
-+ "univpll_d5",
-+ "univpll1_d2",
-+ "univpll2_d2",
-+ "dmpll_ck"
-+};
-+
-+static const char * const pwm_parents[] __initconst = {
-+ "clk26m",
-+ "univpll2_d4",
-+ "univpll3_d2",
-+ "univpll1_d4",
-+};
-+
-+static const char * const vdec_parents[] __initconst = {
-+ "clk26m",
-+ "vdecpll_ck",
-+ "syspll_d5",
-+ "syspll1_d4",
-+ "univpll_d5",
-+ "univpll2_d2",
-+ "vencpll_ck",
-+ "msdcpll_d2",
-+ "mmpll_d2"
-+};
-+
-+static const char * const mfg_parents[] __initconst = {
-+ "clk26m",
-+ "mmpll_ck",
-+ "dmpll_x2_ck",
-+ "msdcpll_ck",
-+ "clk26m",
-+ "syspll_d3",
-+ "univpll_d3",
-+ "univpll1_d2"
-+};
-+
-+static const char * const camtg_parents[] __initconst = {
-+ "clk26m",
-+ "univpll_d26",
-+ "univpll2_d2",
-+ "syspll3_d2",
-+ "syspll3_d4",
-+ "msdcpll_d2",
-+ "mmpll_d2"
-+};
-+
-+static const char * const uart_parents[] __initconst = {
-+ "clk26m",
-+ "univpll2_d8"
-+};
-+
-+static const char * const spi_parents[] __initconst = {
-+ "clk26m",
-+ "syspll3_d2",
-+ "syspll4_d2",
-+ "univpll2_d4",
-+ "univpll1_d8"
-+};
-+
-+static const char * const usb20_parents[] __initconst = {
-+ "clk26m",
-+ "univpll1_d8",
-+ "univpll3_d4"
-+};
-+
-+static const char * const msdc30_parents[] __initconst = {
-+ "clk26m",
-+ "msdcpll_d2",
-+ "syspll2_d2",
-+ "syspll1_d4",
-+ "univpll1_d4",
-+ "univpll2_d4"
-+};
-+
-+static const char * const audio_parents[] __initconst = {
-+ "clk26m",
-+ "syspll1_d16"
-+};
-+
-+static const char * const aud_intbus_parents[] __initconst = {
-+ "clk26m",
-+ "syspll1_d4",
-+ "syspll3_d2",
-+ "syspll4_d2",
-+ "univpll3_d2",
-+ "univpll2_d4"
-+};
-+
-+static const char * const pmicspi_parents[] __initconst = {
-+ "clk26m",
-+ "syspll1_d8",
-+ "syspll2_d4",
-+ "syspll4_d2",
-+ "syspll3_d4",
-+ "syspll2_d8",
-+ "syspll1_d16",
-+ "univpll3_d4",
-+ "univpll_d26",
-+ "dmpll_d2",
-+ "dmpll_d4"
-+};
-+
-+static const char * const scp_parents[] __initconst = {
-+ "clk26m",
-+ "syspll1_d8",
-+ "dmpll_d2",
-+ "dmpll_d4"
-+};
-+
-+static const char * const dpi0_parents[] __initconst = {
-+ "clk26m",
-+ "mipipll",
-+ "mipipll_d2",
-+ "mipipll_d4",
-+ "clk26m",
-+ "tvdpll_ck",
-+ "tvdpll_d2",
-+ "tvdpll_d4"
-+};
-+
-+static const char * const dpi1_parents[] __initconst = {
-+ "clk26m",
-+ "tvdpll_ck",
-+ "tvdpll_d2",
-+ "tvdpll_d4"
-+};
-+
-+static const char * const tve_parents[] __initconst = {
-+ "clk26m",
-+ "mipipll",
-+ "mipipll_d2",
-+ "mipipll_d4",
-+ "clk26m",
-+ "tvdpll_ck",
-+ "tvdpll_d2",
-+ "tvdpll_d4"
-+};
-+
-+static const char * const hdmi_parents[] __initconst = {
-+ "clk26m",
-+ "hdmipll_ck",
-+ "hdmipll_d2",
-+ "hdmipll_d3"
-+};
-+
-+static const char * const apll_parents[] __initconst = {
-+ "clk26m",
-+ "audpll",
-+ "audpll_d4",
-+ "audpll_d8",
-+ "audpll_d16",
-+ "audpll_d24",
-+ "clk26m",
-+ "clk26m"
-+};
-+
-+static const char * const rtc_parents[] __initconst = {
-+ "32k_internal",
-+ "32k_external",
-+ "clk26m",
-+ "univpll3_d8"
-+};
-+
-+static const char * const nfi2x_parents[] __initconst = {
-+ "clk26m",
-+ "syspll2_d2",
-+ "syspll_d7",
-+ "univpll3_d2",
-+ "syspll2_d4",
-+ "univpll3_d4",
-+ "syspll4_d4",
-+ "clk26m"
-+};
-+
-+static const char * const emmc_hclk_parents[] __initconst = {
-+ "clk26m",
-+ "syspll1_d2",
-+ "syspll1_d4",
-+ "syspll2_d2"
-+};
-+
-+static const char * const flash_parents[] __initconst = {
-+ "clk26m_d8",
-+ "clk26m",
-+ "syspll2_d8",
-+ "syspll3_d4",
-+ "univpll3_d4",
-+ "syspll4_d2",
-+ "syspll2_d4",
-+ "univpll2_d4"
-+};
-+
-+static const char * const di_parents[] __initconst = {
-+ "clk26m",
-+ "tvd2pll_ck",
-+ "tvd2pll_d2",
-+ "clk26m"
-+};
-+
-+static const char * const nr_osd_parents[] __initconst = {
-+ "clk26m",
-+ "vencpll_ck",
-+ "syspll1_d2",
-+ "syspll1_d4",
-+ "univpll_d5",
-+ "univpll1_d2",
-+ "univpll2_d2",
-+ "dmpll_ck"
-+};
-+
-+static const char * const hdmirx_bist_parents[] __initconst = {
-+ "clk26m",
-+ "syspll_d3",
-+ "clk26m",
-+ "syspll1_d16",
-+ "syspll4_d2",
-+ "syspll1_d4",
-+ "vencpll_ck",
-+ "clk26m"
-+};
-+
-+static const char * const intdir_parents[] __initconst = {
-+ "clk26m",
-+ "mmpll_ck",
-+ "syspll_d2",
-+ "univpll_d2"
-+};
-+
-+static const char * const asm_parents[] __initconst = {
-+ "clk26m",
-+ "univpll2_d4",
-+ "univpll2_d2",
-+ "syspll_d5"
-+};
-+
-+static const char * const ms_card_parents[] __initconst = {
-+ "clk26m",
-+ "univpll3_d8",
-+ "syspll4_d4"
-+};
-+
-+static const char * const ethif_parents[] __initconst = {
-+ "clk26m",
-+ "syspll1_d2",
-+ "syspll_d5",
-+ "syspll1_d4",
-+ "univpll_d5",
-+ "univpll1_d2",
-+ "dmpll_ck",
-+ "dmpll_d2"
-+};
-+
-+static const char * const hdmirx_parents[] __initconst = {
-+ "clk26m",
-+ "univpll_d52"
-+};
-+
-+static const char * const cmsys_parents[] __initconst = {
-+ "clk26m",
-+ "syspll1_d2",
-+ "univpll1_d2",
-+ "univpll_d5",
-+ "syspll_d5",
-+ "syspll2_d2",
-+ "syspll1_d4",
-+ "syspll3_d2",
-+ "syspll2_d4",
-+ "syspll1_d8",
-+ "clk26m",
-+ "clk26m",
-+ "clk26m",
-+ "clk26m",
-+ "clk26m"
-+};
-+
-+static const char * const clk_8bdac_parents[] __initconst = {
-+ "clkrtc_int",
-+ "8bdac_ck_pre",
-+ "clk26m",
-+ "clk26m"
-+};
-+
-+static const char * const aud2dvd_parents[] __initconst = {
-+ "a1sys_hp_ck",
-+ "a2sys_hp_ck"
-+};
-+
-+static const char * const padmclk_parents[] __initconst = {
-+ "clk26m",
-+ "univpll_d26",
-+ "univpll_d52",
-+ "univpll_d108",
-+ "univpll2_d8",
-+ "univpll2_d16",
-+ "univpll2_d32"
-+};
-+
-+static const char * const aud_mux_parents[] __initconst = {
-+ "clk26m",
-+ "aud1pll_98m_ck",
-+ "aud2pll_90m_ck",
-+ "hadds2pll_98m",
-+ "audio_ext1_ck",
-+ "audio_ext2_ck"
-+};
-+
-+static const char * const aud_src_parents[] __initconst = {
-+ "aud_mux1_sel",
-+ "aud_mux2_sel"
-+};
-+
-+static const char * const cpu_parents[] __initconst = {
-+ "clk26m",
-+ "armpll",
-+ "mainpll",
-+ "mmpll"
-+};
-+
-+static const struct mtk_composite top_muxes[] __initconst = {
-+ MUX_GATE(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
-+ 0x0040, 0, 3, INVALID_MUX_GATE_BIT),
-+ MUX_GATE(CLK_TOP_MEM_SEL, "mem_sel", mem_parents, 0x0040, 8, 1, 15),
-+ MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents, 0x0040, 16, 1, 23),
-+ MUX_GATE(CLK_TOP_MM_SEL, "mm_sel", mm_parents, 0x0040, 24, 3, 31),
-+
-+ MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x0050, 0, 2, 7),
-+ MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x0050, 8, 4, 15),
-+ MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0050, 16, 3, 23),
-+ MUX_GATE(CLK_TOP_CAMTG_SEL, "camtg_sel", camtg_parents, 0x0050, 24, 3, 31),
-+ MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x0060, 0, 1, 7),
-+
-+ MUX_GATE(CLK_TOP_SPI0_SEL, "spi0_sel", spi_parents, 0x0060, 8, 3, 15),
-+ MUX_GATE(CLK_TOP_USB20_SEL, "usb20_sel", usb20_parents, 0x0060, 16, 2, 23),
-+ MUX_GATE(CLK_TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_parents, 0x0060, 24, 3, 31),
-+
-+ MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_parents, 0x0070, 0, 3, 7),
-+ MUX_GATE(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_parents, 0x0070, 8, 3, 15),
-+ MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", msdc30_parents, 0x0070, 16, 1, 23),
-+ MUX_GATE(CLK_TOP_AUDINTBUS_SEL, "aud_intbus_sel", aud_intbus_parents, 0x0070, 24, 3, 31),
-+
-+ MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, 0x0080, 0, 4, 7),
-+ MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel", scp_parents, 0x0080, 8, 2, 15),
-+ MUX_GATE(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_parents, 0x0080, 16, 3, 23),
-+ MUX_GATE(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents, 0x0080, 24, 2, 31),
-+
-+ MUX_GATE(CLK_TOP_TVE_SEL, "tve_sel", tve_parents, 0x0090, 0, 3, 7),
-+ MUX_GATE(CLK_TOP_HDMI_SEL, "hdmi_sel", hdmi_parents, 0x0090, 8, 2, 15),
-+ MUX_GATE(CLK_TOP_APLL_SEL, "apll_sel", apll_parents, 0x0090, 16, 3, 23),
-+
-+ MUX_GATE(CLK_TOP_RTC_SEL, "rtc_sel", rtc_parents, 0x00A0, 0, 2, 7),
-+ MUX_GATE(CLK_TOP_NFI2X_SEL, "nfi2x_sel", nfi2x_parents, 0x00A0, 8, 3, 15),
-+ MUX_GATE(CLK_TOP_EMMC_HCLK_SEL, "emmc_hclk_sel", emmc_hclk_parents, 0x00A0, 24, 2, 31),
-+
-+ MUX_GATE(CLK_TOP_FLASH_SEL, "flash_sel", flash_parents, 0x00B0, 0, 3, 7),
-+ MUX_GATE(CLK_TOP_DI_SEL, "di_sel", di_parents, 0x00B0, 8, 2, 15),
-+ MUX_GATE(CLK_TOP_NR_SEL, "nr_sel", nr_osd_parents, 0x00B0, 16, 3, 23),
-+ MUX_GATE(CLK_TOP_OSD_SEL, "osd_sel", nr_osd_parents, 0x00B0, 24, 3, 31),
-+
-+ MUX_GATE(CLK_TOP_HDMIRX_BIST_SEL, "hdmirx_bist_sel", hdmirx_bist_parents, 0x00C0, 0, 3, 7),
-+ MUX_GATE(CLK_TOP_INTDIR_SEL, "intdir_sel", intdir_parents, 0x00C0, 8, 2, 15),
-+ MUX_GATE(CLK_TOP_ASM_I_SEL, "asm_i_sel", asm_parents, 0x00C0, 16, 2, 23),
-+ MUX_GATE(CLK_TOP_ASM_M_SEL, "asm_m_sel", asm_parents, 0x00C0, 24, 3, 31),
-+
-+ MUX_GATE(CLK_TOP_ASM_H_SEL, "asm_h_sel", asm_parents, 0x00D0, 0, 2, 7),
-+ MUX_GATE(CLK_TOP_MS_CARD_SEL, "ms_card_sel", ms_card_parents, 0x00D0, 16, 2, 23),
-+ MUX_GATE(CLK_TOP_ETHIF_SEL, "ethif_sel", ethif_parents, 0x00D0, 24, 3, 31),
-+
-+ MUX_GATE(CLK_TOP_HDMIRX26_24_SEL, "hdmirx26_24_sel", hdmirx_parents, 0x00E0, 0, 1, 7),
-+ MUX_GATE(CLK_TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_parents, 0x00E0, 8, 3, 15),
-+ MUX_GATE(CLK_TOP_CMSYS_SEL, "cmsys_sel", cmsys_parents, 0x00E0, 16, 4, 23),
-+
-+ MUX_GATE(CLK_TOP_SPI1_SEL, "spi2_sel", spi_parents, 0x00E0, 24, 3, 31),
-+ MUX_GATE(CLK_TOP_SPI2_SEL, "spi1_sel", spi_parents, 0x00F0, 0, 3, 7),
-+ MUX_GATE(CLK_TOP_8BDAC_SEL, "8bdac_sel", clk_8bdac_parents, 0x00F0, 8, 2, 15),
-+ MUX_GATE(CLK_TOP_AUD2DVD_SEL, "aud2dvd_sel", aud2dvd_parents, 0x00F0, 16, 1, 23),
-+
-+ MUX(CLK_TOP_PADMCLK_SEL, "padmclk_sel", padmclk_parents, 0x0100, 0, 3),
-+
-+ MUX(CLK_TOP_AUD_MUX1_SEL, "aud_mux1_sel", aud_mux_parents, 0x012c, 0, 3),
-+ MUX(CLK_TOP_AUD_MUX2_SEL, "aud_mux2_sel", aud_mux_parents, 0x012c, 3, 3),
-+ MUX(CLK_TOP_AUDPLL_MUX_SEL, "audpll_sel", aud_mux_parents, 0x012c, 6, 3),
-+ MUX_GATE(CLK_TOP_AUD_K1_SRC_SEL, "aud_k1_src_sel", aud_src_parents, 0x012c, 15, 1, 23),
-+ MUX_GATE(CLK_TOP_AUD_K2_SRC_SEL, "aud_k2_src_sel", aud_src_parents, 0x012c, 16, 1, 24),
-+ MUX_GATE(CLK_TOP_AUD_K3_SRC_SEL, "aud_k3_src_sel", aud_src_parents, 0x012c, 17, 1, 25),
-+ MUX_GATE(CLK_TOP_AUD_K4_SRC_SEL, "aud_k4_src_sel", aud_src_parents, 0x012c, 18, 1, 26),
-+ MUX_GATE(CLK_TOP_AUD_K5_SRC_SEL, "aud_k5_src_sel", aud_src_parents, 0x012c, 19, 1, 27),
-+ MUX_GATE(CLK_TOP_AUD_K6_SRC_SEL, "aud_k6_src_sel", aud_src_parents, 0x012c, 20, 1, 28),
-+};
-+
-+static const struct mtk_clk_divider top_adj_divs[] __initconst = {
-+ DIV_ADJ(CLK_TOP_AUD_EXTCK1_DIV, "audio_ext1_ck", "aud_ext_ck1", 0x0120, 0, 8),
-+ DIV_ADJ(CLK_TOP_AUD_EXTCK2_DIV, "audio_ext2_ck", "aud_ext_ck2", 0x0120, 8, 8),
-+ DIV_ADJ(CLK_TOP_AUD_MUX1_DIV, "aud_mux1_div", "aud_mux1_sel", 0x0120, 16, 8),
-+ DIV_ADJ(CLK_TOP_AUD_MUX2_DIV, "aud_mux2_div", "aud_mux2_sel", 0x0120, 24, 8),
-+ DIV_ADJ(CLK_TOP_AUD_K1_SRC_DIV, "aud_k1_src_div", "aud_k1_src_sel", 0x0124, 0, 8),
-+ DIV_ADJ(CLK_TOP_AUD_K2_SRC_DIV, "aud_k2_src_div", "aud_k2_src_sel", 0x0124, 8, 8),
-+ DIV_ADJ(CLK_TOP_AUD_K3_SRC_DIV, "aud_k3_src_div", "aud_k3_src_sel", 0x0124, 16, 8),
-+ DIV_ADJ(CLK_TOP_AUD_K4_SRC_DIV, "aud_k4_src_div", "aud_k4_src_sel", 0x0124, 24, 8),
-+ DIV_ADJ(CLK_TOP_AUD_K5_SRC_DIV, "aud_k5_src_div", "aud_k5_src_sel", 0x0128, 0, 8),
-+ DIV_ADJ(CLK_TOP_AUD_K6_SRC_DIV, "aud_k6_src_div", "aud_k6_src_sel", 0x0128, 8, 8),
-+};
-+
-+static const struct mtk_gate_regs top_aud_cg_regs __initconst = {
-+ .sta_ofs = 0x012C,
-+};
-+
-+#define GATE_TOP_AUD(_id, _name, _parent, _shift) { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = &top_aud_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_no_setclr, \
-+ }
-+
-+static const struct mtk_gate top_clks[] __initconst = {
-+ GATE_TOP_AUD(CLK_TOP_AUD_48K_TIMING, "a1sys_hp_ck", "aud_mux1_div", 21),
-+ GATE_TOP_AUD(CLK_TOP_AUD_44K_TIMING, "a2sys_hp_ck", "aud_mux2_div", 22),
-+ GATE_TOP_AUD(CLK_TOP_AUD_I2S1_MCLK, "aud_i2s1_mclk", "aud_k1_src_div", 23),
-+ GATE_TOP_AUD(CLK_TOP_AUD_I2S2_MCLK, "aud_i2s2_mclk", "aud_k2_src_div", 24),
-+ GATE_TOP_AUD(CLK_TOP_AUD_I2S3_MCLK, "aud_i2s3_mclk", "aud_k3_src_div", 25),
-+ GATE_TOP_AUD(CLK_TOP_AUD_I2S4_MCLK, "aud_i2s4_mclk", "aud_k4_src_div", 26),
-+ GATE_TOP_AUD(CLK_TOP_AUD_I2S5_MCLK, "aud_i2s5_mclk", "aud_k5_src_div", 27),
-+ GATE_TOP_AUD(CLK_TOP_AUD_I2S6_MCLK, "aud_i2s6_mclk", "aud_k6_src_div", 28),
-+};
-+
-+static void __init mtk_topckgen_init(struct device_node *node)
-+{
-+ struct clk_onecell_data *clk_data;
-+ void __iomem *base;
-+ int r;
-+
-+ base = of_iomap(node, 0);
-+ if (!base) {
-+ pr_err("%s(): ioremap failed\n", __func__);
-+ return;
-+ }
-+
-+ clk_data = mtk_alloc_clk_data(CLK_TOP_NR);
-+
-+ mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
-+ clk_data);
-+
-+ mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs),
-+ clk_data);
-+
-+ mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes),
-+ base, &lock, clk_data);
-+
-+ mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
-+ base, &lock, clk_data);
-+
-+ mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
-+ clk_data);
-+
-+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-+ if (r)
-+ pr_err("%s(): could not register clock provider: %d\n",
-+ __func__, r);
-+}
-+CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt2701-topckgen", mtk_topckgen_init);
-+
-+static const struct mtk_gate_regs infra_cg_regs __initconst = {
-+ .set_ofs = 0x0040,
-+ .clr_ofs = 0x0044,
-+ .sta_ofs = 0x0048,
-+};
-+
-+#define GATE_ICG(_id, _name, _parent, _shift) { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = &infra_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_setclr, \
-+ }
-+
-+static const struct mtk_gate infra_clks[] __initconst = {
-+ GATE_ICG(CLK_INFRA_DBG, "dbgclk", "axi_sel", 0),
-+ GATE_ICG(CLK_INFRA_SMI, "smi_ck", "mm_sel", 1),
-+ GATE_ICG(CLK_INFRA_QAXI_CM4, "cm4_ck", "axi_sel", 2),
-+ GATE_ICG(CLK_INFRA_AUD_SPLIN_B, "audio_splin_bck", "hadds2_294m_ck", 4),
-+ GATE_ICG(CLK_INFRA_AUDIO, "audio_ck", "clk_null", 5),
-+ GATE_ICG(CLK_INFRA_EFUSE, "efuse_ck", "clk26m", 6),
-+ GATE_ICG(CLK_INFRA_L2C_SRAM, "l2c_sram_ck", "mm_sel", 7),
-+ GATE_ICG(CLK_INFRA_M4U, "m4u_ck", "mem_sel", 8),
-+ GATE_ICG(CLK_INFRA_CONNMCU, "connsys_bus", "wbg_dig_ck_416m", 12),
-+ GATE_ICG(CLK_INFRA_TRNG, "trng_ck", "axi_sel", 13),
-+ GATE_ICG(CLK_INFRA_RAMBUFIF, "rambufif_ck", "mem_sel", 14),
-+ GATE_ICG(CLK_INFRA_CPUM, "cpum_ck", "mem_sel", 15),
-+ GATE_ICG(CLK_INFRA_KP, "kp_ck", "axi_sel", 16),
-+ GATE_ICG(CLK_INFRA_CEC, "cec_ck", "rtc_sel", 18),
-+ GATE_ICG(CLK_INFRA_IRRX, "irrx_ck", "axi_sel", 19),
-+ GATE_ICG(CLK_INFRA_PMICSPI, "pmicspi_ck", "pmicspi_sel", 22),
-+ GATE_ICG(CLK_INFRA_PMICWRAP, "pmicwrap_ck", "axi_sel", 23),
-+ GATE_ICG(CLK_INFRA_DDCCI, "ddcci_ck", "axi_sel", 24),
-+};
-+
-+static const struct mtk_fixed_factor infra_fixed_divs[] __initconst = {
-+ FACTOR(CLK_INFRA_CLK_13M, "clk13m", "clk26m", 1, 2),
-+};
-+
-+static void __init mtk_infrasys_init(struct device_node *node)
-+{
-+ struct clk_onecell_data *clk_data;
-+ int r;
-+
-+ clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
-+
-+ mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
-+ clk_data);
-+ mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
-+ clk_data);
-+
-+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-+ if (r)
-+ pr_err("%s(): could not register clock provider: %d\n",
-+ __func__, r);
-+}
-+CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt2701-infracfg", mtk_infrasys_init);
-+
-+static const struct mtk_gate_regs peri0_cg_regs __initconst = {
-+ .set_ofs = 0x0008,
-+ .clr_ofs = 0x0010,
-+ .sta_ofs = 0x0018,
-+};
-+
-+static const struct mtk_gate_regs peri1_cg_regs __initconst = {
-+ .set_ofs = 0x000c,
-+ .clr_ofs = 0x0014,
-+ .sta_ofs = 0x001c,
-+};
-+
-+#define GATE_PERI0(_id, _name, _parent, _shift) { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = &peri0_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_setclr, \
-+ }
-+
-+#define GATE_PERI1(_id, _name, _parent, _shift) { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = &peri1_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_setclr, \
-+ }
-+
-+static const struct mtk_gate peri_clks[] __initconst = {
-+ GATE_PERI1(CLK_PERI_USB0_MCU, "usb0_mcu_ck", "axi_sel", 31),
-+ GATE_PERI1(CLK_PERI_ETH, "eth_ck", "clk26m", 30),
-+ GATE_PERI1(CLK_PERI_SPI0, "spi0_ck", "spi0_sel", 29),
-+ GATE_PERI1(CLK_PERI_AUXADC, "auxadc_ck", "clk26m", 28),
-+ GATE_PERI0(CLK_PERI_I2C3, "i2c3_ck", "clk26m", 27),
-+ GATE_PERI0(CLK_PERI_I2C2, "i2c2_ck", "axi_sel", 26),
-+ GATE_PERI0(CLK_PERI_I2C1, "i2c1_ck", "axi_sel", 25),
-+ GATE_PERI0(CLK_PERI_I2C0, "i2c0_ck", "axi_sel", 24),
-+ GATE_PERI0(CLK_PERI_BTIF, "bitif_ck", "axi_sel", 23),
-+ GATE_PERI0(CLK_PERI_UART3, "uart3_ck", "axi_sel", 22),
-+ GATE_PERI0(CLK_PERI_UART2, "uart2_ck", "axi_sel", 21),
-+ GATE_PERI0(CLK_PERI_UART1, "uart1_ck", "axi_sel", 20),
-+ GATE_PERI0(CLK_PERI_UART0, "uart0_ck", "axi_sel", 19),
-+ GATE_PERI0(CLK_PERI_NLI, "nli_ck", "axi_sel", 18),
-+ GATE_PERI0(CLK_PERI_MSDC50_3, "msdc50_3_ck", "emmc_hclk_sel", 17),
-+ GATE_PERI0(CLK_PERI_MSDC30_3, "msdc30_3_ck", "msdc30_3_sel", 16),
-+ GATE_PERI0(CLK_PERI_MSDC30_2, "msdc30_2_ck", "msdc30_2_sel", 15),
-+ GATE_PERI0(CLK_PERI_MSDC30_1, "msdc30_1_ck", "msdc30_1_sel", 14),
-+ GATE_PERI0(CLK_PERI_MSDC30_0, "msdc30_0_ck", "msdc30_0_sel", 13),
-+ GATE_PERI0(CLK_PERI_AP_DMA, "ap_dma_ck", "axi_sel", 12),
-+ GATE_PERI0(CLK_PERI_USB1, "usb1_ck", "usb20_sel", 11),
-+ GATE_PERI0(CLK_PERI_USB0, "usb0_ck", "usb20_sel", 10),
-+ GATE_PERI0(CLK_PERI_PWM, "pwm_ck", "axi_sel", 9),
-+ GATE_PERI0(CLK_PERI_PWM7, "pwm7_ck", "axi_sel", 8),
-+ GATE_PERI0(CLK_PERI_PWM6, "pwm6_ck", "axi_sel", 7),
-+ GATE_PERI0(CLK_PERI_PWM5, "pwm5_ck", "axi_sel", 6),
-+ GATE_PERI0(CLK_PERI_PWM4, "pwm4_ck", "axi_sel", 5),
-+ GATE_PERI0(CLK_PERI_PWM3, "pwm3_ck", "axi_sel", 4),
-+ GATE_PERI0(CLK_PERI_PWM2, "pwm2_ck", "axi_sel", 3),
-+ GATE_PERI0(CLK_PERI_PWM1, "pwm1_ck", "axi_sel", 2),
-+ GATE_PERI0(CLK_PERI_THERM, "therm_ck", "axi_sel", 1),
-+ GATE_PERI0(CLK_PERI_NFI, "nfi_ck", "nfi2x_sel", 0),
-+
-+ GATE_PERI1(CLK_PERI_FCI, "fci_ck", "ms_card", 11),
-+ GATE_PERI1(CLK_PERI_SPI2, "spi2_ck", "spi2_sel", 10),
-+ GATE_PERI1(CLK_PERI_SPI1, "spi1_ck", "spi1_sel", 9),
-+ GATE_PERI1(CLK_PERI_HOST89_DVD, "host89_dvd_ck", "aud2dvd_sel", 8),
-+ GATE_PERI1(CLK_PERI_HOST89_SPI, "host89_spi_ck", "spi0_sel", 7),
-+ GATE_PERI1(CLK_PERI_HOST89_INT, "host89_int_ck", "axi_sel", 6),
-+ GATE_PERI1(CLK_PERI_FLASH, "flash_ck", "nfi2x_sel", 5),
-+ GATE_PERI1(CLK_PERI_NFI_PAD, "nfi_pad_ck", "nfi_sel", 4),
-+ GATE_PERI1(CLK_PERI_NFI_ECC, "nfi_ecc_ck", "nfi_sel", 3),
-+ GATE_PERI1(CLK_PERI_GCPU, "gcpu_ck", "axi_sel", 2),
-+ GATE_PERI1(CLK_PERI_USB_SLV, "usbslv_ck", "axi_sel", 1),
-+ GATE_PERI1(CLK_PERI_USB1_MCU, "usb1_mcu_ck", "axi_sel", 0),
-+};
-+
-+static const char * const uart_ck_sel_parents[] __initconst = {
-+ "clk26m",
-+ "uart_sel",
-+};
-+
-+static const struct mtk_composite peri_muxs[] __initconst = {
-+ MUX(CLK_PERI_UART0_SEL, "uart0_ck_sel", uart_ck_sel_parents, 0x40c, 0, 1),
-+ MUX(CLK_PERI_UART1_SEL, "uart1_ck_sel", uart_ck_sel_parents, 0x40c, 1, 1),
-+ MUX(CLK_PERI_UART2_SEL, "uart2_ck_sel", uart_ck_sel_parents, 0x40c, 2, 1),
-+ MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1),
-+};
-+
-+static void __init mtk_pericfg_init(struct device_node *node)
-+{
-+ struct clk_onecell_data *clk_data;
-+ void __iomem *base;
-+ int r;
-+
-+ base = of_iomap(node, 0);
-+ if (!base) {
-+ pr_err("%s(): ioremap failed\n", __func__);
-+ return;
-+ }
-+
-+ clk_data = mtk_alloc_clk_data(CLK_PERI_NR);
-+
-+ mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
-+ clk_data);
-+
-+ mtk_clk_register_composites(peri_muxs, ARRAY_SIZE(peri_muxs), base,
-+ &lock, clk_data);
-+
-+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-+ if (r)
-+ pr_err("%s(): could not register clock provider: %d\n",
-+ __func__, r);
-+}
-+CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt2701-pericfg", mtk_pericfg_init);
-+
-+static const struct mtk_gate_regs disp0_cg_regs __initconst = {
-+ .set_ofs = 0x0104,
-+ .clr_ofs = 0x0108,
-+ .sta_ofs = 0x0100,
-+};
-+
-+static const struct mtk_gate_regs disp1_cg_regs __initconst = {
-+ .set_ofs = 0x0114,
-+ .clr_ofs = 0x0118,
-+ .sta_ofs = 0x0110,
-+};
-+
-+#define GATE_DISP0(_id, _name, _parent, _shift) { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = &disp0_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_setclr, \
-+ }
-+
-+#define GATE_DISP1(_id, _name, _parent, _shift) { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = &disp1_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_setclr, \
-+ }
-+
-+static const struct mtk_gate mm_clks[] __initconst = {
-+ GATE_DISP0(CLK_MM_SMI_COMMON, "mm_smi_comm", "mm_sel", 0),
-+ GATE_DISP0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1),
-+ GATE_DISP0(CLK_MM_CMDQ, "mm_cmdq", "mm_sel", 2),
-+ GATE_DISP0(CLK_MM_MUTEX, "mm_mutex", "mm_sel", 3),
-+ GATE_DISP0(CLK_MM_DISP_COLOR, "mm_disp_color", "mm_sel", 4),
-+ GATE_DISP0(CLK_MM_DISP_BLS, "mm_disp_bls", "mm_sel", 5),
-+ GATE_DISP0(CLK_MM_DISP_WDMA, "mm_disp_wdma", "mm_sel", 6),
-+ GATE_DISP0(CLK_MM_DISP_RDMA, "mm_disp_rdma", "mm_sel", 7),
-+ GATE_DISP0(CLK_MM_DISP_OVL, "mm_disp_ovl", "mm_sel", 8),
-+ GATE_DISP0(CLK_MM_MDP_TDSHP, "mm_mdp_tdshp", "mm_sel", 9),
-+ GATE_DISP0(CLK_MM_MDP_WROT, "mm_mdp_wrot", "mm_sel", 10),
-+ GATE_DISP0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "mm_sel", 11),
-+ GATE_DISP0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 12),
-+ GATE_DISP0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 13),
-+ GATE_DISP0(CLK_MM_MDP_RDMA, "mm_mdp_rdma", "mm_sel", 14),
-+ GATE_DISP0(CLK_MM_MDP_BLS_26M, "mm_mdp_bls_26m", "clk26m", 15),
-+ GATE_DISP0(CLK_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 16),
-+ GATE_DISP0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 17),
-+ GATE_DISP0(CLK_MM_MUTEX_32K, "mm_mutex_32k", "rtc_sel", 18),
-+ GATE_DISP0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 19),
-+ GATE_DISP0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "mm_sel", 20),
-+ GATE_DISP1(CLK_MM_DSI_ENGINE, "mm_dsi_eng", "mm_sel", 0),
-+ GATE_DISP1(CLK_MM_DSI_DIG, "mm_dsi_dig", "dsio_lntc_dsiclk", 1),
-+ GATE_DISP1(CLK_MM_DPI_DIGL, "mm_dpi_digl", "dpi0_sel", 2),
-+ GATE_DISP1(CLK_MM_DPI_ENGINE, "mm_dpi_eng", "mm_sel", 3),
-+ GATE_DISP1(CLK_MM_DPI1_DIGL, "mm_dpi1_digl", "dpi1_sel", 4),
-+ GATE_DISP1(CLK_MM_DPI1_ENGINE, "mm_dpi1_eng", "mm_sel", 5),
-+ GATE_DISP1(CLK_MM_TVE_OUTPUT, "mm_tve_output", "tve_sel", 6),
-+ GATE_DISP1(CLK_MM_TVE_INPUT, "mm_tve_input", "dpi0_sel", 7),
-+ GATE_DISP1(CLK_MM_HDMI_PIXEL, "mm_hdmi_pixel", "dpi1_sel", 8),
-+ GATE_DISP1(CLK_MM_HDMI_PLL, "mm_hdmi_pll", "hdmi_sel", 9),
-+ GATE_DISP1(CLK_MM_HDMI_AUDIO, "mm_hdmi_audio", "apll_sel", 10),
-+ GATE_DISP1(CLK_MM_HDMI_SPDIF, "mm_hdmi_spdif", "apll_sel", 11),
-+ GATE_DISP1(CLK_MM_TVE_FMM, "mm_tve_fmm", "mm_sel", 14),
-+};
-+
-+static void __init mtk_mmsys_init(struct device_node *node)
-+{
-+ struct clk_onecell_data *clk_data;
-+ int r;
-+
-+ clk_data = mtk_alloc_clk_data(CLK_MM_NR);
-+
-+ mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
-+ clk_data);
-+
-+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-+ if (r)
-+ pr_err("%s(): could not register clock provider: %d\n",
-+ __func__, r);
-+}
-+CLK_OF_DECLARE(mtk_mmsys, "mediatek,mt2701-mmsys", mtk_mmsys_init);
-+
-+static const struct mtk_gate_regs img_cg_regs __initconst = {
-+ .set_ofs = 0x0004,
-+ .clr_ofs = 0x0008,
-+ .sta_ofs = 0x0000,
-+};
-+
-+#define GATE_IMG(_id, _name, _parent, _shift) { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = &img_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_setclr, \
-+ }
-+
-+static const struct mtk_gate img_clks[] __initconst = {
-+ GATE_IMG(CLK_IMG_SMI_COMM, "img_smi_comm", "mm_sel", 0),
-+ GATE_IMG(CLK_IMG_RESZ, "img_resz", "mm_sel", 1),
-+ GATE_IMG(CLK_IMG_JPGDEC, "img_jpgdec", "mm_sel", 5),
-+ GATE_IMG(CLK_IMG_VENC_LT, "img_venc_lt", "mm_sel", 8),
-+ GATE_IMG(CLK_IMG_VENC, "img_venc", "mm_sel", 9),
-+};
-+
-+static void __init mtk_imgsys_init(struct device_node *node)
-+{
-+ struct clk_onecell_data *clk_data;
-+ int r;
-+
-+ clk_data = mtk_alloc_clk_data(CLK_IMG_NR);
-+
-+ mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
-+ clk_data);
-+
-+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-+ if (r)
-+ pr_err("%s(): could not register clock provider: %d\n",
-+ __func__, r);
-+}
-+CLK_OF_DECLARE(mtk_imgsys, "mediatek,mt2701-imgsys", mtk_imgsys_init);
-+
-+static const struct mtk_gate_regs vdec0_cg_regs __initconst = {
-+ .set_ofs = 0x0000,
-+ .clr_ofs = 0x0004,
-+ .sta_ofs = 0x0000,
-+};
-+
-+static const struct mtk_gate_regs vdec1_cg_regs __initconst = {
-+ .set_ofs = 0x0008,
-+ .clr_ofs = 0x000c,
-+ .sta_ofs = 0x0008,
-+};
-+
-+#define GATE_VDEC0(_id, _name, _parent, _shift) { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = &vdec0_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_setclr_inv, \
-+ }
-+
-+#define GATE_VDEC1(_id, _name, _parent, _shift) { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = &vdec1_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_setclr_inv, \
-+ }
-+
-+static const struct mtk_gate vdec_clks[] __initconst = {
-+ GATE_VDEC0(CLK_VDEC_CKGEN, "vdec_cken", "vdec_sel", 0),
-+ GATE_VDEC1(CLK_VDEC_LARB, "vdec_larb_cken", "mm_sel", 0),
-+};
-+
-+static void __init mtk_vdecsys_init(struct device_node *node)
-+{
-+ struct clk_onecell_data *clk_data;
-+ int r;
-+
-+ clk_data = mtk_alloc_clk_data(CLK_VDEC_NR);
-+
-+ mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
-+ clk_data);
-+
-+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-+ if (r)
-+ pr_err("%s(): could not register clock provider: %d\n",
-+ __func__, r);
-+}
-+CLK_OF_DECLARE(mtk_vdecsys, "mediatek,mt2701-vdecsys", mtk_vdecsys_init);
-+
-+static const struct mtk_gate_regs hif_cg_regs __initconst = {
-+ .sta_ofs = 0x0008,
-+};
-+
-+#define GATE_HIF(_id, _name, _parent, _shift) { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = &hif_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \
-+ }
-+
-+static const struct mtk_gate hif_clks[] __initconst = {
-+ GATE_HIF(CLK_HIFSYS_USB0PHY, "usb0_phy_clk", "ethpll_500m_ck", 21),
-+ GATE_HIF(CLK_HIFSYS_USB1PHY, "usb1_phy_clk", "ethpll_500m_ck", 22),
-+ GATE_HIF(CLK_HIFSYS_PCIE0, "pcie0_clk", "ethpll_500m_ck", 24),
-+ GATE_HIF(CLK_HIFSYS_PCIE1, "pcie1_clk", "ethpll_500m_ck", 25),
-+ GATE_HIF(CLK_HIFSYS_PCIE2, "pcie2_clk", "ethpll_500m_ck", 26),
-+};
-+
-+static void __init mtk_hifsys_init(struct device_node *node)
-+{
-+ struct clk_onecell_data *clk_data;
-+ int r;
-+
-+ clk_data = mtk_alloc_clk_data(CLK_HIFSYS_NR);
-+
-+ mtk_clk_register_gates(node, hif_clks, ARRAY_SIZE(hif_clks),
-+ clk_data);
-+
-+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-+ if (r)
-+ pr_err("%s(): could not register clock provider: %d\n",
-+ __func__, r);
-+}
-+CLK_OF_DECLARE(mtk_hifsys, "mediatek,mt2701-hifsys", mtk_hifsys_init);
-+
-+static const struct mtk_gate_regs eth_cg_regs __initconst = {
-+ .sta_ofs = 0x0030,
-+};
-+
-+#define GATE_eth(_id, _name, _parent, _shift) { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = &eth_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \
-+ }
-+
-+static const struct mtk_gate eth_clks[] __initconst = {
-+ GATE_HIF(CLK_ETHSYS_HSDMA, "hsdma_clk", "ethif_sel", 5),
-+ GATE_HIF(CLK_ETHSYS_ESW, "esw_clk", "ethpll_500m_ck", 6),
-+ GATE_HIF(CLK_ETHSYS_GP2, "gp2_clk", "trgpll", 7),
-+ GATE_HIF(CLK_ETHSYS_GP1, "gp1_clk", "ethpll_500m_ck", 8),
-+ GATE_HIF(CLK_ETHSYS_PCM, "pcm_clk", "ethif_sel", 11),
-+ GATE_HIF(CLK_ETHSYS_GDMA, "gdma_clk", "ethif_sel", 14),
-+ GATE_HIF(CLK_ETHSYS_I2S, "i2s_clk", "ethif_sel", 17),
-+ GATE_HIF(CLK_ETHSYS_CRYPTO, "crypto_clk", "ethif_sel", 29),
-+};
-+
-+static void __init mtk_ethsys_init(struct device_node *node)
-+{
-+ struct clk_onecell_data *clk_data;
-+ int r;
-+
-+ clk_data = mtk_alloc_clk_data(CLK_ETHSYS_NR);
-+
-+ mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks),
-+ clk_data);
-+
-+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-+ if (r)
-+ pr_err("%s(): could not register clock provider: %d\n",
-+ __func__, r);
-+}
-+CLK_OF_DECLARE(mtk_ethsys, "mediatek,mt2701-ethsys", mtk_ethsys_init);
-+
-+static const struct mtk_gate_regs bdp0_cg_regs __initconst = {
-+ .set_ofs = 0x0104,
-+ .clr_ofs = 0x0108,
-+ .sta_ofs = 0x0100,
-+};
-+
-+static const struct mtk_gate_regs bdp1_cg_regs __initconst = {
-+ .set_ofs = 0x0114,
-+ .clr_ofs = 0x0118,
-+ .sta_ofs = 0x0110,
-+};
-+
-+#define GATE_BDP0(_id, _name, _parent, _shift) { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = &bdp0_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_setclr_inv, \
-+ }
-+
-+#define GATE_BDP1(_id, _name, _parent, _shift) { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = &bdp1_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_setclr_inv, \
-+ }
-+
-+static const struct mtk_gate bdp_clks[] __initconst = {
-+ GATE_BDP0(CLK_BDP_BRG_BA, "brg_baclk", "mm_sel", 0),
-+ GATE_BDP0(CLK_BDP_BRG_DRAM, "brg_dram", "mm_sel", 1),
-+ GATE_BDP0(CLK_BDP_LARB_DRAM, "larb_dram", "mm_sel", 2),
-+ GATE_BDP0(CLK_BDP_WR_VDI_PXL, "wr_vdi_pxl", "hdmi_0_deep340m", 3),
-+ GATE_BDP0(CLK_BDP_WR_VDI_DRAM, "wr_vdi_dram", "mm_sel", 4),
-+ GATE_BDP0(CLK_BDP_WR_B, "wr_bclk", "mm_sel", 5),
-+ GATE_BDP0(CLK_BDP_DGI_IN, "dgi_in", "dpi1_sel", 6),
-+ GATE_BDP0(CLK_BDP_DGI_OUT, "dgi_out", "dpi_sel", 7),
-+ GATE_BDP0(CLK_BDP_FMT_MAST_27, "fmt_mast_27", "dpi1_sel", 8),
-+ GATE_BDP0(CLK_BDP_FMT_B, "fmt_bclk", "mm_sel", 9),
-+ GATE_BDP0(CLK_BDP_OSD_B, "osd_bclk", "mm_sel", 10),
-+ GATE_BDP0(CLK_BDP_OSD_DRAM, "osd_dram", "mm_sel", 11),
-+ GATE_BDP0(CLK_BDP_OSD_AGENT, "osd_agent", "osd_sel", 12),
-+ GATE_BDP0(CLK_BDP_OSD_PXL, "osd_pxl", "dpi1_sel", 13),
-+ GATE_BDP0(CLK_BDP_RLE_B, "rle_bclk", "mm_sel", 14),
-+ GATE_BDP0(CLK_BDP_RLE_AGENT, "rle_agent", "mm_sel", 15),
-+ GATE_BDP0(CLK_BDP_RLE_DRAM, "rle_dram", "mm_sel", 16),
-+ GATE_BDP0(CLK_BDP_F27M, "f27m", "di_sel", 17),
-+ GATE_BDP0(CLK_BDP_F27M_VDOUT, "f27m_vdout", "di_sel", 18),
-+ GATE_BDP0(CLK_BDP_F27_74_74, "f27_74_74", "di_sel", 19),
-+ GATE_BDP0(CLK_BDP_F2FS, "f2fs", "di_sel", 20),
-+ GATE_BDP0(CLK_BDP_F2FS74_148, "f2fs74_148", "di_sel", 21),
-+ GATE_BDP0(CLK_BDP_FB, "fbclk", "mm_sel", 22),
-+ GATE_BDP0(CLK_BDP_VDO_DRAM, "vdo_dram", "mm_sel", 23),
-+ GATE_BDP0(CLK_BDP_VDO_2FS, "vdo_2fs", "di_sel", 24),
-+ GATE_BDP0(CLK_BDP_VDO_B, "vdo_bclk", "mm_sel", 25),
-+ GATE_BDP0(CLK_BDP_WR_DI_PXL, "wr_di_pxl", "di_sel", 26),
-+ GATE_BDP0(CLK_BDP_WR_DI_DRAM, "wr_di_dram", "mm_sel", 27),
-+ GATE_BDP0(CLK_BDP_WR_DI_B, "wr_di_bclk", "mm_sel", 28),
-+ GATE_BDP0(CLK_BDP_NR_PXL, "nr_pxl", "nr_sel", 29),
-+ GATE_BDP0(CLK_BDP_NR_DRAM, "nr_dram", "mm_sel", 30),
-+ GATE_BDP0(CLK_BDP_NR_B, "nr_bclk", "mm_sel", 31),
-+ GATE_BDP1(CLK_BDP_RX_F, "rx_fclk", "hadds2_fbclk", 0),
-+ GATE_BDP1(CLK_BDP_RX_X, "rx_xclk", "clk26m", 1),
-+ GATE_BDP1(CLK_BDP_RXPDT, "rxpdtclk", "hdmi_0_pix340m", 2),
-+ GATE_BDP1(CLK_BDP_RX_CSCL_N, "rx_cscl_n", "clk26m", 3),
-+ GATE_BDP1(CLK_BDP_RX_CSCL, "rx_cscl", "clk26m", 4),
-+ GATE_BDP1(CLK_BDP_RX_DDCSCL_N, "rx_ddcscl_n", "hdmi_scl_rx", 5),
-+ GATE_BDP1(CLK_BDP_RX_DDCSCL, "rx_ddcscl", "hdmi_scl_rx", 6),
-+ GATE_BDP1(CLK_BDP_RX_VCO, "rx_vcoclk", "hadds2pll_294m", 7),
-+ GATE_BDP1(CLK_BDP_RX_DP, "rx_dpclk", "hdmi_0_pll340m", 8),
-+ GATE_BDP1(CLK_BDP_RX_P, "rx_pclk", "hdmi_0_pll340m", 9),
-+ GATE_BDP1(CLK_BDP_RX_M, "rx_mclk", "hadds2pll_294m", 10),
-+ GATE_BDP1(CLK_BDP_RX_PLL, "rx_pllclk", "hdmi_0_pix340m", 11),
-+ GATE_BDP1(CLK_BDP_BRG_RT_B, "brg_rt_bclk", "mm_sel", 12),
-+ GATE_BDP1(CLK_BDP_BRG_RT_DRAM, "brg_rt_dram", "mm_sel", 13),
-+ GATE_BDP1(CLK_BDP_LARBRT_DRAM, "larbrt_dram", "mm_sel", 14),
-+ GATE_BDP1(CLK_BDP_TMDS_SYN, "tmds_syn", "hdmi_0_pll340m", 15),
-+ GATE_BDP1(CLK_BDP_HDMI_MON, "hdmi_mon", "hdmi_0_mon", 16),
-+};
-+
-+static void __init mtk_bdpsys_init(struct device_node *node)
-+{
-+ struct clk_onecell_data *clk_data;
-+ int r;
-+
-+ clk_data = mtk_alloc_clk_data(CLK_BDP_NR);
-+
-+ mtk_clk_register_gates(node, bdp_clks, ARRAY_SIZE(bdp_clks),
-+ clk_data);
-+
-+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-+ if (r)
-+ pr_err("%s(): could not register clock provider: %d\n",
-+ __func__, r);
-+}
-+CLK_OF_DECLARE(mtk_bdpsys, "mediatek,mt2701-bdpsys", mtk_bdpsys_init);
-+
-+#define MT8590_PLL_FMAX (2000 * MHZ)
-+#define CON0_MT8590_RST_BAR BIT(27)
-+
-+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, \
-+ _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \
-+ .id = _id, \
-+ .name = _name, \
-+ .reg = _reg, \
-+ .pwr_reg = _pwr_reg, \
-+ .en_mask = _en_mask, \
-+ .flags = _flags, \
-+ .rst_bar_mask = CON0_MT8590_RST_BAR, \
-+ .fmax = MT8590_PLL_FMAX, \
-+ .pcwbits = _pcwbits, \
-+ .pd_reg = _pd_reg, \
-+ .pd_shift = _pd_shift, \
-+ .tuner_reg = _tuner_reg, \
-+ .pcw_reg = _pcw_reg, \
-+ .pcw_shift = _pcw_shift, \
-+ }
-+
-+static const struct mtk_pll_data apmixed_plls[] = {
-+ PLL(CLK_APMIXED_ARMPLL, "armpll", 0x200, 0x20c, 0x80000001, 0,
-+ 21, 0x204, 24, 0x0, 0x204, 0),
-+ PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x210, 0x21c, 0xf0000001,
-+ HAVE_RST_BAR, 21, 0x210, 4, 0x0, 0x214, 0),
-+ PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x220, 0x22c, 0xf3000001,
-+ HAVE_RST_BAR, 7, 0x220, 4, 0x0, 0x224, 14),
-+ PLL(CLK_APMIXED_MMPLL, "mmpll", 0x230, 0x23c, 0x00000001, 0,
-+ 21, 0x230, 4, 0x0, 0x234, 0),
-+ PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x240, 0x24c, 0x00000001, 0,
-+ 21, 0x240, 4, 0x0, 0x244, 0),
-+ PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x250, 0x25c, 0x00000001, 0,
-+ 21, 0x250, 4, 0x0, 0x254, 0),
-+ PLL(CLK_APMIXED_AUD1PLL, "aud1pll", 0x270, 0x27c, 0x00000001, 0,
-+ 31, 0x270, 4, 0x0, 0x274, 0),
-+ PLL(CLK_APMIXED_TRGPLL, "trgpll", 0x280, 0x28c, 0x00000001, 0,
-+ 31, 0x280, 4, 0x0, 0x284, 0),
-+ PLL(CLK_APMIXED_ETHPLL, "ethpll", 0x290, 0x29c, 0x00000001, 0,
-+ 31, 0x290, 4, 0x0, 0x294, 0),
-+ PLL(CLK_APMIXED_VDECPLL, "vdecpll", 0x2a0, 0x2ac, 0x00000001, 0,
-+ 31, 0x2a0, 4, 0x0, 0x2a4, 0),
-+ PLL(CLK_APMIXED_HADDS2PLL, "hadds2pll", 0x2b0, 0x2bc, 0x00000001, 0,
-+ 31, 0x2b0, 4, 0x0, 0x2b4, 0),
-+ PLL(CLK_APMIXED_AUD2PLL, "aud2pll", 0x2c0, 0x2cc, 0x00000001, 0,
-+ 31, 0x2c0, 4, 0x0, 0x2c4, 0),
-+ PLL(CLK_APMIXED_TVD2PLL, "tvd2pll", 0x2d0, 0x2dc, 0x00000001, 0,
-+ 21, 0x2d0, 4, 0x0, 0x2d4, 0),
-+};
-+
-+static void __init mtk_apmixedsys_init(struct device_node *node)
-+{
-+ struct clk_onecell_data *clk_data;
-+ int r;
-+
-+ clk_data = mtk_alloc_clk_data(ARRAY_SIZE(apmixed_plls));
-+ if (!clk_data)
-+ return;
-+
-+ mtk_clk_register_plls(node, apmixed_plls, ARRAY_SIZE(apmixed_plls),
-+ clk_data);
-+
-+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-+ if (r)
-+ pr_err("%s(): could not register clock provider: %d\n",
-+ __func__, r);
-+}
-+CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt2701-apmixedsys",
-+ mtk_apmixedsys_init);
---- a/drivers/clk/mediatek/clk-mtk.c
-+++ b/drivers/clk/mediatek/clk-mtk.c
-@@ -244,3 +244,28 @@ void mtk_clk_register_composites(const s
- clk_data->clks[mc->id] = clk;
- }
- }
-+
-+void __init mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
-+ int num, void __iomem *base, spinlock_t *lock,
-+ struct clk_onecell_data *clk_data)
-+{
-+ struct clk *clk;
-+ int i;
-+
-+ for (i = 0; i < num; i++) {
-+ const struct mtk_clk_divider *mcd = &mcds[i];
-+
-+ clk = clk_register_divider(NULL, mcd->name, mcd->parent_name,
-+ mcd->flags, base + mcd->div_reg, mcd->div_shift,
-+ mcd->div_width, mcd->clk_divider_flags, lock);
-+
-+ if (IS_ERR(clk)) {
-+ pr_err("Failed to register clk %s: %ld\n",
-+ mcd->name, PTR_ERR(clk));
-+ continue;
-+ }
-+
-+ if (clk_data)
-+ clk_data->clks[mcd->id] = clk;
-+ }
-+}
---- a/drivers/clk/mediatek/clk-mtk.h
-+++ b/drivers/clk/mediatek/clk-mtk.h
-@@ -121,7 +121,8 @@ struct mtk_composite {
- .flags = CLK_SET_RATE_PARENT, \
- }
-
--#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, _div_width, _div_shift) { \
-+#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, \
-+ _div_width, _div_shift) { \
- .id = _id, \
- .parent = _parent, \
- .name = _name, \
-@@ -156,8 +157,36 @@ struct mtk_gate {
- const struct clk_ops *ops;
- };
-
--int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks,
-- int num, struct clk_onecell_data *clk_data);
-+int mtk_clk_register_gates(struct device_node *node,
-+ const struct mtk_gate *clks, int num,
-+ struct clk_onecell_data *clk_data);
-+
-+struct mtk_clk_divider {
-+ int id;
-+ const char *name;
-+ const char *parent_name;
-+ unsigned long flags;
-+
-+ uint32_t div_reg;
-+ unsigned char div_shift;
-+ unsigned char div_width;
-+ unsigned char clk_divider_flags;
-+ const struct clk_div_table *clk_div_table;
-+};
-+
-+#define DIV_ADJ(_id, _name, _parent, _reg, _shift, _width) { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .flags = CLK_SET_RATE_PARENT, \
-+ .div_reg = _reg, \
-+ .div_shift = _shift, \
-+ .div_width = _width, \
-+}
-+
-+void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
-+ int num, void __iomem *base, spinlock_t *lock,
-+ struct clk_onecell_data *clk_data);
-
- struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num);
-
diff --git a/target/linux/mediatek/patches-4.9/0006-reset-mediatek-mt2701-reset-driver.patch b/target/linux/mediatek/patches-4.9/0006-reset-mediatek-mt2701-reset-driver.patch
deleted file mode 100644
index 12bda9c6b1..0000000000
--- a/target/linux/mediatek/patches-4.9/0006-reset-mediatek-mt2701-reset-driver.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 596c3a7300c0419dba71d58cbd4136e0d1e12a4e Mon Sep 17 00:00:00 2001
-From: Shunli Wang <shunli.wang@mediatek.com>
-Date: Tue, 5 Jan 2016 14:30:22 +0800
-Subject: [PATCH 06/57] reset: mediatek: mt2701 reset driver
-
-In infrasys and perifsys, there are many reset
-control bits for kinds of modules. These bits are
-used as actual reset controllers to be registered
-into kernel's generic reset controller framework.
-
-Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
-Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
----
- drivers/clk/mediatek/clk-mt2701.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/clk/mediatek/clk-mt2701.c
-+++ b/drivers/clk/mediatek/clk-mt2701.c
-@@ -665,6 +665,8 @@ static void __init mtk_infrasys_init(str
- if (r)
- pr_err("%s(): could not register clock provider: %d\n",
- __func__, r);
-+
-+ mtk_register_reset_controller(node, 2, 0x30);
- }
- CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt2701-infracfg", mtk_infrasys_init);
-
-@@ -782,6 +784,8 @@ static void __init mtk_pericfg_init(stru
- if (r)
- pr_err("%s(): could not register clock provider: %d\n",
- __func__, r);
-+
-+ mtk_register_reset_controller(node, 2, 0x0);
- }
- CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt2701-pericfg", mtk_pericfg_init);
-
diff --git a/target/linux/mediatek/patches-4.9/0007-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch b/target/linux/mediatek/patches-4.9/0007-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch
deleted file mode 100644
index f38b435c85..0000000000
--- a/target/linux/mediatek/patches-4.9/0007-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 60c14df3cc898b6b03d66ec725f9705bf431b677 Mon Sep 17 00:00:00 2001
-From: Erin Lo <erin.lo@mediatek.com>
-Date: Mon, 28 Dec 2015 15:09:02 +0800
-Subject: [PATCH 07/57] ARM: mediatek: Add MT2701 config options for mediatek
- SoCs.
-
-The upcoming MTK pinctrl driver have a big pin table for each SoC
-and we don't want to bloat the kernel binary if we don't need it.
-Add config options so we can build for one SoC only. Add MT2701.
-
-Signed-off-by: Erin Lo <erin.lo@mediatek.com>
-Acked-by: Linus Walleij <linus.walleij@linaro.org>
----
- arch/arm/mach-mediatek/Kconfig | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/arm/mach-mediatek/Kconfig
-+++ b/arch/arm/mach-mediatek/Kconfig
-@@ -14,6 +14,10 @@ config MACH_MT2701
- bool "MediaTek MT2701 SoCs support"
- default ARCH_MEDIATEK
-
-+config MACH_MT2701
-+ bool "MediaTek MT2701 SoCs support"
-+ default ARCH_MEDIATEK
-+
- config MACH_MT6589
- bool "MediaTek MT6589 SoCs support"
- default ARCH_MEDIATEK
diff --git a/target/linux/mediatek/patches-4.9/0008-soc-mediatek-Refine-scpsys-to-support-multiple-platf.patch b/target/linux/mediatek/patches-4.9/0008-soc-mediatek-Refine-scpsys-to-support-multiple-platf.patch
deleted file mode 100644
index 1d83e9ae5d..0000000000
--- a/target/linux/mediatek/patches-4.9/0008-soc-mediatek-Refine-scpsys-to-support-multiple-platf.patch
+++ /dev/null
@@ -1,487 +0,0 @@
-From b5a1e520d8039c242b2157b511f684ce464d6e21 Mon Sep 17 00:00:00 2001
-From: James Liao <jamesjj.liao@mediatek.com>
-Date: Thu, 20 Oct 2016 16:56:35 +0800
-Subject: [PATCH 08/57] soc: mediatek: Refine scpsys to support multiple
- platform
-
-Refine scpsys driver common code to support multiple SoC / platform.
-
-Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
-Reviewed-by: Kevin Hilman <khilman@baylibre.com>
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- drivers/soc/mediatek/mtk-scpsys.c | 348 +++++++++++++++++++++++---------------
- 1 file changed, 210 insertions(+), 138 deletions(-)
-
---- a/drivers/soc/mediatek/mtk-scpsys.c
-+++ b/drivers/soc/mediatek/mtk-scpsys.c
-@@ -11,17 +11,15 @@
- * GNU General Public License for more details.
- */
- #include <linux/clk.h>
--#include <linux/delay.h>
-+#include <linux/init.h>
- #include <linux/io.h>
--#include <linux/kernel.h>
- #include <linux/mfd/syscon.h>
--#include <linux/init.h>
- #include <linux/of_device.h>
- #include <linux/platform_device.h>
- #include <linux/pm_domain.h>
--#include <linux/regmap.h>
--#include <linux/soc/mediatek/infracfg.h>
- #include <linux/regulator/consumer.h>
-+#include <linux/soc/mediatek/infracfg.h>
-+
- #include <dt-bindings/power/mt8173-power.h>
-
- #define SPM_VDE_PWR_CON 0x0210
-@@ -34,6 +32,7 @@
- #define SPM_MFG_2D_PWR_CON 0x02c0
- #define SPM_MFG_ASYNC_PWR_CON 0x02c4
- #define SPM_USB_PWR_CON 0x02cc
-+
- #define SPM_PWR_STATUS 0x060c
- #define SPM_PWR_STATUS_2ND 0x0610
-
-@@ -55,12 +54,21 @@
- #define PWR_STATUS_USB BIT(25)
-
- enum clk_id {
-- MT8173_CLK_NONE,
-- MT8173_CLK_MM,
-- MT8173_CLK_MFG,
-- MT8173_CLK_VENC,
-- MT8173_CLK_VENC_LT,
-- MT8173_CLK_MAX,
-+ CLK_NONE,
-+ CLK_MM,
-+ CLK_MFG,
-+ CLK_VENC,
-+ CLK_VENC_LT,
-+ CLK_MAX,
-+};
-+
-+static const char * const clk_names[] = {
-+ NULL,
-+ "mm",
-+ "mfg",
-+ "venc",
-+ "venc_lt",
-+ NULL,
- };
-
- #define MAX_CLKS 2
-@@ -76,98 +84,6 @@ struct scp_domain_data {
- bool active_wakeup;
- };
-
--static const struct scp_domain_data scp_domain_data[] = {
-- [MT8173_POWER_DOMAIN_VDEC] = {
-- .name = "vdec",
-- .sta_mask = PWR_STATUS_VDEC,
-- .ctl_offs = SPM_VDE_PWR_CON,
-- .sram_pdn_bits = GENMASK(11, 8),
-- .sram_pdn_ack_bits = GENMASK(12, 12),
-- .clk_id = {MT8173_CLK_MM},
-- },
-- [MT8173_POWER_DOMAIN_VENC] = {
-- .name = "venc",
-- .sta_mask = PWR_STATUS_VENC,
-- .ctl_offs = SPM_VEN_PWR_CON,
-- .sram_pdn_bits = GENMASK(11, 8),
-- .sram_pdn_ack_bits = GENMASK(15, 12),
-- .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC},
-- },
-- [MT8173_POWER_DOMAIN_ISP] = {
-- .name = "isp",
-- .sta_mask = PWR_STATUS_ISP,
-- .ctl_offs = SPM_ISP_PWR_CON,
-- .sram_pdn_bits = GENMASK(11, 8),
-- .sram_pdn_ack_bits = GENMASK(13, 12),
-- .clk_id = {MT8173_CLK_MM},
-- },
-- [MT8173_POWER_DOMAIN_MM] = {
-- .name = "mm",
-- .sta_mask = PWR_STATUS_DISP,
-- .ctl_offs = SPM_DIS_PWR_CON,
-- .sram_pdn_bits = GENMASK(11, 8),
-- .sram_pdn_ack_bits = GENMASK(12, 12),
-- .clk_id = {MT8173_CLK_MM},
-- .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
-- MT8173_TOP_AXI_PROT_EN_MM_M1,
-- },
-- [MT8173_POWER_DOMAIN_VENC_LT] = {
-- .name = "venc_lt",
-- .sta_mask = PWR_STATUS_VENC_LT,
-- .ctl_offs = SPM_VEN2_PWR_CON,
-- .sram_pdn_bits = GENMASK(11, 8),
-- .sram_pdn_ack_bits = GENMASK(15, 12),
-- .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC_LT},
-- },
-- [MT8173_POWER_DOMAIN_AUDIO] = {
-- .name = "audio",
-- .sta_mask = PWR_STATUS_AUDIO,
-- .ctl_offs = SPM_AUDIO_PWR_CON,
-- .sram_pdn_bits = GENMASK(11, 8),
-- .sram_pdn_ack_bits = GENMASK(15, 12),
-- .clk_id = {MT8173_CLK_NONE},
-- },
-- [MT8173_POWER_DOMAIN_USB] = {
-- .name = "usb",
-- .sta_mask = PWR_STATUS_USB,
-- .ctl_offs = SPM_USB_PWR_CON,
-- .sram_pdn_bits = GENMASK(11, 8),
-- .sram_pdn_ack_bits = GENMASK(15, 12),
-- .clk_id = {MT8173_CLK_NONE},
-- .active_wakeup = true,
-- },
-- [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
-- .name = "mfg_async",
-- .sta_mask = PWR_STATUS_MFG_ASYNC,
-- .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
-- .sram_pdn_bits = GENMASK(11, 8),
-- .sram_pdn_ack_bits = 0,
-- .clk_id = {MT8173_CLK_MFG},
-- },
-- [MT8173_POWER_DOMAIN_MFG_2D] = {
-- .name = "mfg_2d",
-- .sta_mask = PWR_STATUS_MFG_2D,
-- .ctl_offs = SPM_MFG_2D_PWR_CON,
-- .sram_pdn_bits = GENMASK(11, 8),
-- .sram_pdn_ack_bits = GENMASK(13, 12),
-- .clk_id = {MT8173_CLK_NONE},
-- },
-- [MT8173_POWER_DOMAIN_MFG] = {
-- .name = "mfg",
-- .sta_mask = PWR_STATUS_MFG,
-- .ctl_offs = SPM_MFG_PWR_CON,
-- .sram_pdn_bits = GENMASK(13, 8),
-- .sram_pdn_ack_bits = GENMASK(21, 16),
-- .clk_id = {MT8173_CLK_NONE},
-- .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
-- MT8173_TOP_AXI_PROT_EN_MFG_M0 |
-- MT8173_TOP_AXI_PROT_EN_MFG_M1 |
-- MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
-- },
--};
--
--#define NUM_DOMAINS ARRAY_SIZE(scp_domain_data)
--
- struct scp;
-
- struct scp_domain {
-@@ -179,7 +95,7 @@ struct scp_domain {
- };
-
- struct scp {
-- struct scp_domain domains[NUM_DOMAINS];
-+ struct scp_domain *domains;
- struct genpd_onecell_data pd_data;
- struct device *dev;
- void __iomem *base;
-@@ -408,57 +324,55 @@ static bool scpsys_active_wakeup(struct
- return scpd->data->active_wakeup;
- }
-
--static int scpsys_probe(struct platform_device *pdev)
-+static void init_clks(struct platform_device *pdev, struct clk **clk)
-+{
-+ int i;
-+
-+ for (i = CLK_NONE + 1; i < CLK_MAX; i++)
-+ clk[i] = devm_clk_get(&pdev->dev, clk_names[i]);
-+}
-+
-+static struct scp *init_scp(struct platform_device *pdev,
-+ const struct scp_domain_data *scp_domain_data, int num)
- {
- struct genpd_onecell_data *pd_data;
- struct resource *res;
-- int i, j, ret;
-+ int i, j;
- struct scp *scp;
-- struct clk *clk[MT8173_CLK_MAX];
-+ struct clk *clk[CLK_MAX];
-
- scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL);
- if (!scp)
-- return -ENOMEM;
-+ return ERR_PTR(-ENOMEM);
-
- scp->dev = &pdev->dev;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- scp->base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(scp->base))
-- return PTR_ERR(scp->base);
-+ return ERR_CAST(scp->base);
-+
-+ scp->domains = devm_kzalloc(&pdev->dev,
-+ sizeof(*scp->domains) * num, GFP_KERNEL);
-+ if (!scp->domains)
-+ return ERR_PTR(-ENOMEM);
-
- pd_data = &scp->pd_data;
-
- pd_data->domains = devm_kzalloc(&pdev->dev,
-- sizeof(*pd_data->domains) * NUM_DOMAINS, GFP_KERNEL);
-+ sizeof(*pd_data->domains) * num, GFP_KERNEL);
- if (!pd_data->domains)
-- return -ENOMEM;
--
-- clk[MT8173_CLK_MM] = devm_clk_get(&pdev->dev, "mm");
-- if (IS_ERR(clk[MT8173_CLK_MM]))
-- return PTR_ERR(clk[MT8173_CLK_MM]);
--
-- clk[MT8173_CLK_MFG] = devm_clk_get(&pdev->dev, "mfg");
-- if (IS_ERR(clk[MT8173_CLK_MFG]))
-- return PTR_ERR(clk[MT8173_CLK_MFG]);
--
-- clk[MT8173_CLK_VENC] = devm_clk_get(&pdev->dev, "venc");
-- if (IS_ERR(clk[MT8173_CLK_VENC]))
-- return PTR_ERR(clk[MT8173_CLK_VENC]);
--
-- clk[MT8173_CLK_VENC_LT] = devm_clk_get(&pdev->dev, "venc_lt");
-- if (IS_ERR(clk[MT8173_CLK_VENC_LT]))
-- return PTR_ERR(clk[MT8173_CLK_VENC_LT]);
-+ return ERR_PTR(-ENOMEM);
-
- scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
- "infracfg");
- if (IS_ERR(scp->infracfg)) {
- dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n",
- PTR_ERR(scp->infracfg));
-- return PTR_ERR(scp->infracfg);
-+ return ERR_CAST(scp->infracfg);
- }
-
-- for (i = 0; i < NUM_DOMAINS; i++) {
-+ for (i = 0; i < num; i++) {
- struct scp_domain *scpd = &scp->domains[i];
- const struct scp_domain_data *data = &scp_domain_data[i];
-
-@@ -467,13 +381,15 @@ static int scpsys_probe(struct platform_
- if (PTR_ERR(scpd->supply) == -ENODEV)
- scpd->supply = NULL;
- else
-- return PTR_ERR(scpd->supply);
-+ return ERR_CAST(scpd->supply);
- }
- }
-
-- pd_data->num_domains = NUM_DOMAINS;
-+ pd_data->num_domains = num;
-+
-+ init_clks(pdev, clk);
-
-- for (i = 0; i < NUM_DOMAINS; i++) {
-+ for (i = 0; i < num; i++) {
- struct scp_domain *scpd = &scp->domains[i];
- struct generic_pm_domain *genpd = &scpd->genpd;
- const struct scp_domain_data *data = &scp_domain_data[i];
-@@ -482,13 +398,37 @@ static int scpsys_probe(struct platform_
- scpd->scp = scp;
-
- scpd->data = data;
-- for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++)
-- scpd->clk[j] = clk[data->clk_id[j]];
-+
-+ for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) {
-+ struct clk *c = clk[data->clk_id[j]];
-+
-+ if (IS_ERR(c)) {
-+ dev_err(&pdev->dev, "%s: clk unavailable\n",
-+ data->name);
-+ return ERR_CAST(c);
-+ }
-+
-+ scpd->clk[j] = c;
-+ }
-
- genpd->name = data->name;
- genpd->power_off = scpsys_power_off;
- genpd->power_on = scpsys_power_on;
- genpd->dev_ops.active_wakeup = scpsys_active_wakeup;
-+ }
-+
-+ return scp;
-+}
-+
-+static void mtk_register_power_domains(struct platform_device *pdev,
-+ struct scp *scp, int num)
-+{
-+ struct genpd_onecell_data *pd_data;
-+ int i, ret;
-+
-+ for (i = 0; i < num; i++) {
-+ struct scp_domain *scpd = &scp->domains[i];
-+ struct generic_pm_domain *genpd = &scpd->genpd;
-
- /*
- * Initially turn on all domains to make the domains usable
-@@ -507,6 +447,123 @@ static int scpsys_probe(struct platform_
- * valid.
- */
-
-+ pd_data = &scp->pd_data;
-+
-+ ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data);
-+ if (ret)
-+ dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret);
-+}
-+
-+/*
-+ * MT8173 power domain support
-+ */
-+
-+static const struct scp_domain_data scp_domain_data_mt8173[] = {
-+ [MT8173_POWER_DOMAIN_VDEC] = {
-+ .name = "vdec",
-+ .sta_mask = PWR_STATUS_VDEC,
-+ .ctl_offs = SPM_VDE_PWR_CON,
-+ .sram_pdn_bits = GENMASK(11, 8),
-+ .sram_pdn_ack_bits = GENMASK(12, 12),
-+ .clk_id = {CLK_MM},
-+ },
-+ [MT8173_POWER_DOMAIN_VENC] = {
-+ .name = "venc",
-+ .sta_mask = PWR_STATUS_VENC,
-+ .ctl_offs = SPM_VEN_PWR_CON,
-+ .sram_pdn_bits = GENMASK(11, 8),
-+ .sram_pdn_ack_bits = GENMASK(15, 12),
-+ .clk_id = {CLK_MM, CLK_VENC},
-+ },
-+ [MT8173_POWER_DOMAIN_ISP] = {
-+ .name = "isp",
-+ .sta_mask = PWR_STATUS_ISP,
-+ .ctl_offs = SPM_ISP_PWR_CON,
-+ .sram_pdn_bits = GENMASK(11, 8),
-+ .sram_pdn_ack_bits = GENMASK(13, 12),
-+ .clk_id = {CLK_MM},
-+ },
-+ [MT8173_POWER_DOMAIN_MM] = {
-+ .name = "mm",
-+ .sta_mask = PWR_STATUS_DISP,
-+ .ctl_offs = SPM_DIS_PWR_CON,
-+ .sram_pdn_bits = GENMASK(11, 8),
-+ .sram_pdn_ack_bits = GENMASK(12, 12),
-+ .clk_id = {CLK_MM},
-+ .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
-+ MT8173_TOP_AXI_PROT_EN_MM_M1,
-+ },
-+ [MT8173_POWER_DOMAIN_VENC_LT] = {
-+ .name = "venc_lt",
-+ .sta_mask = PWR_STATUS_VENC_LT,
-+ .ctl_offs = SPM_VEN2_PWR_CON,
-+ .sram_pdn_bits = GENMASK(11, 8),
-+ .sram_pdn_ack_bits = GENMASK(15, 12),
-+ .clk_id = {CLK_MM, CLK_VENC_LT},
-+ },
-+ [MT8173_POWER_DOMAIN_AUDIO] = {
-+ .name = "audio",
-+ .sta_mask = PWR_STATUS_AUDIO,
-+ .ctl_offs = SPM_AUDIO_PWR_CON,
-+ .sram_pdn_bits = GENMASK(11, 8),
-+ .sram_pdn_ack_bits = GENMASK(15, 12),
-+ .clk_id = {CLK_NONE},
-+ },
-+ [MT8173_POWER_DOMAIN_USB] = {
-+ .name = "usb",
-+ .sta_mask = PWR_STATUS_USB,
-+ .ctl_offs = SPM_USB_PWR_CON,
-+ .sram_pdn_bits = GENMASK(11, 8),
-+ .sram_pdn_ack_bits = GENMASK(15, 12),
-+ .clk_id = {CLK_NONE},
-+ .active_wakeup = true,
-+ },
-+ [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
-+ .name = "mfg_async",
-+ .sta_mask = PWR_STATUS_MFG_ASYNC,
-+ .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
-+ .sram_pdn_bits = GENMASK(11, 8),
-+ .sram_pdn_ack_bits = 0,
-+ .clk_id = {CLK_MFG},
-+ },
-+ [MT8173_POWER_DOMAIN_MFG_2D] = {
-+ .name = "mfg_2d",
-+ .sta_mask = PWR_STATUS_MFG_2D,
-+ .ctl_offs = SPM_MFG_2D_PWR_CON,
-+ .sram_pdn_bits = GENMASK(11, 8),
-+ .sram_pdn_ack_bits = GENMASK(13, 12),
-+ .clk_id = {CLK_NONE},
-+ },
-+ [MT8173_POWER_DOMAIN_MFG] = {
-+ .name = "mfg",
-+ .sta_mask = PWR_STATUS_MFG,
-+ .ctl_offs = SPM_MFG_PWR_CON,
-+ .sram_pdn_bits = GENMASK(13, 8),
-+ .sram_pdn_ack_bits = GENMASK(21, 16),
-+ .clk_id = {CLK_NONE},
-+ .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
-+ MT8173_TOP_AXI_PROT_EN_MFG_M0 |
-+ MT8173_TOP_AXI_PROT_EN_MFG_M1 |
-+ MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
-+ },
-+};
-+
-+#define NUM_DOMAINS_MT8173 ARRAY_SIZE(scp_domain_data_mt8173)
-+
-+static int __init scpsys_probe_mt8173(struct platform_device *pdev)
-+{
-+ struct scp *scp;
-+ struct genpd_onecell_data *pd_data;
-+ int ret;
-+
-+ scp = init_scp(pdev, scp_domain_data_mt8173, NUM_DOMAINS_MT8173);
-+ if (IS_ERR(scp))
-+ return PTR_ERR(scp);
-+
-+ mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT8173);
-+
-+ pd_data = &scp->pd_data;
-+
- ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC],
- pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]);
- if (ret && IS_ENABLED(CONFIG_PM))
-@@ -517,21 +574,36 @@ static int scpsys_probe(struct platform_
- if (ret && IS_ENABLED(CONFIG_PM))
- dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
-
-- ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data);
-- if (ret)
-- dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret);
--
- return 0;
- }
-
-+/*
-+ * scpsys driver init
-+ */
-+
- static const struct of_device_id of_scpsys_match_tbl[] = {
- {
- .compatible = "mediatek,mt8173-scpsys",
-+ .data = scpsys_probe_mt8173,
- }, {
- /* sentinel */
- }
- };
-
-+static int scpsys_probe(struct platform_device *pdev)
-+{
-+ int (*probe)(struct platform_device *);
-+ const struct of_device_id *of_id;
-+
-+ of_id = of_match_node(of_scpsys_match_tbl, pdev->dev.of_node);
-+ if (!of_id || !of_id->data)
-+ return -EINVAL;
-+
-+ probe = of_id->data;
-+
-+ return probe(pdev);
-+}
-+
- static struct platform_driver scpsys_drv = {
- .probe = scpsys_probe,
- .driver = {
diff --git a/target/linux/mediatek/patches-4.9/0009-soc-mediatek-Add-MT2701-scpsys-driver.patch b/target/linux/mediatek/patches-4.9/0009-soc-mediatek-Add-MT2701-scpsys-driver.patch
deleted file mode 100644
index 0b47635170..0000000000
--- a/target/linux/mediatek/patches-4.9/0009-soc-mediatek-Add-MT2701-scpsys-driver.patch
+++ /dev/null
@@ -1,194 +0,0 @@
-From fb9f97e047f5a831a54cd61529b8cfdc4d413bb6 Mon Sep 17 00:00:00 2001
-From: Shunli Wang <shunli.wang@mediatek.com>
-Date: Thu, 20 Oct 2016 16:56:38 +0800
-Subject: [PATCH 09/57] soc: mediatek: Add MT2701 scpsys driver
-
-Add scpsys driver for MT2701.
-
-mtk-scpsys now supports MT8173 (arm64) and MT2701 (arm). So it should
-be enabled on both arm64 and arm platforms.
-
-Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
-Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
-Reviewed-by: Kevin Hilman <khilman@baylibre.com>
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- drivers/soc/mediatek/Kconfig | 2 +-
- drivers/soc/mediatek/mtk-scpsys.c | 108 +++++++++++++++++++++++++++++++++++++-
- 2 files changed, 108 insertions(+), 2 deletions(-)
-
---- a/drivers/soc/mediatek/Kconfig
-+++ b/drivers/soc/mediatek/Kconfig
-@@ -23,7 +23,7 @@ config MTK_PMIC_WRAP
- config MTK_SCPSYS
- bool "MediaTek SCPSYS Support"
- depends on ARCH_MEDIATEK || COMPILE_TEST
-- default ARM64 && ARCH_MEDIATEK
-+ default ARCH_MEDIATEK
- select REGMAP
- select MTK_INFRACFG
- select PM_GENERIC_DOMAINS if PM
---- a/drivers/soc/mediatek/mtk-scpsys.c
-+++ b/drivers/soc/mediatek/mtk-scpsys.c
-@@ -20,6 +20,7 @@
- #include <linux/regulator/consumer.h>
- #include <linux/soc/mediatek/infracfg.h>
-
-+#include <dt-bindings/power/mt2701-power.h>
- #include <dt-bindings/power/mt8173-power.h>
-
- #define SPM_VDE_PWR_CON 0x0210
-@@ -27,8 +28,13 @@
- #define SPM_VEN_PWR_CON 0x0230
- #define SPM_ISP_PWR_CON 0x0238
- #define SPM_DIS_PWR_CON 0x023c
-+#define SPM_CONN_PWR_CON 0x0280
- #define SPM_VEN2_PWR_CON 0x0298
--#define SPM_AUDIO_PWR_CON 0x029c
-+#define SPM_AUDIO_PWR_CON 0x029c /* MT8173 */
-+#define SPM_BDP_PWR_CON 0x029c /* MT2701 */
-+#define SPM_ETH_PWR_CON 0x02a0
-+#define SPM_HIF_PWR_CON 0x02a4
-+#define SPM_IFR_MSC_PWR_CON 0x02a8
- #define SPM_MFG_2D_PWR_CON 0x02c0
- #define SPM_MFG_ASYNC_PWR_CON 0x02c4
- #define SPM_USB_PWR_CON 0x02cc
-@@ -42,10 +48,15 @@
- #define PWR_ON_2ND_BIT BIT(3)
- #define PWR_CLK_DIS_BIT BIT(4)
-
-+#define PWR_STATUS_CONN BIT(1)
- #define PWR_STATUS_DISP BIT(3)
- #define PWR_STATUS_MFG BIT(4)
- #define PWR_STATUS_ISP BIT(5)
- #define PWR_STATUS_VDEC BIT(7)
-+#define PWR_STATUS_BDP BIT(14)
-+#define PWR_STATUS_ETH BIT(15)
-+#define PWR_STATUS_HIF BIT(16)
-+#define PWR_STATUS_IFR_MSC BIT(17)
- #define PWR_STATUS_VENC_LT BIT(20)
- #define PWR_STATUS_VENC BIT(21)
- #define PWR_STATUS_MFG_2D BIT(22)
-@@ -59,6 +70,7 @@ enum clk_id {
- CLK_MFG,
- CLK_VENC,
- CLK_VENC_LT,
-+ CLK_ETHIF,
- CLK_MAX,
- };
-
-@@ -68,6 +80,7 @@ static const char * const clk_names[] =
- "mfg",
- "venc",
- "venc_lt",
-+ "ethif",
- NULL,
- };
-
-@@ -455,6 +468,96 @@ static void mtk_register_power_domains(s
- }
-
- /*
-+ * MT2701 power domain support
-+ */
-+
-+static const struct scp_domain_data scp_domain_data_mt2701[] = {
-+ [MT2701_POWER_DOMAIN_CONN] = {
-+ .name = "conn",
-+ .sta_mask = PWR_STATUS_CONN,
-+ .ctl_offs = SPM_CONN_PWR_CON,
-+ .bus_prot_mask = 0x0104,
-+ .clk_id = {CLK_NONE},
-+ .active_wakeup = true,
-+ },
-+ [MT2701_POWER_DOMAIN_DISP] = {
-+ .name = "disp",
-+ .sta_mask = PWR_STATUS_DISP,
-+ .ctl_offs = SPM_DIS_PWR_CON,
-+ .sram_pdn_bits = GENMASK(11, 8),
-+ .clk_id = {CLK_MM},
-+ .bus_prot_mask = 0x0002,
-+ .active_wakeup = true,
-+ },
-+ [MT2701_POWER_DOMAIN_VDEC] = {
-+ .name = "vdec",
-+ .sta_mask = PWR_STATUS_VDEC,
-+ .ctl_offs = SPM_VDE_PWR_CON,
-+ .sram_pdn_bits = GENMASK(11, 8),
-+ .sram_pdn_ack_bits = GENMASK(12, 12),
-+ .clk_id = {CLK_MM},
-+ .active_wakeup = true,
-+ },
-+ [MT2701_POWER_DOMAIN_ISP] = {
-+ .name = "isp",
-+ .sta_mask = PWR_STATUS_ISP,
-+ .ctl_offs = SPM_ISP_PWR_CON,
-+ .sram_pdn_bits = GENMASK(11, 8),
-+ .sram_pdn_ack_bits = GENMASK(13, 12),
-+ .clk_id = {CLK_MM},
-+ .active_wakeup = true,
-+ },
-+ [MT2701_POWER_DOMAIN_BDP] = {
-+ .name = "bdp",
-+ .sta_mask = PWR_STATUS_BDP,
-+ .ctl_offs = SPM_BDP_PWR_CON,
-+ .sram_pdn_bits = GENMASK(11, 8),
-+ .clk_id = {CLK_NONE},
-+ .active_wakeup = true,
-+ },
-+ [MT2701_POWER_DOMAIN_ETH] = {
-+ .name = "eth",
-+ .sta_mask = PWR_STATUS_ETH,
-+ .ctl_offs = SPM_ETH_PWR_CON,
-+ .sram_pdn_bits = GENMASK(11, 8),
-+ .sram_pdn_ack_bits = GENMASK(15, 12),
-+ .clk_id = {CLK_ETHIF},
-+ .active_wakeup = true,
-+ },
-+ [MT2701_POWER_DOMAIN_HIF] = {
-+ .name = "hif",
-+ .sta_mask = PWR_STATUS_HIF,
-+ .ctl_offs = SPM_HIF_PWR_CON,
-+ .sram_pdn_bits = GENMASK(11, 8),
-+ .sram_pdn_ack_bits = GENMASK(15, 12),
-+ .clk_id = {CLK_ETHIF},
-+ .active_wakeup = true,
-+ },
-+ [MT2701_POWER_DOMAIN_IFR_MSC] = {
-+ .name = "ifr_msc",
-+ .sta_mask = PWR_STATUS_IFR_MSC,
-+ .ctl_offs = SPM_IFR_MSC_PWR_CON,
-+ .clk_id = {CLK_NONE},
-+ .active_wakeup = true,
-+ },
-+};
-+
-+#define NUM_DOMAINS_MT2701 ARRAY_SIZE(scp_domain_data_mt2701)
-+
-+static int __init scpsys_probe_mt2701(struct platform_device *pdev)
-+{
-+ struct scp *scp;
-+
-+ scp = init_scp(pdev, scp_domain_data_mt2701, NUM_DOMAINS_MT2701);
-+ if (IS_ERR(scp))
-+ return PTR_ERR(scp);
-+
-+ mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT2701);
-+
-+ return 0;
-+}
-+
-+/*
- * MT8173 power domain support
- */
-
-@@ -583,6 +686,9 @@ static int __init scpsys_probe_mt8173(st
-
- static const struct of_device_id of_scpsys_match_tbl[] = {
- {
-+ .compatible = "mediatek,mt2701-scpsys",
-+ .data = scpsys_probe_mt2701,
-+ }, {
- .compatible = "mediatek,mt8173-scpsys",
- .data = scpsys_probe_mt8173,
- }, {
diff --git a/target/linux/mediatek/patches-4.9/0010-clk-add-hifsys-reset.patch b/target/linux/mediatek/patches-4.9/0010-clk-add-hifsys-reset.patch
deleted file mode 100644
index a7ebb060ce..0000000000
--- a/target/linux/mediatek/patches-4.9/0010-clk-add-hifsys-reset.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 600e2bd5c3019f31e90ec876f4efb6c209cf0d73 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 6 Jan 2016 20:06:49 +0100
-Subject: [PATCH 10/57] clk: add hifsys reset
-
-Hi,
-
-small patch to add hifsys reset bits. Maybe you could add it to the next
-version of your patch series. i have teste scpsys and clk on mt7623 today
-and it works well.
-
-thanks,
- John
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/clk/mediatek/clk-mt2701.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/clk/mediatek/clk-mt2701.c
-+++ b/drivers/clk/mediatek/clk-mt2701.c
-@@ -1000,6 +1000,8 @@ static void __init mtk_hifsys_init(struc
- if (r)
- pr_err("%s(): could not register clock provider: %d\n",
- __func__, r);
-+
-+ mtk_register_reset_controller(node, 1, 0x34);
- }
- CLK_OF_DECLARE(mtk_hifsys, "mediatek,mt2701-hifsys", mtk_hifsys_init);
-
diff --git a/target/linux/mediatek/patches-4.9/0011-scpsys-various-fixes.patch b/target/linux/mediatek/patches-4.9/0011-scpsys-various-fixes.patch
deleted file mode 100644
index 8a9da5e673..0000000000
--- a/target/linux/mediatek/patches-4.9/0011-scpsys-various-fixes.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From 1e889b3d38ab5fb425762da57313b4cc8fc2f165 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Sun, 21 Feb 2016 13:52:12 +0100
-Subject: [PATCH 11/57] scpsys: various fixes
-
----
- drivers/clk/mediatek/clk-mt2701.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/clk/mediatek/clk-mt2701.c
-+++ b/drivers/clk/mediatek/clk-mt2701.c
-@@ -1043,6 +1043,8 @@ static void __init mtk_ethsys_init(struc
- if (r)
- pr_err("%s(): could not register clock provider: %d\n",
- __func__, r);
-+
-+ mtk_register_reset_controller(node, 1, 0x34);
- }
- CLK_OF_DECLARE(mtk_ethsys, "mediatek,mt2701-ethsys", mtk_ethsys_init);
-
diff --git a/target/linux/mediatek/patches-4.9/0012-clk-dont-disable-unused-clocks.patch b/target/linux/mediatek/patches-4.9/0012-clk-dont-disable-unused-clocks.patch
deleted file mode 100644
index ed4111dce3..0000000000
--- a/target/linux/mediatek/patches-4.9/0012-clk-dont-disable-unused-clocks.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From 0e60d2112968ccb2570535bf19fb5020c9b28c08 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 7 Apr 2016 07:18:35 +0200
-Subject: [PATCH 12/57] clk: dont disable unused clocks
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/clk/clk.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/clk/clk.c
-+++ b/drivers/clk/clk.c
-@@ -796,7 +796,7 @@ unlock_out:
- clk_core_disable_unprepare(core->parent);
- }
-
--static bool clk_ignore_unused;
-+static bool clk_ignore_unused = true;
- static int __init clk_ignore_unused_setup(char *__unused)
- {
- clk_ignore_unused = true;
diff --git a/target/linux/mediatek/patches-4.9/0013-clk-mediatek-enable-critical-clocks.patch b/target/linux/mediatek/patches-4.9/0013-clk-mediatek-enable-critical-clocks.patch
deleted file mode 100644
index 26257bd42f..0000000000
--- a/target/linux/mediatek/patches-4.9/0013-clk-mediatek-enable-critical-clocks.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From 03bead9276653dc842f6970250bc7eba41faf777 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 31 Mar 2016 06:46:51 +0200
-Subject: [PATCH 13/57] clk: mediatek: enable critical clocks
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/clk/mediatek/clk-mt2701.c | 22 ++++++++++++++++++++--
- 1 file changed, 20 insertions(+), 2 deletions(-)
-
---- a/drivers/clk/mediatek/clk-mt2701.c
-+++ b/drivers/clk/mediatek/clk-mt2701.c
-@@ -573,6 +573,20 @@ static const struct mtk_gate top_clks[]
- GATE_TOP_AUD(CLK_TOP_AUD_I2S6_MCLK, "aud_i2s6_mclk", "aud_k6_src_div", 28),
- };
-
-+static struct clk_onecell_data *mt7623_top_clk_data __initdata;
-+static struct clk_onecell_data *mt7623_pll_clk_data __initdata;
-+
-+static void __init mtk_clk_enable_critical(void)
-+{
-+ if (!mt7623_top_clk_data || !mt7623_pll_clk_data)
-+ return;
-+
-+ clk_prepare_enable(mt7623_pll_clk_data->clks[CLK_APMIXED_ARMPLL]);
-+ clk_prepare_enable(mt7623_top_clk_data->clks[CLK_TOP_MEM_SEL]);
-+ clk_prepare_enable(mt7623_top_clk_data->clks[CLK_TOP_DDRPHYCFG_SEL]);
-+ clk_prepare_enable(mt7623_top_clk_data->clks[CLK_TOP_RTC_SEL]);
-+}
-+
- static void __init mtk_topckgen_init(struct device_node *node)
- {
- struct clk_onecell_data *clk_data;
-@@ -585,7 +599,7 @@ static void __init mtk_topckgen_init(str
- return;
- }
-
-- clk_data = mtk_alloc_clk_data(CLK_TOP_NR);
-+ mt7623_top_clk_data = clk_data = mtk_alloc_clk_data(CLK_TOP_NR);
-
- mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
- clk_data);
-@@ -606,6 +620,8 @@ static void __init mtk_topckgen_init(str
- if (r)
- pr_err("%s(): could not register clock provider: %d\n",
- __func__, r);
-+
-+ mtk_clk_enable_critical();
- }
- CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt2701-topckgen", mtk_topckgen_init);
-
-@@ -1202,7 +1218,7 @@ static void __init mtk_apmixedsys_init(s
- struct clk_onecell_data *clk_data;
- int r;
-
-- clk_data = mtk_alloc_clk_data(ARRAY_SIZE(apmixed_plls));
-+ mt7623_pll_clk_data = clk_data = mtk_alloc_clk_data(ARRAY_SIZE(apmixed_plls));
- if (!clk_data)
- return;
-
-@@ -1213,6 +1229,8 @@ static void __init mtk_apmixedsys_init(s
- if (r)
- pr_err("%s(): could not register clock provider: %d\n",
- __func__, r);
-+
-+ mtk_clk_enable_critical();
- }
- CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt2701-apmixedsys",
- mtk_apmixedsys_init);
diff --git a/target/linux/mediatek/patches-4.9/0014-clk-mediatek-Export-CPU-mux-clocks-for-CPU-frequency.patch b/target/linux/mediatek/patches-4.9/0014-clk-mediatek-Export-CPU-mux-clocks-for-CPU-frequency.patch
deleted file mode 100644
index 7e19c6f23b..0000000000
--- a/target/linux/mediatek/patches-4.9/0014-clk-mediatek-Export-CPU-mux-clocks-for-CPU-frequency.patch
+++ /dev/null
@@ -1,287 +0,0 @@
-From 3a947321d72af191ee87a390295c661c876cc6f4 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 31 Mar 2016 02:26:37 +0200
-Subject: [PATCH 14/57] clk: mediatek: Export CPU mux clocks for CPU frequency
- control
-
-This patch adds CPU mux clocks which are used by Mediatek cpufreq driver
-for intermediate clock source switching.
-
-Signed-off-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
----
- drivers/clk/mediatek/Makefile | 2 +-
- drivers/clk/mediatek/clk-cpumux.c | 127 +++++++++++++++++++++++++++++++++
- drivers/clk/mediatek/clk-cpumux.h | 22 ++++++
- drivers/clk/mediatek/clk-mt2701.c | 8 +++
- drivers/clk/mediatek/clk-mt8173.c | 23 ++++++
- include/dt-bindings/clock/mt2701-clk.h | 3 +-
- include/dt-bindings/clock/mt8173-clk.h | 4 +-
- 7 files changed, 186 insertions(+), 3 deletions(-)
- create mode 100644 drivers/clk/mediatek/clk-cpumux.c
- create mode 100644 drivers/clk/mediatek/clk-cpumux.h
-
---- a/drivers/clk/mediatek/Makefile
-+++ b/drivers/clk/mediatek/Makefile
-@@ -1,4 +1,4 @@
--obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o
-+obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o
- obj-$(CONFIG_RESET_CONTROLLER) += reset.o
- obj-$(CONFIG_COMMON_CLK_MT2701) += clk-mt2701.o
- obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
---- /dev/null
-+++ b/drivers/clk/mediatek/clk-cpumux.c
-@@ -0,0 +1,127 @@
-+/*
-+ * Copyright (c) 2015 Linaro Ltd.
-+ * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/slab.h>
-+
-+#include "clk-mtk.h"
-+#include "clk-cpumux.h"
-+
-+struct mtk_clk_cpumux {
-+ struct clk_hw hw;
-+ struct regmap *regmap;
-+ u32 reg;
-+ u32 mask;
-+ u8 shift;
-+};
-+
-+static inline struct mtk_clk_cpumux *to_mtk_clk_mux(struct clk_hw *_hw)
-+{
-+ return container_of(_hw, struct mtk_clk_cpumux, hw);
-+}
-+
-+static u8 clk_cpumux_get_parent(struct clk_hw *hw)
-+{
-+ struct mtk_clk_cpumux *mux = to_mtk_clk_mux(hw);
-+ int num_parents = clk_hw_get_num_parents(hw);
-+ unsigned int val;
-+
-+ regmap_read(mux->regmap, mux->reg, &val);
-+
-+ val >>= mux->shift;
-+ val &= mux->mask;
-+
-+ if (val >= num_parents)
-+ return -EINVAL;
-+
-+ return val;
-+}
-+
-+static int clk_cpumux_set_parent(struct clk_hw *hw, u8 index)
-+{
-+ struct mtk_clk_cpumux *mux = to_mtk_clk_mux(hw);
-+ u32 mask, val;
-+
-+ val = index << mux->shift;
-+ mask = mux->mask << mux->shift;
-+
-+ return regmap_update_bits(mux->regmap, mux->reg, mask, val);
-+}
-+
-+static const struct clk_ops clk_cpumux_ops = {
-+ .get_parent = clk_cpumux_get_parent,
-+ .set_parent = clk_cpumux_set_parent,
-+};
-+
-+static struct clk __init *mtk_clk_register_cpumux(const struct mtk_composite *mux,
-+ struct regmap *regmap)
-+{
-+ struct mtk_clk_cpumux *cpumux;
-+ struct clk *clk;
-+ struct clk_init_data init;
-+
-+ cpumux = kzalloc(sizeof(*cpumux), GFP_KERNEL);
-+ if (!cpumux)
-+ return ERR_PTR(-ENOMEM);
-+
-+ init.name = mux->name;
-+ init.ops = &clk_cpumux_ops;
-+ init.parent_names = mux->parent_names;
-+ init.num_parents = mux->num_parents;
-+ init.flags = mux->flags;
-+
-+ cpumux->reg = mux->mux_reg;
-+ cpumux->shift = mux->mux_shift;
-+ cpumux->mask = BIT(mux->mux_width) - 1;
-+ cpumux->regmap = regmap;
-+ cpumux->hw.init = &init;
-+
-+ clk = clk_register(NULL, &cpumux->hw);
-+ if (IS_ERR(clk))
-+ kfree(cpumux);
-+
-+ return clk;
-+}
-+
-+int __init mtk_clk_register_cpumuxes(struct device_node *node,
-+ const struct mtk_composite *clks, int num,
-+ struct clk_onecell_data *clk_data)
-+{
-+ int i;
-+ struct clk *clk;
-+ struct regmap *regmap;
-+
-+ regmap = syscon_node_to_regmap(node);
-+ if (IS_ERR(regmap)) {
-+ pr_err("Cannot find regmap for %s: %ld\n", node->full_name,
-+ PTR_ERR(regmap));
-+ return PTR_ERR(regmap);
-+ }
-+
-+ for (i = 0; i < num; i++) {
-+ const struct mtk_composite *mux = &clks[i];
-+
-+ clk = mtk_clk_register_cpumux(mux, regmap);
-+ if (IS_ERR(clk)) {
-+ pr_err("Failed to register clk %s: %ld\n",
-+ mux->name, PTR_ERR(clk));
-+ continue;
-+ }
-+
-+ clk_data->clks[mux->id] = clk;
-+ }
-+
-+ return 0;
-+}
---- /dev/null
-+++ b/drivers/clk/mediatek/clk-cpumux.h
-@@ -0,0 +1,22 @@
-+/*
-+ * Copyright (c) 2015 Linaro Ltd.
-+ * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#ifndef __DRV_CLK_CPUMUX_H
-+#define __DRV_CLK_CPUMUX_H
-+
-+int mtk_clk_register_cpumuxes(struct device_node *node,
-+ const struct mtk_composite *clks, int num,
-+ struct clk_onecell_data *clk_data);
-+
-+#endif /* __DRV_CLK_CPUMUX_H */
---- a/drivers/clk/mediatek/clk-mt2701.c
-+++ b/drivers/clk/mediatek/clk-mt2701.c
-@@ -18,6 +18,7 @@
-
- #include "clk-mtk.h"
- #include "clk-gate.h"
-+#include "clk-cpumux.h"
-
- #include <dt-bindings/clock/mt2701-clk.h>
-
-@@ -465,6 +466,10 @@ static const char * const cpu_parents[]
- "mmpll"
- };
-
-+static const struct mtk_composite cpu_muxes[] __initconst = {
-+ MUX(CLK_INFRA_CPUSEL, "infra_cpu_sel", cpu_parents, 0x0000, 2, 2),
-+};
-+
- static const struct mtk_composite top_muxes[] __initconst = {
- MUX_GATE(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
- 0x0040, 0, 3, INVALID_MUX_GATE_BIT),
-@@ -677,6 +682,9 @@ static void __init mtk_infrasys_init(str
- mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
- clk_data);
-
-+ mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
-+ clk_data);
-+
- r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
- if (r)
- pr_err("%s(): could not register clock provider: %d\n",
---- a/drivers/clk/mediatek/clk-mt8173.c
-+++ b/drivers/clk/mediatek/clk-mt8173.c
-@@ -18,6 +18,7 @@
-
- #include "clk-mtk.h"
- #include "clk-gate.h"
-+#include "clk-cpumux.h"
-
- #include <dt-bindings/clock/mt8173-clk.h>
-
-@@ -525,6 +526,25 @@ static const char * const i2s3_b_ck_pare
- "apll2_div5"
- };
-
-+static const char * const ca53_parents[] __initconst = {
-+ "clk26m",
-+ "armca7pll",
-+ "mainpll",
-+ "univpll"
-+};
-+
-+static const char * const ca57_parents[] __initconst = {
-+ "clk26m",
-+ "armca15pll",
-+ "mainpll",
-+ "univpll"
-+};
-+
-+static const struct mtk_composite cpu_muxes[] __initconst = {
-+ MUX(CLK_INFRA_CA53SEL, "infra_ca53_sel", ca53_parents, 0x0000, 0, 2),
-+ MUX(CLK_INFRA_CA57SEL, "infra_ca57_sel", ca57_parents, 0x0000, 2, 2),
-+};
-+
- static const struct mtk_composite top_muxes[] __initconst = {
- /* CLK_CFG_0 */
- MUX(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, 0x0040, 0, 3),
-@@ -948,6 +968,9 @@ static void __init mtk_infrasys_init(str
- clk_data);
- mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
-
-+ mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
-+ clk_data);
-+
- r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
- if (r)
- pr_err("%s(): could not register clock provider: %d\n",
---- a/include/dt-bindings/clock/mt2701-clk.h
-+++ b/include/dt-bindings/clock/mt2701-clk.h
-@@ -221,7 +221,8 @@
- #define CLK_INFRA_PMICWRAP 17
- #define CLK_INFRA_DDCCI 18
- #define CLK_INFRA_CLK_13M 19
--#define CLK_INFRA_NR 20
-+#define CLK_INFRA_CPUSEL 20
-+#define CLK_INFRA_NR 21
-
- /* PERICFG */
-
---- a/include/dt-bindings/clock/mt8173-clk.h
-+++ b/include/dt-bindings/clock/mt8173-clk.h
-@@ -193,7 +193,9 @@
- #define CLK_INFRA_PMICSPI 10
- #define CLK_INFRA_PMICWRAP 11
- #define CLK_INFRA_CLK_13M 12
--#define CLK_INFRA_NR_CLK 13
-+#define CLK_INFRA_CA53SEL 13
-+#define CLK_INFRA_CA57SEL 14
-+#define CLK_INFRA_NR_CLK 15
-
- /* PERI_SYS */
-
diff --git a/target/linux/mediatek/patches-4.9/0015-cpufreq-mediatek-add-driver.patch b/target/linux/mediatek/patches-4.9/0015-cpufreq-mediatek-add-driver.patch
deleted file mode 100644
index af60025c0a..0000000000
--- a/target/linux/mediatek/patches-4.9/0015-cpufreq-mediatek-add-driver.patch
+++ /dev/null
@@ -1,433 +0,0 @@
-From 8aa2c6c4d8b20c0e9c69b15db4a0039d33f8b365 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 30 Mar 2016 23:48:53 +0200
-Subject: [PATCH 15/57] cpufreq: mediatek: add driver
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/cpufreq/Kconfig.arm | 9 +
- drivers/cpufreq/Makefile | 1 +
- drivers/cpufreq/mt7623-cpufreq.c | 389 +++++++++++++++++++++++++++++++++++++++
- 3 files changed, 399 insertions(+)
- create mode 100644 drivers/cpufreq/mt7623-cpufreq.c
-
---- a/drivers/cpufreq/Kconfig.arm
-+++ b/drivers/cpufreq/Kconfig.arm
-@@ -74,6 +74,15 @@ config ARM_KIRKWOOD_CPUFREQ
- This adds the CPUFreq driver for Marvell Kirkwood
- SoCs.
-
-+config ARM_MT7623_CPUFREQ
-+ bool "Mediatek MT7623 CPUFreq support"
-+ depends on ARCH_MEDIATEK && REGULATOR
-+ depends on ARM || (ARM_CPU_TOPOLOGY && COMPILE_TEST)
-+ depends on !CPU_THERMAL || THERMAL=y
-+ select PM_OPP
-+ help
-+ This adds the CPUFreq driver support for Mediatek MT7623 SoC.
-+
- config ARM_MT8173_CPUFREQ
- tristate "Mediatek MT8173 CPUFreq support"
- depends on ARCH_MEDIATEK && REGULATOR
---- a/drivers/cpufreq/Makefile
-+++ b/drivers/cpufreq/Makefile
-@@ -58,6 +58,7 @@ obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += hi
- obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o
- obj-$(CONFIG_ARM_INTEGRATOR) += integrator-cpufreq.o
- obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
-+obj-$(CONFIG_ARM_MT7623_CPUFREQ) += mt7623-cpufreq.o
- obj-$(CONFIG_ARM_MT8173_CPUFREQ) += mt8173-cpufreq.o
- obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
- obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o
---- /dev/null
-+++ b/drivers/cpufreq/mt7623-cpufreq.c
-@@ -0,0 +1,389 @@
-+/*
-+ * Copyright (c) 2015 Linaro Ltd.
-+ * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/cpu.h>
-+#include <linux/cpu_cooling.h>
-+#include <linux/cpufreq.h>
-+#include <linux/cpumask.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_opp.h>
-+#include <linux/regulator/consumer.h>
-+#include <linux/slab.h>
-+#include <linux/thermal.h>
-+
-+#define VOLT_TOL (10000)
-+
-+/*
-+ * When scaling the clock frequency of a CPU clock domain, the clock source
-+ * needs to be switched to another stable PLL clock temporarily until
-+ * the original PLL becomes stable at target frequency.
-+ */
-+struct mtk_cpu_dvfs_info {
-+ struct device *cpu_dev;
-+ struct regulator *proc_reg;
-+ struct clk *cpu_clk;
-+ struct clk *inter_clk;
-+ struct thermal_cooling_device *cdev;
-+ int intermediate_voltage;
-+};
-+
-+static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc)
-+{
-+ return regulator_set_voltage(info->proc_reg, vproc,
-+ vproc + VOLT_TOL);
-+}
-+
-+static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,
-+ unsigned int index)
-+{
-+ struct cpufreq_frequency_table *freq_table = policy->freq_table;
-+ struct clk *cpu_clk = policy->clk;
-+ struct clk *armpll = clk_get_parent(cpu_clk);
-+ struct mtk_cpu_dvfs_info *info = policy->driver_data;
-+ struct device *cpu_dev = info->cpu_dev;
-+ struct dev_pm_opp *opp;
-+ long freq_hz, old_freq_hz;
-+ int vproc, old_vproc, inter_vproc, target_vproc, ret;
-+
-+ inter_vproc = info->intermediate_voltage;
-+
-+ old_freq_hz = clk_get_rate(cpu_clk);
-+ old_vproc = regulator_get_voltage(info->proc_reg);
-+
-+ freq_hz = freq_table[index].frequency * 1000;
-+
-+ rcu_read_lock();
-+ opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
-+ if (IS_ERR(opp)) {
-+ rcu_read_unlock();
-+ pr_err("cpu%d: failed to find OPP for %ld\n",
-+ policy->cpu, freq_hz);
-+ return PTR_ERR(opp);
-+ }
-+ vproc = dev_pm_opp_get_voltage(opp);
-+ rcu_read_unlock();
-+
-+ /*
-+ * If the new voltage or the intermediate voltage is higher than the
-+ * current voltage, scale up voltage first.
-+ */
-+ target_vproc = (inter_vproc > vproc) ? inter_vproc : vproc;
-+ if (old_vproc < target_vproc) {
-+ ret = mtk_cpufreq_set_voltage(info, target_vproc);
-+ if (ret) {
-+ pr_err("cpu%d: failed to scale up voltage!\n",
-+ policy->cpu);
-+ mtk_cpufreq_set_voltage(info, old_vproc);
-+ return ret;
-+ }
-+ }
-+
-+ /* Reparent the CPU clock to intermediate clock. */
-+ ret = clk_set_parent(cpu_clk, info->inter_clk);
-+ if (ret) {
-+ pr_err("cpu%d: failed to re-parent cpu clock!\n",
-+ policy->cpu);
-+ mtk_cpufreq_set_voltage(info, old_vproc);
-+ WARN_ON(1);
-+ return ret;
-+ }
-+
-+ /* Set the original PLL to target rate. */
-+ ret = clk_set_rate(armpll, freq_hz);
-+ if (ret) {
-+ pr_err("cpu%d: failed to scale cpu clock rate!\n",
-+ policy->cpu);
-+ clk_set_parent(cpu_clk, armpll);
-+ mtk_cpufreq_set_voltage(info, old_vproc);
-+ return ret;
-+ }
-+
-+ /* Set parent of CPU clock back to the original PLL. */
-+ ret = clk_set_parent(cpu_clk, armpll);
-+ if (ret) {
-+ pr_err("cpu%d: failed to re-parent cpu clock!\n",
-+ policy->cpu);
-+ mtk_cpufreq_set_voltage(info, inter_vproc);
-+ WARN_ON(1);
-+ return ret;
-+ }
-+
-+ /*
-+ * If the new voltage is lower than the intermediate voltage or the
-+ * original voltage, scale down to the new voltage.
-+ */
-+ if (vproc < inter_vproc || vproc < old_vproc) {
-+ ret = mtk_cpufreq_set_voltage(info, vproc);
-+ if (ret) {
-+ pr_err("cpu%d: failed to scale down voltage!\n",
-+ policy->cpu);
-+ clk_set_parent(cpu_clk, info->inter_clk);
-+ clk_set_rate(armpll, old_freq_hz);
-+ clk_set_parent(cpu_clk, armpll);
-+ return ret;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static void mtk_cpufreq_ready(struct cpufreq_policy *policy)
-+{
-+ struct mtk_cpu_dvfs_info *info = policy->driver_data;
-+ struct device_node *np = of_node_get(info->cpu_dev->of_node);
-+
-+ if (WARN_ON(!np))
-+ return;
-+
-+ if (of_find_property(np, "#cooling-cells", NULL)) {
-+ info->cdev = of_cpufreq_cooling_register(np,
-+ policy->related_cpus);
-+
-+ if (IS_ERR(info->cdev)) {
-+ dev_err(info->cpu_dev,
-+ "running cpufreq without cooling device: %ld\n",
-+ PTR_ERR(info->cdev));
-+
-+ info->cdev = NULL;
-+ }
-+ }
-+
-+ of_node_put(np);
-+}
-+
-+static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
-+{
-+ struct device *cpu_dev;
-+ struct regulator *proc_reg = ERR_PTR(-ENODEV);
-+ struct clk *cpu_clk = ERR_PTR(-ENODEV);
-+ struct clk *inter_clk = ERR_PTR(-ENODEV);
-+ struct dev_pm_opp *opp;
-+ unsigned long rate;
-+ int ret;
-+
-+ cpu_dev = get_cpu_device(cpu);
-+ if (!cpu_dev) {
-+ pr_err("failed to get cpu%d device\n", cpu);
-+ return -ENODEV;
-+ }
-+
-+ cpu_clk = clk_get(cpu_dev, "cpu");
-+ if (IS_ERR(cpu_clk)) {
-+ if (PTR_ERR(cpu_clk) == -EPROBE_DEFER)
-+ pr_warn("cpu clk for cpu%d not ready, retry.\n", cpu);
-+ else
-+ pr_err("failed to get cpu clk for cpu%d\n", cpu);
-+
-+ ret = PTR_ERR(cpu_clk);
-+ return ret;
-+ }
-+
-+ inter_clk = clk_get(cpu_dev, "intermediate");
-+ if (IS_ERR(inter_clk)) {
-+ if (PTR_ERR(inter_clk) == -EPROBE_DEFER)
-+ pr_warn("intermediate clk for cpu%d not ready, retry.\n",
-+ cpu);
-+ else
-+ pr_err("failed to get intermediate clk for cpu%d\n",
-+ cpu);
-+
-+ ret = PTR_ERR(inter_clk);
-+ goto out_free_resources;
-+ }
-+
-+ proc_reg = regulator_get_exclusive(cpu_dev, "proc");
-+ if (IS_ERR(proc_reg)) {
-+ if (PTR_ERR(proc_reg) == -EPROBE_DEFER)
-+ pr_warn("proc regulator for cpu%d not ready, retry.\n",
-+ cpu);
-+ else
-+ pr_err("failed to get proc regulator for cpu%d\n",
-+ cpu);
-+
-+ ret = PTR_ERR(proc_reg);
-+ goto out_free_resources;
-+ }
-+
-+ ret = dev_pm_opp_of_add_table(cpu_dev);
-+ if (ret) {
-+ pr_warn("no OPP table for cpu%d\n", cpu);
-+ goto out_free_resources;
-+ }
-+
-+ /* Search a safe voltage for intermediate frequency. */
-+ rate = clk_get_rate(inter_clk);
-+ rcu_read_lock();
-+ opp = dev_pm_opp_find_freq_ceil(cpu_dev, &rate);
-+ if (IS_ERR(opp)) {
-+ rcu_read_unlock();
-+ pr_err("failed to get intermediate opp for cpu%d\n", cpu);
-+ ret = PTR_ERR(opp);
-+ goto out_free_opp_table;
-+ }
-+ info->intermediate_voltage = dev_pm_opp_get_voltage(opp);
-+ rcu_read_unlock();
-+
-+ info->cpu_dev = cpu_dev;
-+ info->proc_reg = proc_reg;
-+ info->cpu_clk = cpu_clk;
-+ info->inter_clk = inter_clk;
-+
-+ return 0;
-+
-+out_free_opp_table:
-+ dev_pm_opp_of_remove_table(cpu_dev);
-+
-+out_free_resources:
-+ if (!IS_ERR(proc_reg))
-+ regulator_put(proc_reg);
-+ if (!IS_ERR(cpu_clk))
-+ clk_put(cpu_clk);
-+ if (!IS_ERR(inter_clk))
-+ clk_put(inter_clk);
-+
-+ return ret;
-+}
-+
-+static void mtk_cpu_dvfs_info_release(struct mtk_cpu_dvfs_info *info)
-+{
-+ if (!IS_ERR(info->proc_reg))
-+ regulator_put(info->proc_reg);
-+ if (!IS_ERR(info->cpu_clk))
-+ clk_put(info->cpu_clk);
-+ if (!IS_ERR(info->inter_clk))
-+ clk_put(info->inter_clk);
-+
-+ dev_pm_opp_of_remove_table(info->cpu_dev);
-+}
-+
-+static int mtk_cpufreq_init(struct cpufreq_policy *policy)
-+{
-+ struct mtk_cpu_dvfs_info *info;
-+ struct cpufreq_frequency_table *freq_table;
-+ int ret;
-+
-+ info = kzalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return -ENOMEM;
-+
-+ ret = mtk_cpu_dvfs_info_init(info, policy->cpu);
-+ if (ret) {
-+ pr_err("%s failed to initialize dvfs info for cpu%d\n",
-+ __func__, policy->cpu);
-+ goto out_free_dvfs_info;
-+ }
-+
-+ ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table);
-+ if (ret) {
-+ pr_err("failed to init cpufreq table for cpu%d: %d\n",
-+ policy->cpu, ret);
-+ goto out_release_dvfs_info;
-+ }
-+
-+ ret = cpufreq_table_validate_and_show(policy, freq_table);
-+ if (ret) {
-+ pr_err("%s: invalid frequency table: %d\n", __func__, ret);
-+ goto out_free_cpufreq_table;
-+ }
-+
-+ /* CPUs in the same cluster share a clock and power domain. */
-+ cpumask_setall(policy->cpus);
-+ policy->driver_data = info;
-+ policy->clk = info->cpu_clk;
-+
-+ return 0;
-+
-+out_free_cpufreq_table:
-+ dev_pm_opp_free_cpufreq_table(info->cpu_dev, &freq_table);
-+
-+out_release_dvfs_info:
-+ mtk_cpu_dvfs_info_release(info);
-+
-+out_free_dvfs_info:
-+ kfree(info);
-+
-+ return ret;
-+}
-+
-+static int mtk_cpufreq_exit(struct cpufreq_policy *policy)
-+{
-+ struct mtk_cpu_dvfs_info *info = policy->driver_data;
-+
-+ cpufreq_cooling_unregister(info->cdev);
-+ dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table);
-+ mtk_cpu_dvfs_info_release(info);
-+ kfree(info);
-+
-+ return 0;
-+}
-+
-+static struct cpufreq_driver mt7623_cpufreq_driver = {
-+ .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
-+ .verify = cpufreq_generic_frequency_table_verify,
-+ .target_index = mtk_cpufreq_set_target,
-+ .get = cpufreq_generic_get,
-+ .init = mtk_cpufreq_init,
-+ .exit = mtk_cpufreq_exit,
-+ .ready = mtk_cpufreq_ready,
-+ .name = "mtk-cpufreq",
-+ .attr = cpufreq_generic_attr,
-+};
-+
-+static int mt7623_cpufreq_probe(struct platform_device *pdev)
-+{
-+ int ret;
-+
-+ ret = cpufreq_register_driver(&mt7623_cpufreq_driver);
-+ if (ret)
-+ pr_err("failed to register mtk cpufreq driver\n");
-+
-+ return ret;
-+}
-+
-+static struct platform_driver mt7623_cpufreq_platdrv = {
-+ .driver = {
-+ .name = "mt7623-cpufreq",
-+ },
-+ .probe = mt7623_cpufreq_probe,
-+};
-+
-+static int mt7623_cpufreq_driver_init(void)
-+{
-+ struct platform_device *pdev;
-+ int err;
-+
-+ if (!of_machine_is_compatible("mediatek,mt7623"))
-+ return -ENODEV;
-+
-+ err = platform_driver_register(&mt7623_cpufreq_platdrv);
-+ if (err)
-+ return err;
-+
-+ /*
-+ * Since there's no place to hold device registration code and no
-+ * device tree based way to match cpufreq driver yet, both the driver
-+ * and the device registration codes are put here to handle defer
-+ * probing.
-+ */
-+ pdev = platform_device_register_simple("mt7623-cpufreq", -1, NULL, 0);
-+ if (IS_ERR(pdev)) {
-+ pr_err("failed to register mtk-cpufreq platform device\n");
-+ return PTR_ERR(pdev);
-+ }
-+
-+ return 0;
-+}
-+device_initcall(mt7623_cpufreq_driver_init);
diff --git a/target/linux/mediatek/patches-4.9/0016-pwm-add-pwm-mediatek.patch b/target/linux/mediatek/patches-4.9/0016-pwm-add-pwm-mediatek.patch
deleted file mode 100644
index 2e8414ea20..0000000000
--- a/target/linux/mediatek/patches-4.9/0016-pwm-add-pwm-mediatek.patch
+++ /dev/null
@@ -1,274 +0,0 @@
-From 201be68268eddb1568c41780a62868cc1666a2de Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Fri, 6 May 2016 02:55:48 +0200
-Subject: [PATCH 16/57] pwm: add pwm-mediatek
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/pwm/Kconfig | 9 ++
- drivers/pwm/Makefile | 1 +
- drivers/pwm/pwm-mediatek.c | 230 +++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 240 insertions(+)
- create mode 100644 drivers/pwm/pwm-mediatek.c
-
---- a/drivers/pwm/Kconfig
-+++ b/drivers/pwm/Kconfig
-@@ -282,6 +282,15 @@ config PWM_MTK_DISP
- To compile this driver as a module, choose M here: the module
- will be called pwm-mtk-disp.
-
-+config PWM_MEDIATEK
-+ tristate "MediaTek PWM support"
-+ depends on ARCH_MEDIATEK || COMPILE_TEST
-+ help
-+ Generic PWM framework driver for Mediatek ARM SoC.
-+
-+ To compile this driver as a module, choose M here: the module
-+ will be called pwm-mxs.
-+
- config PWM_MXS
- tristate "Freescale MXS PWM support"
- depends on ARCH_MXS && OF
---- a/drivers/pwm/Makefile
-+++ b/drivers/pwm/Makefile
-@@ -25,6 +25,7 @@ obj-$(CONFIG_PWM_LPSS) += pwm-lpss.o
- obj-$(CONFIG_PWM_LPSS_PCI) += pwm-lpss-pci.o
- obj-$(CONFIG_PWM_LPSS_PLATFORM) += pwm-lpss-platform.o
- obj-$(CONFIG_PWM_MESON) += pwm-meson.o
-+obj-$(CONFIG_PWM_MEDIATEK) += pwm-mediatek.o
- obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o
- obj-$(CONFIG_PWM_MXS) += pwm-mxs.o
- obj-$(CONFIG_PWM_OMAP_DMTIMER) += pwm-omap-dmtimer.o
---- /dev/null
-+++ b/drivers/pwm/pwm-mediatek.c
-@@ -0,0 +1,230 @@
-+/*
-+ * Mediatek Pulse Width Modulator driver
-+ *
-+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
-+ *
-+ * This file is licensed under the terms of the GNU General Public
-+ * License version 2. This program is licensed "as is" without any
-+ * warranty of any kind, whether express or implied.
-+ */
-+
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/ioport.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/clk.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/pwm.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+
-+#define NUM_PWM 5
-+
-+/* PWM registers and bits definitions */
-+#define PWMCON 0x00
-+#define PWMHDUR 0x04
-+#define PWMLDUR 0x08
-+#define PWMGDUR 0x0c
-+#define PWMWAVENUM 0x28
-+#define PWMDWIDTH 0x2c
-+#define PWMTHRES 0x30
-+
-+/**
-+ * struct mtk_pwm_chip - struct representing pwm chip
-+ *
-+ * @mmio_base: base address of pwm chip
-+ * @chip: linux pwm chip representation
-+ */
-+struct mtk_pwm_chip {
-+ void __iomem *mmio_base;
-+ struct pwm_chip chip;
-+ struct clk *clk_top;
-+ struct clk *clk_main;
-+ struct clk *clk_pwm[NUM_PWM];
-+};
-+
-+static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
-+{
-+ return container_of(chip, struct mtk_pwm_chip, chip);
-+}
-+
-+static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
-+ unsigned long offset)
-+{
-+ return ioread32(chip->mmio_base + 0x10 + (num * 0x40) + offset);
-+}
-+
-+static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
-+ unsigned int num, unsigned long offset,
-+ unsigned long val)
-+{
-+ iowrite32(val, chip->mmio_base + 0x10 + (num * 0x40) + offset);
-+}
-+
-+static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
-+ int duty_ns, int period_ns)
-+{
-+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
-+ u32 resolution = 100 / 4;
-+ u32 clkdiv = 0;
-+
-+ resolution = 1000000000 / (clk_get_rate(pc->clk_pwm[pwm->hwpwm]));
-+
-+ while (period_ns / resolution > 8191) {
-+ clkdiv++;
-+ resolution *= 2;
-+ }
-+
-+ if (clkdiv > 7)
-+ return -1;
-+
-+ mtk_pwm_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | BIT(3) | clkdiv);
-+ mtk_pwm_writel(pc, pwm->hwpwm, PWMDWIDTH, period_ns / resolution);
-+ mtk_pwm_writel(pc, pwm->hwpwm, PWMTHRES, duty_ns / resolution);
-+ return 0;
-+}
-+
-+static int mtk_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
-+{
-+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
-+ u32 val;
-+ int ret;
-+
-+ ret = clk_prepare(pc->clk_pwm[pwm->hwpwm]);
-+ if (ret < 0)
-+ return ret;
-+
-+ val = ioread32(pc->mmio_base);
-+ val |= BIT(pwm->hwpwm);
-+ iowrite32(val, pc->mmio_base);
-+
-+ return 0;
-+}
-+
-+static void mtk_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
-+{
-+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
-+ u32 val;
-+
-+ val = ioread32(pc->mmio_base);
-+ val &= ~BIT(pwm->hwpwm);
-+ iowrite32(val, pc->mmio_base);
-+ clk_unprepare(pc->clk_pwm[pwm->hwpwm]);
-+}
-+
-+static const struct pwm_ops mtk_pwm_ops = {
-+ .config = mtk_pwm_config,
-+ .enable = mtk_pwm_enable,
-+ .disable = mtk_pwm_disable,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int mtk_pwm_probe(struct platform_device *pdev)
-+{
-+ struct mtk_pwm_chip *pc;
-+ struct resource *r;
-+ int ret;
-+
-+ pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
-+ if (!pc)
-+ return -ENOMEM;
-+
-+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ pc->mmio_base = devm_ioremap_resource(&pdev->dev, r);
-+ if (IS_ERR(pc->mmio_base))
-+ return PTR_ERR(pc->mmio_base);
-+
-+ pc->clk_main = devm_clk_get(&pdev->dev, "main");
-+ if (IS_ERR(pc->clk_main))
-+ return PTR_ERR(pc->clk_main);
-+
-+ pc->clk_top = devm_clk_get(&pdev->dev, "top");
-+ if (IS_ERR(pc->clk_top))
-+ return PTR_ERR(pc->clk_top);
-+
-+ pc->clk_pwm[0] = devm_clk_get(&pdev->dev, "pwm1");
-+ if (IS_ERR(pc->clk_pwm[0]))
-+ return PTR_ERR(pc->clk_pwm[0]);
-+
-+ pc->clk_pwm[1] = devm_clk_get(&pdev->dev, "pwm2");
-+ if (IS_ERR(pc->clk_pwm[1]))
-+ return PTR_ERR(pc->clk_pwm[1]);
-+
-+ pc->clk_pwm[2] = devm_clk_get(&pdev->dev, "pwm3");
-+ if (IS_ERR(pc->clk_pwm[2]))
-+ return PTR_ERR(pc->clk_pwm[2]);
-+
-+ pc->clk_pwm[3] = devm_clk_get(&pdev->dev, "pwm4");
-+ if (IS_ERR(pc->clk_pwm[3]))
-+ return PTR_ERR(pc->clk_pwm[3]);
-+
-+ pc->clk_pwm[4] = devm_clk_get(&pdev->dev, "pwm5");
-+ if (IS_ERR(pc->clk_pwm[4]))
-+ return PTR_ERR(pc->clk_pwm[4]);
-+
-+ ret = clk_prepare(pc->clk_top);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = clk_prepare(pc->clk_main);
-+ if (ret < 0)
-+ goto disable_clk_top;
-+
-+ platform_set_drvdata(pdev, pc);
-+
-+ pc->chip.dev = &pdev->dev;
-+ pc->chip.ops = &mtk_pwm_ops;
-+ pc->chip.base = -1;
-+ pc->chip.npwm = NUM_PWM;
-+
-+ ret = pwmchip_add(&pc->chip);
-+ if (ret < 0) {
-+ dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
-+ goto disable_clk_main;
-+ }
-+
-+ return 0;
-+
-+disable_clk_main:
-+ clk_unprepare(pc->clk_main);
-+disable_clk_top:
-+ clk_unprepare(pc->clk_top);
-+
-+ return ret;
-+}
-+
-+static int mtk_pwm_remove(struct platform_device *pdev)
-+{
-+ struct mtk_pwm_chip *pc = platform_get_drvdata(pdev);
-+ int i;
-+
-+ for (i = 0; i < NUM_PWM; i++)
-+ pwm_disable(&pc->chip.pwms[i]);
-+
-+ return pwmchip_remove(&pc->chip);
-+}
-+
-+static const struct of_device_id mtk_pwm_of_match[] = {
-+ { .compatible = "mediatek,mt7623-pwm" },
-+ { }
-+};
-+
-+MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
-+
-+static struct platform_driver mtk_pwm_driver = {
-+ .driver = {
-+ .name = "mtk-pwm",
-+ .owner = THIS_MODULE,
-+ .of_match_table = mtk_pwm_of_match,
-+ },
-+ .probe = mtk_pwm_probe,
-+ .remove = mtk_pwm_remove,
-+};
-+
-+module_platform_driver(mtk_pwm_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
-+MODULE_ALIAS("platform:mtk-pwm");
diff --git a/target/linux/mediatek/patches-4.9/0017-mfd-mt6397-Add-MT6323-LED-support-into-MT6397-driver.patch b/target/linux/mediatek/patches-4.9/0017-mfd-mt6397-Add-MT6323-LED-support-into-MT6397-driver.patch
deleted file mode 100644
index 73ac0eead2..0000000000
--- a/target/linux/mediatek/patches-4.9/0017-mfd-mt6397-Add-MT6323-LED-support-into-MT6397-driver.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 2b866d69f6198701457d29c5886c0ad7865c785f Mon Sep 17 00:00:00 2001
-From: Sean Wang <sean.wang@mediatek.com>
-Date: Sat, 25 Feb 2017 02:47:21 +0800
-Subject: [PATCH 17/57] mfd: mt6397: Add MT6323 LED support into MT6397 driver
-
-Add compatible string as "mt6323-led" that will make
-the OF core spawn child devices for the LED subnode
-of that MT6323 MFD device.
-
-Signed-off-by: Sean Wang <sean.wang@mediatek.com>
----
- drivers/mfd/mt6397-core.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/mfd/mt6397-core.c
-+++ b/drivers/mfd/mt6397-core.c
-@@ -48,6 +48,10 @@ static const struct mfd_cell mt6323_devs
- .name = "mt6323-regulator",
- .of_compatible = "mediatek,mt6323-regulator"
- },
-+ {
-+ .name = "mt6323-led",
-+ .of_compatible = "mediatek,mt6323-led"
-+ },
- };
-
- static const struct mfd_cell mt6397_devs[] = {
diff --git a/target/linux/mediatek/patches-4.9/0018-dt-bindings-leds-Add-document-bindings-for-leds-mt63.patch b/target/linux/mediatek/patches-4.9/0018-dt-bindings-leds-Add-document-bindings-for-leds-mt63.patch
deleted file mode 100644
index ca0ee0443a..0000000000
--- a/target/linux/mediatek/patches-4.9/0018-dt-bindings-leds-Add-document-bindings-for-leds-mt63.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From 424ca23e68b043ce26d6981839ca825ef8637aba Mon Sep 17 00:00:00 2001
-From: Sean Wang <sean.wang@mediatek.com>
-Date: Mon, 20 Mar 2017 14:47:24 +0800
-Subject: [PATCH 18/57] dt-bindings: leds: Add document bindings for
- leds-mt6323
-
-This patch adds documentation for devicetree bindings for LED support on
-MT6323 PMIC.
-
-Signed-off-by: Sean Wang <sean.wang@mediatek.com>
----
- .../devicetree/bindings/leds/leds-mt6323.txt | 60 ++++++++++++++++++++++
- 1 file changed, 60 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/leds/leds-mt6323.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/leds/leds-mt6323.txt
-@@ -0,0 +1,60 @@
-+Device Tree Bindings for LED support on MT6323 PMIC
-+
-+MT6323 LED controller is subfunction provided by MT6323 PMIC, so the LED
-+controllers are defined as the subnode of the function node provided by MT6323
-+PMIC controller that is being defined as one kind of Muti-Function Device (MFD)
-+using shared bus called PMIC wrapper for each subfunction to access remote
-+MT6323 PMIC hardware.
-+
-+For MT6323 MFD bindings see:
-+Documentation/devicetree/bindings/mfd/mt6397.txt
-+For MediaTek PMIC wrapper bindings see:
-+Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
-+
-+Required properties:
-+- compatible : Must be "mediatek,mt6323-led"
-+- address-cells : Must be 1
-+- size-cells : Must be 0
-+
-+Each led is represented as a child node of the mediatek,mt6323-led that
-+describes the initial behavior for each LED physically and currently only four
-+LED child nodes can be supported.
-+
-+Required properties for the LED child node:
-+- reg : LED channel number (0..3)
-+
-+Optional properties for the LED child node:
-+- label : See Documentation/devicetree/bindings/leds/common.txt
-+- linux,default-trigger : See Documentation/devicetree/bindings/leds/common.txt
-+- default-state: See Documentation/devicetree/bindings/leds/common.txt
-+
-+Example:
-+
-+ mt6323: pmic {
-+ compatible = "mediatek,mt6323";
-+
-+ ...
-+
-+ mt6323led: leds {
-+ compatible = "mediatek,mt6323-led";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ led@0 {
-+ reg = <0>;
-+ label = "LED0";
-+ linux,default-trigger = "timer";
-+ default-state = "on";
-+ };
-+ led@1 {
-+ reg = <1>;
-+ label = "LED1";
-+ default-state = "off";
-+ };
-+ led@2 {
-+ reg = <2>;
-+ label = "LED2";
-+ default-state = "on";
-+ };
-+ };
-+ };
diff --git a/target/linux/mediatek/patches-4.9/0019-dt-bindings-mfd-Add-the-description-for-LED-as-the-s.patch b/target/linux/mediatek/patches-4.9/0019-dt-bindings-mfd-Add-the-description-for-LED-as-the-s.patch
deleted file mode 100644
index c8afdc0888..0000000000
--- a/target/linux/mediatek/patches-4.9/0019-dt-bindings-mfd-Add-the-description-for-LED-as-the-s.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 7c137e4b83f32a67ccf6b39fa455aca71980a21f Mon Sep 17 00:00:00 2001
-From: Sean Wang <sean.wang@mediatek.com>
-Date: Mon, 20 Mar 2017 14:47:25 +0800
-Subject: [PATCH 19/57] dt-bindings: mfd: Add the description for LED as the
- sub module
-
-This patch adds description for LED as the sub-module on MT6397/MT6323
-multifunction device.
-
-Signed-off-by: Sean Wang <sean.wang@mediatek.com>
----
- Documentation/devicetree/bindings/mfd/mt6397.txt | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/Documentation/devicetree/bindings/mfd/mt6397.txt
-+++ b/Documentation/devicetree/bindings/mfd/mt6397.txt
-@@ -6,6 +6,7 @@ MT6397/MT6323 is a multifunction device
- - Audio codec
- - GPIO
- - Clock
-+- LED
-
- It is interfaced to host controller using SPI interface by a proprietary hardware
- called PMIC wrapper or pwrap. MT6397/MT6323 MFD is a child device of pwrap.
diff --git a/target/linux/mediatek/patches-4.9/0020-leds-Add-LED-support-for-MT6323-PMIC.patch b/target/linux/mediatek/patches-4.9/0020-leds-Add-LED-support-for-MT6323-PMIC.patch
deleted file mode 100644
index 37b926de18..0000000000
--- a/target/linux/mediatek/patches-4.9/0020-leds-Add-LED-support-for-MT6323-PMIC.patch
+++ /dev/null
@@ -1,539 +0,0 @@
-From e482f9590f2e831c68bcf85e3f9f4c88bbd3329f Mon Sep 17 00:00:00 2001
-From: Sean Wang <sean.wang@mediatek.com>
-Date: Mon, 20 Mar 2017 14:47:26 +0800
-Subject: [PATCH 20/57] leds: Add LED support for MT6323 PMIC
-
-MT6323 PMIC is a multi-function device that includes LED function.
-It allows attaching up to 4 LEDs which can either be on, off or dimmed
-and/or blinked with the controller.
-
-Signed-off-by: Sean Wang <sean.wang@mediatek.com>
-Reviewed-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
----
- drivers/leds/Kconfig | 8 +
- drivers/leds/leds-mt6323.c | 502 +++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 510 insertions(+)
- create mode 100644 drivers/leds/leds-mt6323.c
-
---- a/drivers/leds/Kconfig
-+++ b/drivers/leds/Kconfig
-@@ -117,6 +117,14 @@ config LEDS_MIKROTIK_RB532
- This option enables support for the so called "User LED" of
- Mikrotik's Routerboard 532.
-
-+config LEDS_MT6323
-+ tristate "LED Support for Mediatek MT6323 PMIC"
-+ depends on LEDS_CLASS
-+ depends on MFD_MT6397
-+ help
-+ This option enables support for on-chip LED drivers found on
-+ Mediatek MT6323 PMIC.
-+
- config LEDS_S3C24XX
- tristate "LED Support for Samsung S3C24XX GPIO LEDs"
- depends on LEDS_CLASS
---- /dev/null
-+++ b/drivers/leds/leds-mt6323.c
-@@ -0,0 +1,502 @@
-+/*
-+ * LED driver for Mediatek MT6323 PMIC
-+ *
-+ * Copyright (C) 2017 Sean Wang <sean.wang@mediatek.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 Free Software Foundation; either version 2 of
-+ * the License, or (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+#include <linux/kernel.h>
-+#include <linux/leds.h>
-+#include <linux/mfd/mt6323/registers.h>
-+#include <linux/mfd/mt6397/core.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/regmap.h>
-+
-+/*
-+ * Register field for MT6323_TOP_CKPDN0 to enable
-+ * 32K clock common for LED device.
-+ */
-+#define MT6323_RG_DRV_32K_CK_PDN BIT(11)
-+#define MT6323_RG_DRV_32K_CK_PDN_MASK BIT(11)
-+
-+/*
-+ * Register field for MT6323_TOP_CKPDN2 to enable
-+ * individual clock for LED device.
-+ */
-+#define MT6323_RG_ISINK_CK_PDN(i) BIT(i)
-+#define MT6323_RG_ISINK_CK_PDN_MASK(i) BIT(i)
-+
-+/*
-+ * Register field for MT6323_TOP_CKCON1 to select
-+ * clock source.
-+ */
-+#define MT6323_RG_ISINK_CK_SEL_MASK(i) (BIT(10) << (i))
-+
-+/*
-+ * Register for MT6323_ISINK_CON0 to setup the
-+ * duty cycle of the blink.
-+ */
-+#define MT6323_ISINK_CON0(i) (MT6323_ISINK0_CON0 + 0x8 * (i))
-+#define MT6323_ISINK_DIM_DUTY_MASK (0x1f << 8)
-+#define MT6323_ISINK_DIM_DUTY(i) (((i) << 8) & \
-+ MT6323_ISINK_DIM_DUTY_MASK)
-+
-+/* Register to setup the period of the blink. */
-+#define MT6323_ISINK_CON1(i) (MT6323_ISINK0_CON1 + 0x8 * (i))
-+#define MT6323_ISINK_DIM_FSEL_MASK (0xffff)
-+#define MT6323_ISINK_DIM_FSEL(i) ((i) & MT6323_ISINK_DIM_FSEL_MASK)
-+
-+/* Register to control the brightness. */
-+#define MT6323_ISINK_CON2(i) (MT6323_ISINK0_CON2 + 0x8 * (i))
-+#define MT6323_ISINK_CH_STEP_SHIFT 12
-+#define MT6323_ISINK_CH_STEP_MASK (0x7 << 12)
-+#define MT6323_ISINK_CH_STEP(i) (((i) << 12) & \
-+ MT6323_ISINK_CH_STEP_MASK)
-+#define MT6323_ISINK_SFSTR0_TC_MASK (0x3 << 1)
-+#define MT6323_ISINK_SFSTR0_TC(i) (((i) << 1) & \
-+ MT6323_ISINK_SFSTR0_TC_MASK)
-+#define MT6323_ISINK_SFSTR0_EN_MASK BIT(0)
-+#define MT6323_ISINK_SFSTR0_EN BIT(0)
-+
-+/* Register to LED channel enablement. */
-+#define MT6323_ISINK_CH_EN_MASK(i) BIT(i)
-+#define MT6323_ISINK_CH_EN(i) BIT(i)
-+
-+#define MT6323_MAX_PERIOD 10000
-+#define MT6323_MAX_LEDS 4
-+#define MT6323_MAX_BRIGHTNESS 6
-+#define MT6323_UNIT_DUTY 3125
-+#define MT6323_CAL_HW_DUTY(o, p) DIV_ROUND_CLOSEST((o) * 100000ul,\
-+ (p) * MT6323_UNIT_DUTY)
-+
-+struct mt6323_leds;
-+
-+/**
-+ * struct mt6323_led - state container for the LED device
-+ * @id: the identifier in MT6323 LED device
-+ * @parent: the pointer to MT6323 LED controller
-+ * @cdev: LED class device for this LED device
-+ * @current_brightness: current state of the LED device
-+ */
-+struct mt6323_led {
-+ int id;
-+ struct mt6323_leds *parent;
-+ struct led_classdev cdev;
-+ enum led_brightness current_brightness;
-+};
-+
-+/**
-+ * struct mt6323_leds - state container for holding LED controller
-+ * of the driver
-+ * @dev: the device pointer
-+ * @hw: the underlying hardware providing shared
-+ * bus for the register operations
-+ * @lock: the lock among process context
-+ * @led: the array that contains the state of individual
-+ * LED device
-+ */
-+struct mt6323_leds {
-+ struct device *dev;
-+ struct mt6397_chip *hw;
-+ /* protect among process context */
-+ struct mutex lock;
-+ struct mt6323_led *led[MT6323_MAX_LEDS];
-+};
-+
-+static int mt6323_led_hw_brightness(struct led_classdev *cdev,
-+ enum led_brightness brightness)
-+{
-+ struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev);
-+ struct mt6323_leds *leds = led->parent;
-+ struct regmap *regmap = leds->hw->regmap;
-+ u32 con2_mask = 0, con2_val = 0;
-+ int ret;
-+
-+ /*
-+ * Setup current output for the corresponding
-+ * brightness level.
-+ */
-+ con2_mask |= MT6323_ISINK_CH_STEP_MASK |
-+ MT6323_ISINK_SFSTR0_TC_MASK |
-+ MT6323_ISINK_SFSTR0_EN_MASK;
-+ con2_val |= MT6323_ISINK_CH_STEP(brightness - 1) |
-+ MT6323_ISINK_SFSTR0_TC(2) |
-+ MT6323_ISINK_SFSTR0_EN;
-+
-+ ret = regmap_update_bits(regmap, MT6323_ISINK_CON2(led->id),
-+ con2_mask, con2_val);
-+ return ret;
-+}
-+
-+static int mt6323_led_hw_off(struct led_classdev *cdev)
-+{
-+ struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev);
-+ struct mt6323_leds *leds = led->parent;
-+ struct regmap *regmap = leds->hw->regmap;
-+ unsigned int status;
-+ int ret;
-+
-+ status = MT6323_ISINK_CH_EN(led->id);
-+ ret = regmap_update_bits(regmap, MT6323_ISINK_EN_CTRL,
-+ MT6323_ISINK_CH_EN_MASK(led->id), ~status);
-+ if (ret < 0)
-+ return ret;
-+
-+ usleep_range(100, 300);
-+ ret = regmap_update_bits(regmap, MT6323_TOP_CKPDN2,
-+ MT6323_RG_ISINK_CK_PDN_MASK(led->id),
-+ MT6323_RG_ISINK_CK_PDN(led->id));
-+ if (ret < 0)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+static enum led_brightness
-+mt6323_get_led_hw_brightness(struct led_classdev *cdev)
-+{
-+ struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev);
-+ struct mt6323_leds *leds = led->parent;
-+ struct regmap *regmap = leds->hw->regmap;
-+ unsigned int status;
-+ int ret;
-+
-+ ret = regmap_read(regmap, MT6323_TOP_CKPDN2, &status);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (status & MT6323_RG_ISINK_CK_PDN_MASK(led->id))
-+ return 0;
-+
-+ ret = regmap_read(regmap, MT6323_ISINK_EN_CTRL, &status);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (!(status & MT6323_ISINK_CH_EN(led->id)))
-+ return 0;
-+
-+ ret = regmap_read(regmap, MT6323_ISINK_CON2(led->id), &status);
-+ if (ret < 0)
-+ return ret;
-+
-+ return ((status & MT6323_ISINK_CH_STEP_MASK)
-+ >> MT6323_ISINK_CH_STEP_SHIFT) + 1;
-+}
-+
-+static int mt6323_led_hw_on(struct led_classdev *cdev,
-+ enum led_brightness brightness)
-+{
-+ struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev);
-+ struct mt6323_leds *leds = led->parent;
-+ struct regmap *regmap = leds->hw->regmap;
-+ unsigned int status;
-+ int ret;
-+
-+ /*
-+ * Setup required clock source, enable the corresponding
-+ * clock and channel and let work with continuous blink as
-+ * the default.
-+ */
-+ ret = regmap_update_bits(regmap, MT6323_TOP_CKCON1,
-+ MT6323_RG_ISINK_CK_SEL_MASK(led->id), 0);
-+ if (ret < 0)
-+ return ret;
-+
-+ status = MT6323_RG_ISINK_CK_PDN(led->id);
-+ ret = regmap_update_bits(regmap, MT6323_TOP_CKPDN2,
-+ MT6323_RG_ISINK_CK_PDN_MASK(led->id),
-+ ~status);
-+ if (ret < 0)
-+ return ret;
-+
-+ usleep_range(100, 300);
-+
-+ ret = regmap_update_bits(regmap, MT6323_ISINK_EN_CTRL,
-+ MT6323_ISINK_CH_EN_MASK(led->id),
-+ MT6323_ISINK_CH_EN(led->id));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = mt6323_led_hw_brightness(cdev, brightness);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = regmap_update_bits(regmap, MT6323_ISINK_CON0(led->id),
-+ MT6323_ISINK_DIM_DUTY_MASK,
-+ MT6323_ISINK_DIM_DUTY(31));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = regmap_update_bits(regmap, MT6323_ISINK_CON1(led->id),
-+ MT6323_ISINK_DIM_FSEL_MASK,
-+ MT6323_ISINK_DIM_FSEL(1000));
-+ if (ret < 0)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+static int mt6323_led_set_blink(struct led_classdev *cdev,
-+ unsigned long *delay_on,
-+ unsigned long *delay_off)
-+{
-+ struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev);
-+ struct mt6323_leds *leds = led->parent;
-+ struct regmap *regmap = leds->hw->regmap;
-+ unsigned long period;
-+ u8 duty_hw;
-+ int ret;
-+
-+ /*
-+ * Units are in ms, if over the hardware able
-+ * to support, fallback into software blink
-+ */
-+ period = *delay_on + *delay_off;
-+
-+ if (period > MT6323_MAX_PERIOD)
-+ return -EINVAL;
-+
-+ /*
-+ * LED subsystem requires a default user
-+ * friendly blink pattern for the LED so using
-+ * 1Hz duty cycle 50% here if without specific
-+ * value delay_on and delay off being assigned.
-+ */
-+ if (!*delay_on && !*delay_off) {
-+ *delay_on = 500;
-+ *delay_off = 500;
-+ }
-+
-+ /*
-+ * Calculate duty_hw based on the percentage of period during
-+ * which the led is ON.
-+ */
-+ duty_hw = MT6323_CAL_HW_DUTY(*delay_on, period);
-+
-+ /* hardware doesn't support zero duty cycle. */
-+ if (!duty_hw)
-+ return -EINVAL;
-+
-+ mutex_lock(&leds->lock);
-+ /*
-+ * Set max_brightness as the software blink behavior
-+ * when no blink brightness.
-+ */
-+ if (!led->current_brightness) {
-+ ret = mt6323_led_hw_on(cdev, cdev->max_brightness);
-+ if (ret < 0)
-+ goto out;
-+ led->current_brightness = cdev->max_brightness;
-+ }
-+
-+ ret = regmap_update_bits(regmap, MT6323_ISINK_CON0(led->id),
-+ MT6323_ISINK_DIM_DUTY_MASK,
-+ MT6323_ISINK_DIM_DUTY(duty_hw - 1));
-+ if (ret < 0)
-+ goto out;
-+
-+ ret = regmap_update_bits(regmap, MT6323_ISINK_CON1(led->id),
-+ MT6323_ISINK_DIM_FSEL_MASK,
-+ MT6323_ISINK_DIM_FSEL(period - 1));
-+out:
-+ mutex_unlock(&leds->lock);
-+
-+ return ret;
-+}
-+
-+static int mt6323_led_set_brightness(struct led_classdev *cdev,
-+ enum led_brightness brightness)
-+{
-+ struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev);
-+ struct mt6323_leds *leds = led->parent;
-+ int ret;
-+
-+ mutex_lock(&leds->lock);
-+
-+ if (!led->current_brightness && brightness) {
-+ ret = mt6323_led_hw_on(cdev, brightness);
-+ if (ret < 0)
-+ goto out;
-+ } else if (brightness) {
-+ ret = mt6323_led_hw_brightness(cdev, brightness);
-+ if (ret < 0)
-+ goto out;
-+ } else {
-+ ret = mt6323_led_hw_off(cdev);
-+ if (ret < 0)
-+ goto out;
-+ }
-+
-+ led->current_brightness = brightness;
-+out:
-+ mutex_unlock(&leds->lock);
-+
-+ return ret;
-+}
-+
-+static int mt6323_led_set_dt_default(struct led_classdev *cdev,
-+ struct device_node *np)
-+{
-+ struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev);
-+ const char *state;
-+ int ret = 0;
-+
-+ led->cdev.name = of_get_property(np, "label", NULL) ? : np->name;
-+ led->cdev.default_trigger = of_get_property(np,
-+ "linux,default-trigger",
-+ NULL);
-+
-+ state = of_get_property(np, "default-state", NULL);
-+ if (state) {
-+ if (!strcmp(state, "keep")) {
-+ ret = mt6323_get_led_hw_brightness(cdev);
-+ if (ret < 0)
-+ return ret;
-+ led->current_brightness = ret;
-+ ret = 0;
-+ } else if (!strcmp(state, "on")) {
-+ ret =
-+ mt6323_led_set_brightness(cdev, cdev->max_brightness);
-+ } else {
-+ ret = mt6323_led_set_brightness(cdev, LED_OFF);
-+ }
-+ }
-+
-+ return ret;
-+}
-+
-+static int mt6323_led_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct device_node *np = pdev->dev.of_node;
-+ struct device_node *child;
-+ struct mt6397_chip *hw = dev_get_drvdata(pdev->dev.parent);
-+ struct mt6323_leds *leds;
-+ struct mt6323_led *led;
-+ int ret;
-+ unsigned int status;
-+ u32 reg;
-+
-+ leds = devm_kzalloc(dev, sizeof(*leds), GFP_KERNEL);
-+ if (!leds)
-+ return -ENOMEM;
-+
-+ platform_set_drvdata(pdev, leds);
-+ leds->dev = dev;
-+
-+ /*
-+ * leds->hw points to the underlying bus for the register
-+ * controlled.
-+ */
-+ leds->hw = hw;
-+ mutex_init(&leds->lock);
-+
-+ status = MT6323_RG_DRV_32K_CK_PDN;
-+ ret = regmap_update_bits(leds->hw->regmap, MT6323_TOP_CKPDN0,
-+ MT6323_RG_DRV_32K_CK_PDN_MASK, ~status);
-+ if (ret < 0) {
-+ dev_err(leds->dev,
-+ "Failed to update MT6323_TOP_CKPDN0 Register\n");
-+ return ret;
-+ }
-+
-+ for_each_available_child_of_node(np, child) {
-+ ret = of_property_read_u32(child, "reg", &reg);
-+ if (ret) {
-+ dev_err(dev, "Failed to read led 'reg' property\n");
-+ goto put_child_node;
-+ }
-+
-+ if (reg < 0 || reg > MT6323_MAX_LEDS || leds->led[reg]) {
-+ dev_err(dev, "Invalid led reg %u\n", reg);
-+ ret = -EINVAL;
-+ goto put_child_node;
-+ }
-+
-+ led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
-+ if (!led) {
-+ ret = -ENOMEM;
-+ goto put_child_node;
-+ }
-+
-+ leds->led[reg] = led;
-+ leds->led[reg]->id = reg;
-+ leds->led[reg]->cdev.max_brightness = MT6323_MAX_BRIGHTNESS;
-+ leds->led[reg]->cdev.brightness_set_blocking =
-+ mt6323_led_set_brightness;
-+ leds->led[reg]->cdev.blink_set = mt6323_led_set_blink;
-+ leds->led[reg]->cdev.brightness_get =
-+ mt6323_get_led_hw_brightness;
-+ leds->led[reg]->parent = leds;
-+
-+ ret = mt6323_led_set_dt_default(&leds->led[reg]->cdev, child);
-+ if (ret < 0) {
-+ dev_err(leds->dev,
-+ "Failed to LED set default from devicetree\n");
-+ goto put_child_node;
-+ }
-+
-+ ret = devm_led_classdev_register(dev, &leds->led[reg]->cdev);
-+ if (ret) {
-+ dev_err(&pdev->dev, "Failed to register LED: %d\n",
-+ ret);
-+ goto put_child_node;
-+ }
-+ leds->led[reg]->cdev.dev->of_node = child;
-+ }
-+
-+ return 0;
-+
-+put_child_node:
-+ of_node_put(child);
-+ return ret;
-+}
-+
-+static int mt6323_led_remove(struct platform_device *pdev)
-+{
-+ struct mt6323_leds *leds = platform_get_drvdata(pdev);
-+ int i;
-+
-+ /* Turn the LEDs off on driver removal. */
-+ for (i = 0 ; leds->led[i] ; i++)
-+ mt6323_led_hw_off(&leds->led[i]->cdev);
-+
-+ regmap_update_bits(leds->hw->regmap, MT6323_TOP_CKPDN0,
-+ MT6323_RG_DRV_32K_CK_PDN_MASK,
-+ MT6323_RG_DRV_32K_CK_PDN);
-+
-+ mutex_destroy(&leds->lock);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id mt6323_led_dt_match[] = {
-+ { .compatible = "mediatek,mt6323-led" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, mt6323_led_dt_match);
-+
-+static struct platform_driver mt6323_led_driver = {
-+ .probe = mt6323_led_probe,
-+ .remove = mt6323_led_remove,
-+ .driver = {
-+ .name = "mt6323-led",
-+ .of_match_table = mt6323_led_dt_match,
-+ },
-+};
-+
-+module_platform_driver(mt6323_led_driver);
-+
-+MODULE_DESCRIPTION("LED driver for Mediatek MT6323 PMIC");
-+MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/mediatek/patches-4.9/0021-mfd-mt6397-Align-the-placement-at-which-the-mfd_cell.patch b/target/linux/mediatek/patches-4.9/0021-mfd-mt6397-Align-the-placement-at-which-the-mfd_cell.patch
deleted file mode 100644
index 79e11e8c69..0000000000
--- a/target/linux/mediatek/patches-4.9/0021-mfd-mt6397-Align-the-placement-at-which-the-mfd_cell.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 6e81b4fee93c004078465589128ba07b6855be02 Mon Sep 17 00:00:00 2001
-From: Sean Wang <sean.wang@mediatek.com>
-Date: Mon, 20 Mar 2017 14:47:27 +0800
-Subject: [PATCH 21/57] mfd: mt6397: Align the placement at which the mfd_cell
- of LED is defined
-
-Align the placement as which the mfd_cell of LED is defined as the other
-members done on the structure.
-
-Signed-off-by: Sean Wang <sean.wang@mediatek.com>
-Acked-by: Lee Jones <lee.jones@linaro.org>
----
- drivers/mfd/mt6397-core.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/mfd/mt6397-core.c
-+++ b/drivers/mfd/mt6397-core.c
-@@ -47,8 +47,7 @@ static const struct mfd_cell mt6323_devs
- {
- .name = "mt6323-regulator",
- .of_compatible = "mediatek,mt6323-regulator"
-- },
-- {
-+ }, {
- .name = "mt6323-led",
- .of_compatible = "mediatek,mt6323-led"
- },
diff --git a/target/linux/mediatek/patches-4.9/0022-nand-make-bootrom-work-with-upstream-driver.patch b/target/linux/mediatek/patches-4.9/0022-nand-make-bootrom-work-with-upstream-driver.patch
deleted file mode 100644
index f01c841108..0000000000
--- a/target/linux/mediatek/patches-4.9/0022-nand-make-bootrom-work-with-upstream-driver.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 453ebd5d6b535388972fcea747025ced3afca5cc Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 14:47:06 +0200
-Subject: [PATCH 22/57] nand: make bootrom work with upstream driver
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/mtd/nand/mtk_nand.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/mtd/nand/mtk_nand.c
-+++ b/drivers/mtd/nand/mtk_nand.c
-@@ -1073,8 +1073,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;
- }
-@@ -1114,7 +1114,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/mediatek/patches-4.9/0023-rng-add-mediatek-hw-rng.patch b/target/linux/mediatek/patches-4.9/0023-rng-add-mediatek-hw-rng.patch
deleted file mode 100644
index 153031b35a..0000000000
--- a/target/linux/mediatek/patches-4.9/0023-rng-add-mediatek-hw-rng.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From 4ad0accdfb0941de1440906461c08bee715378d5 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 15:57:44 +0200
-Subject: [PATCH 23/57] rng: add mediatek hw rng
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/char/hw_random/Kconfig | 14 ++++++++++++++
- drivers/char/hw_random/Makefile | 1 +
- drivers/crypto/Kconfig | 18 ++++++++++++++++++
- drivers/crypto/Makefile | 1 +
- 4 files changed, 34 insertions(+)
-
---- a/drivers/char/hw_random/Kconfig
-+++ b/drivers/char/hw_random/Kconfig
-@@ -166,6 +166,20 @@ config HW_RANDOM_IXP4XX
-
- If unsure, say Y.
-
-+config HW_RANDOM_MTK
-+ tristate "Mediatek Random Number Generator support"
-+ depends on HW_RANDOM
-+ depends on ARCH_MEDIATEK || COMPILE_TEST
-+ default y
-+ ---help---
-+ This driver provides kernel-side support for the Random Number
-+ Generator hardware found on Mediatek SoCs.
-+
-+ To compile this driver as a module, choose M here. the
-+ module will be called mtk-rng.
-+
-+ If unsure, say Y.
-+
- config HW_RANDOM_OMAP
- tristate "OMAP Random Number Generator support"
- depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
---- a/drivers/char/hw_random/Makefile
-+++ b/drivers/char/hw_random/Makefile
-@@ -35,4 +35,5 @@ obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-r
- obj-$(CONFIG_HW_RANDOM_STM32) += stm32-rng.o
- obj-$(CONFIG_HW_RANDOM_PIC32) += pic32-rng.o
- obj-$(CONFIG_HW_RANDOM_MESON) += meson-rng.o
-+obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o
- obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o
---- a/drivers/crypto/Kconfig
-+++ b/drivers/crypto/Kconfig
-@@ -553,6 +553,24 @@ config CRYPTO_DEV_ROCKCHIP
- This driver interfaces with the hardware crypto accelerator.
- Supporting cbc/ecb chainmode, and aes/des/des3_ede cipher mode.
-
-+config CRYPTO_DEV_MEDIATEK
-+ tristate "MediaTek's EIP97 Cryptographic Engine driver"
-+ depends on HAS_DMA
-+ depends on (ARM && ARCH_MEDIATEK) || COMPILE_TEST
-+ select CRYPTO_AES
-+ select CRYPTO_AEAD
-+ select CRYPTO_BLKCIPHER
-+ select CRYPTO_CTR
-+ select CRYPTO_SHA1
-+ select CRYPTO_SHA256
-+ select CRYPTO_SHA512
-+ select CRYPTO_HMAC
-+ help
-+ This driver allows you to utilize the hardware crypto accelerator
-+ EIP97 which can be found on the MT7623 MT2701, MT8521p, etc ....
-+ Select this if you want to use it for AES/SHA1/SHA2 algorithms.
-+
-+
- source "drivers/crypto/chelsio/Kconfig"
-
- endif # CRYPTO_HW
---- a/drivers/crypto/Makefile
-+++ b/drivers/crypto/Makefile
-@@ -10,6 +10,7 @@ obj-$(CONFIG_CRYPTO_DEV_IMGTEC_HASH) +=
- obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o
- obj-$(CONFIG_CRYPTO_DEV_MV_CESA) += mv_cesa.o
- obj-$(CONFIG_CRYPTO_DEV_MARVELL_CESA) += marvell/
-+obj-$(CONFIG_CRYPTO_DEV_MEDIATEK) += mediatek/
- obj-$(CONFIG_CRYPTO_DEV_MXS_DCP) += mxs-dcp.o
- obj-$(CONFIG_CRYPTO_DEV_NIAGARA2) += n2_crypto.o
- n2_crypto-y := n2_core.o n2_asm.o
diff --git a/target/linux/mediatek/patches-4.9/0024-media-rc-add-driver-for-IR-remote-receiver-on-MT7623.patch b/target/linux/mediatek/patches-4.9/0024-media-rc-add-driver-for-IR-remote-receiver-on-MT7623.patch
deleted file mode 100644
index fbdfbe9041..0000000000
--- a/target/linux/mediatek/patches-4.9/0024-media-rc-add-driver-for-IR-remote-receiver-on-MT7623.patch
+++ /dev/null
@@ -1,1034 +0,0 @@
-From 6e0336d1660725c06b6ab4f5361873538dbaa9f9 Mon Sep 17 00:00:00 2001
-From: Sean Wang <sean.wang@mediatek.com>
-Date: Fri, 13 Jan 2017 15:35:39 +0800
-Subject: [PATCH 24/57] media: rc: add driver for IR remote receiver on MT7623
- SoC
-
-This patch adds driver for IR controller on MT7623 SoC.
-and should also work on similar Mediatek SoC. Currently
-testing successfully on NEC and SONY remote controller
-only but it should work on others (lirc, rc-5 and rc-6).
-
-Signed-off-by: Sean Wang <sean.wang@mediatek.com>
-Reviewed-by: Sean Young <sean@mess.org>
----
- drivers/media/rc/Kconfig | 11 ++
- drivers/media/rc/mtk-cir.c | 329 +++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 340 insertions(+)
- create mode 100644 drivers/media/rc/mtk-cir.c
-
---- a/drivers/media/rc/Kconfig
-+++ b/drivers/media/rc/Kconfig
-@@ -235,6 +235,17 @@ config IR_MESON
- To compile this driver as a module, choose M here: the
- module will be called meson-ir.
-
-+config IR_MTK
-+ tristate "Mediatek IR remote receiver"
-+ depends on RC_CORE
-+ depends on ARCH_MEDIATEK || COMPILE_TEST
-+ ---help---
-+ Say Y if you want to use the IR remote receiver available
-+ on Mediatek SoCs.
-+
-+ To compile this driver as a module, choose M here: the
-+ module will be called mtk-cir.
-+
- config IR_NUVOTON
- tristate "Nuvoton w836x7hg Consumer Infrared Transceiver"
- depends on PNP
---- /dev/null
-+++ b/drivers/media/rc/mtk-cir.c
-@@ -0,0 +1,329 @@
-+/*
-+ * Driver for Mediatek IR Receiver Controller
-+ *
-+ * Copyright (C) 2017 Sean Wang <sean.wang@mediatek.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 Free Software Foundation; either version 2 of
-+ * the License, or (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/interrupt.h>
-+#include <linux/module.h>
-+#include <linux/of_platform.h>
-+#include <linux/reset.h>
-+#include <media/rc-core.h>
-+
-+#define MTK_IR_DEV KBUILD_MODNAME
-+
-+/* Register to enable PWM and IR */
-+#define MTK_CONFIG_HIGH_REG 0x0c
-+/* Enable IR pulse width detection */
-+#define MTK_PWM_EN BIT(13)
-+/* Enable IR hardware function */
-+#define MTK_IR_EN BIT(0)
-+
-+/* Register to setting sample period */
-+#define MTK_CONFIG_LOW_REG 0x10
-+/* Field to set sample period */
-+#define CHK_PERIOD DIV_ROUND_CLOSEST(MTK_IR_SAMPLE, \
-+ MTK_IR_CLK_PERIOD)
-+#define MTK_CHK_PERIOD (((CHK_PERIOD) << 8) & (GENMASK(20, 8)))
-+#define MTK_CHK_PERIOD_MASK (GENMASK(20, 8))
-+
-+/* Register to clear state of state machine */
-+#define MTK_IRCLR_REG 0x20
-+/* Bit to restart IR receiving */
-+#define MTK_IRCLR BIT(0)
-+
-+/* Register containing pulse width data */
-+#define MTK_CHKDATA_REG(i) (0x88 + 4 * (i))
-+#define MTK_WIDTH_MASK (GENMASK(7, 0))
-+
-+/* Register to enable IR interrupt */
-+#define MTK_IRINT_EN_REG 0xcc
-+/* Bit to enable interrupt */
-+#define MTK_IRINT_EN BIT(0)
-+
-+/* Register to ack IR interrupt */
-+#define MTK_IRINT_CLR_REG 0xd0
-+/* Bit to clear interrupt status */
-+#define MTK_IRINT_CLR BIT(0)
-+
-+/* Maximum count of samples */
-+#define MTK_MAX_SAMPLES 0xff
-+/* Indicate the end of IR message */
-+#define MTK_IR_END(v, p) ((v) == MTK_MAX_SAMPLES && (p) == 0)
-+/* Number of registers to record the pulse width */
-+#define MTK_CHKDATA_SZ 17
-+/* Source clock frequency */
-+#define MTK_IR_BASE_CLK 273000000
-+/* Frequency after IR internal divider */
-+#define MTK_IR_CLK_FREQ (MTK_IR_BASE_CLK / 4)
-+/* Period for MTK_IR_CLK in ns*/
-+#define MTK_IR_CLK_PERIOD DIV_ROUND_CLOSEST(1000000000ul, \
-+ MTK_IR_CLK_FREQ)
-+/* Sample period in ns */
-+#define MTK_IR_SAMPLE (MTK_IR_CLK_PERIOD * 0xc00)
-+
-+/* struct mtk_ir - This is the main datasructure for holding the state
-+ * of the driver
-+ * @dev: The device pointer
-+ * @rc: The rc instrance
-+ * @irq: The IRQ that we are using
-+ * @base: The mapped register i/o base
-+ * @clk: The clock that we are using
-+ */
-+struct mtk_ir {
-+ struct device *dev;
-+ struct rc_dev *rc;
-+ void __iomem *base;
-+ int irq;
-+ struct clk *clk;
-+};
-+
-+static void mtk_w32_mask(struct mtk_ir *ir, u32 val, u32 mask, unsigned int reg)
-+{
-+ u32 tmp;
-+
-+ tmp = __raw_readl(ir->base + reg);
-+ tmp = (tmp & ~mask) | val;
-+ __raw_writel(tmp, ir->base + reg);
-+}
-+
-+static void mtk_w32(struct mtk_ir *ir, u32 val, unsigned int reg)
-+{
-+ __raw_writel(val, ir->base + reg);
-+}
-+
-+static u32 mtk_r32(struct mtk_ir *ir, unsigned int reg)
-+{
-+ return __raw_readl(ir->base + reg);
-+}
-+
-+static inline void mtk_irq_disable(struct mtk_ir *ir, u32 mask)
-+{
-+ u32 val;
-+
-+ val = mtk_r32(ir, MTK_IRINT_EN_REG);
-+ mtk_w32(ir, val & ~mask, MTK_IRINT_EN_REG);
-+}
-+
-+static inline void mtk_irq_enable(struct mtk_ir *ir, u32 mask)
-+{
-+ u32 val;
-+
-+ val = mtk_r32(ir, MTK_IRINT_EN_REG);
-+ mtk_w32(ir, val | mask, MTK_IRINT_EN_REG);
-+}
-+
-+static irqreturn_t mtk_ir_irq(int irqno, void *dev_id)
-+{
-+ struct mtk_ir *ir = dev_id;
-+ u8 wid = 0;
-+ u32 i, j, val;
-+ DEFINE_IR_RAW_EVENT(rawir);
-+
-+ /* Reset decoder state machine explicitly is required
-+ * because 1) the longest duration for space MTK IR hardware
-+ * could record is not safely long. e.g 12ms if rx resolution
-+ * is 46us by default. There is still the risk to satisfying
-+ * every decoder to reset themselves through long enough
-+ * trailing spaces and 2) the IRQ handler guarantees that
-+ * start of IR message is always contained in and starting
-+ * from register MTK_CHKDATA_REG(0).
-+ */
-+ ir_raw_event_reset(ir->rc);
-+
-+ /* First message must be pulse */
-+ rawir.pulse = false;
-+
-+ /* Handle all pulse and space IR controller captures */
-+ for (i = 0 ; i < MTK_CHKDATA_SZ ; i++) {
-+ val = mtk_r32(ir, MTK_CHKDATA_REG(i));
-+ dev_dbg(ir->dev, "@reg%d=0x%08x\n", i, val);
-+
-+ for (j = 0 ; j < 4 ; j++) {
-+ wid = (val & (MTK_WIDTH_MASK << j * 8)) >> j * 8;
-+ rawir.pulse = !rawir.pulse;
-+ rawir.duration = wid * (MTK_IR_SAMPLE + 1);
-+ ir_raw_event_store_with_filter(ir->rc, &rawir);
-+ }
-+ }
-+
-+ /* The maximum number of edges the IR controller can
-+ * hold is MTK_CHKDATA_SZ * 4. So if received IR messages
-+ * is over the limit, the last incomplete IR message would
-+ * be appended trailing space and still would be sent into
-+ * ir-rc-raw to decode. That helps it is possible that it
-+ * has enough information to decode a scancode even if the
-+ * trailing end of the message is missing.
-+ */
-+ if (!MTK_IR_END(wid, rawir.pulse)) {
-+ rawir.pulse = false;
-+ rawir.duration = MTK_MAX_SAMPLES * (MTK_IR_SAMPLE + 1);
-+ ir_raw_event_store_with_filter(ir->rc, &rawir);
-+ }
-+
-+ ir_raw_event_handle(ir->rc);
-+
-+ /* Restart controller for the next receive that would
-+ * clear up all CHKDATA registers
-+ */
-+ mtk_w32_mask(ir, 0x1, MTK_IRCLR, MTK_IRCLR_REG);
-+
-+ /* Clear interrupt status */
-+ mtk_w32_mask(ir, 0x1, MTK_IRINT_CLR, MTK_IRINT_CLR_REG);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static int mtk_ir_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct device_node *dn = dev->of_node;
-+ struct resource *res;
-+ struct mtk_ir *ir;
-+ u32 val;
-+ int ret = 0;
-+ const char *map_name;
-+
-+ ir = devm_kzalloc(dev, sizeof(struct mtk_ir), GFP_KERNEL);
-+ if (!ir)
-+ return -ENOMEM;
-+
-+ ir->dev = dev;
-+
-+ if (!of_device_is_compatible(dn, "mediatek,mt7623-cir"))
-+ return -ENODEV;
-+
-+ ir->clk = devm_clk_get(dev, "clk");
-+ if (IS_ERR(ir->clk)) {
-+ dev_err(dev, "failed to get a ir clock.\n");
-+ return PTR_ERR(ir->clk);
-+ }
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ ir->base = devm_ioremap_resource(dev, res);
-+ if (IS_ERR(ir->base)) {
-+ dev_err(dev, "failed to map registers\n");
-+ return PTR_ERR(ir->base);
-+ }
-+
-+ ir->rc = devm_rc_allocate_device(dev, RC_DRIVER_IR_RAW);
-+ if (!ir->rc) {
-+ dev_err(dev, "failed to allocate device\n");
-+ return -ENOMEM;
-+ }
-+
-+ ir->rc->priv = ir;
-+ ir->rc->input_name = MTK_IR_DEV;
-+ ir->rc->input_phys = MTK_IR_DEV "/input0";
-+ ir->rc->input_id.bustype = BUS_HOST;
-+ ir->rc->input_id.vendor = 0x0001;
-+ ir->rc->input_id.product = 0x0001;
-+ ir->rc->input_id.version = 0x0001;
-+ map_name = of_get_property(dn, "linux,rc-map-name", NULL);
-+ ir->rc->map_name = map_name ?: RC_MAP_EMPTY;
-+ ir->rc->dev.parent = dev;
-+ ir->rc->driver_name = MTK_IR_DEV;
-+ ir->rc->allowed_protocols = RC_BIT_ALL;
-+ ir->rc->rx_resolution = MTK_IR_SAMPLE;
-+ ir->rc->timeout = MTK_MAX_SAMPLES * (MTK_IR_SAMPLE + 1);
-+
-+ ret = devm_rc_register_device(dev, ir->rc);
-+ if (ret) {
-+ dev_err(dev, "failed to register rc device\n");
-+ return ret;
-+ }
-+
-+ platform_set_drvdata(pdev, ir);
-+
-+ ir->irq = platform_get_irq(pdev, 0);
-+ if (ir->irq < 0) {
-+ dev_err(dev, "no irq resource\n");
-+ return -ENODEV;
-+ }
-+
-+ /* Enable interrupt after proper hardware
-+ * setup and IRQ handler registration
-+ */
-+ if (clk_prepare_enable(ir->clk)) {
-+ dev_err(dev, "try to enable ir_clk failed\n");
-+ ret = -EINVAL;
-+ goto exit_clkdisable_clk;
-+ }
-+
-+ mtk_irq_disable(ir, MTK_IRINT_EN);
-+
-+ ret = devm_request_irq(dev, ir->irq, mtk_ir_irq, 0, MTK_IR_DEV, ir);
-+ if (ret) {
-+ dev_err(dev, "failed request irq\n");
-+ goto exit_clkdisable_clk;
-+ }
-+
-+ /* Enable IR and PWM */
-+ val = mtk_r32(ir, MTK_CONFIG_HIGH_REG);
-+ val |= MTK_PWM_EN | MTK_IR_EN;
-+ mtk_w32(ir, val, MTK_CONFIG_HIGH_REG);
-+
-+ /* Setting sample period */
-+ mtk_w32_mask(ir, MTK_CHK_PERIOD, MTK_CHK_PERIOD_MASK,
-+ MTK_CONFIG_LOW_REG);
-+
-+ mtk_irq_enable(ir, MTK_IRINT_EN);
-+
-+ dev_info(dev, "Initialized MT7623 IR driver, sample period = %luus\n",
-+ DIV_ROUND_CLOSEST(MTK_IR_SAMPLE, 1000));
-+
-+ return 0;
-+
-+exit_clkdisable_clk:
-+ clk_disable_unprepare(ir->clk);
-+
-+ return ret;
-+}
-+
-+static int mtk_ir_remove(struct platform_device *pdev)
-+{
-+ struct mtk_ir *ir = platform_get_drvdata(pdev);
-+
-+ /* Avoid contention between remove handler and
-+ * IRQ handler so that disabling IR interrupt and
-+ * waiting for pending IRQ handler to complete
-+ */
-+ mtk_irq_disable(ir, MTK_IRINT_EN);
-+ synchronize_irq(ir->irq);
-+
-+ clk_disable_unprepare(ir->clk);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id mtk_ir_match[] = {
-+ { .compatible = "mediatek,mt7623-cir" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, mtk_ir_match);
-+
-+static struct platform_driver mtk_ir_driver = {
-+ .probe = mtk_ir_probe,
-+ .remove = mtk_ir_remove,
-+ .driver = {
-+ .name = MTK_IR_DEV,
-+ .of_match_table = mtk_ir_match,
-+ },
-+};
-+
-+module_platform_driver(mtk_ir_driver);
-+
-+MODULE_DESCRIPTION("Mediatek IR Receiver Controller Driver");
-+MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
-+MODULE_LICENSE("GPL");
---- a/drivers/media/rc/Makefile
-+++ b/drivers/media/rc/Makefile
-@@ -37,3 +37,4 @@ obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o
- obj-$(CONFIG_RC_ST) += st_rc.o
- obj-$(CONFIG_IR_SUNXI) += sunxi-cir.o
- obj-$(CONFIG_IR_IMG) += img-ir/
-+obj-$(CONFIG_IR_MTK) += mtk-cir.o
---- a/drivers/media/rc/rc-main.c
-+++ b/drivers/media/rc/rc-main.c
-@@ -1355,7 +1355,7 @@ static struct device_type rc_dev_type =
- .uevent = rc_dev_uevent,
- };
-
--struct rc_dev *rc_allocate_device(void)
-+struct rc_dev *rc_allocate_device(enum rc_driver_type type)
- {
- struct rc_dev *dev;
-
-@@ -1382,6 +1382,8 @@ struct rc_dev *rc_allocate_device(void)
- dev->dev.class = &rc_class;
- device_initialize(&dev->dev);
-
-+ dev->driver_type = type;
-+
- __module_get(THIS_MODULE);
- return dev;
- }
-@@ -1403,6 +1405,35 @@ void rc_free_device(struct rc_dev *dev)
- }
- EXPORT_SYMBOL_GPL(rc_free_device);
-
-+static void devm_rc_alloc_release(struct device *dev, void *res)
-+{
-+ rc_free_device(*(struct rc_dev **)res);
-+}
-+
-+struct rc_dev *devm_rc_allocate_device(struct device *dev,
-+ enum rc_driver_type type)
-+{
-+ struct rc_dev **dr, *rc;
-+
-+ dr = devres_alloc(devm_rc_alloc_release, sizeof(*dr), GFP_KERNEL);
-+ if (!dr)
-+ return NULL;
-+
-+ rc = rc_allocate_device(type);
-+ if (!rc) {
-+ devres_free(dr);
-+ return NULL;
-+ }
-+
-+ rc->dev.parent = dev;
-+ rc->managed_alloc = true;
-+ *dr = rc;
-+ devres_add(dev, dr);
-+
-+ return rc;
-+}
-+EXPORT_SYMBOL_GPL(devm_rc_allocate_device);
-+
- int rc_register_device(struct rc_dev *dev)
- {
- static bool raw_init = false; /* raw decoders loaded? */
-@@ -1536,6 +1567,33 @@ out_unlock:
- }
- EXPORT_SYMBOL_GPL(rc_register_device);
-
-+static void devm_rc_release(struct device *dev, void *res)
-+{
-+ rc_unregister_device(*(struct rc_dev **)res);
-+}
-+
-+int devm_rc_register_device(struct device *parent, struct rc_dev *dev)
-+{
-+ struct rc_dev **dr;
-+ int ret;
-+
-+ dr = devres_alloc(devm_rc_release, sizeof(*dr), GFP_KERNEL);
-+ if (!dr)
-+ return -ENOMEM;
-+
-+ ret = rc_register_device(dev);
-+ if (ret) {
-+ devres_free(dr);
-+ return ret;
-+ }
-+
-+ *dr = dev;
-+ devres_add(parent, dr);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(devm_rc_register_device);
-+
- void rc_unregister_device(struct rc_dev *dev)
- {
- if (!dev)
-@@ -1557,7 +1615,8 @@ void rc_unregister_device(struct rc_dev
-
- ida_simple_remove(&rc_ida, dev->minor);
-
-- rc_free_device(dev);
-+ if (!dev->managed_alloc)
-+ rc_free_device(dev);
- }
-
- EXPORT_SYMBOL_GPL(rc_unregister_device);
---- a/include/media/rc-core.h
-+++ b/include/media/rc-core.h
-@@ -68,6 +68,7 @@ enum rc_filter_type {
- * struct rc_dev - represents a remote control device
- * @dev: driver model's view of this device
- * @initialized: 1 if the device init has completed, 0 otherwise
-+ * @managed_alloc: devm_rc_allocate_device was used to create rc_dev
- * @sysfs_groups: sysfs attribute groups
- * @input_name: name of the input child device
- * @input_phys: physical path to the input child device
-@@ -131,6 +132,7 @@ enum rc_filter_type {
- struct rc_dev {
- struct device dev;
- atomic_t initialized;
-+ bool managed_alloc;
- const struct attribute_group *sysfs_groups[5];
- const char *input_name;
- const char *input_phys;
-@@ -198,9 +200,19 @@ struct rc_dev {
- /**
- * rc_allocate_device - Allocates a RC device
- *
-+ * @rc_driver_type: specifies the type of the RC output to be allocated
- * returns a pointer to struct rc_dev.
- */
--struct rc_dev *rc_allocate_device(void);
-+struct rc_dev *rc_allocate_device(enum rc_driver_type);
-+
-+/**
-+ * devm_rc_allocate_device - Managed RC device allocation
-+ *
-+ * @dev: pointer to struct device
-+ * @rc_driver_type: specifies the type of the RC output to be allocated
-+ * returns a pointer to struct rc_dev.
-+ */
-+struct rc_dev *devm_rc_allocate_device(struct device *dev, enum rc_driver_type);
-
- /**
- * rc_free_device - Frees a RC device
-@@ -217,6 +229,14 @@ void rc_free_device(struct rc_dev *dev);
- int rc_register_device(struct rc_dev *dev);
-
- /**
-+ * devm_rc_register_device - Manageded registering of a RC device
-+ *
-+ * @parent: pointer to struct device.
-+ * @dev: pointer to struct rc_dev.
-+ */
-+int devm_rc_register_device(struct device *parent, struct rc_dev *dev);
-+
-+/**
- * rc_unregister_device - Unregisters a RC device
- *
- * @dev: pointer to struct rc_dev.
---- a/drivers/media/common/siano/smsir.c
-+++ b/drivers/media/common/siano/smsir.c
-@@ -58,7 +58,7 @@ int sms_ir_init(struct smscore_device_t
- struct rc_dev *dev;
-
- pr_debug("Allocating rc device\n");
-- dev = rc_allocate_device();
-+ dev = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!dev)
- return -ENOMEM;
-
---- a/drivers/media/i2c/ir-kbd-i2c.c
-+++ b/drivers/media/i2c/ir-kbd-i2c.c
-@@ -428,7 +428,7 @@ static int ir_probe(struct i2c_client *c
- * If platform_data doesn't specify rc_dev, initialize it
- * internally
- */
-- rc = rc_allocate_device();
-+ rc = rc_allocate_device(RC_DRIVER_SCANCODE);
- if (!rc)
- return -ENOMEM;
- }
---- a/drivers/media/pci/bt8xx/bttv-input.c
-+++ b/drivers/media/pci/bt8xx/bttv-input.c
-@@ -424,7 +424,7 @@ int bttv_input_init(struct bttv *btv)
- return -ENODEV;
-
- ir = kzalloc(sizeof(*ir),GFP_KERNEL);
-- rc = rc_allocate_device();
-+ rc = rc_allocate_device(RC_DRIVER_SCANCODE);
- if (!ir || !rc)
- goto err_out_free;
-
---- a/drivers/media/pci/cx23885/cx23885-input.c
-+++ b/drivers/media/pci/cx23885/cx23885-input.c
-@@ -267,7 +267,6 @@ int cx23885_input_init(struct cx23885_de
- struct cx23885_kernel_ir *kernel_ir;
- struct rc_dev *rc;
- char *rc_map;
-- enum rc_driver_type driver_type;
- u64 allowed_protos;
-
- int ret;
-@@ -352,7 +351,7 @@ int cx23885_input_init(struct cx23885_de
- pci_name(dev->pci));
-
- /* input device */
-- rc = rc_allocate_device();
-+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!rc) {
- ret = -ENOMEM;
- goto err_out_free;
-@@ -371,7 +370,6 @@ int cx23885_input_init(struct cx23885_de
- rc->input_id.product = dev->pci->device;
- }
- rc->dev.parent = &dev->pci->dev;
-- rc->driver_type = driver_type;
- rc->allowed_protocols = allowed_protos;
- rc->priv = kernel_ir;
- rc->open = cx23885_input_ir_open;
---- a/drivers/media/pci/cx88/cx88-input.c
-+++ b/drivers/media/pci/cx88/cx88-input.c
-@@ -272,7 +272,7 @@ int cx88_ir_init(struct cx88_core *core,
- */
-
- ir = kzalloc(sizeof(*ir), GFP_KERNEL);
-- dev = rc_allocate_device();
-+ dev = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!ir || !dev)
- goto err_out_free;
-
-@@ -482,7 +482,6 @@ int cx88_ir_init(struct cx88_core *core,
- dev->scancode_mask = hardware_mask;
-
- if (ir->sampling) {
-- dev->driver_type = RC_DRIVER_IR_RAW;
- dev->timeout = 10 * 1000 * 1000; /* 10 ms */
- } else {
- dev->driver_type = RC_DRIVER_SCANCODE;
---- a/drivers/media/pci/dm1105/dm1105.c
-+++ b/drivers/media/pci/dm1105/dm1105.c
-@@ -744,7 +744,7 @@ static int dm1105_ir_init(struct dm1105_
- struct rc_dev *dev;
- int err = -ENOMEM;
-
-- dev = rc_allocate_device();
-+ dev = rc_allocate_device(RC_DRIVER_SCANCODE);
- if (!dev)
- return -ENOMEM;
-
-@@ -753,7 +753,6 @@ static int dm1105_ir_init(struct dm1105_
-
- dev->driver_name = MODULE_NAME;
- dev->map_name = RC_MAP_DM1105_NEC;
-- dev->driver_type = RC_DRIVER_SCANCODE;
- dev->input_name = "DVB on-card IR receiver";
- dev->input_phys = dm1105->ir.input_phys;
- dev->input_id.bustype = BUS_PCI;
---- a/drivers/media/pci/mantis/mantis_input.c
-+++ b/drivers/media/pci/mantis/mantis_input.c
-@@ -39,7 +39,7 @@ int mantis_input_init(struct mantis_pci
- struct rc_dev *dev;
- int err;
-
-- dev = rc_allocate_device();
-+ dev = rc_allocate_device(RC_DRIVER_SCANCODE);
- if (!dev) {
- dprintk(MANTIS_ERROR, 1, "Remote device allocation failed");
- err = -ENOMEM;
---- a/drivers/media/pci/saa7134/saa7134-input.c
-+++ b/drivers/media/pci/saa7134/saa7134-input.c
-@@ -849,7 +849,7 @@ int saa7134_input_init1(struct saa7134_d
- }
-
- ir = kzalloc(sizeof(*ir), GFP_KERNEL);
-- rc = rc_allocate_device();
-+ rc = rc_allocate_device(RC_DRIVER_SCANCODE);
- if (!ir || !rc) {
- err = -ENOMEM;
- goto err_out_free;
---- a/drivers/media/pci/smipcie/smipcie-ir.c
-+++ b/drivers/media/pci/smipcie/smipcie-ir.c
-@@ -183,7 +183,7 @@ int smi_ir_init(struct smi_dev *dev)
- struct rc_dev *rc_dev;
- struct smi_rc *ir = &dev->ir;
-
-- rc_dev = rc_allocate_device();
-+ rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE);
- if (!rc_dev)
- return -ENOMEM;
-
-@@ -202,7 +202,6 @@ int smi_ir_init(struct smi_dev *dev)
- rc_dev->input_id.product = dev->pci_dev->subsystem_device;
- rc_dev->dev.parent = &dev->pci_dev->dev;
-
-- rc_dev->driver_type = RC_DRIVER_SCANCODE;
- rc_dev->map_name = dev->info->rc_map;
-
- ir->rc_dev = rc_dev;
---- a/drivers/media/pci/ttpci/budget-ci.c
-+++ b/drivers/media/pci/ttpci/budget-ci.c
-@@ -177,7 +177,7 @@ static int msp430_ir_init(struct budget_
- struct rc_dev *dev;
- int error;
-
-- dev = rc_allocate_device();
-+ dev = rc_allocate_device(RC_DRIVER_SCANCODE);
- if (!dev) {
- printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
- return -ENOMEM;
---- a/drivers/media/rc/ati_remote.c
-+++ b/drivers/media/rc/ati_remote.c
-@@ -765,7 +765,6 @@ static void ati_remote_rc_init(struct at
- struct rc_dev *rdev = ati_remote->rdev;
-
- rdev->priv = ati_remote;
-- rdev->driver_type = RC_DRIVER_SCANCODE;
- rdev->allowed_protocols = RC_BIT_OTHER;
- rdev->driver_name = "ati_remote";
-
-@@ -852,7 +851,7 @@ static int ati_remote_probe(struct usb_i
- }
-
- ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL);
-- rc_dev = rc_allocate_device();
-+ rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE);
- if (!ati_remote || !rc_dev)
- goto exit_free_dev_rdev;
-
---- a/drivers/media/rc/ene_ir.c
-+++ b/drivers/media/rc/ene_ir.c
-@@ -1012,7 +1012,7 @@ static int ene_probe(struct pnp_dev *pnp
-
- /* allocate memory */
- dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL);
-- rdev = rc_allocate_device();
-+ rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!dev || !rdev)
- goto exit_free_dev_rdev;
-
---- a/drivers/media/rc/fintek-cir.c
-+++ b/drivers/media/rc/fintek-cir.c
-@@ -496,7 +496,7 @@ static int fintek_probe(struct pnp_dev *
- return ret;
-
- /* input device for IR remote (and tx) */
-- rdev = rc_allocate_device();
-+ rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!rdev)
- goto exit_free_dev_rdev;
-
---- a/drivers/media/rc/gpio-ir-recv.c
-+++ b/drivers/media/rc/gpio-ir-recv.c
-@@ -143,14 +143,13 @@ static int gpio_ir_recv_probe(struct pla
- if (!gpio_dev)
- return -ENOMEM;
-
-- rcdev = rc_allocate_device();
-+ rcdev = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!rcdev) {
- rc = -ENOMEM;
- goto err_allocate_device;
- }
-
- rcdev->priv = gpio_dev;
-- rcdev->driver_type = RC_DRIVER_IR_RAW;
- rcdev->input_name = GPIO_IR_DEVICE_NAME;
- rcdev->input_phys = GPIO_IR_DEVICE_NAME "/input0";
- rcdev->input_id.bustype = BUS_HOST;
---- a/drivers/media/rc/igorplugusb.c
-+++ b/drivers/media/rc/igorplugusb.c
-@@ -190,7 +190,7 @@ static int igorplugusb_probe(struct usb_
-
- usb_make_path(udev, ir->phys, sizeof(ir->phys));
-
-- rc = rc_allocate_device();
-+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!rc)
- goto fail;
-
-@@ -198,7 +198,6 @@ static int igorplugusb_probe(struct usb_
- rc->input_phys = ir->phys;
- usb_to_input_id(udev, &rc->input_id);
- rc->dev.parent = &intf->dev;
-- rc->driver_type = RC_DRIVER_IR_RAW;
- /*
- * This device can only store 36 pulses + spaces, which is not enough
- * for the NEC protocol and many others.
---- a/drivers/media/rc/iguanair.c
-+++ b/drivers/media/rc/iguanair.c
-@@ -431,7 +431,7 @@ static int iguanair_probe(struct usb_int
- struct usb_host_interface *idesc;
-
- ir = kzalloc(sizeof(*ir), GFP_KERNEL);
-- rc = rc_allocate_device();
-+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!ir || !rc) {
- ret = -ENOMEM;
- goto out;
---- a/drivers/media/rc/img-ir/img-ir-hw.c
-+++ b/drivers/media/rc/img-ir/img-ir-hw.c
-@@ -1071,7 +1071,7 @@ int img_ir_probe_hw(struct img_ir_priv *
- }
-
- /* Allocate hardware decoder */
-- hw->rdev = rdev = rc_allocate_device();
-+ hw->rdev = rdev = rc_allocate_device(RC_DRIVER_SCANCODE);
- if (!rdev) {
- dev_err(priv->dev, "cannot allocate input device\n");
- error = -ENOMEM;
---- a/drivers/media/rc/img-ir/img-ir-raw.c
-+++ b/drivers/media/rc/img-ir/img-ir-raw.c
-@@ -110,7 +110,7 @@ int img_ir_probe_raw(struct img_ir_priv
- setup_timer(&raw->timer, img_ir_echo_timer, (unsigned long)priv);
-
- /* Allocate raw decoder */
-- raw->rdev = rdev = rc_allocate_device();
-+ raw->rdev = rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!rdev) {
- dev_err(priv->dev, "cannot allocate raw input device\n");
- return -ENOMEM;
-@@ -118,7 +118,6 @@ int img_ir_probe_raw(struct img_ir_priv
- rdev->priv = priv;
- rdev->map_name = RC_MAP_EMPTY;
- rdev->input_name = "IMG Infrared Decoder Raw";
-- rdev->driver_type = RC_DRIVER_IR_RAW;
-
- /* Register raw decoder */
- error = rc_register_device(rdev);
---- a/drivers/media/rc/imon.c
-+++ b/drivers/media/rc/imon.c
-@@ -1951,7 +1951,7 @@ static struct rc_dev *imon_init_rdev(str
- const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x88 };
-
-- rdev = rc_allocate_device();
-+ rdev = rc_allocate_device(RC_DRIVER_SCANCODE);
- if (!rdev) {
- dev_err(ictx->dev, "remote control dev allocation failed\n");
- goto out;
-@@ -1969,7 +1969,6 @@ static struct rc_dev *imon_init_rdev(str
- rdev->dev.parent = ictx->dev;
-
- rdev->priv = ictx;
-- rdev->driver_type = RC_DRIVER_SCANCODE;
- rdev->allowed_protocols = RC_BIT_OTHER | RC_BIT_RC6_MCE; /* iMON PAD or MCE */
- rdev->change_protocol = imon_ir_change_protocol;
- rdev->driver_name = MOD_NAME;
---- a/drivers/media/rc/ir-hix5hd2.c
-+++ b/drivers/media/rc/ir-hix5hd2.c
-@@ -222,7 +222,7 @@ static int hix5hd2_ir_probe(struct platf
- return priv->irq;
- }
-
-- rdev = rc_allocate_device();
-+ rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!rdev)
- return -ENOMEM;
-
---- a/drivers/media/rc/ite-cir.c
-+++ b/drivers/media/rc/ite-cir.c
-@@ -1472,7 +1472,7 @@ static int ite_probe(struct pnp_dev *pde
- return ret;
-
- /* input device for IR remote (and tx) */
-- rdev = rc_allocate_device();
-+ rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!rdev)
- goto exit_free_dev_rdev;
- itdev->rdev = rdev;
---- a/drivers/media/rc/mceusb.c
-+++ b/drivers/media/rc/mceusb.c
-@@ -1220,7 +1220,7 @@ static struct rc_dev *mceusb_init_rc_dev
- struct rc_dev *rc;
- int ret;
-
-- rc = rc_allocate_device();
-+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!rc) {
- dev_err(dev, "remote dev allocation failed");
- goto out;
---- a/drivers/media/rc/meson-ir.c
-+++ b/drivers/media/rc/meson-ir.c
-@@ -131,7 +131,7 @@ static int meson_ir_probe(struct platfor
- return ir->irq;
- }
-
-- ir->rc = rc_allocate_device();
-+ ir->rc = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!ir->rc) {
- dev_err(dev, "failed to allocate rc device\n");
- return -ENOMEM;
---- a/drivers/media/rc/rc-loopback.c
-+++ b/drivers/media/rc/rc-loopback.c
-@@ -181,7 +181,7 @@ static int __init loop_init(void)
- struct rc_dev *rc;
- int ret;
-
-- rc = rc_allocate_device();
-+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!rc) {
- printk(KERN_ERR DRIVER_NAME ": rc_dev allocation failed\n");
- return -ENOMEM;
---- a/drivers/media/rc/st_rc.c
-+++ b/drivers/media/rc/st_rc.c
-@@ -235,7 +235,7 @@ static int st_rc_probe(struct platform_d
- if (!rc_dev)
- return -ENOMEM;
-
-- rdev = rc_allocate_device();
-+ rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
-
- if (!rdev)
- return -ENOMEM;
---- a/drivers/media/rc/streamzap.c
-+++ b/drivers/media/rc/streamzap.c
-@@ -291,7 +291,7 @@ static struct rc_dev *streamzap_init_rc_
- struct device *dev = sz->dev;
- int ret;
-
-- rdev = rc_allocate_device();
-+ rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!rdev) {
- dev_err(dev, "remote dev allocation failed\n");
- goto out;
---- a/drivers/media/rc/sunxi-cir.c
-+++ b/drivers/media/rc/sunxi-cir.c
-@@ -212,7 +212,7 @@ static int sunxi_ir_probe(struct platfor
- goto exit_clkdisable_clk;
- }
-
-- ir->rc = rc_allocate_device();
-+ ir->rc = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!ir->rc) {
- dev_err(dev, "failed to allocate device\n");
- ret = -ENOMEM;
---- a/drivers/media/rc/ttusbir.c
-+++ b/drivers/media/rc/ttusbir.c
-@@ -205,7 +205,7 @@ static int ttusbir_probe(struct usb_inte
- int altsetting = -1;
-
- tt = kzalloc(sizeof(*tt), GFP_KERNEL);
-- rc = rc_allocate_device();
-+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!tt || !rc) {
- ret = -ENOMEM;
- goto out;
---- a/drivers/media/rc/winbond-cir.c
-+++ b/drivers/media/rc/winbond-cir.c
-@@ -1062,13 +1062,12 @@ wbcir_probe(struct pnp_dev *device, cons
- if (err)
- goto exit_free_data;
-
-- data->dev = rc_allocate_device();
-+ data->dev = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!data->dev) {
- err = -ENOMEM;
- goto exit_unregister_led;
- }
-
-- data->dev->driver_type = RC_DRIVER_IR_RAW;
- data->dev->driver_name = DRVNAME;
- data->dev->input_name = WBCIR_NAME;
- data->dev->input_phys = "wbcir/cir0";
---- a/drivers/media/usb/au0828/au0828-input.c
-+++ b/drivers/media/usb/au0828/au0828-input.c
-@@ -298,7 +298,7 @@ int au0828_rc_register(struct au0828_dev
- return -ENODEV;
-
- ir = kzalloc(sizeof(*ir), GFP_KERNEL);
-- rc = rc_allocate_device();
-+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!ir || !rc)
- goto error;
-
-@@ -343,7 +343,6 @@ int au0828_rc_register(struct au0828_dev
- rc->input_id.product = le16_to_cpu(dev->usbdev->descriptor.idProduct);
- rc->dev.parent = &dev->usbdev->dev;
- rc->driver_name = "au0828-input";
-- rc->driver_type = RC_DRIVER_IR_RAW;
- rc->allowed_protocols = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32 |
- RC_BIT_RC5;
-
---- a/drivers/media/usb/cx231xx/cx231xx-input.c
-+++ b/drivers/media/usb/cx231xx/cx231xx-input.c
-@@ -72,7 +72,7 @@ int cx231xx_ir_init(struct cx231xx *dev)
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- memset(&dev->init_data, 0, sizeof(dev->init_data));
-- dev->init_data.rc_dev = rc_allocate_device();
-+ dev->init_data.rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE);
- if (!dev->init_data.rc_dev)
- return -ENOMEM;
-
---- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
-+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
-@@ -147,7 +147,7 @@ static int dvb_usbv2_remote_init(struct
- if (!d->rc.map_name)
- return 0;
-
-- dev = rc_allocate_device();
-+ dev = rc_allocate_device(d->rc.driver_type);
- if (!dev) {
- ret = -ENOMEM;
- goto err;
-@@ -162,7 +162,6 @@ static int dvb_usbv2_remote_init(struct
- /* TODO: likely RC-core should took const char * */
- dev->driver_name = (char *) d->props->driver_name;
- dev->map_name = d->rc.map_name;
-- dev->driver_type = d->rc.driver_type;
- dev->allowed_protocols = d->rc.allowed_protos;
- dev->change_protocol = d->rc.change_protocol;
- dev->priv = d;
---- a/drivers/media/usb/dvb-usb/dvb-usb-remote.c
-+++ b/drivers/media/usb/dvb-usb/dvb-usb-remote.c
-@@ -265,7 +265,7 @@ static int rc_core_dvb_usb_remote_init(s
- int err, rc_interval;
- struct rc_dev *dev;
-
-- dev = rc_allocate_device();
-+ dev = rc_allocate_device(d->props.rc.core.driver_type);
- if (!dev)
- return -ENOMEM;
-
-@@ -273,7 +273,6 @@ static int rc_core_dvb_usb_remote_init(s
- dev->map_name = d->props.rc.core.rc_codes;
- dev->change_protocol = d->props.rc.core.change_protocol;
- dev->allowed_protocols = d->props.rc.core.allowed_protos;
-- dev->driver_type = d->props.rc.core.driver_type;
- usb_to_input_id(d->udev, &dev->input_id);
- dev->input_name = "IR-receiver inside an USB DVB receiver";
- dev->input_phys = d->rc_phys;
---- a/drivers/media/usb/em28xx/em28xx-input.c
-+++ b/drivers/media/usb/em28xx/em28xx-input.c
-@@ -713,7 +713,7 @@ static int em28xx_ir_init(struct em28xx
- ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- if (!ir)
- return -ENOMEM;
-- rc = rc_allocate_device();
-+ rc = rc_allocate_device(RC_DRIVER_SCANCODE);
- if (!rc)
- goto error;
-
---- a/drivers/media/usb/tm6000/tm6000-input.c
-+++ b/drivers/media/usb/tm6000/tm6000-input.c
-@@ -429,7 +429,7 @@ int tm6000_ir_init(struct tm6000_core *d
- return 0;
-
- ir = kzalloc(sizeof(*ir), GFP_ATOMIC);
-- rc = rc_allocate_device();
-+ rc = rc_allocate_device(RC_DRIVER_SCANCODE);
- if (!ir || !rc)
- goto out;
-
-@@ -456,7 +456,6 @@ int tm6000_ir_init(struct tm6000_core *d
- ir->polling = 50;
- INIT_DELAYED_WORK(&ir->work, tm6000_ir_handle_key);
- }
-- rc->driver_type = RC_DRIVER_SCANCODE;
-
- snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)",
- dev->name);
diff --git a/target/linux/mediatek/patches-4.9/0025-dt-bindings-net-dsa-add-Mediatek-MT7530-binding.patch b/target/linux/mediatek/patches-4.9/0025-dt-bindings-net-dsa-add-Mediatek-MT7530-binding.patch
deleted file mode 100644
index 24e13d1a3c..0000000000
--- a/target/linux/mediatek/patches-4.9/0025-dt-bindings-net-dsa-add-Mediatek-MT7530-binding.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From 3b9b46b5705214b16c5356284ad68be32ae56a26 Mon Sep 17 00:00:00 2001
-From: Sean Wang <sean.wang@mediatek.com>
-Date: Wed, 29 Mar 2017 17:38:19 +0800
-Subject: [PATCH 25/57] dt-bindings: net: dsa: add Mediatek MT7530 binding
-
-Add device-tree binding for Mediatek MT7530 switch.
-
-Cc: devicetree@vger.kernel.org
-Signed-off-by: Sean Wang <sean.wang@mediatek.com>
-Acked-by: Rob Herring <robh@kernel.org>
----
- .../devicetree/bindings/net/dsa/mt7530.txt | 92 ++++++++++++++++++++++
- 1 file changed, 92 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/net/dsa/mt7530.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/net/dsa/mt7530.txt
-@@ -0,0 +1,92 @@
-+Mediatek MT7530 Ethernet switch
-+================================
-+
-+Required properties:
-+
-+- compatible: Must be compatible = "mediatek,mt7530";
-+- #address-cells: Must be 1.
-+- #size-cells: Must be 0.
-+- mediatek,mcm: Boolean; if defined, indicates that either MT7530 is the part
-+ on multi-chip module belong to MT7623A has or the remotely standalone
-+ chip as the function MT7623N reference board provided for.
-+- core-supply: Phandle to the regulator node necessary for the core power.
-+- io-supply: Phandle to the regulator node necessary for the I/O power.
-+ See Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
-+ for details for the regulator setup on these boards.
-+
-+If the property mediatek,mcm isn't defined, following property is required
-+
-+- reset-gpios: Should be a gpio specifier for a reset line.
-+
-+Else, following properties are required
-+
-+- resets : Phandle pointing to the system reset controller with
-+ line index for the ethsys.
-+- reset-names : Should be set to "mcm".
-+
-+Required properties for the child nodes within ports container:
-+
-+- reg: Port address described must be 6 for CPU port and from 0 to 5 for
-+ user ports.
-+- phy-mode: String, must be either "trgmii" or "rgmii" for port labeled
-+ "cpu".
-+
-+See Documentation/devicetree/bindings/dsa/dsa.txt for a list of additional
-+required, optional properties and how the integrated switch subnodes must
-+be specified.
-+
-+Example:
-+
-+ &mdio0 {
-+ switch@0 {
-+ compatible = "mediatek,mt7530";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0>;
-+
-+ core-supply = <&mt6323_vpa_reg>;
-+ io-supply = <&mt6323_vemc3v3_reg>;
-+ reset-gpios = <&pio 33 0>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0>;
-+ port@0 {
-+ reg = <0>;
-+ label = "lan0";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "wan";
-+ };
-+
-+ port@6 {
-+ reg = <6>;
-+ label = "cpu";
-+ ethernet = <&gmac0>;
-+ phy-mode = "trgmii";
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+ };
-+ };
-+ };
diff --git a/target/linux/mediatek/patches-4.9/0026-net-mediatek-backport-v4.10-driver.patch b/target/linux/mediatek/patches-4.9/0026-net-mediatek-backport-v4.10-driver.patch
deleted file mode 100644
index 8a6d593624..0000000000
--- a/target/linux/mediatek/patches-4.9/0026-net-mediatek-backport-v4.10-driver.patch
+++ /dev/null
@@ -1,1788 +0,0 @@
-From 99d9d02a05df503184be094de336e7515fe3e235 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 14:26:29 +0200
-Subject: [PATCH 26/57] net: mediatek: backport v4.10 driver
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 49 ++-
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 16 +-
- drivers/net/ethernet/mediatek/mtk_hnat/Makefile | 4 +
- drivers/net/ethernet/mediatek/mtk_hnat/hnat.c | 315 +++++++++++++++
- drivers/net/ethernet/mediatek/mtk_hnat/hnat.h | 425 +++++++++++++++++++++
- .../net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c | 259 +++++++++++++
- .../net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c | 289 ++++++++++++++
- .../net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h | 44 +++
- 8 files changed, 1378 insertions(+), 23 deletions(-)
- create mode 100644 drivers/net/ethernet/mediatek/mtk_hnat/Makefile
- create mode 100644 drivers/net/ethernet/mediatek/mtk_hnat/hnat.c
- create mode 100644 drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
- create mode 100644 drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c
- create mode 100644 drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
- create mode 100644 drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -462,8 +462,8 @@ static void mtk_stats_update(struct mtk_
- }
- }
-
--static struct rtnl_link_stats64 *mtk_get_stats64(struct net_device *dev,
-- struct rtnl_link_stats64 *storage)
-+static struct rtnl_link_stats64 * mtk_get_stats64(struct net_device *dev,
-+ struct rtnl_link_stats64 *storage)
- {
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_hw_stats *hw_stats = mac->hw_stats;
-@@ -615,7 +615,7 @@ static int mtk_tx_map(struct sk_buff *sk
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
- struct mtk_tx_dma *itxd, *txd;
-- struct mtk_tx_buf *tx_buf;
-+ struct mtk_tx_buf *itx_buf, *tx_buf;
- dma_addr_t mapped_addr;
- unsigned int nr_frags;
- int i, n_desc = 1;
-@@ -629,8 +629,8 @@ static int mtk_tx_map(struct sk_buff *sk
- fport = (mac->id + 1) << TX_DMA_FPORT_SHIFT;
- txd4 |= fport;
-
-- tx_buf = mtk_desc_to_tx_buf(ring, itxd);
-- memset(tx_buf, 0, sizeof(*tx_buf));
-+ itx_buf = mtk_desc_to_tx_buf(ring, itxd);
-+ memset(itx_buf, 0, sizeof(*itx_buf));
-
- if (gso)
- txd4 |= TX_DMA_TSO;
-@@ -649,9 +649,11 @@ static int mtk_tx_map(struct sk_buff *sk
- return -ENOMEM;
-
- WRITE_ONCE(itxd->txd1, mapped_addr);
-- tx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
-- dma_unmap_addr_set(tx_buf, dma_addr0, mapped_addr);
-- dma_unmap_len_set(tx_buf, dma_len0, skb_headlen(skb));
-+ itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
-+ itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
-+ MTK_TX_FLAGS_FPORT1;
-+ dma_unmap_addr_set(itx_buf, dma_addr0, mapped_addr);
-+ dma_unmap_len_set(itx_buf, dma_len0, skb_headlen(skb));
-
- /* TX SG offload */
- txd = itxd;
-@@ -687,11 +689,13 @@ static int mtk_tx_map(struct sk_buff *sk
- last_frag * TX_DMA_LS0));
- WRITE_ONCE(txd->txd4, fport);
-
-- tx_buf->skb = (struct sk_buff *)MTK_DMA_DUMMY_DESC;
- tx_buf = mtk_desc_to_tx_buf(ring, txd);
- memset(tx_buf, 0, sizeof(*tx_buf));
--
-+ tx_buf->skb = (struct sk_buff *)MTK_DMA_DUMMY_DESC;
- tx_buf->flags |= MTK_TX_FLAGS_PAGE0;
-+ tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
-+ MTK_TX_FLAGS_FPORT1;
-+
- dma_unmap_addr_set(tx_buf, dma_addr0, mapped_addr);
- dma_unmap_len_set(tx_buf, dma_len0, frag_map_size);
- frag_size -= frag_map_size;
-@@ -700,7 +704,7 @@ static int mtk_tx_map(struct sk_buff *sk
- }
-
- /* store skb to cleanup */
-- tx_buf->skb = skb;
-+ itx_buf->skb = skb;
-
- WRITE_ONCE(itxd->txd4, txd4);
- WRITE_ONCE(itxd->txd3, (TX_DMA_SWC | TX_DMA_PLEN0(skb_headlen(skb)) |
-@@ -845,7 +849,7 @@ static int mtk_start_xmit(struct sk_buff
- drop:
- spin_unlock(&eth->page_lock);
- stats->tx_dropped++;
-- dev_kfree_skb(skb);
-+ dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
- }
-
-@@ -1014,17 +1018,16 @@ static int mtk_poll_tx(struct mtk_eth *e
-
- while ((cpu != dma) && budget) {
- u32 next_cpu = desc->txd2;
-- int mac;
-+ int mac = 0;
-
- desc = mtk_qdma_phys_to_virt(ring, desc->txd2);
- if ((desc->txd3 & TX_DMA_OWNER_CPU) == 0)
- break;
-
-- mac = (desc->txd4 >> TX_DMA_FPORT_SHIFT) &
-- TX_DMA_FPORT_MASK;
-- mac--;
--
- tx_buf = mtk_desc_to_tx_buf(ring, desc);
-+ if (tx_buf->flags & MTK_TX_FLAGS_FPORT1)
-+ mac = 1;
-+
- skb = tx_buf->skb;
- if (!skb) {
- condition = 1;
-@@ -1848,6 +1851,12 @@ static int mtk_hw_init(struct mtk_eth *e
- /* GE2, Force 1000M/FD, FC ON */
- mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(1));
-
-+ /* Indicates CDM to parse the MTK special tag from CPU
-+ * which also is working out for untag packets.
-+ */
-+ val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
-+ mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
-+
- /* Enable RX VLan Offloading */
- mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
-
-@@ -1910,10 +1919,9 @@ static int __init mtk_init(struct net_de
-
- /* If the mac address is invalid, use random mac address */
- if (!is_valid_ether_addr(dev->dev_addr)) {
-- random_ether_addr(dev->dev_addr);
-+ eth_hw_addr_random(dev);
- dev_err(eth->dev, "generated random MAC address %pM\n",
- dev->dev_addr);
-- dev->addr_assign_type = NET_ADDR_RANDOM;
- }
-
- return mtk_phy_connect(dev);
-@@ -2247,7 +2255,6 @@ static const struct net_device_ops mtk_n
- .ndo_set_mac_address = mtk_set_mac_address,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_do_ioctl = mtk_do_ioctl,
-- .ndo_change_mtu = eth_change_mtu,
- .ndo_tx_timeout = mtk_tx_timeout,
- .ndo_get_stats64 = mtk_get_stats64,
- .ndo_fix_features = mtk_fix_features,
-@@ -2320,6 +2327,8 @@ static int mtk_add_mac(struct mtk_eth *e
- eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops;
-
- eth->netdev[id]->irq = eth->irq[0];
-+ eth->netdev[id]->dev.of_node = np;
-+
- return 0;
-
- free_netdev:
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -70,6 +70,10 @@
- /* Frame Engine Interrupt Grouping Register */
- #define MTK_FE_INT_GRP 0x20
-
-+/* CDMP Ingress Control Register */
-+#define MTK_CDMQ_IG_CTRL 0x1400
-+#define MTK_CDMQ_STAG_EN BIT(0)
-+
- /* CDMP Exgress Control Register */
- #define MTK_CDMP_EG_CTRL 0x404
-
-@@ -406,12 +410,18 @@ struct mtk_hw_stats {
- struct u64_stats_sync syncp;
- };
-
--/* PDMA descriptor can point at 1-2 segments. This enum allows us to track how
-- * memory was allocated so that it can be freed properly
-- */
- enum mtk_tx_flags {
-+ /* PDMA descriptor can point at 1-2 segments. This enum allows us to
-+ * track how memory was allocated so that it can be freed properly.
-+ */
- MTK_TX_FLAGS_SINGLE0 = 0x01,
- MTK_TX_FLAGS_PAGE0 = 0x02,
-+
-+ /* MTK_TX_FLAGS_FPORTx allows tracking which port the transmitted
-+ * SKB out instead of looking up through hardware TX descriptor.
-+ */
-+ MTK_TX_FLAGS_FPORT0 = 0x04,
-+ MTK_TX_FLAGS_FPORT1 = 0x08,
- };
-
- /* This enum allows us to identify how the clock is defined on the array of the
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_hnat/Makefile
-@@ -0,0 +1,4 @@
-+ccflags-y=-Werror
-+
-+obj-$(CONFIG_NET_MEDIATEK_HNAT) += mtkhnat.o
-+mtkhnat-objs := hnat.o hnat_nf_hook.o hnat_debugfs.o
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c
-@@ -0,0 +1,315 @@
-+/* This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; version 2 of the License
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * Copyright (C) 2014-2016 Sean Wang <sean.wang@mediatek.com>
-+ * Copyright (C) 2016-2017 John Crispin <blogic@openwrt.org>
-+ */
-+
-+#include <linux/dma-mapping.h>
-+#include <linux/delay.h>
-+#include <linux/if.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset.h>
-+
-+#include "hnat.h"
-+
-+struct hnat_priv *host;
-+
-+static void cr_set_bits(void __iomem * reg, u32 bs)
-+{
-+ u32 val = readl(reg);
-+
-+ val |= bs;
-+ writel(val, reg);
-+}
-+
-+static void cr_clr_bits(void __iomem * reg, u32 bs)
-+{
-+ u32 val = readl(reg);
-+
-+ val &= ~bs;
-+ writel(val, reg);
-+}
-+
-+static void cr_set_field(void __iomem * reg, u32 field, u32 val)
-+{
-+ unsigned int tv = readl(reg);
-+
-+ tv &= ~field;
-+ tv |= ((val) << (ffs((unsigned int)field) - 1));
-+ writel(tv, reg);
-+}
-+
-+static int hnat_start(void)
-+{
-+ u32 foe_table_sz;
-+
-+ /* mapp the FOE table */
-+ foe_table_sz = FOE_4TB_SIZ * sizeof(struct foe_entry);
-+ host->foe_table_cpu =
-+ dma_alloc_coherent(host->dev, foe_table_sz, &host->foe_table_dev,
-+ GFP_KERNEL);
-+ if (!host->foe_table_cpu)
-+ return -1;
-+
-+ writel(host->foe_table_dev, host->ppe_base + PPE_TB_BASE);
-+ memset(host->foe_table_cpu, 0, foe_table_sz);
-+
-+ /* setup hashing */
-+ cr_set_field(host->ppe_base + PPE_TB_CFG, TB_ETRY_NUM, TABLE_4K);
-+ cr_set_field(host->ppe_base + PPE_TB_CFG, HASH_MODE, HASH_MODE_1);
-+ writel(HASH_SEED_KEY, host->ppe_base + PPE_HASH_SEED);
-+ cr_set_field(host->ppe_base + PPE_TB_CFG, XMODE, 0);
-+ cr_set_field(host->ppe_base + PPE_TB_CFG, TB_ENTRY_SIZE, ENTRY_64B);
-+ cr_set_field(host->ppe_base + PPE_TB_CFG, SMA, SMA_FWD_CPU_BUILD_ENTRY);
-+
-+ /* set ip proto */
-+ writel(0xFFFFFFFF, host->ppe_base + PPE_IP_PROT_CHK);
-+
-+ /* setup caching */
-+ cr_set_field(host->ppe_base + PPE_CAH_CTRL, CAH_X_MODE, 1);
-+ cr_set_field(host->ppe_base + PPE_CAH_CTRL, CAH_X_MODE, 0);
-+ cr_set_field(host->ppe_base + PPE_CAH_CTRL, CAH_EN, 1);
-+
-+ /* enable FOE */
-+ cr_set_bits(host->ppe_base + PPE_FLOW_CFG,
-+ BIT_IPV4_NAT_EN | BIT_IPV4_NAPT_EN |
-+ BIT_IPV4_NAT_FRAG_EN | BIT_IPV4_HASH_GREK);
-+
-+ /* setup FOE aging */
-+ cr_set_field(host->ppe_base + PPE_TB_CFG, NTU_AGE, 1);
-+ cr_set_field(host->ppe_base + PPE_TB_CFG, UNBD_AGE, 1);
-+ cr_set_field(host->ppe_base + PPE_UNB_AGE, UNB_MNP, 1000);
-+ cr_set_field(host->ppe_base + PPE_UNB_AGE, UNB_DLTA, 3);
-+ cr_set_field(host->ppe_base + PPE_TB_CFG, TCP_AGE, 1);
-+ cr_set_field(host->ppe_base + PPE_TB_CFG, UDP_AGE, 1);
-+ cr_set_field(host->ppe_base + PPE_TB_CFG, FIN_AGE, 1);
-+ cr_set_field(host->ppe_base + PPE_BND_AGE_0, UDP_DLTA, 5);
-+ cr_set_field(host->ppe_base + PPE_BND_AGE_0, NTU_DLTA, 5);
-+ cr_set_field(host->ppe_base + PPE_BND_AGE_1, FIN_DLTA, 5);
-+ cr_set_field(host->ppe_base + PPE_BND_AGE_1, TCP_DLTA, 5);
-+
-+ /* setup FOE ka */
-+ cr_set_field(host->ppe_base + PPE_TB_CFG, KA_CFG, 3);
-+ cr_set_field(host->ppe_base + PPE_KA, KA_T, 1);
-+ cr_set_field(host->ppe_base + PPE_KA, TCP_KA, 1);
-+ cr_set_field(host->ppe_base + PPE_KA, UDP_KA, 1);
-+ cr_set_field(host->ppe_base + PPE_BIND_LMT_1, NTU_KA, 1);
-+
-+ /* setup FOE rate limit */
-+ cr_set_field(host->ppe_base + PPE_BIND_LMT_0, QURT_LMT, 16383);
-+ cr_set_field(host->ppe_base + PPE_BIND_LMT_0, HALF_LMT, 16383);
-+ cr_set_field(host->ppe_base + PPE_BIND_LMT_1, FULL_LMT, 16383);
-+ cr_set_field(host->ppe_base + PPE_BNDR, BIND_RATE, 1);
-+
-+ /* setup FOE cf gen */
-+ cr_set_field(host->ppe_base + PPE_GLO_CFG, PPE_EN, 1);
-+ writel(0, host->ppe_base + PPE_DFT_CPORT); // pdma
-+ //writel(0x55555555, host->ppe_base + PPE_DFT_CPORT); //qdma
-+ cr_set_field(host->ppe_base + PPE_GLO_CFG, TTL0_DRP, 1);
-+
-+ /* fwd packets from gmac to PPE */
-+ cr_clr_bits(host->fe_base + GDMA1_FWD_CFG, GDM1_ALL_FRC_MASK);
-+ cr_set_bits(host->fe_base + GDMA1_FWD_CFG,
-+ BITS_GDM1_ALL_FRC_P_PPE);
-+ cr_clr_bits(host->fe_base + GDMA2_FWD_CFG, GDM2_ALL_FRC_MASK);
-+ cr_set_bits(host->fe_base + GDMA2_FWD_CFG,
-+ BITS_GDM2_ALL_FRC_P_PPE);
-+
-+ dev_info(host->dev, "hwnat start\n");
-+
-+ return 0;
-+}
-+
-+static int ppe_busy_wait(void)
-+{
-+ unsigned long t_start = jiffies;
-+ u32 r = 0;
-+
-+ while (1) {
-+ r = readl((host->ppe_base + 0x0));
-+ if (!(r & BIT(31)))
-+ return 0;
-+ if (time_after(jiffies, t_start + HZ))
-+ break;
-+ usleep_range(10, 20);
-+ }
-+
-+ dev_err(host->dev, "ppe:%s timeout\n", __func__);
-+
-+ return -1;
-+}
-+
-+static void hnat_stop(void)
-+{
-+ u32 foe_table_sz;
-+ struct foe_entry *entry, *end;
-+ u32 r1 = 0, r2 = 0;
-+
-+ /* discard all traffic while we disable the PPE */
-+ cr_clr_bits(host->fe_base + GDMA1_FWD_CFG, GDM1_ALL_FRC_MASK);
-+ cr_set_bits(host->fe_base + GDMA1_FWD_CFG,
-+ BITS_GDM1_ALL_FRC_P_DISCARD);
-+ cr_clr_bits(host->fe_base + GDMA2_FWD_CFG, GDM2_ALL_FRC_MASK);
-+ cr_set_bits(host->fe_base + GDMA2_FWD_CFG,
-+ BITS_GDM2_ALL_FRC_P_DISCARD);
-+
-+ if (ppe_busy_wait()) {
-+ reset_control_reset(host->rstc);
-+ msleep(2000);
-+ return;
-+ }
-+
-+ entry = host->foe_table_cpu;
-+ end = host->foe_table_cpu + FOE_4TB_SIZ;
-+ while (entry < end) {
-+ entry->bfib1.state = INVALID;
-+ entry++;
-+ }
-+
-+ /* disable caching */
-+ cr_set_field(host->ppe_base + PPE_CAH_CTRL, CAH_X_MODE, 1);
-+ cr_set_field(host->ppe_base + PPE_CAH_CTRL, CAH_X_MODE, 0);
-+ cr_set_field(host->ppe_base + PPE_CAH_CTRL, CAH_EN, 0);
-+
-+ /* flush cache has to be ahead of hnat diable --*/
-+ cr_set_field(host->ppe_base + PPE_GLO_CFG, PPE_EN, 0);
-+
-+ /* disable FOE */
-+ cr_clr_bits(host->ppe_base + PPE_FLOW_CFG,
-+ BIT_IPV4_NAPT_EN | BIT_IPV4_NAT_EN |
-+ BIT_IPV4_NAT_FRAG_EN |
-+ BIT_FUC_FOE | BIT_FMC_FOE | BIT_FUC_FOE);
-+
-+ /* disable FOE aging */
-+ cr_set_field(host->ppe_base + PPE_TB_CFG, NTU_AGE, 0);
-+ cr_set_field(host->ppe_base + PPE_TB_CFG, UNBD_AGE, 0);
-+ cr_set_field(host->ppe_base + PPE_TB_CFG, TCP_AGE, 0);
-+ cr_set_field(host->ppe_base + PPE_TB_CFG, UDP_AGE, 0);
-+ cr_set_field(host->ppe_base + PPE_TB_CFG, FIN_AGE, 0);
-+
-+ r1 = readl(host->fe_base + 0x100);
-+ r2 = readl(host->fe_base + 0x10c);
-+
-+ dev_info(host->dev, "0x100 = 0x%x, 0x10c = 0x%x\n", r1, r2);
-+
-+ if (((r1 & 0xff00) >> 0x8) >= (r1 & 0xff) ||
-+ ((r1 & 0xff00) >> 0x8) >= (r2 & 0xff)) {
-+ dev_info(host->dev, "reset pse\n");
-+ writel(0x1, host->fe_base + 0x4);
-+ }
-+
-+ /* free the FOE table */
-+ foe_table_sz = FOE_4TB_SIZ * sizeof(struct foe_entry);
-+ dma_free_coherent(NULL, foe_table_sz, host->foe_table_cpu,
-+ host->foe_table_dev);
-+ writel(0, host->ppe_base + PPE_TB_BASE);
-+
-+ if (ppe_busy_wait()) {
-+ reset_control_reset(host->rstc);
-+ msleep(2000);
-+ return;
-+ }
-+
-+ /* send all traffic back to the DMA engine */
-+ cr_clr_bits(host->fe_base + GDMA1_FWD_CFG, GDM1_ALL_FRC_MASK);
-+ cr_set_bits(host->fe_base + GDMA1_FWD_CFG,
-+ BITS_GDM1_ALL_FRC_P_CPU_PDMA);
-+ cr_clr_bits(host->fe_base + GDMA2_FWD_CFG, GDM2_ALL_FRC_MASK);
-+ cr_set_bits(host->fe_base + GDMA2_FWD_CFG,
-+ BITS_GDM2_ALL_FRC_P_CPU_PDMA);
-+}
-+
-+static int hnat_probe(struct platform_device *pdev)
-+{
-+ int err = 0;
-+ struct resource *res ;
-+ const char *name;
-+ struct device_node *np;
-+
-+ host = devm_kzalloc(&pdev->dev, sizeof(struct hnat_priv), GFP_KERNEL);
-+ if (!host)
-+ return -ENOMEM;
-+
-+ host->dev = &pdev->dev;
-+ np = host->dev->of_node;
-+
-+ err = of_property_read_string(np, "mtketh-wan", &name);
-+ if (err < 0)
-+ return -EINVAL;
-+
-+ strncpy(host->wan, (char *)name, IFNAMSIZ);
-+ dev_info(&pdev->dev, "wan = %s\n", host->wan);
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ if (!res)
-+ return -ENOENT;
-+
-+ host->fe_base = devm_ioremap_nocache(&pdev->dev, res->start,
-+ res->end - res->start + 1);
-+ if (!host->fe_base)
-+ return -EADDRNOTAVAIL;
-+
-+ host->ppe_base = host->fe_base + 0xe00;
-+ err = hnat_init_debugfs(host);
-+ if (err)
-+ return err;
-+
-+ host->rstc = devm_reset_control_get(&pdev->dev, NULL);
-+ if (IS_ERR(host->rstc))
-+ return PTR_ERR(host->rstc);
-+
-+ err = hnat_start();
-+ if (err)
-+ goto err_out;
-+
-+ err = hnat_register_nf_hooks();
-+ if (err)
-+ goto err_out;
-+
-+ return 0;
-+
-+err_out:
-+ hnat_stop();
-+ hnat_deinit_debugfs(host);
-+ return err;
-+}
-+
-+static int hnat_remove(struct platform_device *pdev)
-+{
-+ hnat_unregister_nf_hooks();
-+ hnat_stop();
-+ hnat_deinit_debugfs(host);
-+
-+ return 0;
-+}
-+
-+const struct of_device_id of_hnat_match[] = {
-+ { .compatible = "mediatek,mt7623-hnat" },
-+ {},
-+};
-+
-+static struct platform_driver hnat_driver = {
-+ .probe = hnat_probe,
-+ .remove = hnat_remove,
-+ .driver = {
-+ .name = "mediatek_soc_hnat",
-+ .of_match_table = of_hnat_match,
-+ },
-+};
-+
-+module_platform_driver(hnat_driver);
-+
-+MODULE_LICENSE("GPL v2");
-+MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
-+MODULE_AUTHOR("John Crispin <john@phrozen.org>");
-+MODULE_DESCRIPTION("Mediatek Hardware NAT");
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
-@@ -0,0 +1,425 @@
-+/* This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; version 2 of the License
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * Copyright (C) 2014-2016 Sean Wang <sean.wang@mediatek.com>
-+ * Copyright (C) 2016-2017 John Crispin <blogic@openwrt.org>
-+ */
-+
-+#include <linux/debugfs.h>
-+#include <linux/string.h>
-+#include <linux/if.h>
-+#include <linux/if_ether.h>
-+
-+/*--------------------------------------------------------------------------*/
-+/* Register Offset*/
-+/*--------------------------------------------------------------------------*/
-+#define PPE_GLO_CFG 0x00
-+#define PPE_FLOW_CFG 0x04
-+#define PPE_IP_PROT_CHK 0x08
-+#define PPE_IP_PROT_0 0x0C
-+#define PPE_IP_PROT_1 0x10
-+#define PPE_IP_PROT_2 0x14
-+#define PPE_IP_PROT_3 0x18
-+#define PPE_TB_CFG 0x1C
-+#define PPE_TB_BASE 0x20
-+#define PPE_TB_USED 0x24
-+#define PPE_BNDR 0x28
-+#define PPE_BIND_LMT_0 0x2C
-+#define PPE_BIND_LMT_1 0x30
-+#define PPE_KA 0x34
-+#define PPE_UNB_AGE 0x38
-+#define PPE_BND_AGE_0 0x3C
-+#define PPE_BND_AGE_1 0x40
-+#define PPE_HASH_SEED 0x44
-+#define PPE_DFT_CPORT 0x48
-+#define PPE_MCAST_PPSE 0x84
-+#define PPE_MCAST_L_0 0x88
-+#define PPE_MCAST_H_0 0x8C
-+#define PPE_MCAST_L_1 0x90
-+#define PPE_MCAST_H_1 0x94
-+#define PPE_MCAST_L_2 0x98
-+#define PPE_MCAST_H_2 0x9C
-+#define PPE_MCAST_L_3 0xA0
-+#define PPE_MCAST_H_3 0xA4
-+#define PPE_MCAST_L_4 0xA8
-+#define PPE_MCAST_H_4 0xAC
-+#define PPE_MCAST_L_5 0xB0
-+#define PPE_MCAST_H_5 0xB4
-+#define PPE_MCAST_L_6 0xBC
-+#define PPE_MCAST_H_6 0xC0
-+#define PPE_MCAST_L_7 0xC4
-+#define PPE_MCAST_H_7 0xC8
-+#define PPE_MCAST_L_8 0xCC
-+#define PPE_MCAST_H_8 0xD0
-+#define PPE_MCAST_L_9 0xD4
-+#define PPE_MCAST_H_9 0xD8
-+#define PPE_MCAST_L_A 0xDC
-+#define PPE_MCAST_H_A 0xE0
-+#define PPE_MCAST_L_B 0xE4
-+#define PPE_MCAST_H_B 0xE8
-+#define PPE_MCAST_L_C 0xEC
-+#define PPE_MCAST_H_C 0xF0
-+#define PPE_MCAST_L_D 0xF4
-+#define PPE_MCAST_H_D 0xF8
-+#define PPE_MCAST_L_E 0xFC
-+#define PPE_MCAST_H_E 0xE0
-+#define PPE_MCAST_L_F 0x100
-+#define PPE_MCAST_H_F 0x104
-+#define PPE_MTU_DRP 0x108
-+#define PPE_MTU_VLYR_0 0x10C
-+#define PPE_MTU_VLYR_1 0x110
-+#define PPE_MTU_VLYR_2 0x114
-+#define PPE_VPM_TPID 0x118
-+#define PPE_CAH_CTRL 0x120
-+#define PPE_CAH_TAG_SRH 0x124
-+#define PPE_CAH_LINE_RW 0x128
-+#define PPE_CAH_WDATA 0x12C
-+#define PPE_CAH_RDATA 0x130
-+
-+#define GDMA1_FWD_CFG 0x500
-+#define GDMA2_FWD_CFG 0x1500
-+/*--------------------------------------------------------------------------*/
-+/* Register Mask*/
-+/*--------------------------------------------------------------------------*/
-+/* PPE_TB_CFG mask */
-+#define TB_ETRY_NUM (0x7 << 0) /* RW */
-+#define TB_ENTRY_SIZE (0x1 << 3) /* RW */
-+#define SMA (0x3 << 4) /* RW */
-+#define NTU_AGE (0x1 << 7) /* RW */
-+#define UNBD_AGE (0x1 << 8) /* RW */
-+#define TCP_AGE (0x1 << 9) /* RW */
-+#define UDP_AGE (0x1 << 10) /* RW */
-+#define FIN_AGE (0x1 << 11) /* RW */
-+#define KA_CFG (0x3<< 12)
-+#define HASH_MODE (0x3 << 14) /* RW */
-+#define XMODE (0x3 << 18) /* RW */
-+
-+/*PPE_CAH_CTRL mask*/
-+#define CAH_EN (0x1 << 0) /* RW */
-+#define CAH_X_MODE (0x1 << 9) /* RW */
-+
-+/*PPE_UNB_AGE mask*/
-+#define UNB_DLTA (0xff << 0) /* RW */
-+#define UNB_MNP (0xffff << 16) /* RW */
-+
-+/*PPE_BND_AGE_0 mask*/
-+#define UDP_DLTA (0xffff << 0) /* RW */
-+#define NTU_DLTA (0xffff << 16) /* RW */
-+
-+/*PPE_BND_AGE_1 mask*/
-+#define TCP_DLTA (0xffff << 0) /* RW */
-+#define FIN_DLTA (0xffff << 16) /* RW */
-+
-+/*PPE_KA mask*/
-+#define KA_T (0xffff << 0) /* RW */
-+#define TCP_KA (0xff << 16) /* RW */
-+#define UDP_KA (0xff << 24) /* RW */
-+
-+/*PPE_BIND_LMT_0 mask*/
-+#define QURT_LMT (0x3ff << 0) /* RW */
-+#define HALF_LMT (0x3ff << 16) /* RW */
-+
-+/*PPE_BIND_LMT_1 mask*/
-+#define FULL_LMT (0x3fff << 0) /* RW */
-+#define NTU_KA (0xff << 16) /* RW */
-+
-+/*PPE_BNDR mask*/
-+#define BIND_RATE (0xffff << 0) /* RW */
-+#define PBND_RD_PRD (0xffff << 16) /* RW */
-+
-+/*PPE_GLO_CFG mask*/
-+#define PPE_EN (0x1 << 0) /* RW */
-+#define TTL0_DRP (0x1 << 4) /* RW */
-+
-+/*GDMA1_FWD_CFG mask */
-+#define GDM1_UFRC_MASK (0x7 << 12) /* RW */
-+#define GDM1_BFRC_MASK (0x7 << 8) /*RW*/
-+#define GDM1_MFRC_MASK (0x7 << 4) /*RW*/
-+#define GDM1_OFRC_MASK (0x7 << 0) /*RW*/
-+#define GDM1_ALL_FRC_MASK (GDM1_UFRC_MASK | GDM1_BFRC_MASK | GDM1_MFRC_MASK | GDM1_OFRC_MASK)
-+
-+#define GDM2_UFRC_MASK (0x7 << 12) /* RW */
-+#define GDM2_BFRC_MASK (0x7 << 8) /*RW*/
-+#define GDM2_MFRC_MASK (0x7 << 4) /*RW*/
-+#define GDM2_OFRC_MASK (0x7 << 0) /*RW*/
-+#define GDM2_ALL_FRC_MASK (GDM2_UFRC_MASK | GDM2_BFRC_MASK | GDM2_MFRC_MASK | GDM2_OFRC_MASK)
-+
-+/*--------------------------------------------------------------------------*/
-+/* Descriptor Structure */
-+/*--------------------------------------------------------------------------*/
-+#define HNAT_SKB_CB(__skb) ((struct hnat_skb_cb *)&((__skb)->cb[40]))
-+struct hnat_skb_cb {
-+ __u16 iif;
-+};
-+
-+struct hnat_unbind_info_blk {
-+ u32 time_stamp:8;
-+ u32 pcnt:16; /* packet count */
-+ u32 preb:1;
-+ u32 pkt_type:3;
-+ u32 state:2;
-+ u32 udp:1;
-+ u32 sta:1; /* static entry */
-+} __attribute__ ((packed));
-+
-+struct hnat_bind_info_blk {
-+ u32 time_stamp:15;
-+ u32 ka:1; /* keep alive */
-+ u32 vlan_layer:3;
-+ u32 psn:1; /* egress packet has PPPoE session */
-+ u32 vpm:1; /* 0:ethertype remark, 1:0x8100(CR default) */
-+ u32 ps:1; /* packet sampling */
-+ u32 cah:1; /* cacheable flag */
-+ u32 rmt:1; /* remove tunnel ip header (6rd/dslite only) */
-+ u32 ttl:1;
-+ u32 pkt_type:3;
-+ u32 state:2;
-+ u32 udp:1;
-+ u32 sta:1; /* static entry */
-+} __attribute__ ((packed));
-+
-+struct hnat_info_blk2 {
-+ u32 qid:4; /* QID in Qos Port */
-+ u32 fqos:1; /* force to PSE QoS port */
-+ u32 dp:3; /* force to PSE port x
-+ 0:PSE,1:GSW, 2:GMAC,4:PPE,5:QDMA,7=DROP */
-+ u32 mcast:1; /* multicast this packet to CPU */
-+ u32 pcpl:1; /* OSBN */
-+ u32 mlen:1; /* 0:post 1:pre packet length in meter */
-+ u32 alen:1; /* 0:post 1:pre packet length in accounting */
-+ u32 port_mg:6; /* port meter group */
-+ u32 port_ag:6; /* port account group */
-+ u32 dscp:8; /* DSCP value */
-+} __attribute__ ((packed));
-+
-+struct hnat_ipv4_hnapt {
-+ union {
-+ struct hnat_bind_info_blk bfib1;
-+ struct hnat_unbind_info_blk udib1;
-+ u32 info_blk1;
-+ };
-+ u32 sip;
-+ u32 dip;
-+ u16 dport;
-+ u16 sport;
-+ union {
-+ struct hnat_info_blk2 iblk2;
-+ u32 info_blk2;
-+ };
-+ u32 new_sip;
-+ u32 new_dip;
-+ u16 new_dport;
-+ u16 new_sport;
-+ u32 resv1;
-+ u32 resv2;
-+ u32 resv3:26;
-+ u32 act_dp:6; /* UDF */
-+ u16 vlan1;
-+ u16 etype;
-+ u32 dmac_hi;
-+ u16 vlan2;
-+ u16 dmac_lo;
-+ u32 smac_hi;
-+ u16 pppoe_id;
-+ u16 smac_lo;
-+} __attribute__ ((packed));
-+
-+struct foe_entry {
-+ union {
-+ struct hnat_unbind_info_blk udib1;
-+ struct hnat_bind_info_blk bfib1;
-+ struct hnat_ipv4_hnapt ipv4_hnapt;
-+ };
-+};
-+
-+#define HNAT_AC_BYTE_LO(x) (0x2000 + (x * 16))
-+#define HNAT_AC_BYTE_HI(x) (0x2004 + (x * 16))
-+#define HNAT_AC_PACKET(x) (0x2008 + (x * 16))
-+#define HNAT_COUNTER_MAX 64
-+#define HNAT_AC_TIMER_INTERVAL (HZ)
-+
-+struct hnat_accounting {
-+ u64 bytes;
-+ u64 packets;
-+};
-+
-+struct hnat_priv {
-+ struct device *dev;
-+ void __iomem *fe_base;
-+ void __iomem *ppe_base;
-+ struct foe_entry *foe_table_cpu;
-+ dma_addr_t foe_table_dev;
-+ u8 enable;
-+ u8 enable1;
-+ struct dentry *root;
-+ struct debugfs_regset32 *regset;
-+
-+ struct timer_list ac_timer;
-+ struct hnat_accounting acct[HNAT_COUNTER_MAX];
-+
-+ /*devices we plays for*/
-+ char wan[IFNAMSIZ];
-+
-+ struct reset_control *rstc;
-+};
-+
-+enum FoeEntryState {
-+ INVALID = 0,
-+ UNBIND = 1,
-+ BIND = 2,
-+ FIN = 3
-+};
-+/*--------------------------------------------------------------------------*/
-+/* Common Definition*/
-+/*--------------------------------------------------------------------------*/
-+
-+#define FOE_4TB_SIZ 4096
-+#define HASH_SEED_KEY 0x12345678
-+
-+/*PPE_TB_CFG value*/
-+#define ENTRY_80B 1
-+#define ENTRY_64B 0
-+#define TABLE_1K 0
-+#define TABLE_2K 1
-+#define TABLE_4K 2
-+#define TABLE_8K 3
-+#define TABLE_16K 4
-+#define SMA_DROP 0 /* Drop the packet */
-+#define SMA_DROP2 1 /* Drop the packet */
-+#define SMA_ONLY_FWD_CPU 2 /* Only Forward to CPU */
-+#define SMA_FWD_CPU_BUILD_ENTRY 3 /* Forward to CPU and build new FOE entry */
-+#define HASH_MODE_0 0
-+#define HASH_MODE_1 1
-+#define HASH_MODE_2 2
-+#define HASH_MODE_3 3
-+
-+/*PPE_FLOW_CFG*/
-+#define BIT_FUC_FOE BIT(2)
-+#define BIT_FMC_FOE BIT(1)
-+#define BIT_FBC_FOE BIT(0)
-+#define BIT_IPV4_NAT_EN BIT(12)
-+#define BIT_IPV4_NAPT_EN BIT(13)
-+#define BIT_IPV4_NAT_FRAG_EN BIT(17)
-+#define BIT_IPV4_HASH_GREK BIT(19)
-+
-+/*GDMA1_FWD_CFG value */
-+#define BITS_GDM1_UFRC_P_PPE (NR_PPE_PORT << 12)
-+#define BITS_GDM1_BFRC_P_PPE (NR_PPE_PORT << 8)
-+#define BITS_GDM1_MFRC_P_PPE (NR_PPE_PORT << 4)
-+#define BITS_GDM1_OFRC_P_PPE (NR_PPE_PORT << 0)
-+#define BITS_GDM1_ALL_FRC_P_PPE (BITS_GDM1_UFRC_P_PPE | BITS_GDM1_BFRC_P_PPE | BITS_GDM1_MFRC_P_PPE | BITS_GDM1_OFRC_P_PPE)
-+
-+#define BITS_GDM1_UFRC_P_CPU_PDMA (NR_PDMA_PORT << 12)
-+#define BITS_GDM1_BFRC_P_CPU_PDMA (NR_PDMA_PORT << 8)
-+#define BITS_GDM1_MFRC_P_CPU_PDMA (NR_PDMA_PORT << 4)
-+#define BITS_GDM1_OFRC_P_CPU_PDMA (NR_PDMA_PORT << 0)
-+#define BITS_GDM1_ALL_FRC_P_CPU_PDMA (BITS_GDM1_UFRC_P_CPU_PDMA | BITS_GDM1_BFRC_P_CPU_PDMA | BITS_GDM1_MFRC_P_CPU_PDMA | BITS_GDM1_OFRC_P_CPU_PDMA)
-+
-+#define BITS_GDM1_UFRC_P_CPU_QDMA (NR_QDMA_PORT << 12)
-+#define BITS_GDM1_BFRC_P_CPU_QDMA (NR_QDMA_PORT << 8)
-+#define BITS_GDM1_MFRC_P_CPU_QDMA (NR_QDMA_PORT << 4)
-+#define BITS_GDM1_OFRC_P_CPU_QDMA (NR_QDMA_PORT << 0)
-+#define BITS_GDM1_ALL_FRC_P_CPU_QDMA (BITS_GDM1_UFRC_P_CPU_QDMA | BITS_GDM1_BFRC_P_CPU_QDMA | BITS_GDM1_MFRC_P_CPU_QDMA | BITS_GDM1_OFRC_P_CPU_QDMA)
-+
-+#define BITS_GDM1_UFRC_P_DISCARD (NR_DISCARD << 12)
-+#define BITS_GDM1_BFRC_P_DISCARD (NR_DISCARD << 8)
-+#define BITS_GDM1_MFRC_P_DISCARD (NR_DISCARD << 4)
-+#define BITS_GDM1_OFRC_P_DISCARD (NR_DISCARD << 0)
-+#define BITS_GDM1_ALL_FRC_P_DISCARD (BITS_GDM1_UFRC_P_DISCARD | BITS_GDM1_BFRC_P_DISCARD | BITS_GDM1_MFRC_P_DISCARD | BITS_GDM1_OFRC_P_DISCARD)
-+
-+#define BITS_GDM2_UFRC_P_PPE (NR_PPE_PORT << 12)
-+#define BITS_GDM2_BFRC_P_PPE (NR_PPE_PORT << 8)
-+#define BITS_GDM2_MFRC_P_PPE (NR_PPE_PORT << 4)
-+#define BITS_GDM2_OFRC_P_PPE (NR_PPE_PORT << 0)
-+#define BITS_GDM2_ALL_FRC_P_PPE (BITS_GDM2_UFRC_P_PPE | BITS_GDM2_BFRC_P_PPE | BITS_GDM2_MFRC_P_PPE | BITS_GDM2_OFRC_P_PPE)
-+
-+#define BITS_GDM2_UFRC_P_CPU_PDMA (NR_PDMA_PORT << 12)
-+#define BITS_GDM2_BFRC_P_CPU_PDMA (NR_PDMA_PORT << 8)
-+#define BITS_GDM2_MFRC_P_CPU_PDMA (NR_PDMA_PORT << 4)
-+#define BITS_GDM2_OFRC_P_CPU_PDMA (NR_PDMA_PORT << 0)
-+#define BITS_GDM2_ALL_FRC_P_CPU_PDMA (BITS_GDM2_UFRC_P_CPU_PDMA | BITS_GDM2_BFRC_P_CPU_PDMA | BITS_GDM2_MFRC_P_CPU_PDMA | BITS_GDM2_OFRC_P_CPU_PDMA)
-+
-+#define BITS_GDM2_UFRC_P_CPU_QDMA (NR_QDMA_PORT << 12)
-+#define BITS_GDM2_BFRC_P_CPU_QDMA (NR_QDMA_PORT << 8)
-+#define BITS_GDM2_MFRC_P_CPU_QDMA (NR_QDMA_PORT << 4)
-+#define BITS_GDM2_OFRC_P_CPU_QDMA (NR_QDMA_PORT << 0)
-+#define BITS_GDM2_ALL_FRC_P_CPU_QDMA (BITS_GDM2_UFRC_P_CPU_QDMA | BITS_GDM2_BFRC_P_CPU_QDMA | BITS_GDM2_MFRC_P_CPU_QDMA | BITS_GDM2_OFRC_P_CPU_QDMA)
-+
-+#define BITS_GDM2_UFRC_P_DISCARD (NR_DISCARD << 12)
-+#define BITS_GDM2_BFRC_P_DISCARD (NR_DISCARD << 8)
-+#define BITS_GDM2_MFRC_P_DISCARD (NR_DISCARD << 4)
-+#define BITS_GDM2_OFRC_P_DISCARD (NR_DISCARD << 0)
-+#define BITS_GDM2_ALL_FRC_P_DISCARD (BITS_GDM2_UFRC_P_DISCARD | BITS_GDM2_BFRC_P_DISCARD | BITS_GDM2_MFRC_P_DISCARD | BITS_GDM2_OFRC_P_DISCARD)
-+
-+#define hnat_is_enabled(host) (host->enable)
-+#define hnat_enabled(host) (host->enable = 1)
-+#define hnat_disabled(host) (host->enable = 0)
-+#define hnat_is_enabled1(host) (host->enable1)
-+#define hnat_enabled1(host) (host->enable1 = 1)
-+#define hnat_disabled1(host) (host->enable1 = 0)
-+
-+#define entry_hnat_is_bound(e) (e->bfib1.state == BIND)
-+#define entry_hnat_state(e) (e->bfib1.state)
-+
-+#define skb_hnat_is_hashed(skb) (skb_hnat_entry(skb)!=0x3fff && skb_hnat_entry(skb)< FOE_4TB_SIZ)
-+#define FROM_GE_LAN(skb) (HNAT_SKB_CB(skb)->iif == FOE_MAGIC_GE_LAN)
-+#define FROM_GE_WAN(skb) (HNAT_SKB_CB(skb)->iif == FOE_MAGIC_GE_WAN)
-+#define FROM_GE_PPD(skb) (HNAT_SKB_CB(skb)->iif == FOE_MAGIC_GE_PPD)
-+#define FOE_MAGIC_GE_WAN 0x7273
-+#define FOE_MAGIC_GE_LAN 0x7272
-+#define FOE_INVALID 0xffff
-+
-+#define TCP_FIN_SYN_RST 0x0C /* Ingress packet is TCP fin/syn/rst (for IPv4 NAPT/DS-Lite or IPv6 5T-route/6RD) */
-+#define UN_HIT 0x0D/* FOE Un-hit */
-+#define HIT_UNBIND 0x0E/* FOE Hit unbind */
-+#define HIT_UNBIND_RATE_REACH 0xf
-+#define HNAT_HIT_BIND_OLD_DUP_HDR 0x15
-+#define HNAT_HIT_BIND_FORCE_TO_CPU 0x16
-+
-+#define HIT_BIND_KEEPALIVE_MC_NEW_HDR 0x14
-+#define HIT_BIND_KEEPALIVE_DUP_OLD_HDR 0x15
-+#define IPV4_HNAPT 0
-+#define IPV4_HNAT 1
-+#define IP_FORMAT(addr) \
-+ ((unsigned char *)&addr)[3], \
-+ ((unsigned char *)&addr)[2], \
-+ ((unsigned char *)&addr)[1], \
-+ ((unsigned char *)&addr)[0]
-+
-+/*PSE Ports*/
-+#define NR_PDMA_PORT 0
-+#define NR_GMAC1_PORT 1
-+#define NR_GMAC2_PORT 2
-+#define NR_PPE_PORT 4
-+#define NR_QDMA_PORT 5
-+#define NR_DISCARD 7
-+#define IS_LAN(dev) (!strncmp(dev->name, "lan", 3))
-+#define IS_WAN(dev) (!strcmp(dev->name, host->wan))
-+#define IS_BR(dev) (!strncmp(dev->name, "br", 2))
-+#define IS_IPV4_HNAPT(x) (((x)->bfib1.pkt_type == IPV4_HNAPT) ? 1: 0)
-+#define IS_IPV4_HNAT(x) (((x)->bfib1.pkt_type == IPV4_HNAT) ? 1 : 0)
-+#define IS_IPV4_GRP(x) (IS_IPV4_HNAPT(x) | IS_IPV4_HNAT(x))
-+
-+#define es(entry) (entry_state[entry->bfib1.state])
-+#define ei(entry, end) (FOE_4TB_SIZ - (int)(end - entry))
-+#define pt(entry) (packet_type[entry->ipv4_hnapt.bfib1.pkt_type])
-+#define ipv4_smac(mac,e) ({mac[0]=e->ipv4_hnapt.smac_hi[3]; mac[1]=e->ipv4_hnapt.smac_hi[2];\
-+ mac[2]=e->ipv4_hnapt.smac_hi[1]; mac[3]=e->ipv4_hnapt.smac_hi[0];\
-+ mac[4]=e->ipv4_hnapt.smac_lo[1]; mac[5]=e->ipv4_hnapt.smac_lo[0];})
-+#define ipv4_dmac(mac,e) ({mac[0]=e->ipv4_hnapt.dmac_hi[3]; mac[1]=e->ipv4_hnapt.dmac_hi[2];\
-+ mac[2]=e->ipv4_hnapt.dmac_hi[1]; mac[3]=e->ipv4_hnapt.dmac_hi[0];\
-+ mac[4]=e->ipv4_hnapt.dmac_lo[1]; mac[5]=e->ipv4_hnapt.dmac_lo[0];})
-+
-+extern struct hnat_priv *host;
-+
-+extern void hnat_deinit_debugfs(struct hnat_priv *h);
-+extern int __init hnat_init_debugfs(struct hnat_priv *h);
-+extern int hnat_register_nf_hooks(void);
-+extern void hnat_unregister_nf_hooks(void);
-+
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c
-@@ -0,0 +1,489 @@
-+/* This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; version 2 of the License
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * Copyright (C) 2014-2016 Sean Wang <sean.wang@mediatek.com>
-+ * Copyright (C) 2016-2017 John Crispin <blogic@openwrt.org>
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/dma-mapping.h>
-+
-+#include "hnat.h"
-+
-+static const char *entry_state[] = {
-+ "INVALID",
-+ "UNBIND",
-+ "BIND",
-+ "FIN"
-+};
-+
-+static const char *packet_type[] = {
-+ "IPV4_HNAPT",
-+ "IPV4_HNAT",
-+ "IPV6_1T_ROUTE",
-+ "IPV4_DSLITE",
-+ "IPV6_3T_ROUTE",
-+ "IPV6_5T_ROUTE",
-+ "IPV6_6RD",
-+};
-+
-+static int hnat_debug_show(struct seq_file *m, void *private)
-+{
-+ struct hnat_priv *h = host;
-+ struct foe_entry *entry, *end;
-+
-+ entry = h->foe_table_cpu;
-+ end = h->foe_table_cpu + FOE_4TB_SIZ;
-+ while (entry < end) {
-+ if (!entry->bfib1.state) {
-+ entry++;
-+ continue;
-+ }
-+
-+ if (IS_IPV4_HNAPT(entry)) {
-+ __be32 saddr = htonl(entry->ipv4_hnapt.sip);
-+ __be32 daddr = htonl(entry->ipv4_hnapt.dip);
-+ __be32 nsaddr = htonl(entry->ipv4_hnapt.new_sip);
-+ __be32 ndaddr = htonl(entry->ipv4_hnapt.new_dip);
-+ unsigned char h_dest[ETH_ALEN];
-+ unsigned char h_source[ETH_ALEN];
-+
-+ *((u32*) h_source) = swab32(entry->ipv4_hnapt.smac_hi);
-+ *((u16*) &h_source[4]) = swab16(entry->ipv4_hnapt.smac_lo);
-+ *((u32*) h_dest) = swab32(entry->ipv4_hnapt.dmac_hi);
-+ *((u16*) &h_dest[4]) = swab16(entry->ipv4_hnapt.dmac_lo);
-+ seq_printf(m,
-+ "(%p)0x%05x|state=%s|type=%s|%pI4:%d->%pI4:%d=>%pI4:%d->%pI4:%d|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x|vlan1=%d|vlan2=%d\n",
-+ (void *)h->foe_table_dev + ((void *)(entry) - (void *)h->foe_table_cpu),
-+ ei(entry, end), es(entry), pt(entry),
-+ &saddr, entry->ipv4_hnapt.sport,
-+ &daddr, entry->ipv4_hnapt.dport,
-+ &nsaddr, entry->ipv4_hnapt.new_sport,
-+ &ndaddr, entry->ipv4_hnapt.new_dport, h_source,
-+ h_dest, ntohs(entry->ipv4_hnapt.etype),
-+ entry->ipv4_hnapt.info_blk1,
-+ entry->ipv4_hnapt.info_blk2,
-+ entry->ipv4_hnapt.vlan1,
-+ entry->ipv4_hnapt.vlan2);
-+ } else
-+ seq_printf(m, "0x%05x state=%s\n",
-+ ei(entry, end), es(entry));
-+ entry++;
-+ }
-+
-+ return 0;
-+}
-+
-+static int hnat_debug_open(struct inode *inode, struct file *file)
-+{
-+ return single_open(file, hnat_debug_show, file->private_data);
-+}
-+
-+static const struct file_operations hnat_debug_fops = {
-+ .open = hnat_debug_open,
-+ .read = seq_read,
-+ .llseek = seq_lseek,
-+ .release = single_release,
-+};
-+
-+#define QDMA_TX_SCH_TX 0x1a14
-+
-+static ssize_t hnat_sched_show(struct file *file, char __user *user_buf,
-+ size_t count, loff_t *ppos)
-+{
-+ int id = (int) file->private_data;
-+ struct hnat_priv *h = host;
-+ u32 reg = readl(h->fe_base + QDMA_TX_SCH_TX);
-+ int enable;
-+ int max_rate;
-+ char *buf;
-+ unsigned int len = 0, buf_len = 1500;
-+ ssize_t ret_cnt;
-+
-+ buf = kzalloc(buf_len, GFP_KERNEL);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+
-+ if (id)
-+ reg >>= 16;
-+ reg &= 0xffff;
-+ enable = !! (reg & BIT(11));
-+ max_rate = ((reg >> 4) & 0x7f);
-+ reg &= 0xf;
-+ while (reg--)
-+ max_rate *= 10;
-+
-+ len += scnprintf(buf + len, buf_len - len,
-+ "EN\tMAX\n%d\t%d\n", enable, max_rate);
-+
-+ if (len > buf_len)
-+ len = buf_len;
-+
-+ ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
-+
-+ kfree(buf);
-+ return ret_cnt;
-+}
-+
-+static ssize_t hnat_sched_write(struct file *file,
-+ const char __user *buf, size_t length, loff_t *offset)
-+{
-+ int id = (int) file->private_data;
-+ struct hnat_priv *h = host;
-+ char line[64];
-+ int enable, rate, exp = 0, shift = 0;
-+ size_t size;
-+ u32 reg = readl(h->fe_base + QDMA_TX_SCH_TX);
-+ u32 val = 0;
-+
-+ if (length > sizeof(line))
-+ return -EINVAL;
-+
-+ if (copy_from_user(line, buf, length))
-+ return -EFAULT;
-+
-+ sscanf(line, "%d %d", &enable, &rate);
-+
-+ while (rate > 127) {
-+ rate /= 10;
-+ exp++;
-+ }
-+
-+ if (enable)
-+ val |= BIT(11);
-+ val |= (rate & 0x7f) << 4;
-+ val |= exp & 0xf;
-+ if (id)
-+ shift = 16;
-+ reg &= ~(0xffff << shift);
-+ reg |= val << shift;
-+ writel(reg, h->fe_base + QDMA_TX_SCH_TX);
-+
-+ size = strlen(line);
-+ *offset += size;
-+
-+ return length;
-+}
-+
-+static const struct file_operations hnat_sched_fops = {
-+ .open = simple_open,
-+ .read = hnat_sched_show,
-+ .write = hnat_sched_write,
-+ .llseek = default_llseek,
-+};
-+
-+#define QTX_CFG(x) (0x1800 + (x * 0x10))
-+#define QTX_SCH(x) (0x1804 + (x * 0x10))
-+
-+static ssize_t hnat_queue_show(struct file *file, char __user *user_buf,
-+ size_t count, loff_t *ppos)
-+{
-+ struct hnat_priv *h = host;
-+ int id = (int) file->private_data;
-+ u32 reg = readl(h->fe_base + QTX_SCH(id));
-+ u32 cfg = readl(h->fe_base + QTX_CFG(id));
-+ int scheduler = !!(reg & BIT(31));
-+ int min_rate_en = !!(reg & BIT(27));
-+ int min_rate = (reg >> 20) & 0x7f;
-+ int min_rate_exp = (reg >> 16) & 0xf;
-+ int max_rate_en = !!(reg & BIT(11));
-+ int max_weight = (reg >> 12) & 0xf;
-+ int max_rate = (reg >> 4) & 0x7f;
-+ int max_rate_exp = reg & 0xf;
-+ char *buf;
-+ unsigned int len = 0, buf_len = 1500;
-+ ssize_t ret_cnt;
-+
-+ buf = kzalloc(buf_len, GFP_KERNEL);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ while (min_rate_exp--)
-+ min_rate *= 10;
-+
-+ while (max_rate_exp--)
-+ max_rate *= 10;
-+
-+ len += scnprintf(buf + len, buf_len - len,
-+ "scheduler: %d\nhw resv: %d\nsw resv: %d\n",
-+ scheduler, (cfg >> 8) & 0xff, cfg & 0xff);
-+ len += scnprintf(buf + len, buf_len - len,
-+ "\tEN\tRATE\t\tWEIGHT\n");
-+ len += scnprintf(buf + len, buf_len - len,
-+ "max\t%d\t%8d\t%d\n", max_rate_en, max_rate, max_weight);
-+ len += scnprintf(buf + len, buf_len - len,
-+ "min\t%d\t%8d\t-\n", min_rate_en, min_rate);
-+
-+ if (len > buf_len)
-+ len = buf_len;
-+
-+ ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
-+
-+ kfree(buf);
-+ return ret_cnt;
-+}
-+
-+static ssize_t hnat_queue_write(struct file *file,
-+ const char __user *buf, size_t length, loff_t *offset)
-+{
-+ int id = (int) file->private_data;
-+ struct hnat_priv *h = host;
-+ char line[64];
-+ int max_enable, max_rate, max_exp = 0;
-+ int min_enable, min_rate, min_exp = 0;
-+ int weight;
-+ int resv;
-+ int scheduler;
-+ size_t size;
-+ u32 reg = readl(h->fe_base + QTX_SCH(id));
-+
-+ if (length > sizeof(line))
-+ return -EINVAL;
-+
-+ if (copy_from_user(line, buf, length))
-+ return -EFAULT;
-+
-+ sscanf(line, "%d %d %d %d %d %d %d", &scheduler, &min_enable, &min_rate, &max_enable, &max_rate, &weight, &resv);
-+
-+ while (max_rate > 127) {
-+ max_rate /= 10;
-+ max_exp++;
-+ }
-+
-+ while (min_rate > 127) {
-+ min_rate /= 10;
-+ min_exp++;
-+ }
-+
-+ reg &= 0x70000000;
-+ if (scheduler)
-+ reg |= BIT(31);
-+ if (min_enable)
-+ reg |= BIT(27);
-+ reg |= (min_rate & 0x7f) << 20;
-+ reg |= (min_exp & 0xf) << 16;
-+ if (max_enable)
-+ reg |= BIT(11);
-+ reg |= (weight & 0xf) << 12;
-+ reg |= (max_rate & 0x7f) << 4;
-+ reg |= max_exp & 0xf;
-+ writel(reg, h->fe_base + QTX_SCH(id));
-+
-+ resv &= 0xff;
-+ reg = readl(h->fe_base + QTX_CFG(id));
-+ reg &= 0xffff0000;
-+ reg |= (resv << 8) | resv;
-+ writel(reg, h->fe_base + QTX_CFG(id));
-+
-+ size = strlen(line);
-+ *offset += size;
-+
-+ return length;
-+}
-+
-+static const struct file_operations hnat_queue_fops = {
-+ .open = simple_open,
-+ .read = hnat_queue_show,
-+ .write = hnat_queue_write,
-+ .llseek = default_llseek,
-+};
-+
-+static void hnat_ac_timer_handle(unsigned long priv)
-+{
-+ struct hnat_priv *h = (struct hnat_priv*) priv;
-+ int i;
-+
-+ for (i = 0; i < HNAT_COUNTER_MAX; i++) {
-+ u32 b_hi, b_lo;
-+ u64 b;
-+
-+ b_lo = readl(h->fe_base + HNAT_AC_BYTE_LO(i));
-+ b_hi = readl(h->fe_base + HNAT_AC_BYTE_HI(i));
-+ b = b_hi;
-+ b <<= 32;
-+ b += b_lo;
-+ h->acct[i].bytes += b;
-+ h->acct[i].packets += readl(h->fe_base + HNAT_AC_PACKET(i));
-+ }
-+
-+ mod_timer(&h->ac_timer, jiffies + HNAT_AC_TIMER_INTERVAL);
-+}
-+
-+static ssize_t hnat_counter_show(struct file *file, char __user *user_buf,
-+ size_t count, loff_t *ppos)
-+{
-+ struct hnat_priv *h = host;
-+ int id = (int) file->private_data;
-+ char *buf;
-+ unsigned int len = 0, buf_len = 1500;
-+ ssize_t ret_cnt;
-+ int id2 = id + (HNAT_COUNTER_MAX / 2);
-+
-+ buf = kzalloc(buf_len, GFP_KERNEL);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ len += scnprintf(buf + len, buf_len - len,
-+ "tx pkts : %llu\ntx bytes: %llu\nrx pktks : %llu\nrx bytes : %llu\n",
-+ h->acct[id].packets, h->acct[id].bytes,
-+ h->acct[id2].packets, h->acct[id2].bytes);
-+
-+ if (len > buf_len)
-+ len = buf_len;
-+
-+ ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
-+
-+ kfree(buf);
-+ return ret_cnt;
-+}
-+
-+static const struct file_operations hnat_counter_fops = {
-+ .open = simple_open,
-+ .read = hnat_counter_show,
-+ .llseek = default_llseek,
-+};
-+
-+#define dump_register(nm) \
-+{ \
-+ .name = __stringify(nm), \
-+ .offset = PPE_ ##nm , \
-+}
-+
-+static const struct debugfs_reg32 hnat_regs[] = {
-+ dump_register(GLO_CFG),
-+ dump_register(FLOW_CFG),
-+ dump_register(IP_PROT_CHK),
-+ dump_register(IP_PROT_0),
-+ dump_register(IP_PROT_1),
-+ dump_register(IP_PROT_2),
-+ dump_register(IP_PROT_3),
-+ dump_register(TB_CFG),
-+ dump_register(TB_BASE),
-+ dump_register(TB_USED),
-+ dump_register(BNDR),
-+ dump_register(BIND_LMT_0),
-+ dump_register(BIND_LMT_1),
-+ dump_register(KA),
-+ dump_register(UNB_AGE),
-+ dump_register(BND_AGE_0),
-+ dump_register(BND_AGE_1),
-+ dump_register(HASH_SEED),
-+ dump_register(DFT_CPORT),
-+ dump_register(MCAST_PPSE),
-+ dump_register(MCAST_L_0),
-+ dump_register(MCAST_H_0),
-+ dump_register(MCAST_L_1),
-+ dump_register(MCAST_H_1),
-+ dump_register(MCAST_L_2),
-+ dump_register(MCAST_H_2),
-+ dump_register(MCAST_L_3),
-+ dump_register(MCAST_H_3),
-+ dump_register(MCAST_L_4),
-+ dump_register(MCAST_H_4),
-+ dump_register(MCAST_L_5),
-+ dump_register(MCAST_H_5),
-+ dump_register(MCAST_L_6),
-+ dump_register(MCAST_H_6),
-+ dump_register(MCAST_L_7),
-+ dump_register(MCAST_H_7),
-+ dump_register(MCAST_L_8),
-+ dump_register(MCAST_H_8),
-+ dump_register(MCAST_L_9),
-+ dump_register(MCAST_H_9),
-+ dump_register(MCAST_L_A),
-+ dump_register(MCAST_H_A),
-+ dump_register(MCAST_L_B),
-+ dump_register(MCAST_H_B),
-+ dump_register(MCAST_L_C),
-+ dump_register(MCAST_H_C),
-+ dump_register(MCAST_L_D),
-+ dump_register(MCAST_H_D),
-+ dump_register(MCAST_L_E),
-+ dump_register(MCAST_H_E),
-+ dump_register(MCAST_L_F),
-+ dump_register(MCAST_H_F),
-+ dump_register(MTU_DRP),
-+ dump_register(MTU_VLYR_0),
-+ dump_register(MTU_VLYR_1),
-+ dump_register(MTU_VLYR_2),
-+ dump_register(VPM_TPID),
-+ dump_register(VPM_TPID),
-+ dump_register(CAH_CTRL),
-+ dump_register(CAH_TAG_SRH),
-+ dump_register(CAH_LINE_RW),
-+ dump_register(CAH_WDATA),
-+ dump_register(CAH_RDATA),
-+};
-+
-+int __init hnat_init_debugfs(struct hnat_priv *h)
-+{
-+ int ret = 0;
-+ struct dentry *root;
-+ struct dentry *file;
-+ int i;
-+ char name[16];
-+
-+ root = debugfs_create_dir("hnat", NULL);
-+ if (!root) {
-+ dev_err(h->dev, "%s:err at %d\n", __func__, __LINE__);
-+ ret = -ENOMEM;
-+ goto err0;
-+ }
-+ h->root = root;
-+ h->regset = kzalloc(sizeof(*h->regset), GFP_KERNEL);
-+ if (!h->regset) {
-+ dev_err(h->dev, "%s:err at %d\n", __func__, __LINE__);
-+ ret = -ENOMEM;
-+ goto err1;
-+ }
-+ h->regset->regs = hnat_regs;
-+ h->regset->nregs = ARRAY_SIZE(hnat_regs);
-+ h->regset->base = h->ppe_base;
-+
-+ file = debugfs_create_regset32("regdump", S_IRUGO, root, h->regset);
-+ if (!file) {
-+ dev_err(h->dev, "%s:err at %d\n", __func__, __LINE__);
-+ ret = -ENOMEM;
-+ goto err1;
-+ }
-+ debugfs_create_file("all_entry", S_IRUGO, root, h, &hnat_debug_fops);
-+ for (i = 0; i < HNAT_COUNTER_MAX / 2; i++) {
-+ snprintf(name, sizeof(name), "counter%d", i);
-+ debugfs_create_file(name, S_IRUGO, root, (void *)i, &hnat_counter_fops);
-+ }
-+
-+ for (i = 0; i < 2; i++) {
-+ snprintf(name, sizeof(name), "scheduler%d", i);
-+ debugfs_create_file(name, S_IRUGO, root, (void *)i, &hnat_sched_fops);
-+ }
-+
-+ for (i = 0; i < 16; i++) {
-+ snprintf(name, sizeof(name), "queue%d", i);
-+ debugfs_create_file(name, S_IRUGO, root, (void *)i, &hnat_queue_fops);
-+ }
-+
-+ setup_timer(&h->ac_timer, hnat_ac_timer_handle, (unsigned long) h);
-+ mod_timer(&h->ac_timer, jiffies + HNAT_AC_TIMER_INTERVAL);
-+
-+ return 0;
-+
-+ err1:
-+ debugfs_remove_recursive(root);
-+ err0:
-+ return ret;
-+}
-+
-+void hnat_deinit_debugfs(struct hnat_priv *h)
-+{
-+ del_timer(&h->ac_timer);
-+ debugfs_remove_recursive(h->root);
-+ h->root = NULL;
-+}
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
-@@ -0,0 +1,289 @@
-+/* This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; version 2 of the License
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * Copyright (C) 2014-2016 Sean Wang <sean.wang@mediatek.com>
-+ * Copyright (C) 2016-2017 John Crispin <blogic@openwrt.org>
-+ */
-+
-+#include <linux/netfilter_bridge.h>
-+
-+#include <net/arp.h>
-+#include <net/neighbour.h>
-+#include <net/netfilter/nf_conntrack_helper.h>
-+
-+#include "nf_hnat_mtk.h"
-+#include "hnat.h"
-+
-+#include "../mtk_eth_soc.h"
-+
-+static unsigned int skb_to_hnat_info(struct sk_buff *skb,
-+ const struct net_device *dev,
-+ struct foe_entry *foe)
-+{
-+ struct foe_entry entry = { 0 };
-+ int lan = IS_LAN(dev);
-+ struct ethhdr *eth;
-+ struct iphdr *iph;
-+ struct tcphdr *tcph;
-+ struct udphdr *udph;
-+ int tcp = 0;
-+ int ipv4 = 0;
-+ u32 gmac;
-+
-+ eth = eth_hdr(skb);
-+ switch (ntohs(eth->h_proto)) {
-+ case ETH_P_IP:
-+ ipv4 = 1;
-+ break;
-+
-+ default:
-+ return -1;
-+ }
-+
-+ iph = ip_hdr(skb);
-+ switch (iph->protocol) {
-+ case IPPROTO_TCP:
-+ tcph = tcp_hdr(skb);
-+ tcp = 1;
-+ break;
-+
-+ case IPPROTO_UDP:
-+ udph = udp_hdr(skb);
-+ break;
-+
-+ default:
-+ return -1;
-+ }
-+
-+ entry.ipv4_hnapt.etype = htons(ETH_P_IP);
-+
-+ if (lan) {
-+ entry.ipv4_hnapt.etype = htons(ETH_P_8021Q);
-+ entry.bfib1.vlan_layer = 1;
-+ entry.ipv4_hnapt.vlan1 = BIT(dev->name[3] - '0');
-+ }
-+
-+ if (dev->priv_flags & IFF_802_1Q_VLAN) {
-+ struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
-+
-+ entry.ipv4_hnapt.etype = htons(ETH_P_8021Q);
-+ entry.bfib1.vlan_layer = 1;
-+ if (lan)
-+ entry.ipv4_hnapt.vlan2 = vlan->vlan_id;
-+ else
-+ entry.ipv4_hnapt.vlan1 = vlan->vlan_id;
-+ }
-+
-+ entry.ipv4_hnapt.dmac_hi = swab32(*((u32*) eth->h_dest));
-+ entry.ipv4_hnapt.dmac_lo = swab16(*((u16*) &eth->h_dest[4]));
-+ entry.ipv4_hnapt.smac_hi = swab32(*((u32*) eth->h_source));
-+ entry.ipv4_hnapt.smac_lo = swab16(*((u16*) &eth->h_source[4]));
-+ entry.ipv4_hnapt.pppoe_id = 0;
-+ entry.bfib1.psn = 0;
-+ entry.ipv4_hnapt.bfib1.vpm = 1;
-+
-+ if (ipv4)
-+ entry.ipv4_hnapt.bfib1.pkt_type = IPV4_HNAPT;
-+
-+ entry.ipv4_hnapt.new_sip = ntohl(iph->saddr);
-+ entry.ipv4_hnapt.new_dip = ntohl(iph->daddr);
-+ entry.ipv4_hnapt.iblk2.dscp = iph->tos;
-+#if defined(CONFIG_NET_MEDIATEK_HW_QOS)
-+ entry.ipv4_hnapt.iblk2.qid = skb->mark & 0x7;
-+ if (lan)
-+ entry.ipv4_hnapt.iblk2.qid += 8;
-+ entry.ipv4_hnapt.iblk2.fqos = 1;
-+#endif
-+ if (tcp) {
-+ entry.ipv4_hnapt.new_sport = ntohs(tcph->source);
-+ entry.ipv4_hnapt.new_dport = ntohs(tcph->dest);
-+ entry.ipv4_hnapt.bfib1.udp = 0;
-+ } else {
-+ entry.ipv4_hnapt.new_sport = ntohs(udph->source);
-+ entry.ipv4_hnapt.new_dport = ntohs(udph->dest);
-+ entry.ipv4_hnapt.bfib1.udp = 1;
-+ }
-+
-+ if (IS_LAN(dev))
-+ gmac = NR_GMAC1_PORT;
-+ else if (IS_WAN(dev))
-+ gmac = NR_GMAC2_PORT;
-+
-+ if (is_multicast_ether_addr(&eth->h_dest[0]))
-+ entry.ipv4_hnapt.iblk2.mcast = 1;
-+ else
-+ entry.ipv4_hnapt.iblk2.mcast = 0;
-+
-+ entry.ipv4_hnapt.iblk2.dp = gmac;
-+ entry.ipv4_hnapt.iblk2.port_mg = 0x3f;
-+ entry.ipv4_hnapt.iblk2.port_ag = (skb->mark >> 3) & 0x1f;
-+ if (IS_LAN(dev))
-+ entry.ipv4_hnapt.iblk2.port_ag += 32;
-+ entry.bfib1.time_stamp = readl((host->fe_base + 0x0010)) & (0xFFFF);
-+ entry.ipv4_hnapt.bfib1.ttl = 1;
-+ entry.ipv4_hnapt.bfib1.cah = 1;
-+ entry.ipv4_hnapt.bfib1.ka = 1;
-+ entry.bfib1.state = BIND;
-+
-+ entry.ipv4_hnapt.sip = foe->ipv4_hnapt.sip;
-+ entry.ipv4_hnapt.dip = foe->ipv4_hnapt.dip;
-+ entry.ipv4_hnapt.sport = foe->ipv4_hnapt.sport;
-+ entry.ipv4_hnapt.dport = foe->ipv4_hnapt.dport;
-+
-+ memcpy(foe, &entry, sizeof(entry));
-+
-+ return 0;
-+}
-+
-+static unsigned int mtk_hnat_nf_post_routing(struct sk_buff *skb,
-+ const struct net_device *out,
-+ unsigned int (*fn)(struct sk_buff *, const struct net_device *),
-+ const char *func)
-+{
-+ struct foe_entry *entry;
-+ struct nf_conn *ct;
-+ enum ip_conntrack_info ctinfo;
-+ const struct nf_conn_help *help;
-+
-+ if ((skb->mark & 0x7) < 4)
-+ return 0;
-+
-+ ct = nf_ct_get(skb, &ctinfo);
-+ if (!ct)
-+ return 0;
-+
-+ /* rcu_read_lock()ed by nf_hook_slow */
-+ help = nfct_help(ct);
-+ if (help && rcu_dereference(help->helper))
-+ return 0;
-+
-+ if ((FROM_GE_WAN(skb) || FROM_GE_LAN(skb)) &&
-+ skb_hnat_is_hashed(skb) &&
-+ (skb_hnat_reason(skb) == HIT_BIND_KEEPALIVE_DUP_OLD_HDR))
-+ return -1;
-+
-+ if ((IS_LAN(out) && FROM_GE_WAN(skb)) ||
-+ (IS_WAN(out) && FROM_GE_LAN(skb))) {
-+ if (!skb_hnat_is_hashed(skb))
-+ return 0;
-+
-+ entry = &host->foe_table_cpu[skb_hnat_entry(skb)];
-+ if (entry_hnat_is_bound(entry))
-+ return 0;
-+
-+ if (skb_hnat_reason(skb) == HIT_UNBIND_RATE_REACH &&
-+ skb_hnat_alg(skb) == 0) {
-+ if (fn && fn(skb, out))
-+ return 0;
-+ skb_to_hnat_info(skb, out, entry);
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static unsigned int mtk_hnat_nf_pre_routing(void *priv,
-+ struct sk_buff *skb,
-+ const struct nf_hook_state *state)
-+{
-+ if (IS_WAN(state->in))
-+ HNAT_SKB_CB(skb)->iif = FOE_MAGIC_GE_WAN;
-+ else if (IS_LAN(state->in))
-+ HNAT_SKB_CB(skb)->iif = FOE_MAGIC_GE_LAN;
-+ else if (!IS_BR(state->in))
-+ HNAT_SKB_CB(skb)->iif = FOE_INVALID;
-+
-+ return NF_ACCEPT;
-+}
-+
-+static unsigned int hnat_get_nexthop(struct sk_buff *skb, const struct net_device *out) {
-+
-+ u32 nexthop;
-+ struct neighbour *neigh;
-+ struct dst_entry *dst = skb_dst(skb);
-+ struct rtable *rt = (struct rtable *)dst;
-+ struct net_device *dev = (__force struct net_device *)out;
-+
-+ rcu_read_lock_bh();
-+ nexthop = (__force u32) rt_nexthop(rt, ip_hdr(skb)->daddr);
-+ neigh = __ipv4_neigh_lookup_noref(dev, nexthop);
-+ if (unlikely(!neigh)) {
-+ dev_err(host->dev, "%s:++ no neigh\n", __func__);
-+ return -1;
-+ }
-+
-+ /* why do we get all zero ethernet address ? */
-+ if (!is_valid_ether_addr(neigh->ha)){
-+ rcu_read_unlock_bh();
-+ return -1;
-+ }
-+
-+ memcpy(eth_hdr(skb)->h_dest, neigh->ha, ETH_ALEN);
-+ memcpy(eth_hdr(skb)->h_source, out->dev_addr, ETH_ALEN);
-+
-+ rcu_read_unlock_bh();
-+
-+ return 0;
-+}
-+
-+static unsigned int mtk_hnat_ipv4_nf_post_routing(void *priv,
-+ struct sk_buff *skb,
-+ const struct nf_hook_state *state)
-+{
-+ if (!mtk_hnat_nf_post_routing(skb, state->out, hnat_get_nexthop, __func__))
-+ return NF_ACCEPT;
-+
-+ return NF_DROP;
-+}
-+
-+static unsigned int mtk_hnat_br_nf_post_routing(void *priv,
-+ struct sk_buff *skb,
-+ const struct nf_hook_state *state)
-+{
-+ if (!mtk_hnat_nf_post_routing(skb, state->out , 0, __func__))
-+ return NF_ACCEPT;
-+
-+ return NF_DROP;
-+}
-+
-+static struct nf_hook_ops mtk_hnat_nf_ops[] __read_mostly = {
-+ {
-+ .hook = mtk_hnat_nf_pre_routing,
-+ .pf = NFPROTO_IPV4,
-+ .hooknum = NF_INET_PRE_ROUTING,
-+ .priority = NF_IP_PRI_FIRST,
-+ }, {
-+ .hook = mtk_hnat_ipv4_nf_post_routing,
-+ .pf = NFPROTO_IPV4,
-+ .hooknum = NF_INET_POST_ROUTING,
-+ .priority = NF_IP_PRI_LAST,
-+ }, {
-+ .hook = mtk_hnat_nf_pre_routing,
-+ .pf = NFPROTO_BRIDGE,
-+ .hooknum = NF_BR_PRE_ROUTING,
-+ .priority = NF_BR_PRI_FIRST,
-+ }, {
-+ .hook = mtk_hnat_br_nf_post_routing,
-+ .pf = NFPROTO_BRIDGE,
-+ .hooknum = NF_BR_POST_ROUTING,
-+ .priority = NF_BR_PRI_LAST - 1,
-+ },
-+};
-+
-+int hnat_register_nf_hooks(void)
-+{
-+ return nf_register_hooks(mtk_hnat_nf_ops,
-+ ARRAY_SIZE(mtk_hnat_nf_ops));
-+}
-+
-+void hnat_unregister_nf_hooks(void)
-+{
-+ nf_unregister_hooks(mtk_hnat_nf_ops,
-+ ARRAY_SIZE(mtk_hnat_nf_ops));
-+}
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
-@@ -0,0 +1,44 @@
-+/* This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; version 2 of the License
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * Copyright (C) 2014-2016 Sean Wang <sean.wang@mediatek.com>
-+ * Copyright (C) 2016-2017 John Crispin <blogic@openwrt.org>
-+ */
-+
-+#ifndef NF_HNAT_MTK_H
-+#define NF_HNAT_MTK_H
-+
-+#include <asm/dma-mapping.h>
-+#include <linux/netdevice.h>
-+
-+#define HNAT_SKB_CB2(__skb) ((struct hnat_skb_cb2 *)&((__skb)->cb[44]))
-+struct hnat_skb_cb2 {
-+ __u32 magic;
-+};
-+
-+struct hnat_desc {
-+ u32 entry:14;
-+ u32 crsn:5;
-+ u32 sport:4;
-+ u32 alg:9;
-+} __attribute__ ((packed));
-+
-+#define skb_hnat_magic(skb) (((struct hnat_desc *)(skb->head))->magic)
-+#define skb_hnat_reason(skb) (((struct hnat_desc *)(skb->head))->crsn)
-+#define skb_hnat_entry(skb) (((struct hnat_desc *)(skb->head))->entry)
-+#define skb_hnat_sport(skb) (((struct hnat_desc *)(skb->head))->sport)
-+#define skb_hnat_alg(skb) (((struct hnat_desc *)(skb->head))->alg)
-+
-+u32 hnat_tx(struct sk_buff *skb);
-+u32 hnat_set_skb_info(struct sk_buff *skb, u32 *rxd);
-+u32 hnat_reg(struct net_device *, void __iomem *);
-+u32 hnat_unreg(void);
-+
-+#endif
-+
diff --git a/target/linux/mediatek/patches-4.9/0027-net-next-mediatek-fix-DQL-support.patch b/target/linux/mediatek/patches-4.9/0027-net-next-mediatek-fix-DQL-support.patch
deleted file mode 100644
index d21c8eedb1..0000000000
--- a/target/linux/mediatek/patches-4.9/0027-net-next-mediatek-fix-DQL-support.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From f974e397b806f7b16d11cc1542538616291924f1 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Sat, 23 Apr 2016 11:57:21 +0200
-Subject: [PATCH 27/57] net-next: mediatek: fix DQL support
-
-The MTK ethernet core has 2 MACs both sitting on the same DMA ring. The
-current code will assign the TX traffic of each MAC to its own DQL. This
-results in the amount of data, that DQL says is in the queue incorrect. As
-the data from multiple devices is infact enqueued. This makes any decision
-based on these value non deterministic. Fix this by tracking all TX
-traffic, regardless of the MAC it belongs to in the DQL of all devices
-using the DMA.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 35 +++++++++++++++++------------
- 1 file changed, 21 insertions(+), 14 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -710,7 +710,16 @@ static int mtk_tx_map(struct sk_buff *sk
- WRITE_ONCE(itxd->txd3, (TX_DMA_SWC | TX_DMA_PLEN0(skb_headlen(skb)) |
- (!nr_frags * TX_DMA_LS0)));
-
-- netdev_sent_queue(dev, skb->len);
-+ /* we have a single DMA ring so BQL needs to be updated for all devices
-+ * sitting on this ring
-+ */
-+ for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ if (!eth->netdev[i])
-+ continue;
-+
-+ netdev_sent_queue(eth->netdev[i], skb->len);
-+ }
-+
- skb_tx_timestamp(skb);
-
- ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2);
-@@ -1002,21 +1011,18 @@ static int mtk_poll_tx(struct mtk_eth *e
- struct mtk_tx_dma *desc;
- struct sk_buff *skb;
- struct mtk_tx_buf *tx_buf;
-- unsigned int done[MTK_MAX_DEVS];
-- unsigned int bytes[MTK_MAX_DEVS];
-+ int total = 0, done = 0;
-+ unsigned int bytes = 0;
- u32 cpu, dma;
- static int condition;
-- int total = 0, i;
--
-- memset(done, 0, sizeof(done));
-- memset(bytes, 0, sizeof(bytes));
-+ int i;
-
- cpu = mtk_r32(eth, MTK_QTX_CRX_PTR);
- dma = mtk_r32(eth, MTK_QTX_DRX_PTR);
-
- desc = mtk_qdma_phys_to_virt(ring, cpu);
-
-- while ((cpu != dma) && budget) {
-+ while ((cpu != dma) && done < budget) {
- u32 next_cpu = desc->txd2;
- int mac = 0;
-
-@@ -1035,9 +1041,8 @@ static int mtk_poll_tx(struct mtk_eth *e
- }
-
- if (skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC) {
-- bytes[mac] += skb->len;
-- done[mac]++;
-- budget--;
-+ bytes += skb->len;
-+ done++;
- }
- mtk_tx_unmap(eth, tx_buf);
-
-@@ -1049,11 +1054,13 @@ static int mtk_poll_tx(struct mtk_eth *e
-
- mtk_w32(eth, cpu, MTK_QTX_CRX_PTR);
-
-+ /* we have a single DMA ring so BQL needs to be updated for all devices
-+ * sitting on this ring
-+ */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
-- if (!eth->netdev[i] || !done[i])
-+ if (!eth->netdev[i])
- continue;
-- netdev_completed_queue(eth->netdev[i], done[i], bytes[i]);
-- total += done[i];
-+ netdev_completed_queue(eth->netdev[i], done, bytes);
- }
-
- if (mtk_queue_stopped(eth) &&
diff --git a/target/linux/mediatek/patches-4.9/0028-net-next-dsa-add-Mediatek-tag-RX-TX-handler.patch b/target/linux/mediatek/patches-4.9/0028-net-next-dsa-add-Mediatek-tag-RX-TX-handler.patch
deleted file mode 100644
index ef545e3db4..0000000000
--- a/target/linux/mediatek/patches-4.9/0028-net-next-dsa-add-Mediatek-tag-RX-TX-handler.patch
+++ /dev/null
@@ -1,192 +0,0 @@
-From 5c01c03920c63630864d2b8641924a8c7c6cb62f Mon Sep 17 00:00:00 2001
-From: Sean Wang <sean.wang@mediatek.com>
-Date: Wed, 29 Mar 2017 17:38:20 +0800
-Subject: [PATCH 28/57] net-next: dsa: add Mediatek tag RX/TX handler
-
-Add the support for the 4-bytes tag for DSA port distinguishing inserted
-allowing receiving and transmitting the packet via the particular port.
-The tag is being added after the source MAC address in the ethernet
-header.
-
-Signed-off-by: Sean Wang <sean.wang@mediatek.com>
-Signed-off-by: Landen Chao <Landen.Chao@mediatek.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
----
- include/net/dsa.h | 1 +
- net/dsa/Kconfig | 2 +
- net/dsa/Makefile | 1 +
- net/dsa/dsa.c | 3 ++
- net/dsa/dsa_priv.h | 3 ++
- net/dsa/tag_mtk.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++
- 6 files changed, 127 insertions(+)
- create mode 100644 net/dsa/tag_mtk.c
-
---- a/include/net/dsa.h
-+++ b/include/net/dsa.h
-@@ -27,6 +27,7 @@ enum dsa_tag_protocol {
- DSA_TAG_PROTO_EDSA,
- DSA_TAG_PROTO_BRCM,
- DSA_TAG_PROTO_QCA,
-+ DSA_TAG_PROTO_MTK,
- DSA_TAG_LAST, /* MUST BE LAST */
- };
-
---- a/net/dsa/Kconfig
-+++ b/net/dsa/Kconfig
-@@ -42,4 +42,6 @@ config NET_DSA_TAG_TRAILER
- config NET_DSA_TAG_QCA
- bool
-
-+config NET_DSA_TAG_MTK
-+ bool
- endif
---- a/net/dsa/Makefile
-+++ b/net/dsa/Makefile
-@@ -8,3 +8,4 @@ dsa_core-$(CONFIG_NET_DSA_TAG_DSA) += ta
- dsa_core-$(CONFIG_NET_DSA_TAG_EDSA) += tag_edsa.o
- dsa_core-$(CONFIG_NET_DSA_TAG_TRAILER) += tag_trailer.o
- dsa_core-$(CONFIG_NET_DSA_TAG_QCA) += tag_qca.o
-+dsa_core-$(CONFIG_NET_DSA_TAG_MTK) += tag_mtk.o
---- a/net/dsa/dsa.c
-+++ b/net/dsa/dsa.c
-@@ -57,6 +57,9 @@ const struct dsa_device_ops *dsa_device_
- #ifdef CONFIG_NET_DSA_TAG_QCA
- [DSA_TAG_PROTO_QCA] = &qca_netdev_ops,
- #endif
-+#ifdef CONFIG_NET_DSA_TAG_MTK
-+ [DSA_TAG_PROTO_MTK] = &mtk_netdev_ops,
-+#endif
- [DSA_TAG_PROTO_NONE] = &none_ops,
- };
-
---- a/net/dsa/dsa_priv.h
-+++ b/net/dsa/dsa_priv.h
-@@ -84,4 +84,7 @@ extern const struct dsa_device_ops brcm_
- /* tag_qca.c */
- extern const struct dsa_device_ops qca_netdev_ops;
-
-+/* tag_mtk.c */
-+extern const struct dsa_device_ops mtk_netdev_ops;
-+
- #endif
---- /dev/null
-+++ b/net/dsa/tag_mtk.c
-@@ -0,0 +1,117 @@
-+/*
-+ * Mediatek DSA Tag support
-+ * Copyright (C) 2017 Landen Chao <landen.chao@mediatek.com>
-+ * Sean Wang <sean.wang@mediatek.com>
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/etherdevice.h>
-+#include "dsa_priv.h"
-+
-+#define MTK_HDR_LEN 4
-+#define MTK_HDR_RECV_SOURCE_PORT_MASK GENMASK(2, 0)
-+#define MTK_HDR_XMIT_DP_BIT_MASK GENMASK(5, 0)
-+
-+static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
-+ struct net_device *dev)
-+{
-+ struct dsa_slave_priv *p = netdev_priv(dev);
-+ u8 *mtk_tag;
-+
-+ if (skb_cow_head(skb, MTK_HDR_LEN) < 0)
-+ goto out_free;
-+
-+ skb_push(skb, MTK_HDR_LEN);
-+
-+ memmove(skb->data, skb->data + MTK_HDR_LEN, 2 * ETH_ALEN);
-+
-+ /* Build the tag after the MAC Source Address */
-+ mtk_tag = skb->data + 2 * ETH_ALEN;
-+ mtk_tag[0] = 0;
-+ mtk_tag[1] = (1 << p->dp->index) & MTK_HDR_XMIT_DP_BIT_MASK;
-+ mtk_tag[2] = 0;
-+ mtk_tag[3] = 0;
-+
-+ return skb;
-+
-+out_free:
-+ kfree_skb(skb);
-+ return NULL;
-+}
-+
-+static int mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev,
-+ struct packet_type *pt, struct net_device *orig_dev)
-+{
-+ struct dsa_switch_tree *dst = dev->dsa_ptr;
-+ struct dsa_switch *ds;
-+ int port;
-+ __be16 *phdr, hdr;
-+
-+ if (unlikely(!dst))
-+ goto out_drop;
-+
-+ skb = skb_unshare(skb, GFP_ATOMIC);
-+ if (!skb)
-+ goto out;
-+
-+ if (unlikely(!pskb_may_pull(skb, MTK_HDR_LEN)))
-+ goto out_drop;
-+
-+ /* The MTK header is added by the switch between src addr
-+ * and ethertype at this point, skb->data points to 2 bytes
-+ * after src addr so header should be 2 bytes right before.
-+ */
-+ phdr = (__be16 *)(skb->data - 2);
-+ hdr = ntohs(*phdr);
-+
-+ /* Remove MTK tag and recalculate checksum. */
-+ skb_pull_rcsum(skb, MTK_HDR_LEN);
-+
-+ memmove(skb->data - ETH_HLEN,
-+ skb->data - ETH_HLEN - MTK_HDR_LEN,
-+ 2 * ETH_ALEN);
-+
-+ /* This protocol doesn't support cascading multiple
-+ * switches so it's safe to assume the switch is first
-+ * in the tree.
-+ */
-+ ds = dst->ds[0];
-+ if (!ds)
-+ goto out_drop;
-+
-+ /* Get source port information */
-+ port = (hdr & MTK_HDR_RECV_SOURCE_PORT_MASK);
-+ if (!ds->ports[port].netdev)
-+ goto out_drop;
-+
-+ /* Update skb & forward the frame accordingly */
-+ skb_push(skb, ETH_HLEN);
-+
-+ skb->pkt_type = PACKET_HOST;
-+ skb->dev = ds->ports[port].netdev;
-+ skb->protocol = eth_type_trans(skb, skb->dev);
-+
-+ skb->dev->stats.rx_packets++;
-+ skb->dev->stats.rx_bytes += skb->len;
-+
-+ netif_receive_skb(skb);
-+
-+ return 0;
-+
-+out_drop:
-+ kfree_skb(skb);
-+out:
-+ return 0;
-+}
-+
-+const struct dsa_device_ops mtk_netdev_ops = {
-+ .xmit = mtk_tag_xmit,
-+ .rcv = mtk_tag_rcv,
-+};
diff --git a/target/linux/mediatek/patches-4.9/0029-net-next-ethernet-mediatek-add-CDM-able-to-recognize.patch b/target/linux/mediatek/patches-4.9/0029-net-next-ethernet-mediatek-add-CDM-able-to-recognize.patch
deleted file mode 100644
index 5c7e6e43cd..0000000000
--- a/target/linux/mediatek/patches-4.9/0029-net-next-ethernet-mediatek-add-CDM-able-to-recognize.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From de3c04b820e1d396bf12e88ea87271a84f6fedb7 Mon Sep 17 00:00:00 2001
-From: Sean Wang <sean.wang@mediatek.com>
-Date: Wed, 29 Mar 2017 17:38:21 +0800
-Subject: [PATCH 29/57] net-next: ethernet: mediatek: add CDM able to recognize
- the tag for DSA
-
-The patch adds the setup for allowing CDM can recognize these packets with
-carrying port-distinguishing tag. Otherwise, these tagging packets will be
-handled incorrectly by CDM. The setup is also working out for general
-untag packets as well.
-
-Signed-off-by: Sean Wang <sean.wang@mediatek.com>
-Signed-off-by: Landen Chao <Landen.Chao@mediatek.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 ++++++
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++++
- 2 files changed, 10 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1864,6 +1864,12 @@ static int mtk_hw_init(struct mtk_eth *e
- val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
- mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
-
-+ /* Indicates CDM to parse the MTK special tag from CPU
-+ * which also is working out for untag packets.
-+ */
-+ val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
-+ mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
-+
- /* Enable RX VLan Offloading */
- mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -74,6 +74,10 @@
- #define MTK_CDMQ_IG_CTRL 0x1400
- #define MTK_CDMQ_STAG_EN BIT(0)
-
-+/* CDMP Ingress Control Register */
-+#define MTK_CDMQ_IG_CTRL 0x1400
-+#define MTK_CDMQ_STAG_EN BIT(0)
-+
- /* CDMP Exgress Control Register */
- #define MTK_CDMP_EG_CTRL 0x404
-
diff --git a/target/linux/mediatek/patches-4.9/0030-net-next-dsa-add-dsa-support-for-Mediatek-MT7530-swi.patch b/target/linux/mediatek/patches-4.9/0030-net-next-dsa-add-dsa-support-for-Mediatek-MT7530-swi.patch
deleted file mode 100644
index 47a06838a3..0000000000
--- a/target/linux/mediatek/patches-4.9/0030-net-next-dsa-add-dsa-support-for-Mediatek-MT7530-swi.patch
+++ /dev/null
@@ -1,1584 +0,0 @@
-From 6a0a62dec3c582db4260f411294770448efc3d6c Mon Sep 17 00:00:00 2001
-From: Sean Wang <sean.wang@mediatek.com>
-Date: Wed, 29 Mar 2017 17:38:23 +0800
-Subject: [PATCH 30/57] net-next: dsa: add dsa support for Mediatek MT7530
- switch
-
-MT7530 is a 7-ports Gigabit Ethernet Switch that could be found on
-Mediatek router platforms such as MT7623A or MT7623N platform which
-includes 7-port Gigabit Ethernet MAC and 5-port Gigabit Ethernet PHY.
-Among these ports, The port from 0 to 4 are the user ports connecting
-with the remote devices while the port 5 and 6 are the CPU ports
-connecting into Mediatek Ethernet GMAC.
-
-For port 6, it can communicate with the CPU via Mediatek Ethernet GMAC
-through either the TRGMII or RGMII which could be controlled by phy-mode
-in the dt-bindings to specify which mode is preferred to use. And for
-port 5, only RGMII can be specified. However, currently, only port 6 is
-being supported in this DSA driver.
-
-The driver is made with the reference to qca8k and other existing DSA
-driver. The most of the essential callbacks of the DSA are already
-support in the driver, including tag insert for user port distinguishing,
-port control, bridge offloading, STP setup and ethtool operation to allow
-DSA to model each user port into a standalone netdevice as the other DSA
-driver had done.
-
-Signed-off-by: Sean Wang <sean.wang@mediatek.com>
-Signed-off-by: Landen Chao <Landen.Chao@mediatek.com>
----
- drivers/net/dsa/Kconfig | 8 +
- drivers/net/dsa/Makefile | 2 +-
- drivers/net/dsa/mt7530.c | 1126 ++++++++++++++++++++++++++++++++++++++++++++++
- drivers/net/dsa/mt7530.h | 390 ++++++++++++++++
- 4 files changed, 1525 insertions(+), 1 deletion(-)
- create mode 100644 drivers/net/dsa/mt7530.c
- create mode 100644 drivers/net/dsa/mt7530.h
-
---- a/drivers/net/dsa/Kconfig
-+++ b/drivers/net/dsa/Kconfig
-@@ -34,4 +34,12 @@ config NET_DSA_QCA8K
- This enables support for the Qualcomm Atheros QCA8K Ethernet
- switch chips.
-
-+config NET_DSA_MT7530
-+ tristate "Mediatek MT7530 Ethernet switch support"
-+ depends on NET_DSA
-+ select NET_DSA_TAG_MTK
-+ ---help---
-+ This enables support for the Mediatek MT7530 Ethernet switch
-+ chip.
-+
- endmenu
---- a/drivers/net/dsa/Makefile
-+++ b/drivers/net/dsa/Makefile
-@@ -1,6 +1,6 @@
- obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
- obj-$(CONFIG_NET_DSA_BCM_SF2) += bcm_sf2.o
- obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o
--
-+obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
- obj-y += b53/
- obj-y += mv88e6xxx/
---- /dev/null
-+++ b/drivers/net/dsa/mt7530.c
-@@ -0,0 +1,1126 @@
-+/*
-+ * Mediatek MT7530 DSA Switch driver
-+ * Copyright (C) 2017 Sean Wang <sean.wang@mediatek.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+#include <linux/etherdevice.h>
-+#include <linux/if_bridge.h>
-+#include <linux/iopoll.h>
-+#include <linux/mdio.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/module.h>
-+#include <linux/netdevice.h>
-+#include <linux/of_gpio.h>
-+#include <linux/of_mdio.h>
-+#include <linux/of_net.h>
-+#include <linux/of_platform.h>
-+#include <linux/phy.h>
-+#include <linux/regmap.h>
-+#include <linux/regulator/consumer.h>
-+#include <linux/reset.h>
-+#include <net/dsa.h>
-+#include <net/switchdev.h>
-+
-+#include "mt7530.h"
-+
-+/* String, offset, and register size in bytes if different from 4 bytes */
-+static const struct mt7530_mib_desc mt7530_mib[] = {
-+ MIB_DESC(1, 0x00, "TxDrop"),
-+ MIB_DESC(1, 0x04, "TxCrcErr"),
-+ MIB_DESC(1, 0x08, "TxUnicast"),
-+ MIB_DESC(1, 0x0c, "TxMulticast"),
-+ MIB_DESC(1, 0x10, "TxBroadcast"),
-+ MIB_DESC(1, 0x14, "TxCollision"),
-+ MIB_DESC(1, 0x18, "TxSingleCollision"),
-+ MIB_DESC(1, 0x1c, "TxMultipleCollision"),
-+ MIB_DESC(1, 0x20, "TxDeferred"),
-+ MIB_DESC(1, 0x24, "TxLateCollision"),
-+ MIB_DESC(1, 0x28, "TxExcessiveCollistion"),
-+ MIB_DESC(1, 0x2c, "TxPause"),
-+ MIB_DESC(1, 0x30, "TxPktSz64"),
-+ MIB_DESC(1, 0x34, "TxPktSz65To127"),
-+ MIB_DESC(1, 0x38, "TxPktSz128To255"),
-+ MIB_DESC(1, 0x3c, "TxPktSz256To511"),
-+ MIB_DESC(1, 0x40, "TxPktSz512To1023"),
-+ MIB_DESC(1, 0x44, "Tx1024ToMax"),
-+ MIB_DESC(2, 0x48, "TxBytes"),
-+ MIB_DESC(1, 0x60, "RxDrop"),
-+ MIB_DESC(1, 0x64, "RxFiltering"),
-+ MIB_DESC(1, 0x6c, "RxMulticast"),
-+ MIB_DESC(1, 0x70, "RxBroadcast"),
-+ MIB_DESC(1, 0x74, "RxAlignErr"),
-+ MIB_DESC(1, 0x78, "RxCrcErr"),
-+ MIB_DESC(1, 0x7c, "RxUnderSizeErr"),
-+ MIB_DESC(1, 0x80, "RxFragErr"),
-+ MIB_DESC(1, 0x84, "RxOverSzErr"),
-+ MIB_DESC(1, 0x88, "RxJabberErr"),
-+ MIB_DESC(1, 0x8c, "RxPause"),
-+ MIB_DESC(1, 0x90, "RxPktSz64"),
-+ MIB_DESC(1, 0x94, "RxPktSz65To127"),
-+ MIB_DESC(1, 0x98, "RxPktSz128To255"),
-+ MIB_DESC(1, 0x9c, "RxPktSz256To511"),
-+ MIB_DESC(1, 0xa0, "RxPktSz512To1023"),
-+ MIB_DESC(1, 0xa4, "RxPktSz1024ToMax"),
-+ MIB_DESC(2, 0xa8, "RxBytes"),
-+ MIB_DESC(1, 0xb0, "RxCtrlDrop"),
-+ MIB_DESC(1, 0xb4, "RxIngressDrop"),
-+ MIB_DESC(1, 0xb8, "RxArlDrop"),
-+};
-+
-+static struct mt7530_priv *lpriv;
-+static void mt7530_port_disable(struct dsa_switch *ds, int port,
-+ struct phy_device *phy);
-+static int mt7530_cpu_port_enable(struct mt7530_priv *priv,
-+ int port);
-+
-+static int
-+mt7623_trgmii_write(struct mt7530_priv *priv, u32 reg, u32 val)
-+{
-+ int ret;
-+
-+ ret = regmap_write(priv->ethernet, TRGMII_BASE(reg), val);
-+ if (ret < 0)
-+ dev_err(priv->dev,
-+ "failed to priv write register\n");
-+ return ret;
-+}
-+
-+static u32
-+mt7623_trgmii_read(struct mt7530_priv *priv, u32 reg)
-+{
-+ int ret;
-+ u32 val;
-+
-+ ret = regmap_read(priv->ethernet, TRGMII_BASE(reg), &val);
-+ if (ret < 0) {
-+ dev_err(priv->dev,
-+ "failed to priv read register\n");
-+ return ret;
-+ }
-+
-+ return val;
-+}
-+
-+static void
-+mt7623_trgmii_rmw(struct mt7530_priv *priv, u32 reg,
-+ u32 mask, u32 set)
-+{
-+ u32 val;
-+
-+ val = mt7623_trgmii_read(priv, reg);
-+ val &= ~mask;
-+ val |= set;
-+ mt7623_trgmii_write(priv, reg, val);
-+}
-+
-+static void
-+mt7623_trgmii_set(struct mt7530_priv *priv, u32 reg, u32 val)
-+{
-+ mt7623_trgmii_rmw(priv, reg, 0, val);
-+}
-+
-+static void
-+mt7623_trgmii_clear(struct mt7530_priv *priv, u32 reg, u32 val)
-+{
-+ mt7623_trgmii_rmw(priv, reg, val, 0);
-+}
-+
-+static int
-+core_read_mmd_indirect(struct mt7530_priv *priv, int prtad, int devad)
-+{
-+ struct mii_bus *bus = priv->bus;
-+ int value, ret;
-+
-+ /* Write the desired MMD Devad */
-+ ret = bus->write(bus, 0, MII_MMD_CTRL, devad);
-+ if (ret < 0)
-+ goto err;
-+
-+ /* Write the desired MMD register address */
-+ ret = bus->write(bus, 0, MII_MMD_DATA, prtad);
-+ if (ret < 0)
-+ goto err;
-+
-+ /* Select the Function : DATA with no post increment */
-+ ret = bus->write(bus, 0, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
-+ if (ret < 0)
-+ goto err;
-+
-+ /* Read the content of the MMD's selected register */
-+ value = bus->read(bus, 0, MII_MMD_DATA);
-+
-+ return value;
-+err:
-+ dev_err(&bus->dev, "failed to read mmd register\n");
-+
-+ return ret;
-+}
-+
-+static int
-+core_write_mmd_indirect(struct mt7530_priv *priv, int prtad,
-+ int devad, u32 data)
-+{
-+ struct mii_bus *bus = priv->bus;
-+ int ret;
-+
-+ /* Write the desired MMD Devad */
-+ ret = bus->write(bus, 0, MII_MMD_CTRL, devad);
-+ if (ret < 0)
-+ goto err;
-+
-+ /* Write the desired MMD register address */
-+ ret = bus->write(bus, 0, MII_MMD_DATA, prtad);
-+ if (ret < 0)
-+ goto err;
-+
-+ /* Select the Function : DATA with no post increment */
-+ ret = bus->write(bus, 0, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
-+ if (ret < 0)
-+ goto err;
-+
-+ /* Write the data into MMD's selected register */
-+ ret = bus->write(bus, 0, MII_MMD_DATA, data);
-+err:
-+ if (ret < 0)
-+ dev_err(&bus->dev,
-+ "failed to write mmd register\n");
-+ return ret;
-+}
-+
-+static void
-+core_write(struct mt7530_priv *priv, u32 reg, u32 val)
-+{
-+ struct mii_bus *bus = priv->bus;
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
-+
-+ mutex_unlock(&bus->mdio_lock);
-+}
-+
-+static void
-+core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
-+{
-+ struct mii_bus *bus = priv->bus;
-+ u32 val;
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ val = core_read_mmd_indirect(priv, reg, MDIO_MMD_VEND2);
-+ val &= ~mask;
-+ val |= set;
-+ core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
-+
-+ mutex_unlock(&bus->mdio_lock);
-+}
-+
-+static void
-+core_set(struct mt7530_priv *priv, u32 reg, u32 val)
-+{
-+ core_rmw(priv, reg, 0, val);
-+}
-+
-+static void
-+core_clear(struct mt7530_priv *priv, u32 reg, u32 val)
-+{
-+ core_rmw(priv, reg, val, 0);
-+}
-+
-+static int
-+mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
-+{
-+ struct mii_bus *bus = priv->bus;
-+ u16 page, r, lo, hi;
-+ int ret;
-+
-+ page = (reg >> 6) & 0x3ff;
-+ r = (reg >> 2) & 0xf;
-+ lo = val & 0xffff;
-+ hi = val >> 16;
-+
-+ /* MT7530 uses 31 as the pseudo port */
-+ ret = bus->write(bus, 0x1f, 0x1f, page);
-+ if (ret < 0)
-+ goto err;
-+
-+ ret = bus->write(bus, 0x1f, r, lo);
-+ if (ret < 0)
-+ goto err;
-+
-+ ret = bus->write(bus, 0x1f, 0x10, hi);
-+err:
-+ if (ret < 0)
-+ dev_err(&bus->dev,
-+ "failed to write mt7530 register\n");
-+ return ret;
-+}
-+
-+static u32
-+mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
-+{
-+ struct mii_bus *bus = priv->bus;
-+ u16 page, r, lo, hi;
-+ int ret;
-+
-+ page = (reg >> 6) & 0x3ff;
-+ r = (reg >> 2) & 0xf;
-+
-+ /* MT7530 uses 31 as the pseudo port */
-+ ret = bus->write(bus, 0x1f, 0x1f, page);
-+ if (ret < 0) {
-+ dev_err(&bus->dev,
-+ "failed to read mt7530 register\n");
-+ return ret;
-+ }
-+
-+ lo = bus->read(bus, 0x1f, r);
-+ hi = bus->read(bus, 0x1f, 0x10);
-+
-+ return (hi << 16) | (lo & 0xffff);
-+}
-+
-+static void
-+mt7530_write(struct mt7530_priv *priv, u32 reg, u32 val)
-+{
-+ struct mii_bus *bus = priv->bus;
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ mt7530_mii_write(priv, reg, val);
-+
-+ mutex_unlock(&bus->mdio_lock);
-+}
-+
-+static u32
-+_mt7530_read(u32 reg)
-+{
-+ struct mt7530_priv *priv = lpriv;
-+ struct mii_bus *bus = priv->bus;
-+ u32 val;
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ val = mt7530_mii_read(priv, reg);
-+
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return val;
-+}
-+
-+static u32
-+mt7530_read(struct mt7530_priv *priv, u32 reg)
-+{
-+ return _mt7530_read(reg);
-+}
-+
-+static void
-+mt7530_rmw(struct mt7530_priv *priv, u32 reg,
-+ u32 mask, u32 set)
-+{
-+ struct mii_bus *bus = priv->bus;
-+ u32 val;
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ val = mt7530_mii_read(priv, reg);
-+ val &= ~mask;
-+ val |= set;
-+ mt7530_mii_write(priv, reg, val);
-+
-+ mutex_unlock(&bus->mdio_lock);
-+}
-+
-+static void
-+mt7530_set(struct mt7530_priv *priv, u32 reg, u32 val)
-+{
-+ mt7530_rmw(priv, reg, 0, val);
-+}
-+
-+static void
-+mt7530_clear(struct mt7530_priv *priv, u32 reg, u32 val)
-+{
-+ mt7530_rmw(priv, reg, val, 0);
-+}
-+
-+static int
-+mt7530_fdb_cmd(struct mt7530_priv *priv, enum mt7530_fdb_cmd cmd, u32 *rsp)
-+{
-+ u32 val;
-+ int ret;
-+
-+ /* Set the command operating upon the MAC address entries */
-+ val = ATC_BUSY | ATC_MAT(0) | cmd;
-+ mt7530_write(priv, MT7530_ATC, val);
-+
-+ ret = readx_poll_timeout(_mt7530_read, MT7530_ATC, val,
-+ !(val & ATC_BUSY), 20, 20000);
-+ if (ret < 0) {
-+ dev_err(priv->dev, "reset timeout\n");
-+ return ret;
-+ }
-+
-+ /* Additional sanity for read command if the specified
-+ * entry is invalid
-+ */
-+ val = mt7530_read(priv, MT7530_ATC);
-+ if ((cmd == MT7530_FDB_READ) && (val & ATC_INVALID))
-+ return -EINVAL;
-+
-+ if (rsp)
-+ *rsp = val;
-+
-+ return 0;
-+}
-+
-+static void
-+mt7530_fdb_read(struct mt7530_priv *priv, struct mt7530_fdb *fdb)
-+{
-+ u32 reg[3];
-+ int i;
-+
-+ /* Read from ARL table into an array */
-+ for (i = 0; i < 3; i++) {
-+ reg[i] = mt7530_read(priv, MT7530_TSRA1 + (i * 4));
-+
-+ dev_dbg(priv->dev, "%s(%d) reg[%d]=0x%x\n",
-+ __func__, __LINE__, i, reg[i]);
-+ }
-+
-+ fdb->vid = (reg[1] >> CVID) & CVID_MASK;
-+ fdb->aging = (reg[2] >> AGE_TIMER) & AGE_TIMER_MASK;
-+ fdb->port_mask = (reg[2] >> PORT_MAP) & PORT_MAP_MASK;
-+ fdb->mac[0] = (reg[0] >> MAC_BYTE_0) & MAC_BYTE_MASK;
-+ fdb->mac[1] = (reg[0] >> MAC_BYTE_1) & MAC_BYTE_MASK;
-+ fdb->mac[2] = (reg[0] >> MAC_BYTE_2) & MAC_BYTE_MASK;
-+ fdb->mac[3] = (reg[0] >> MAC_BYTE_3) & MAC_BYTE_MASK;
-+ fdb->mac[4] = (reg[1] >> MAC_BYTE_4) & MAC_BYTE_MASK;
-+ fdb->mac[5] = (reg[1] >> MAC_BYTE_5) & MAC_BYTE_MASK;
-+ fdb->noarp = ((reg[2] >> ENT_STATUS) & ENT_STATUS_MASK) == STATIC_ENT;
-+}
-+
-+static void
-+mt7530_fdb_write(struct mt7530_priv *priv, u16 vid,
-+ u8 port_mask, const u8 *mac,
-+ u8 aging, u8 type)
-+{
-+ u32 reg[3] = { 0 };
-+ int i;
-+
-+ reg[1] |= vid & CVID_MASK;
-+ reg[2] |= (aging & AGE_TIMER_MASK) << AGE_TIMER;
-+ reg[2] |= (port_mask & PORT_MAP_MASK) << PORT_MAP;
-+ /* STATIC_ENT indicate that entry is static wouldn't
-+ * be aged out and STATIC_EMP specified as erasing an
-+ * entry
-+ */
-+ reg[2] |= (type & ENT_STATUS_MASK) << ENT_STATUS;
-+ reg[1] |= mac[5] << MAC_BYTE_5;
-+ reg[1] |= mac[4] << MAC_BYTE_4;
-+ reg[0] |= mac[3] << MAC_BYTE_3;
-+ reg[0] |= mac[2] << MAC_BYTE_2;
-+ reg[0] |= mac[1] << MAC_BYTE_1;
-+ reg[0] |= mac[0] << MAC_BYTE_0;
-+
-+ /* Write array into the ARL table */
-+ for (i = 0; i < 3; i++)
-+ mt7530_write(priv, MT7530_ATA1 + (i * 4), reg[i]);
-+}
-+
-+static int
-+mt7530_pad_clk_setup(struct dsa_switch *ds, int mode)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ u32 ncpo1, ssc_delta, trgint, i;
-+
-+ switch (mode) {
-+ case PHY_INTERFACE_MODE_RGMII:
-+ trgint = 0;
-+ ncpo1 = 0x0c80;
-+ ssc_delta = 0x87;
-+ break;
-+ case PHY_INTERFACE_MODE_TRGMII:
-+ trgint = 1;
-+ ncpo1 = 0x1400;
-+ ssc_delta = 0x57;
-+ break;
-+ default:
-+ dev_err(priv->dev, "xMII mode %d not supported\n", mode);
-+ return -EINVAL;
-+ }
-+
-+ mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK,
-+ P6_INTF_MODE(trgint));
-+
-+ /* Lower Tx Driving for TRGMII path */
-+ for (i = 0 ; i < NUM_TRGMII_CTRL ; i++)
-+ mt7530_write(priv, MT7530_TRGMII_TD_ODT(i),
-+ TD_DM_DRVP(8) | TD_DM_DRVN(8));
-+
-+ /* Setup core clock for MT7530 */
-+ if (!trgint) {
-+ /* Disable MT7530 core clock */
-+ core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
-+
-+ /* Disable PLL, since phy_device has not yet been created
-+ * provided for phy_[read,write]_mmd_indirect is called, we
-+ * provide our own core_write_mmd_indirect to complete this
-+ * function.
-+ */
-+ core_write_mmd_indirect(priv,
-+ CORE_GSWPLL_GRP1,
-+ MDIO_MMD_VEND2,
-+ 0);
-+
-+ /* Set core clock into 500Mhz */
-+ core_write(priv, CORE_GSWPLL_GRP2,
-+ RG_GSWPLL_POSDIV_500M(1) |
-+ RG_GSWPLL_FBKDIV_500M(25));
-+
-+ /* Enable PLL */
-+ core_write(priv, CORE_GSWPLL_GRP1,
-+ RG_GSWPLL_EN_PRE |
-+ RG_GSWPLL_POSDIV_200M(2) |
-+ RG_GSWPLL_FBKDIV_200M(32));
-+
-+ /* Enable MT7530 core clock */
-+ core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
-+ }
-+
-+ /* Setup the MT7530 TRGMII Tx Clock */
-+ core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
-+ core_write(priv, CORE_PLL_GROUP5, RG_LCDDS_PCW_NCPO1(ncpo1));
-+ core_write(priv, CORE_PLL_GROUP6, RG_LCDDS_PCW_NCPO0(0));
-+ core_write(priv, CORE_PLL_GROUP10, RG_LCDDS_SSC_DELTA(ssc_delta));
-+ core_write(priv, CORE_PLL_GROUP11, RG_LCDDS_SSC_DELTA1(ssc_delta));
-+ core_write(priv, CORE_PLL_GROUP4,
-+ RG_SYSPLL_DDSFBK_EN | RG_SYSPLL_BIAS_EN |
-+ RG_SYSPLL_BIAS_LPF_EN);
-+ core_write(priv, CORE_PLL_GROUP2,
-+ RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN |
-+ RG_SYSPLL_POSDIV(1));
-+ core_write(priv, CORE_PLL_GROUP7,
-+ RG_LCDDS_PCW_NCPO_CHG | RG_LCCDS_C(3) |
-+ RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
-+ core_set(priv, CORE_TRGMII_GSW_CLK_CG,
-+ REG_GSWCK_EN | REG_TRGMIICK_EN);
-+
-+ if (!trgint)
-+ for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
-+ mt7530_rmw(priv, MT7530_TRGMII_RD(i),
-+ RD_TAP_MASK, RD_TAP(16));
-+ else
-+ mt7623_trgmii_set(priv, GSW_INTF_MODE, INTF_MODE_TRGMII);
-+
-+ return 0;
-+}
-+
-+static int
-+mt7623_pad_clk_setup(struct dsa_switch *ds)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ int i;
-+
-+ for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
-+ mt7623_trgmii_write(priv, GSW_TRGMII_TD_ODT(i),
-+ TD_DM_DRVP(8) | TD_DM_DRVN(8));
-+
-+ mt7623_trgmii_set(priv, GSW_TRGMII_RCK_CTRL, RX_RST | RXC_DQSISEL);
-+ mt7623_trgmii_clear(priv, GSW_TRGMII_RCK_CTRL, RX_RST);
-+
-+ return 0;
-+}
-+
-+static void
-+mt7530_mib_reset(struct dsa_switch *ds)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ mt7530_write(priv, MT7530_MIB_CCR, CCR_MIB_FLUSH);
-+ mt7530_write(priv, MT7530_MIB_CCR, CCR_MIB_ACTIVATE);
-+}
-+
-+static void
-+mt7530_port_set_status(struct mt7530_priv *priv, int port, int enable)
-+{
-+ u32 mask = PMCR_TX_EN | PMCR_RX_EN;
-+
-+ if (enable)
-+ mt7530_set(priv, MT7530_PMCR_P(port), mask);
-+ else
-+ mt7530_clear(priv, MT7530_PMCR_P(port), mask);
-+}
-+
-+static int
-+mt7530_setup(struct dsa_switch *ds)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ int ret, i;
-+ u32 id, val;
-+ struct device_node *dn;
-+
-+ /* The parent node of master_netdev which holds the common system
-+ * controller also is the container for two GMACs nodes representing
-+ * as two netdev instances.
-+ */
-+ dn = ds->master_netdev->dev.of_node->parent;
-+ priv->ethernet = syscon_node_to_regmap(dn);
-+ if (IS_ERR(priv->ethernet))
-+ return PTR_ERR(priv->ethernet);
-+
-+ regulator_set_voltage(priv->core_pwr, 1000000, 1000000);
-+ ret = regulator_enable(priv->core_pwr);
-+ if (ret < 0) {
-+ dev_err(priv->dev,
-+ "Failed to enable core power: %d\n", ret);
-+ return ret;
-+ }
-+
-+ regulator_set_voltage(priv->io_pwr, 3300000, 3300000);
-+ ret = regulator_enable(priv->io_pwr);
-+ if (ret < 0) {
-+ dev_err(priv->dev, "Failed to enable io pwr: %d\n",
-+ ret);
-+ return ret;
-+ }
-+
-+ /* Reset whole chip through gpio pin or memory-mapped registers for
-+ * different type of hardware
-+ */
-+ if (priv->mcm) {
-+ reset_control_assert(priv->rstc);
-+ usleep_range(1000, 1100);
-+ reset_control_deassert(priv->rstc);
-+ } else {
-+ gpiod_set_value_cansleep(priv->reset, 0);
-+ usleep_range(1000, 1100);
-+ gpiod_set_value_cansleep(priv->reset, 1);
-+ }
-+
-+ /* Waiting for MT7530 got to stable */
-+ ret = readx_poll_timeout(_mt7530_read, MT7530_HWTRAP, val, val != 0,
-+ 20, 1000000);
-+ if (ret < 0) {
-+ dev_err(priv->dev, "reset timeout\n");
-+ return ret;
-+ }
-+
-+ id = mt7530_read(priv, MT7530_CREV);
-+ id >>= CHIP_NAME_SHIFT;
-+ if (id != MT7530_ID) {
-+ dev_err(priv->dev, "chip %x can't be supported\n", id);
-+ return -ENODEV;
-+ }
-+
-+ /* Reset the switch through internal reset */
-+ mt7530_write(priv, MT7530_SYS_CTRL,
-+ SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
-+ SYS_CTRL_REG_RST);
-+
-+ /* Enable Port 6 only; P5 as GMAC5 which currently is not supported */
-+ val = mt7530_read(priv, MT7530_MHWTRAP);
-+ val &= ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS;
-+ val |= MHWTRAP_MANUAL;
-+ mt7530_write(priv, MT7530_MHWTRAP, val);
-+
-+ /* Enable and reset MIB counters */
-+ mt7530_mib_reset(ds);
-+
-+ mt7530_clear(priv, MT7530_MFC, UNU_FFP_MASK);
-+
-+ for (i = 0; i < MT7530_NUM_PORTS; i++) {
-+ /* Disable forwarding by default on all ports */
-+ mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
-+ PCR_MATRIX_CLR);
-+
-+ if (dsa_is_cpu_port(ds, i))
-+ mt7530_cpu_port_enable(priv, i);
-+ else
-+ mt7530_port_disable(ds, i, NULL);
-+ }
-+
-+ /* Flush the FDB table */
-+ ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, 0);
-+ if (ret < 0)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+static int mt7530_phy_read(struct dsa_switch *ds, int port, int regnum)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ return mdiobus_read_nested(priv->bus, port, regnum);
-+}
-+
-+int mt7530_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ return mdiobus_write_nested(priv->bus, port, regnum, val);
-+}
-+
-+static void
-+mt7530_get_strings(struct dsa_switch *ds, int port, uint8_t *data)
-+{
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(mt7530_mib); i++)
-+ strncpy(data + i * ETH_GSTRING_LEN, mt7530_mib[i].name,
-+ ETH_GSTRING_LEN);
-+}
-+
-+static void
-+mt7530_get_ethtool_stats(struct dsa_switch *ds, int port,
-+ uint64_t *data)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ const struct mt7530_mib_desc *mib;
-+ u32 reg, i;
-+ u64 hi;
-+
-+ for (i = 0; i < ARRAY_SIZE(mt7530_mib); i++) {
-+ mib = &mt7530_mib[i];
-+ reg = MT7530_PORT_MIB_COUNTER(port) + mib->offset;
-+
-+ data[i] = mt7530_read(priv, reg);
-+ if (mib->size == 2) {
-+ hi = mt7530_read(priv, reg + 4);
-+ data[i] |= hi << 32;
-+ }
-+ }
-+}
-+
-+static int
-+mt7530_get_sset_count(struct dsa_switch *ds)
-+{
-+ return ARRAY_SIZE(mt7530_mib);
-+}
-+
-+static void mt7530_adjust_link(struct dsa_switch *ds, int port,
-+ struct phy_device *phydev)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ if (phy_is_pseudo_fixed_link(phydev)) {
-+ dev_dbg(priv->dev, "phy-mode for master device = %x\n",
-+ phydev->interface);
-+
-+ /* Setup TX circuit incluing relevant PAD and driving */
-+ mt7530_pad_clk_setup(ds, phydev->interface);
-+
-+ /* Setup RX circuit, relevant PAD and driving on the host
-+ * which must be placed after the setup on the device side is
-+ * all finished.
-+ */
-+ mt7623_pad_clk_setup(ds);
-+ }
-+}
-+
-+static int
-+mt7530_cpu_port_enable(struct mt7530_priv *priv,
-+ int port)
-+{
-+ /* Enable Mediatek header mode on the cpu port */
-+ mt7530_write(priv, MT7530_PVC_P(port),
-+ PORT_SPEC_TAG);
-+
-+ /* Setup the MAC by default for the cpu port */
-+ mt7530_write(priv, MT7530_PMCR_P(port), PMCR_CPUP_LINK);
-+
-+ /* Disable auto learning on the cpu port */
-+ mt7530_set(priv, MT7530_PSC_P(port), SA_DIS);
-+
-+ /* Unknown unicast frame fordwarding to the cpu port */
-+ mt7530_set(priv, MT7530_MFC, UNU_FFP(BIT(port)));
-+
-+ /* CPU port gets connected to all user ports of
-+ * the switch
-+ */
-+ mt7530_write(priv, MT7530_PCR_P(port),
-+ PCR_MATRIX(priv->ds->enabled_port_mask));
-+
-+ return 0;
-+}
-+
-+static int
-+mt7530_port_enable(struct dsa_switch *ds, int port,
-+ struct phy_device *phy)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ mutex_lock(&priv->reg_mutex);
-+
-+ /* Setup the MAC for the user port */
-+ mt7530_write(priv, MT7530_PMCR_P(port), PMCR_USERP_LINK);
-+
-+ /* Allow the user port gets connected to the cpu port and also
-+ * restore the port matrix if the port is the member of a certain
-+ * bridge.
-+ */
-+ priv->ports[port].pm |= PCR_MATRIX(BIT(MT7530_CPU_PORT));
-+ priv->ports[port].enable = true;
-+ mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
-+ priv->ports[port].pm);
-+ mt7530_port_set_status(priv, port, 1);
-+
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return 0;
-+}
-+
-+static void
-+mt7530_port_disable(struct dsa_switch *ds, int port,
-+ struct phy_device *phy)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ mutex_lock(&priv->reg_mutex);
-+
-+ /* Clear up all port matrix which could be restored in the next
-+ * enablement for the port.
-+ */
-+ priv->ports[port].enable = false;
-+ mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
-+ PCR_MATRIX_CLR);
-+ mt7530_port_set_status(priv, port, 0);
-+
-+ mutex_unlock(&priv->reg_mutex);
-+}
-+
-+static void
-+mt7530_stp_state_set(struct dsa_switch *ds, int port, u8 state)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ u32 stp_state;
-+
-+ switch (state) {
-+ case BR_STATE_DISABLED:
-+ stp_state = MT7530_STP_DISABLED;
-+ break;
-+ case BR_STATE_BLOCKING:
-+ stp_state = MT7530_STP_BLOCKING;
-+ break;
-+ case BR_STATE_LISTENING:
-+ stp_state = MT7530_STP_LISTENING;
-+ break;
-+ case BR_STATE_LEARNING:
-+ stp_state = MT7530_STP_LEARNING;
-+ break;
-+ case BR_STATE_FORWARDING:
-+ default:
-+ stp_state = MT7530_STP_FORWARDING;
-+ break;
-+ }
-+
-+ mt7530_rmw(priv, MT7530_SSP_P(port), FID_PST_MASK, stp_state);
-+}
-+
-+static int
-+mt7530_port_bridge_join(struct dsa_switch *ds, int port,
-+ struct net_device *bridge)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ u32 port_bitmap = BIT(MT7530_CPU_PORT);
-+ int i;
-+
-+ mutex_lock(&priv->reg_mutex);
-+
-+ for (i = 0; i < MT7530_NUM_PORTS; i++) {
-+ /* Add this port to the port matrix of the other ports in the
-+ * same bridge. If the port is disabled, port matrix is kept
-+ * and not being setup until the port becomes enabled.
-+ */
-+ if (ds->enabled_port_mask & BIT(i) && i != port) {
-+ if (ds->ports[i].bridge_dev != bridge)
-+ continue;
-+ if (priv->ports[i].enable)
-+ mt7530_set(priv, MT7530_PCR_P(i),
-+ PCR_MATRIX(BIT(port)));
-+ priv->ports[i].pm |= PCR_MATRIX(BIT(port));
-+
-+ port_bitmap |= BIT(i);
-+ }
-+ }
-+
-+ /* Add the all other ports to this port matrix. */
-+ if (priv->ports[port].enable)
-+ mt7530_rmw(priv, MT7530_PCR_P(port),
-+ PCR_MATRIX_MASK, PCR_MATRIX(port_bitmap));
-+ priv->ports[port].pm |= PCR_MATRIX(port_bitmap);
-+
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return 0;
-+}
-+
-+static void
-+mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
-+ struct net_device *bridge)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ int i;
-+
-+ mutex_lock(&priv->reg_mutex);
-+
-+ for (i = 0; i < MT7530_NUM_PORTS; i++) {
-+ /* Remove this port from the port matrix of the other ports
-+ * in the same bridge. If the port is disabled, port matrix
-+ * is kept and not being setup until the port becomes enabled.
-+ */
-+ if (ds->enabled_port_mask & BIT(i) && i != port) {
-+ if (ds->ports[i].bridge_dev != bridge)
-+ continue;
-+ if (priv->ports[i].enable)
-+ mt7530_clear(priv, MT7530_PCR_P(i),
-+ PCR_MATRIX(BIT(port)));
-+ priv->ports[i].pm &= ~PCR_MATRIX(BIT(port));
-+ }
-+ }
-+
-+ /* Set the cpu port to be the only one in the port matrix of
-+ * this port.
-+ */
-+ if (priv->ports[port].enable)
-+ mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
-+ PCR_MATRIX(BIT(MT7530_CPU_PORT)));
-+ priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT));
-+
-+ mutex_unlock(&priv->reg_mutex);
-+}
-+
-+static int
-+mt7530_port_fdb_prepare(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_fdb *fdb,
-+ struct switchdev_trans *trans)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ int ret;
-+
-+ /* Because auto-learned entrie shares the same FDB table.
-+ * an entry is reserved with no port_mask to make sure fdb_add
-+ * is called while the entry is still available.
-+ */
-+ mutex_lock(&priv->reg_mutex);
-+ mt7530_fdb_write(priv, fdb->vid, 0, fdb->addr, -1, STATIC_ENT);
-+ ret = mt7530_fdb_cmd(priv, MT7530_FDB_WRITE, 0);
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return ret;
-+}
-+
-+static void
-+mt7530_port_fdb_add(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_fdb *fdb,
-+ struct switchdev_trans *trans)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ u8 port_mask = BIT(port);
-+
-+ mutex_lock(&priv->reg_mutex);
-+ mt7530_fdb_write(priv, fdb->vid, port_mask, fdb->addr, -1, STATIC_ENT);
-+ mt7530_fdb_cmd(priv, MT7530_FDB_WRITE, 0);
-+ mutex_unlock(&priv->reg_mutex);
-+}
-+
-+static int
-+mt7530_port_fdb_del(struct dsa_switch *ds, int port,
-+ const struct switchdev_obj_port_fdb *fdb)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ int ret;
-+ u8 port_mask = BIT(port);
-+
-+ mutex_lock(&priv->reg_mutex);
-+ mt7530_fdb_write(priv, fdb->vid, port_mask, fdb->addr, -1, STATIC_EMP);
-+ ret = mt7530_fdb_cmd(priv, MT7530_FDB_WRITE, 0);
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return ret;
-+}
-+
-+static int
-+mt7530_port_fdb_dump(struct dsa_switch *ds, int port,
-+ struct switchdev_obj_port_fdb *fdb,
-+ int (*cb)(struct switchdev_obj *obj))
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ struct mt7530_fdb _fdb = { 0 };
-+ int cnt = MT7530_NUM_FDB_RECORDS;
-+ int ret = 0;
-+ u32 rsp = 0;
-+
-+ mutex_lock(&priv->reg_mutex);
-+
-+ ret = mt7530_fdb_cmd(priv, MT7530_FDB_START, &rsp);
-+ if (ret < 0)
-+ goto err;
-+
-+ do {
-+ if (rsp & ATC_SRCH_HIT) {
-+ mt7530_fdb_read(priv, &_fdb);
-+ if (_fdb.port_mask & BIT(port)) {
-+ ether_addr_copy(fdb->addr, _fdb.mac);
-+ fdb->vid = _fdb.vid;
-+ fdb->ndm_state = _fdb.noarp ?
-+ NUD_NOARP : NUD_REACHABLE;
-+ ret = cb(&fdb->obj);
-+ if (ret < 0)
-+ break;
-+ }
-+ }
-+ } while (--cnt &&
-+ !(rsp & ATC_SRCH_END) &&
-+ !mt7530_fdb_cmd(priv, MT7530_FDB_NEXT, &rsp));
-+err:
-+ mutex_unlock(&priv->reg_mutex);
-+
-+ return 0;
-+}
-+
-+static enum dsa_tag_protocol
-+mtk_get_tag_protocol(struct dsa_switch *ds)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ if (!dsa_is_cpu_port(ds, MT7530_CPU_PORT)) {
-+ dev_warn(priv->dev,
-+ "port not matched with tagging CPU port\n");
-+ return DSA_TAG_PROTO_NONE;
-+ } else {
-+ return DSA_TAG_PROTO_MTK;
-+ }
-+}
-+
-+static struct dsa_switch_ops mt7530_switch_ops = {
-+ .get_tag_protocol = mtk_get_tag_protocol,
-+ .setup = mt7530_setup,
-+ .get_strings = mt7530_get_strings,
-+ .phy_read = mt7530_phy_read,
-+ .phy_write = mt7530_phy_write,
-+ .get_ethtool_stats = mt7530_get_ethtool_stats,
-+ .get_sset_count = mt7530_get_sset_count,
-+ .adjust_link = mt7530_adjust_link,
-+ .port_enable = mt7530_port_enable,
-+ .port_disable = mt7530_port_disable,
-+ .port_stp_state_set = mt7530_stp_state_set,
-+ .port_bridge_join = mt7530_port_bridge_join,
-+ .port_bridge_leave = mt7530_port_bridge_leave,
-+ .port_fdb_prepare = mt7530_port_fdb_prepare,
-+ .port_fdb_add = mt7530_port_fdb_add,
-+ .port_fdb_del = mt7530_port_fdb_del,
-+ .port_fdb_dump = mt7530_port_fdb_dump,
-+};
-+
-+static int
-+mt7530_probe(struct mdio_device *mdiodev)
-+{
-+ struct mt7530_priv *priv;
-+ struct device_node *dn;
-+
-+ dn = mdiodev->dev.of_node;
-+
-+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->ds = dsa_switch_alloc(&mdiodev->dev, DSA_MAX_PORTS);
-+ if (!priv->ds)
-+ return -ENOMEM;
-+
-+ /* Use medatek,mcm property to distinguish hardware type that would
-+ * casues a little bit differences on power-on sequence.
-+ */
-+ priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
-+ if (priv->mcm) {
-+ dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
-+
-+ priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
-+ if (IS_ERR(priv->rstc)) {
-+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
-+ return PTR_ERR(priv->rstc);
-+ }
-+ }
-+
-+ priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
-+ if (IS_ERR(priv->core_pwr))
-+ return PTR_ERR(priv->core_pwr);
-+
-+ priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
-+ if (IS_ERR(priv->io_pwr))
-+ return PTR_ERR(priv->io_pwr);
-+
-+ /* Not MCM that indicates switch works as the remote standalone
-+ * integrated circuit so the GPIO pin would be used to complete
-+ * the reset, otherwise memory-mapped register accessing used
-+ * through syscon provides in the case of MCM.
-+ */
-+ if (!priv->mcm) {
-+ priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
-+ GPIOD_OUT_LOW);
-+ if (IS_ERR(priv->reset)) {
-+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
-+ return PTR_ERR(priv->reset);
-+ }
-+ }
-+
-+ priv->bus = mdiodev->bus;
-+ priv->dev = &mdiodev->dev;
-+ priv->ds->priv = priv;
-+ priv->ds->ops = &mt7530_switch_ops;
-+ mutex_init(&priv->reg_mutex);
-+ lpriv = priv;
-+ dev_set_drvdata(&mdiodev->dev, priv);
-+
-+ return dsa_register_switch(priv->ds, &mdiodev->dev);
-+}
-+
-+static void
-+mt7530_remove(struct mdio_device *mdiodev)
-+{
-+ struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
-+ int ret = 0;
-+
-+ ret = regulator_disable(priv->core_pwr);
-+ if (ret < 0)
-+ dev_err(priv->dev,
-+ "Failed to disable core power: %d\n", ret);
-+
-+ ret = regulator_disable(priv->io_pwr);
-+ if (ret < 0)
-+ dev_err(priv->dev, "Failed to disable io pwr: %d\n",
-+ ret);
-+
-+ dsa_unregister_switch(priv->ds);
-+ mutex_destroy(&priv->reg_mutex);
-+}
-+
-+static const struct of_device_id mt7530_of_match[] = {
-+ { .compatible = "mediatek,mt7530" },
-+ { /* sentinel */ },
-+};
-+
-+static struct mdio_driver mt7530_mdio_driver = {
-+ .probe = mt7530_probe,
-+ .remove = mt7530_remove,
-+ .mdiodrv.driver = {
-+ .name = "mt7530",
-+ .of_match_table = mt7530_of_match,
-+ },
-+};
-+
-+mdio_module_driver(mt7530_mdio_driver);
-+
-+MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
-+MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("platform:mediatek-mt7530");
---- /dev/null
-+++ b/drivers/net/dsa/mt7530.h
-@@ -0,0 +1,390 @@
-+/*
-+ * Copyright (C) 2017 Sean Wang <sean.wang@mediatek.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#ifndef __MT7530_H
-+#define __MT7530_H
-+
-+#define MT7530_NUM_PORTS 7
-+#define MT7530_CPU_PORT 6
-+#define MT7530_NUM_FDB_RECORDS 2048
-+
-+#define NUM_TRGMII_CTRL 5
-+
-+#define TRGMII_BASE(x) (0x10000 + (x))
-+
-+/* Registers to ethsys access */
-+#define ETHSYS_CLKCFG0 0x2c
-+#define ETHSYS_TRGMII_CLK_SEL362_5 BIT(11)
-+
-+#define SYSC_REG_RSTCTRL 0x34
-+#define RESET_MCM BIT(2)
-+
-+/* Registers to mac forward control for unknown frames */
-+#define MT7530_MFC 0x10
-+#define BC_FFP(x) (((x) & 0xff) << 24)
-+#define UNM_FFP(x) (((x) & 0xff) << 16)
-+#define UNU_FFP(x) (((x) & 0xff) << 8)
-+#define UNU_FFP_MASK UNU_FFP(~0)
-+
-+/* Registers for address table access */
-+#define MT7530_ATA1 0x74
-+#define STATIC_EMP 0
-+#define STATIC_ENT 3
-+#define MT7530_ATA2 0x78
-+
-+/* Register for address table write data */
-+#define MT7530_ATWD 0x7c
-+
-+/* Register for address table control */
-+#define MT7530_ATC 0x80
-+#define ATC_HASH (((x) & 0xfff) << 16)
-+#define ATC_BUSY BIT(15)
-+#define ATC_SRCH_END BIT(14)
-+#define ATC_SRCH_HIT BIT(13)
-+#define ATC_INVALID BIT(12)
-+#define ATC_MAT(x) (((x) & 0xf) << 8)
-+#define ATC_MAT_MACTAB ATC_MAT(0)
-+
-+enum mt7530_fdb_cmd {
-+ MT7530_FDB_READ = 0,
-+ MT7530_FDB_WRITE = 1,
-+ MT7530_FDB_FLUSH = 2,
-+ MT7530_FDB_START = 4,
-+ MT7530_FDB_NEXT = 5,
-+};
-+
-+/* Registers for table search read address */
-+#define MT7530_TSRA1 0x84
-+#define MAC_BYTE_0 24
-+#define MAC_BYTE_1 16
-+#define MAC_BYTE_2 8
-+#define MAC_BYTE_3 0
-+#define MAC_BYTE_MASK 0xff
-+
-+#define MT7530_TSRA2 0x88
-+#define MAC_BYTE_4 24
-+#define MAC_BYTE_5 16
-+#define CVID 0
-+#define CVID_MASK 0xfff
-+
-+#define MT7530_ATRD 0x8C
-+#define AGE_TIMER 24
-+#define AGE_TIMER_MASK 0xff
-+#define PORT_MAP 4
-+#define PORT_MAP_MASK 0xff
-+#define ENT_STATUS 2
-+#define ENT_STATUS_MASK 0x3
-+
-+/* Register for vlan table control */
-+#define MT7530_VTCR 0x90
-+#define VTCR_BUSY BIT(31)
-+#define VTCR_FUNC (((x) & 0xf) << 12)
-+#define VTCR_FUNC_RD_VID 0x1
-+#define VTCR_FUNC_WR_VID 0x2
-+#define VTCR_FUNC_INV_VID 0x3
-+#define VTCR_FUNC_VAL_VID 0x4
-+#define VTCR_VID ((x) & 0xfff)
-+
-+/* Register for setup vlan and acl write data */
-+#define MT7530_VAWD1 0x94
-+#define PORT_STAG BIT(31)
-+#define IVL_MAC BIT(30)
-+#define PORT_MEM(x) (((x) & 0xff) << 16)
-+#define VALID BIT(1)
-+
-+#define MT7530_VAWD2 0x98
-+
-+/* Register for port STP state control */
-+#define MT7530_SSP_P(x) (0x2000 + ((x) * 0x100))
-+#define FID_PST(x) ((x) & 0x3)
-+#define FID_PST_MASK FID_PST(0x3)
-+
-+enum mt7530_stp_state {
-+ MT7530_STP_DISABLED = 0,
-+ MT7530_STP_BLOCKING = 1,
-+ MT7530_STP_LISTENING = 1,
-+ MT7530_STP_LEARNING = 2,
-+ MT7530_STP_FORWARDING = 3
-+};
-+
-+/* Register for port control */
-+#define MT7530_PCR_P(x) (0x2004 + ((x) * 0x100))
-+#define PORT_VLAN(x) ((x) & 0x3)
-+#define PCR_MATRIX(x) (((x) & 0xff) << 16)
-+#define PORT_PRI(x) (((x) & 0x7) << 24)
-+#define EG_TAG(x) (((x) & 0x3) << 28)
-+#define PCR_MATRIX_MASK PCR_MATRIX(0xff)
-+#define PCR_MATRIX_CLR PCR_MATRIX(0)
-+
-+/* Register for port security control */
-+#define MT7530_PSC_P(x) (0x200c + ((x) * 0x100))
-+#define SA_DIS BIT(4)
-+
-+/* Register for port vlan control */
-+#define MT7530_PVC_P(x) (0x2010 + ((x) * 0x100))
-+#define PORT_SPEC_TAG BIT(5)
-+#define VLAN_ATTR(x) (((x) & 0x3) << 6)
-+#define STAG_VPID (((x) & 0xffff) << 16)
-+
-+/* Register for port port-and-protocol based vlan 1 control */
-+#define MT7530_PPBV1_P(x) (0x2014 + ((x) * 0x100))
-+
-+/* Register for port MAC control register */
-+#define MT7530_PMCR_P(x) (0x3000 + ((x) * 0x100))
-+#define PMCR_IFG_XMIT(x) (((x) & 0x3) << 18)
-+#define PMCR_MAC_MODE BIT(16)
-+#define PMCR_FORCE_MODE BIT(15)
-+#define PMCR_TX_EN BIT(14)
-+#define PMCR_RX_EN BIT(13)
-+#define PMCR_BACKOFF_EN BIT(9)
-+#define PMCR_BACKPR_EN BIT(8)
-+#define PMCR_TX_FC_EN BIT(5)
-+#define PMCR_RX_FC_EN BIT(4)
-+#define PMCR_FORCE_SPEED_1000 BIT(3)
-+#define PMCR_FORCE_FDX BIT(1)
-+#define PMCR_FORCE_LNK BIT(0)
-+#define PMCR_COMMON_LINK (PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | \
-+ PMCR_BACKOFF_EN | PMCR_BACKPR_EN | \
-+ PMCR_TX_EN | PMCR_RX_EN | \
-+ PMCR_TX_FC_EN | PMCR_RX_FC_EN)
-+#define PMCR_CPUP_LINK (PMCR_COMMON_LINK | PMCR_FORCE_MODE | \
-+ PMCR_FORCE_SPEED_1000 | \
-+ PMCR_FORCE_FDX | \
-+ PMCR_FORCE_LNK)
-+#define PMCR_USERP_LINK PMCR_COMMON_LINK
-+#define PMCR_FIXED_LINK (PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | \
-+ PMCR_FORCE_MODE | PMCR_TX_EN | \
-+ PMCR_RX_EN | PMCR_BACKPR_EN | \
-+ PMCR_BACKOFF_EN | \
-+ PMCR_FORCE_SPEED_1000 | \
-+ PMCR_FORCE_FDX | \
-+ PMCR_FORCE_LNK)
-+#define PMCR_FIXED_LINK_FC (PMCR_FIXED_LINK | \
-+ PMCR_TX_FC_EN | PMCR_RX_FC_EN)
-+
-+#define MT7530_PMSR_P(x) (0x3008 + (x) * 0x100)
-+
-+/* Register for MIB */
-+#define MT7530_PORT_MIB_COUNTER(x) (0x4000 + (x) * 0x100)
-+#define MT7530_MIB_CCR 0x4fe0
-+#define CCR_MIB_ENABLE BIT(31)
-+#define CCR_RX_OCT_CNT_GOOD BIT(7)
-+#define CCR_RX_OCT_CNT_BAD BIT(6)
-+#define CCR_TX_OCT_CNT_GOOD BIT(5)
-+#define CCR_TX_OCT_CNT_BAD BIT(4)
-+#define CCR_MIB_FLUSH (CCR_RX_OCT_CNT_GOOD | \
-+ CCR_RX_OCT_CNT_BAD | \
-+ CCR_TX_OCT_CNT_GOOD | \
-+ CCR_TX_OCT_CNT_BAD)
-+#define CCR_MIB_ACTIVATE (CCR_MIB_ENABLE | \
-+ CCR_RX_OCT_CNT_GOOD | \
-+ CCR_RX_OCT_CNT_BAD | \
-+ CCR_TX_OCT_CNT_GOOD | \
-+ CCR_TX_OCT_CNT_BAD)
-+/* Register for system reset */
-+#define MT7530_SYS_CTRL 0x7000
-+#define SYS_CTRL_PHY_RST BIT(2)
-+#define SYS_CTRL_SW_RST BIT(1)
-+#define SYS_CTRL_REG_RST BIT(0)
-+
-+/* Register for hw trap status */
-+#define MT7530_HWTRAP 0x7800
-+
-+/* Register for hw trap modification */
-+#define MT7530_MHWTRAP 0x7804
-+#define MHWTRAP_MANUAL BIT(16)
-+#define MHWTRAP_P5_MAC_SEL BIT(13)
-+#define MHWTRAP_P6_DIS BIT(8)
-+#define MHWTRAP_P5_RGMII_MODE BIT(7)
-+#define MHWTRAP_P5_DIS BIT(6)
-+#define MHWTRAP_PHY_ACCESS BIT(5)
-+
-+/* Register for TOP signal control */
-+#define MT7530_TOP_SIG_CTRL 0x7808
-+#define TOP_SIG_CTRL_NORMAL (BIT(17) | BIT(16))
-+
-+#define MT7530_IO_DRV_CR 0x7810
-+#define P5_IO_CLK_DRV(x) ((x) & 0x3)
-+#define P5_IO_DATA_DRV(x) (((x) & 0x3) << 4)
-+
-+#define MT7530_P6ECR 0x7830
-+#define P6_INTF_MODE_MASK 0x3
-+#define P6_INTF_MODE(x) ((x) & 0x3)
-+
-+/* Registers for TRGMII on the both side */
-+#define MT7530_TRGMII_RCK_CTRL 0x7a00
-+#define GSW_TRGMII_RCK_CTRL 0x300
-+#define RX_RST BIT(31)
-+#define RXC_DQSISEL BIT(30)
-+#define DQSI1_TAP_MASK (0x7f << 8)
-+#define DQSI0_TAP_MASK 0x7f
-+#define DQSI1_TAP(x) (((x) & 0x7f) << 8)
-+#define DQSI0_TAP(x) ((x) & 0x7f)
-+
-+#define MT7530_TRGMII_RCK_RTT 0x7a04
-+#define GSW_TRGMII_RCK_RTT 0x304
-+#define DQS1_GATE BIT(31)
-+#define DQS0_GATE BIT(30)
-+
-+#define MT7530_TRGMII_RD(x) (0x7a10 + (x) * 8)
-+#define GSW_TRGMII_RD(x) (0x310 + (x) * 8)
-+#define BSLIP_EN BIT(31)
-+#define EDGE_CHK BIT(30)
-+#define RD_TAP_MASK 0x7f
-+#define RD_TAP(x) ((x) & 0x7f)
-+
-+#define GSW_TRGMII_TXCTRL 0x340
-+#define MT7530_TRGMII_TXCTRL 0x7a40
-+#define TRAIN_TXEN BIT(31)
-+#define TXC_INV BIT(30)
-+#define TX_RST BIT(28)
-+
-+#define MT7530_TRGMII_TD_ODT(i) (0x7a54 + 8 * (i))
-+#define GSW_TRGMII_TD_ODT(i) (0x354 + 8 * (i))
-+#define TD_DM_DRVP(x) ((x) & 0xf)
-+#define TD_DM_DRVN(x) (((x) & 0xf) << 4)
-+
-+#define GSW_INTF_MODE 0x390
-+#define INTF_MODE_TRGMII BIT(1)
-+
-+#define MT7530_TRGMII_TCK_CTRL 0x7a78
-+#define TCK_TAP(x) (((x) & 0xf) << 8)
-+
-+#define MT7530_P5RGMIIRXCR 0x7b00
-+#define CSR_RGMII_EDGE_ALIGN BIT(8)
-+#define CSR_RGMII_RXC_0DEG_CFG(x) ((x) & 0xf)
-+
-+#define MT7530_P5RGMIITXCR 0x7b04
-+#define CSR_RGMII_TXC_CFG(x) ((x) & 0x1f)
-+
-+#define MT7530_CREV 0x7ffc
-+#define CHIP_NAME_SHIFT 16
-+#define MT7530_ID 0x7530
-+
-+/* Registers for core PLL access through mmd indirect */
-+#define CORE_PLL_GROUP2 0x401
-+#define RG_SYSPLL_EN_NORMAL BIT(15)
-+#define RG_SYSPLL_VODEN BIT(14)
-+#define RG_SYSPLL_LF BIT(13)
-+#define RG_SYSPLL_RST_DLY(x) (((x) & 0x3) << 12)
-+#define RG_SYSPLL_LVROD_EN BIT(10)
-+#define RG_SYSPLL_PREDIV(x) (((x) & 0x3) << 8)
-+#define RG_SYSPLL_POSDIV(x) (((x) & 0x3) << 5)
-+#define RG_SYSPLL_FBKSEL BIT(4)
-+#define RT_SYSPLL_EN_AFE_OLT BIT(0)
-+
-+#define CORE_PLL_GROUP4 0x403
-+#define RG_SYSPLL_DDSFBK_EN BIT(12)
-+#define RG_SYSPLL_BIAS_EN BIT(11)
-+#define RG_SYSPLL_BIAS_LPF_EN BIT(10)
-+
-+#define CORE_PLL_GROUP5 0x404
-+#define RG_LCDDS_PCW_NCPO1(x) ((x) & 0xffff)
-+
-+#define CORE_PLL_GROUP6 0x405
-+#define RG_LCDDS_PCW_NCPO0(x) ((x) & 0xffff)
-+
-+#define CORE_PLL_GROUP7 0x406
-+#define RG_LCDDS_PWDB BIT(15)
-+#define RG_LCDDS_ISO_EN BIT(13)
-+#define RG_LCCDS_C(x) (((x) & 0x7) << 4)
-+#define RG_LCDDS_PCW_NCPO_CHG BIT(3)
-+
-+#define CORE_PLL_GROUP10 0x409
-+#define RG_LCDDS_SSC_DELTA(x) ((x) & 0xfff)
-+
-+#define CORE_PLL_GROUP11 0x40a
-+#define RG_LCDDS_SSC_DELTA1(x) ((x) & 0xfff)
-+
-+#define CORE_GSWPLL_GRP1 0x40d
-+#define RG_GSWPLL_PREDIV(x) (((x) & 0x3) << 14)
-+#define RG_GSWPLL_POSDIV_200M(x) (((x) & 0x3) << 12)
-+#define RG_GSWPLL_EN_PRE BIT(11)
-+#define RG_GSWPLL_FBKSEL BIT(10)
-+#define RG_GSWPLL_BP BIT(9)
-+#define RG_GSWPLL_BR BIT(8)
-+#define RG_GSWPLL_FBKDIV_200M(x) ((x) & 0xff)
-+
-+#define CORE_GSWPLL_GRP2 0x40e
-+#define RG_GSWPLL_POSDIV_500M(x) (((x) & 0x3) << 8)
-+#define RG_GSWPLL_FBKDIV_500M(x) ((x) & 0xff)
-+
-+#define CORE_TRGMII_GSW_CLK_CG 0x410
-+#define REG_GSWCK_EN BIT(0)
-+#define REG_TRGMIICK_EN BIT(1)
-+
-+#define MIB_DESC(_s, _o, _n) \
-+ { \
-+ .size = (_s), \
-+ .offset = (_o), \
-+ .name = (_n), \
-+ }
-+
-+struct mt7530_mib_desc {
-+ unsigned int size;
-+ unsigned int offset;
-+ const char *name;
-+};
-+
-+struct mt7530_fdb {
-+ u16 vid;
-+ u8 port_mask;
-+ u8 aging;
-+ u8 mac[6];
-+ bool noarp;
-+};
-+
-+struct mt7530_port {
-+ bool enable;
-+ u32 pm;
-+};
-+
-+/* struct mt7530_priv - This is the main data structure for holding the state
-+ * of the driver
-+ * @dev: The device pointer
-+ * @ds: The pointer to the dsa core structure
-+ * @bus: The bus used for the device and built-in PHY
-+ * @rstc: The pointer to reset control used by MCM
-+ * @ethernet: The regmap used for access TRGMII-based registers
-+ * @core_pwr: The power supplied into the core
-+ * @io_pwr: The power supplied into the I/O
-+ * @reset: The descriptor for GPIO line tied to its reset pin
-+ * @mcm: Flag for distinguishing if standalone IC or module
-+ * coupling
-+ * @ports: Holding the state among ports
-+ * @reg_mutex: The lock for protecting among process accessing
-+ * registers
-+ */
-+struct mt7530_priv {
-+ struct device *dev;
-+ struct dsa_switch *ds;
-+ struct mii_bus *bus;
-+ struct reset_control *rstc;
-+ struct regmap *ethernet;
-+ struct regulator *core_pwr;
-+ struct regulator *io_pwr;
-+ struct gpio_desc *reset;
-+ bool mcm;
-+
-+ struct mt7530_port ports[MT7530_NUM_PORTS];
-+ /* protect among processes for registers access*/
-+ struct mutex reg_mutex;
-+};
-+
-+struct mt7530_hw_stats {
-+ const char *string;
-+ u16 reg;
-+ u8 sizeof_stat;
-+};
-+
-+#endif /* __MT7530_H */
diff --git a/target/linux/mediatek/patches-4.9/0031-net-dsa-dsa-api-compat.patch b/target/linux/mediatek/patches-4.9/0031-net-dsa-dsa-api-compat.patch
deleted file mode 100644
index 9e52be845b..0000000000
--- a/target/linux/mediatek/patches-4.9/0031-net-dsa-dsa-api-compat.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From a319687ac18dcc557a88054282508e061ad8495f Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 14:42:19 +0200
-Subject: [PATCH 31/57] net: dsa: dsa api compat
-
-make the latest driver work on the old API
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/dsa/mt7530.c | 14 ++++++++------
- drivers/net/dsa/mt7530.h | 2 ++
- net/dsa/tag_mtk.c | 2 +-
- 3 files changed, 11 insertions(+), 7 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -834,6 +834,7 @@ mt7530_port_bridge_join(struct dsa_switc
- int i;
-
- mutex_lock(&priv->reg_mutex);
-+ priv->bridge_dev[port] = bridge;
-
- for (i = 0; i < MT7530_NUM_PORTS; i++) {
- /* Add this port to the port matrix of the other ports in the
-@@ -841,7 +842,7 @@ mt7530_port_bridge_join(struct dsa_switc
- * and not being setup until the port becomes enabled.
- */
- if (ds->enabled_port_mask & BIT(i) && i != port) {
-- if (ds->ports[i].bridge_dev != bridge)
-+ if (priv->bridge_dev[i] != bridge)
- continue;
- if (priv->ports[i].enable)
- mt7530_set(priv, MT7530_PCR_P(i),
-@@ -864,8 +865,7 @@ mt7530_port_bridge_join(struct dsa_switc
- }
-
- static void
--mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
-- struct net_device *bridge)
-+mt7530_port_bridge_leave(struct dsa_switch *ds, int port)
- {
- struct mt7530_priv *priv = ds->priv;
- int i;
-@@ -878,7 +878,7 @@ mt7530_port_bridge_leave(struct dsa_swit
- * is kept and not being setup until the port becomes enabled.
- */
- if (ds->enabled_port_mask & BIT(i) && i != port) {
-- if (ds->ports[i].bridge_dev != bridge)
-+ if (priv->bridge_dev[i] != priv->bridge_dev[port])
- continue;
- if (priv->ports[i].enable)
- mt7530_clear(priv, MT7530_PCR_P(i),
-@@ -890,6 +890,7 @@ mt7530_port_bridge_leave(struct dsa_swit
- /* Set the cpu port to be the only one in the port matrix of
- * this port.
- */
-+ priv->bridge_dev[port] = NULL;
- if (priv->ports[port].enable)
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
- PCR_MATRIX(BIT(MT7530_CPU_PORT)));
-@@ -1033,7 +1034,7 @@ mt7530_probe(struct mdio_device *mdiodev
- if (!priv)
- return -ENOMEM;
-
-- priv->ds = dsa_switch_alloc(&mdiodev->dev, DSA_MAX_PORTS);
-+ priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
- if (!priv->ds)
- return -ENOMEM;
-
-@@ -1076,12 +1077,13 @@ mt7530_probe(struct mdio_device *mdiodev
- priv->bus = mdiodev->bus;
- priv->dev = &mdiodev->dev;
- priv->ds->priv = priv;
-+ priv->ds->dev = &mdiodev->dev;
- priv->ds->ops = &mt7530_switch_ops;
- mutex_init(&priv->reg_mutex);
- lpriv = priv;
- dev_set_drvdata(&mdiodev->dev, priv);
-
-- return dsa_register_switch(priv->ds, &mdiodev->dev);
-+ return dsa_register_switch(priv->ds, priv->ds->dev->of_node);
- }
-
- static void
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -379,6 +379,8 @@ struct mt7530_priv {
- struct mt7530_port ports[MT7530_NUM_PORTS];
- /* protect among processes for registers access*/
- struct mutex reg_mutex;
-+
-+ struct net_device *bridge_dev[MT7530_NUM_PORTS];
- };
-
- struct mt7530_hw_stats {
---- a/net/dsa/tag_mtk.c
-+++ b/net/dsa/tag_mtk.c
-@@ -35,7 +35,7 @@ static struct sk_buff *mtk_tag_xmit(stru
- /* Build the tag after the MAC Source Address */
- mtk_tag = skb->data + 2 * ETH_ALEN;
- mtk_tag[0] = 0;
-- mtk_tag[1] = (1 << p->dp->index) & MTK_HDR_XMIT_DP_BIT_MASK;
-+ mtk_tag[1] = (1 << p->port) & MTK_HDR_XMIT_DP_BIT_MASK;
- mtk_tag[2] = 0;
- mtk_tag[3] = 0;
-
diff --git a/target/linux/mediatek/patches-4.9/0032-net-dsa-mediatek-add-support-for-GMAC2-wired-to-ext-.patch b/target/linux/mediatek/patches-4.9/0032-net-dsa-mediatek-add-support-for-GMAC2-wired-to-ext-.patch
deleted file mode 100644
index 6c96b067dc..0000000000
--- a/target/linux/mediatek/patches-4.9/0032-net-dsa-mediatek-add-support-for-GMAC2-wired-to-ext-.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 52e9ce30a2b3c414e0efb20632fefa7cfc5096e6 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 14:44:18 +0200
-Subject: [PATCH 32/57] net: dsa: mediatek: add support for GMAC2 wired to ext
- phy
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/dsa/mt7530.c | 5 +++++
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +++
- 2 files changed, 8 insertions(+)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -629,6 +629,11 @@ mt7530_setup(struct dsa_switch *ds)
- val = mt7530_read(priv, MT7530_MHWTRAP);
- val &= ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS;
- val |= MHWTRAP_MANUAL;
-+ if (!dsa_is_cpu_port(ds, 5)) {
-+ val |= MHWTRAP_P5_DIS;
-+ val |= MHWTRAP_P5_MAC_SEL;
-+ val |= MHWTRAP_P5_RGMII_MODE;
-+ }
- mt7530_write(priv, MT7530_MHWTRAP, val);
-
- /* Enable and reset MIB counters */
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -221,6 +221,9 @@ static void mtk_phy_link_adjust(struct n
- netif_carrier_on(dev);
- else
- netif_carrier_off(dev);
-+
-+ if (!of_phy_is_fixed_link(mac->of_node))
-+ phy_print_status(dev->phydev);
- }
-
- static int mtk_phy_connect_node(struct mtk_eth *eth, struct mtk_mac *mac,
diff --git a/target/linux/mediatek/patches-4.9/0033-net-dsa-add-multi-gmac-support.patch b/target/linux/mediatek/patches-4.9/0033-net-dsa-add-multi-gmac-support.patch
deleted file mode 100644
index 8ff2bed8c1..0000000000
--- a/target/linux/mediatek/patches-4.9/0033-net-dsa-add-multi-gmac-support.patch
+++ /dev/null
@@ -1,272 +0,0 @@
-From cce5dd6034ed1651ee25c910edee708e6b84a44a Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 14:45:08 +0200
-Subject: [PATCH 33/57] net: dsa: add multi gmac support
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/dsa/mt7530.c | 10 +---------
- include/net/dsa.h | 21 ++++++++++++++++++++-
- net/dsa/dsa2.c | 40 +++++++++++++++++++++++++++++++++-------
- net/dsa/dsa_priv.h | 1 +
- net/dsa/slave.c | 26 ++++++++++++++++----------
- 5 files changed, 71 insertions(+), 27 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -996,15 +996,7 @@ err:
- static enum dsa_tag_protocol
- mtk_get_tag_protocol(struct dsa_switch *ds)
- {
-- struct mt7530_priv *priv = ds->priv;
--
-- if (!dsa_is_cpu_port(ds, MT7530_CPU_PORT)) {
-- dev_warn(priv->dev,
-- "port not matched with tagging CPU port\n");
-- return DSA_TAG_PROTO_NONE;
-- } else {
-- return DSA_TAG_PROTO_MTK;
-- }
-+ return DSA_TAG_PROTO_MTK;
- }
-
- static struct dsa_switch_ops mt7530_switch_ops = {
---- a/include/net/dsa.h
-+++ b/include/net/dsa.h
-@@ -145,6 +145,8 @@ struct dsa_port {
- struct device_node *dn;
- unsigned int ageing_time;
- u8 stp_state;
-+ struct net_device *ethernet;
-+ int upstream;
- };
-
- struct dsa_switch {
-@@ -205,7 +207,7 @@ struct dsa_switch {
-
- static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p)
- {
-- return !!(ds->index == ds->dst->cpu_switch && p == ds->dst->cpu_port);
-+ return !!(ds->cpu_port_mask & (1 << p));
- }
-
- static inline bool dsa_is_dsa_port(struct dsa_switch *ds, int p)
-@@ -218,6 +220,11 @@ static inline bool dsa_is_port_initializ
- return ds->enabled_port_mask & (1 << p) && ds->ports[p].netdev;
- }
-
-+static inline bool dsa_is_upstream_port(struct dsa_switch *ds, int p)
-+{
-+ return dsa_is_cpu_port(ds, p) || dsa_is_dsa_port(ds, p);
-+}
-+
- static inline u8 dsa_upstream_port(struct dsa_switch *ds)
- {
- struct dsa_switch_tree *dst = ds->dst;
-@@ -234,6 +241,18 @@ static inline u8 dsa_upstream_port(struc
- return ds->rtable[dst->cpu_switch];
- }
-
-+static inline u8 dsa_port_upstream_port(struct dsa_switch *ds, int port)
-+{
-+ /*
-+ * If this port has a specific upstream cpu port, use it,
-+ * otherwise use the switch default.
-+ */
-+ if (ds->ports[port].upstream)
-+ return ds->ports[port].upstream;
-+ else
-+ return dsa_upstream_port(ds);
-+}
-+
- struct switchdev_trans;
- struct switchdev_obj;
- struct switchdev_obj_port_fdb;
---- a/net/dsa/dsa2.c
-+++ b/net/dsa/dsa2.c
-@@ -248,8 +248,6 @@ static int dsa_cpu_port_apply(struct dev
- return err;
- }
-
-- ds->cpu_port_mask |= BIT(index);
--
- return 0;
- }
-
-@@ -259,6 +257,10 @@ static void dsa_cpu_port_unapply(struct
- dsa_cpu_dsa_destroy(port);
- ds->cpu_port_mask &= ~BIT(index);
-
-+ if (ds->ports[index].ethernet) {
-+ dev_put(ds->ports[index].ethernet);
-+ ds->ports[index].ethernet = NULL;
-+ }
- }
-
- static int dsa_user_port_apply(struct device_node *port, u32 index,
-@@ -479,6 +481,29 @@ static int dsa_cpu_parse(struct device_n
-
- dst->rcv = dst->tag_ops->rcv;
-
-+ dev_hold(ethernet_dev);
-+ ds->ports[index].ethernet = ethernet_dev;
-+ ds->cpu_port_mask |= BIT(index);
-+
-+ return 0;
-+}
-+
-+static int dsa_user_parse(struct device_node *port, u32 index,
-+ struct dsa_switch *ds)
-+{
-+ struct device_node *cpu_port;
-+ const unsigned int *cpu_port_reg;
-+ int cpu_port_index;
-+
-+ cpu_port = of_parse_phandle(port, "cpu", 0);
-+ if (cpu_port) {
-+ cpu_port_reg = of_get_property(cpu_port, "reg", NULL);
-+ if (!cpu_port_reg)
-+ return -EINVAL;
-+ cpu_port_index = be32_to_cpup(cpu_port_reg);
-+ ds->ports[index].upstream = cpu_port_index;
-+ }
-+
- return 0;
- }
-
-@@ -486,18 +511,19 @@ static int dsa_ds_parse(struct dsa_switc
- {
- struct device_node *port;
- u32 index;
-- int err;
-+ int err = 0;
-
- for (index = 0; index < DSA_MAX_PORTS; index++) {
- port = ds->ports[index].dn;
- if (!port)
- continue;
-
-- if (dsa_port_is_cpu(port)) {
-+ if (dsa_port_is_cpu(port))
- err = dsa_cpu_parse(port, index, dst, ds);
-- if (err)
-- return err;
-- }
-+ else if (!dsa_port_is_dsa(port))
-+ err = dsa_user_parse(port, index, ds);
-+ if (err)
-+ return err;
- }
-
- pr_info("DSA: switch %d %d parsed\n", dst->tree, ds->index);
---- a/net/dsa/dsa_priv.h
-+++ b/net/dsa/dsa_priv.h
-@@ -43,6 +43,7 @@ struct dsa_slave_priv {
- int old_duplex;
-
- struct net_device *bridge_dev;
-+ struct net_device *master;
- #ifdef CONFIG_NET_POLL_CONTROLLER
- struct netpoll *netpoll;
- #endif
---- a/net/dsa/slave.c
-+++ b/net/dsa/slave.c
-@@ -61,7 +61,7 @@ static int dsa_slave_get_iflink(const st
- {
- struct dsa_slave_priv *p = netdev_priv(dev);
-
-- return p->parent->dst->master_netdev->ifindex;
-+ return p->master->ifindex;
- }
-
- static inline bool dsa_port_is_bridged(struct dsa_slave_priv *p)
-@@ -96,7 +96,7 @@ static void dsa_port_set_stp_state(struc
- static int dsa_slave_open(struct net_device *dev)
- {
- struct dsa_slave_priv *p = netdev_priv(dev);
-- struct net_device *master = p->parent->dst->master_netdev;
-+ struct net_device *master = p->master;
- struct dsa_switch *ds = p->parent;
- u8 stp_state = dsa_port_is_bridged(p) ?
- BR_STATE_BLOCKING : BR_STATE_FORWARDING;
-@@ -151,7 +151,7 @@ out:
- static int dsa_slave_close(struct net_device *dev)
- {
- struct dsa_slave_priv *p = netdev_priv(dev);
-- struct net_device *master = p->parent->dst->master_netdev;
-+ struct net_device *master = p->master;
- struct dsa_switch *ds = p->parent;
-
- if (p->phy)
-@@ -178,7 +178,7 @@ static int dsa_slave_close(struct net_de
- static void dsa_slave_change_rx_flags(struct net_device *dev, int change)
- {
- struct dsa_slave_priv *p = netdev_priv(dev);
-- struct net_device *master = p->parent->dst->master_netdev;
-+ struct net_device *master = p->master;
-
- if (change & IFF_ALLMULTI)
- dev_set_allmulti(master, dev->flags & IFF_ALLMULTI ? 1 : -1);
-@@ -189,7 +189,7 @@ static void dsa_slave_change_rx_flags(st
- static void dsa_slave_set_rx_mode(struct net_device *dev)
- {
- struct dsa_slave_priv *p = netdev_priv(dev);
-- struct net_device *master = p->parent->dst->master_netdev;
-+ struct net_device *master = p->master;
-
- dev_mc_sync(master, dev);
- dev_uc_sync(master, dev);
-@@ -198,7 +198,7 @@ static void dsa_slave_set_rx_mode(struct
- static int dsa_slave_set_mac_address(struct net_device *dev, void *a)
- {
- struct dsa_slave_priv *p = netdev_priv(dev);
-- struct net_device *master = p->parent->dst->master_netdev;
-+ struct net_device *master = p->master;
- struct sockaddr *addr = a;
- int err;
-
-@@ -633,7 +633,7 @@ static netdev_tx_t dsa_slave_xmit(struct
- /* Queue the SKB for transmission on the parent interface, but
- * do not modify its EtherType
- */
-- nskb->dev = p->parent->dst->master_netdev;
-+ nskb->dev = p->master;
- dev_queue_xmit(nskb);
-
- return NETDEV_TX_OK;
-@@ -945,7 +945,7 @@ static int dsa_slave_netpoll_setup(struc
- {
- struct dsa_slave_priv *p = netdev_priv(dev);
- struct dsa_switch *ds = p->parent;
-- struct net_device *master = ds->dst->master_netdev;
-+ struct net_device *master = p->master;
- struct netpoll *netpoll;
- int err = 0;
-
-@@ -1233,11 +1233,16 @@ int dsa_slave_create(struct dsa_switch *
- struct net_device *master;
- struct net_device *slave_dev;
- struct dsa_slave_priv *p;
-+ int port_cpu = ds->ports[port].upstream;
- int ret;
-
-- master = ds->dst->master_netdev;
-- if (ds->master_netdev)
-+ if (port_cpu && ds->ports[port_cpu].ethernet)
-+ master = ds->ports[port_cpu].ethernet;
-+ else if (ds->master_netdev)
- master = ds->master_netdev;
-+ else
-+ master = ds->dst->master_netdev;
-+ master->dsa_ptr = (void *)ds->dst;
-
- slave_dev = alloc_netdev(sizeof(struct dsa_slave_priv), name,
- NET_NAME_UNKNOWN, ether_setup);
-@@ -1263,6 +1268,7 @@ int dsa_slave_create(struct dsa_switch *
- p->parent = ds;
- p->port = port;
- p->xmit = dst->tag_ops->xmit;
-+ p->master = master;
-
- p->old_pause = -1;
- p->old_link = -1;
diff --git a/target/linux/mediatek/patches-4.9/0034-net-dsa-mediatek-add-dual-gmac-support.patch b/target/linux/mediatek/patches-4.9/0034-net-dsa-mediatek-add-dual-gmac-support.patch
deleted file mode 100644
index ae0614681f..0000000000
--- a/target/linux/mediatek/patches-4.9/0034-net-dsa-mediatek-add-dual-gmac-support.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-From dcb751a52b2ee69c16db2fef8f92a96ab13b6bb4 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 14:45:34 +0200
-Subject: [PATCH 34/57] net: dsa: mediatek: add dual gmac support
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/dsa/mt7530.c | 22 ++++++++++++++++------
- 1 file changed, 16 insertions(+), 6 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -627,7 +627,7 @@ mt7530_setup(struct dsa_switch *ds)
-
- /* Enable Port 6 only; P5 as GMAC5 which currently is not supported */
- val = mt7530_read(priv, MT7530_MHWTRAP);
-- val &= ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS;
-+ val &= ~MHWTRAP_P5_DIS & ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS;
- val |= MHWTRAP_MANUAL;
- if (!dsa_is_cpu_port(ds, 5)) {
- val |= MHWTRAP_P5_DIS;
-@@ -735,6 +735,9 @@ static int
- mt7530_cpu_port_enable(struct mt7530_priv *priv,
- int port)
- {
-+ u8 port_mask = 0;
-+ int i;
-+
- /* Enable Mediatek header mode on the cpu port */
- mt7530_write(priv, MT7530_PVC_P(port),
- PORT_SPEC_TAG);
-@@ -751,8 +754,12 @@ mt7530_cpu_port_enable(struct mt7530_pri
- /* CPU port gets connected to all user ports of
- * the switch
- */
-+ for (i = 0; i < MT7530_NUM_PORTS; i++)
-+ if ((priv->ds->enabled_port_mask & BIT(i)) &&
-+ (dsa_port_upstream_port(priv->ds, i) == port))
-+ port_mask |= BIT(i);
- mt7530_write(priv, MT7530_PCR_P(port),
-- PCR_MATRIX(priv->ds->enabled_port_mask));
-+ PCR_MATRIX(port_mask));
-
- return 0;
- }
-@@ -762,6 +769,7 @@ mt7530_port_enable(struct dsa_switch *ds
- struct phy_device *phy)
- {
- struct mt7530_priv *priv = ds->priv;
-+ u8 upstream = dsa_port_upstream_port(ds, port);
-
- mutex_lock(&priv->reg_mutex);
-
-@@ -772,7 +780,7 @@ mt7530_port_enable(struct dsa_switch *ds
- * restore the port matrix if the port is the member of a certain
- * bridge.
- */
-- priv->ports[port].pm |= PCR_MATRIX(BIT(MT7530_CPU_PORT));
-+ priv->ports[port].pm |= PCR_MATRIX(BIT(upstream));
- priv->ports[port].enable = true;
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
- priv->ports[port].pm);
-@@ -835,7 +843,8 @@ mt7530_port_bridge_join(struct dsa_switc
- struct net_device *bridge)
- {
- struct mt7530_priv *priv = ds->priv;
-- u32 port_bitmap = BIT(MT7530_CPU_PORT);
-+ u8 upstream = dsa_port_upstream_port(ds, port);
-+ u32 port_bitmap = BIT(upstream);
- int i;
-
- mutex_lock(&priv->reg_mutex);
-@@ -873,6 +882,7 @@ static void
- mt7530_port_bridge_leave(struct dsa_switch *ds, int port)
- {
- struct mt7530_priv *priv = ds->priv;
-+ u8 upstream = dsa_port_upstream_port(ds, port);
- int i;
-
- mutex_lock(&priv->reg_mutex);
-@@ -898,8 +908,8 @@ mt7530_port_bridge_leave(struct dsa_swit
- priv->bridge_dev[port] = NULL;
- if (priv->ports[port].enable)
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
-- PCR_MATRIX(BIT(MT7530_CPU_PORT)));
-- priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT));
-+ PCR_MATRIX(BIT(upstream)));
-+ priv->ports[port].pm = PCR_MATRIX(BIT(upstream));
-
- mutex_unlock(&priv->reg_mutex);
- }
diff --git a/target/linux/mediatek/patches-4.9/0035-net-mediatek-disable-RX-VLan-offloading.patch b/target/linux/mediatek/patches-4.9/0035-net-mediatek-disable-RX-VLan-offloading.patch
deleted file mode 100644
index 36321c55cf..0000000000
--- a/target/linux/mediatek/patches-4.9/0035-net-mediatek-disable-RX-VLan-offloading.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 35b83b85e752a6660b92f08c0fb912308f25cf6d Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 15:56:40 +0200
-Subject: [PATCH 35/57] net: mediatek: disable RX VLan offloading
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 9 ++++++---
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 --
- 2 files changed, 6 insertions(+), 5 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -643,8 +643,8 @@ static int mtk_tx_map(struct sk_buff *sk
- txd4 |= TX_DMA_CHKSUM;
-
- /* VLAN header offload */
-- if (skb_vlan_tag_present(skb))
-- txd4 |= TX_DMA_INS_VLAN | skb_vlan_tag_get(skb);
-+// if (skb_vlan_tag_present(skb))
-+// txd4 |= TX_DMA_INS_VLAN | skb_vlan_tag_get(skb);
-
- mapped_addr = dma_map_single(eth->dev, skb->data,
- skb_headlen(skb), DMA_TO_DEVICE);
-@@ -1874,7 +1874,10 @@ static int mtk_hw_init(struct mtk_eth *e
- mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
-
- /* Enable RX VLan Offloading */
-- mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
-+ if (MTK_HW_FEATURES & NETIF_F_HW_VLAN_CTAG_RX)
-+ mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
-+ else
-+ mtk_w32(eth, 0, MTK_CDMP_EG_CTRL);
-
- /* disable delay and normal interrupt */
- mtk_w32(eth, 0, MTK_QDMA_DELAY_INT);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -34,8 +34,6 @@
- NETIF_MSG_TX_ERR)
- #define MTK_HW_FEATURES (NETIF_F_IP_CSUM | \
- NETIF_F_RXCSUM | \
-- NETIF_F_HW_VLAN_CTAG_TX | \
-- NETIF_F_HW_VLAN_CTAG_RX | \
- NETIF_F_SG | NETIF_F_TSO | \
- NETIF_F_TSO6 | \
- NETIF_F_IPV6_CSUM)
diff --git a/target/linux/mediatek/patches-4.9/0036-net-next-mediatek-fix-typos-inside-the-header-file.patch b/target/linux/mediatek/patches-4.9/0036-net-next-mediatek-fix-typos-inside-the-header-file.patch
deleted file mode 100644
index e96374fdd1..0000000000
--- a/target/linux/mediatek/patches-4.9/0036-net-next-mediatek-fix-typos-inside-the-header-file.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From bf25fbdc7dfb256f267725336e29e232aadd5123 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Fri, 21 Jul 2017 08:43:58 +0200
-Subject: [PATCH 36/57] net-next: mediatek: fix typos inside the header file
-
-Trivial patch fixing 2 typos.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -525,8 +525,8 @@ struct mtk_rx_ring {
- * @pctl: The register map pointing at the range used to setup
- * GMAC port drive/slew values
- * @dma_refcnt: track how many netdevs are using the DMA engine
-- * @tx_ring: Pointer to the memore holding info about the TX ring
-- * @rx_ring: Pointer to the memore holding info about the RX ring
-+ * @tx_ring: Pointer to the memory holding info about the TX ring
-+ * @rx_ring: Pointer to the memory holding info about the RX ring
- * @tx_napi: The TX NAPI struct
- * @rx_napi: The RX NAPI struct
- * @scratch_ring: Newer SoCs need memory for a second HW managed TX ring
diff --git a/target/linux/mediatek/patches-4.9/0037-net-next-mediatek-bring-up-QDMA-RX-ring-0.patch b/target/linux/mediatek/patches-4.9/0037-net-next-mediatek-bring-up-QDMA-RX-ring-0.patch
deleted file mode 100644
index 9d6a089c5e..0000000000
--- a/target/linux/mediatek/patches-4.9/0037-net-next-mediatek-bring-up-QDMA-RX-ring-0.patch
+++ /dev/null
@@ -1,128 +0,0 @@
-From 047a4e7b17322c1b32d8db32a0df9899cb4963a3 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Fri, 21 Jul 2017 08:48:38 +0200
-Subject: [PATCH 37/57] net-next: mediatek: bring up QDMA RX ring 0
-
-This patch is in peparation for adding HW flow and QoS offloading. For
-those features to work, the driver needs to bring up the first QDMA RX
-ring. This ring is used by the PPE offloading HW.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 38 ++++++++++++++++++++---------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 3 +++
- 2 files changed, 30 insertions(+), 11 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1224,11 +1224,21 @@ static void mtk_tx_clean(struct mtk_eth
-
- static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
- {
-- struct mtk_rx_ring *ring = &eth->rx_ring[ring_no];
-+ struct mtk_rx_ring *ring;
- int rx_data_len, rx_dma_size;
- int i;
-+ u32 offset = 0;
-
-- if (rx_flag == MTK_RX_FLAGS_HWLRO) {
-+ if (rx_flag & MTK_RX_FLAGS_QDMA) {
-+ if (ring_no)
-+ return -EINVAL;
-+ ring = &eth->rx_ring_qdma;
-+ offset = 0x1000;
-+ } else {
-+ ring = &eth->rx_ring[ring_no];
-+ }
-+
-+ if (rx_flag & MTK_RX_FLAGS_HWLRO) {
- rx_data_len = MTK_MAX_LRO_RX_LENGTH;
- rx_dma_size = MTK_HW_LRO_DMA_SIZE;
- } else {
-@@ -1276,17 +1286,16 @@ static int mtk_rx_alloc(struct mtk_eth *
- */
- wmb();
-
-- mtk_w32(eth, ring->phys, MTK_PRX_BASE_PTR_CFG(ring_no));
-- mtk_w32(eth, rx_dma_size, MTK_PRX_MAX_CNT_CFG(ring_no));
-- mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg);
-- mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), MTK_PDMA_RST_IDX);
-+ mtk_w32(eth, ring->phys, MTK_PRX_BASE_PTR_CFG(ring_no) + offset);
-+ mtk_w32(eth, rx_dma_size, MTK_PRX_MAX_CNT_CFG(ring_no) + offset);
-+ mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg + offset);
-+ mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), MTK_PDMA_RST_IDX + offset);
-
- return 0;
- }
-
--static void mtk_rx_clean(struct mtk_eth *eth, int ring_no)
-+static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring)
- {
-- struct mtk_rx_ring *ring = &eth->rx_ring[ring_no];
- int i;
-
- if (ring->data && ring->dma) {
-@@ -1612,6 +1621,10 @@ static int mtk_dma_init(struct mtk_eth *
- if (err)
- return err;
-
-+ err = mtk_rx_alloc(eth, 0, MTK_RX_FLAGS_QDMA);
-+ if (err)
-+ return err;
-+
- err = mtk_rx_alloc(eth, 0, MTK_RX_FLAGS_NORMAL);
- if (err)
- return err;
-@@ -1651,12 +1664,13 @@ static void mtk_dma_free(struct mtk_eth
- eth->phy_scratch_ring = 0;
- }
- mtk_tx_clean(eth);
-- mtk_rx_clean(eth, 0);
-+ mtk_rx_clean(eth, &eth->rx_ring[0]);
-+ mtk_rx_clean(eth, &eth->rx_ring_qdma);
-
- if (eth->hwlro) {
- mtk_hwlro_rx_uninit(eth);
- for (i = 1; i < MTK_MAX_RX_RING_NUM; i++)
-- mtk_rx_clean(eth, i);
-+ mtk_rx_clean(eth, &eth->rx_ring[i]);
- }
-
- kfree(eth->scratch_head);
-@@ -1723,7 +1737,9 @@ static int mtk_start_dma(struct mtk_eth
-
- mtk_w32(eth,
- MTK_TX_WB_DDONE | MTK_TX_DMA_EN |
-- MTK_DMA_SIZE_16DWORDS | MTK_NDP_CO_PRO,
-+ MTK_DMA_SIZE_16DWORDS | MTK_NDP_CO_PRO |
-+ MTK_RX_DMA_EN | MTK_RX_2B_OFFSET |
-+ MTK_RX_BT_32DWORDS,
- MTK_QDMA_GLO_CFG);
-
- mtk_w32(eth,
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -484,6 +484,7 @@ struct mtk_tx_ring {
- enum mtk_rx_flags {
- MTK_RX_FLAGS_NORMAL = 0,
- MTK_RX_FLAGS_HWLRO,
-+ MTK_RX_FLAGS_QDMA,
- };
-
- /* struct mtk_rx_ring - This struct holds info describing a RX ring
-@@ -527,6 +528,7 @@ struct mtk_rx_ring {
- * @dma_refcnt: track how many netdevs are using the DMA engine
- * @tx_ring: Pointer to the memory holding info about the TX ring
- * @rx_ring: Pointer to the memory holding info about the RX ring
-+ * @rx_ring_qdma: Pointer to the memory holding info about the QDMA RX ring
- * @tx_napi: The TX NAPI struct
- * @rx_napi: The RX NAPI struct
- * @scratch_ring: Newer SoCs need memory for a second HW managed TX ring
-@@ -556,6 +558,7 @@ struct mtk_eth {
- atomic_t dma_refcnt;
- struct mtk_tx_ring tx_ring;
- struct mtk_rx_ring rx_ring[MTK_MAX_RX_RING_NUM];
-+ struct mtk_rx_ring rx_ring_qdma;
- struct napi_struct tx_napi;
- struct napi_struct rx_napi;
- struct mtk_tx_dma *scratch_ring;
diff --git a/target/linux/mediatek/patches-4.9/0038-net-next-dsa-move-struct-dsa_device_ops-to-the-globa.patch b/target/linux/mediatek/patches-4.9/0038-net-next-dsa-move-struct-dsa_device_ops-to-the-globa.patch
deleted file mode 100644
index cb1c1b9e97..0000000000
--- a/target/linux/mediatek/patches-4.9/0038-net-next-dsa-move-struct-dsa_device_ops-to-the-globa.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From b58bf0220f666705e63fe8d361f37c913aee2d8f Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Fri, 21 Jul 2017 09:32:54 +0200
-Subject: [PATCH 38/57] net-next: dsa: move struct dsa_device_ops to the global
- header file
-
-We need to access this struct from within the flow_dissector to fix
-dissection for packets coming in on DSA devices.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- include/net/dsa.h | 7 +++++++
- net/dsa/dsa_priv.h | 6 ------
- 2 files changed, 7 insertions(+), 6 deletions(-)
-
---- a/include/net/dsa.h
-+++ b/include/net/dsa.h
-@@ -88,6 +88,13 @@ struct dsa_platform_data {
-
- struct packet_type;
-
-+struct dsa_device_ops {
-+ struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev);
-+ int sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev,
-+ struct packet_type *pt,
-+ struct net_device *orig_dev);
-+};
-+
- struct dsa_switch_tree {
- struct list_head list;
-
---- a/net/dsa/dsa_priv.h
-+++ b/net/dsa/dsa_priv.h
-@@ -15,12 +15,6 @@
- #include <linux/netdevice.h>
- #include <linux/netpoll.h>
-
--struct dsa_device_ops {
-- struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev);
-- int (*rcv)(struct sk_buff *skb, struct net_device *dev,
-- struct packet_type *pt, struct net_device *orig_dev);
--};
--
- struct dsa_slave_priv {
- struct sk_buff * (*xmit)(struct sk_buff *skb,
- struct net_device *dev);
diff --git a/target/linux/mediatek/patches-4.9/0039-net-next-dsa-add-flow_dissect-callback-to-struct-dsa.patch b/target/linux/mediatek/patches-4.9/0039-net-next-dsa-add-flow_dissect-callback-to-struct-dsa.patch
deleted file mode 100644
index ebc52c83fe..0000000000
--- a/target/linux/mediatek/patches-4.9/0039-net-next-dsa-add-flow_dissect-callback-to-struct-dsa.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 22e8b65ea4bf8a1fa757137bdcbdefe505fa4044 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Mon, 7 Aug 2017 16:35:43 +0200
-Subject: [PATCH 39/57] net-next: dsa: add flow_dissect callback to struct
- dsa_device_ops
-
-When the flow dissector first sees packets coming in on a DSA devices the
-802.3 header wont be located where the code expects it to be as the tag
-is still present. Adding this new callback allows a DSA device to provide a
-new function that the flow_disscetor can use to get the correct offsets
-for the protocol field and network header offset.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- include/net/dsa.h | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
---- a/include/net/dsa.h
-+++ b/include/net/dsa.h
-@@ -90,9 +90,11 @@ struct packet_type;
-
- struct dsa_device_ops {
- struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev);
-- int sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev,
-+ int (*rcv)(struct sk_buff *skb, struct net_device *dev,
- struct packet_type *pt,
- struct net_device *orig_dev);
-+ int (*flow_dissect)(const struct sk_buff *skb, __be16 *proto,
-+ int *offset);
- };
-
- struct dsa_switch_tree {
diff --git a/target/linux/mediatek/patches-4.9/0040-net-next-tag_mtk-add-flow_dissect-callback-to-the-op.patch b/target/linux/mediatek/patches-4.9/0040-net-next-tag_mtk-add-flow_dissect-callback-to-the-op.patch
deleted file mode 100644
index da98a21380..0000000000
--- a/target/linux/mediatek/patches-4.9/0040-net-next-tag_mtk-add-flow_dissect-callback-to-the-op.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 9d6806e16e5ea68a49225da1ab065ef0b5d7704b Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Mon, 7 Aug 2017 16:55:56 +0200
-Subject: [PATCH 40/57] net-next: tag_mtk: add flow_dissect callback to the ops
- struct
-
-The MT7530 inserts the 4 magic header in between the 802.3 address and
-protocol field. The patch implements the callback that can be called by
-the flow dissector to figure out the real protocol and offset of the
-network header. With this patch applied we can properly parse the packet
-and thus make hashing function properly.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- net/dsa/tag_mtk.c | 14 ++++++++++++--
- 1 file changed, 12 insertions(+), 2 deletions(-)
-
---- a/net/dsa/tag_mtk.c
-+++ b/net/dsa/tag_mtk.c
-@@ -111,7 +111,17 @@ out:
- return 0;
- }
-
-+static int mtk_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
-+ int *offset)
-+{
-+ *offset = 4;
-+ *proto = ((__be16 *)skb->data)[1];
-+
-+ return 0;
-+}
-+
- const struct dsa_device_ops mtk_netdev_ops = {
-- .xmit = mtk_tag_xmit,
-- .rcv = mtk_tag_rcv,
-+ .xmit = mtk_tag_xmit,
-+ .rcv = mtk_tag_rcv,
-+ .flow_dissect = mtk_tag_flow_dissect,
- };
diff --git a/target/linux/mediatek/patches-4.9/0041-net-next-dsa-fix-flow-dissection.patch b/target/linux/mediatek/patches-4.9/0041-net-next-dsa-fix-flow-dissection.patch
deleted file mode 100644
index 54359623e2..0000000000
--- a/target/linux/mediatek/patches-4.9/0041-net-next-dsa-fix-flow-dissection.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 04c825484d6ecdcc8ce09b350235c9077eaca6e3 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Wed, 9 Aug 2017 08:20:21 +0200
-Subject: [PATCH 41/57] net-next: dsa: fix flow dissection
-
-RPS and probably other kernel features are currently broken on some if not
-all DSA devices. The root cause of this is that skb_hash will call the
-flow_dissector. At this point the skb still contains the magic switch
-header and the skb->protocol field is not set up to the correct 802.3
-value yet. By the time the tag specific code is called, removing the header
-and =roperly setting the protocol an invalid hash is already set. In the
-case of the mt7530 this will result in all flows always having the same
-hash.
-
-This patch makes the flow dissector honour the nh and protocol offset
-defined by the dsa tag driver thus fixing dissection, hashing and RPS.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- net/core/flow_dissector.c | 14 +++++++++++++-
- 1 file changed, 13 insertions(+), 1 deletion(-)
-
---- a/net/core/flow_dissector.c
-+++ b/net/core/flow_dissector.c
-@@ -4,6 +4,7 @@
- #include <linux/ip.h>
- #include <linux/ipv6.h>
- #include <linux/if_vlan.h>
-+#include <net/dsa.h>
- #include <net/ip.h>
- #include <net/ipv6.h>
- #include <net/gre.h>
-@@ -123,13 +124,23 @@ bool __skb_flow_dissect(const struct sk_
- bool skip_vlan = false;
- u8 ip_proto = 0;
- bool ret;
--
- if (!data) {
- data = skb->data;
- proto = skb_vlan_tag_present(skb) ?
- skb->vlan_proto : skb->protocol;
- nhoff = skb_network_offset(skb);
- hlen = skb_headlen(skb);
-+ if (unlikely(netdev_uses_dsa(skb->dev))) {
-+ const struct dsa_device_ops *ops;
-+ int offset;
-+
-+ ops = skb->dev->dsa_ptr->tag_ops;
-+ if (ops->flow_dissect &&
-+ !ops->flow_dissect(skb, &proto, &offset)) {
-+ hlen -= offset;
-+ nhoff += offset;
-+ }
-+ }
- }
-
- /* It is ensured by skb_flow_dissector_init() that control key will
-@@ -162,6 +173,7 @@ again:
- case htons(ETH_P_IP): {
- const struct iphdr *iph;
- struct iphdr _iph;
-+
- ip:
- iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
- if (!iph || iph->ihl < 5)
diff --git a/target/linux/mediatek/patches-4.9/0042-net-next-mediatek-honour-special-tag-bit-inside-RX-D.patch b/target/linux/mediatek/patches-4.9/0042-net-next-mediatek-honour-special-tag-bit-inside-RX-D.patch
deleted file mode 100644
index 4f2c7b2e6e..0000000000
--- a/target/linux/mediatek/patches-4.9/0042-net-next-mediatek-honour-special-tag-bit-inside-RX-D.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From a306af3b97c56b9e224a2f9ee04838a2d32ff60b Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Wed, 9 Aug 2017 14:44:07 +0200
-Subject: [PATCH 42/57] net-next: mediatek: honour special tag bit inside RX
- DMA descriptor
-
-For HW NAT/QoS to work the DSA driver needs to turn the special tag bit
-inside the ingress control register on. This has the side effect that
-the code working out which ingress gmac we have breaks. Fix this by
-honouring the special tag bit inside the RX free descriptor.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 14 ++++++++++----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 +
- 2 files changed, 11 insertions(+), 4 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -933,10 +933,16 @@ static int mtk_poll_rx(struct napi_struc
- if (!(trxd.rxd2 & RX_DMA_DONE))
- break;
-
-- /* find out which mac the packet come from. values start at 1 */
-- mac = (trxd.rxd4 >> RX_DMA_FPORT_SHIFT) &
-- RX_DMA_FPORT_MASK;
-- mac--;
-+ /* find out which mac the packet comes from. If the special tag is
-+ * we can assume that the traffic is coming from the builtin mt7530
-+ * and the DSA driver has loaded. FPORT will be the physical switch
-+ * port in this case rather than the FE forward port id. */
-+ if (!(trxd.rxd4 & RX_DMA_SP_TAG)) {
-+ /* values start at 1 */
-+ mac = (trxd.rxd4 >> RX_DMA_FPORT_SHIFT) &
-+ RX_DMA_FPORT_MASK;
-+ mac--;
-+ }
-
- netdev = eth->netdev[mac];
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -284,6 +284,7 @@
-
- /* QDMA descriptor rxd4 */
- #define RX_DMA_L4_VALID BIT(24)
-+#define RX_DMA_SP_TAG BIT(22)
- #define RX_DMA_FPORT_SHIFT 19
- #define RX_DMA_FPORT_MASK 0x7
-
diff --git a/target/linux/mediatek/patches-4.9/0043-net-next-mediatek-enable-special-tag-indication-for-.patch b/target/linux/mediatek/patches-4.9/0043-net-next-mediatek-enable-special-tag-indication-for-.patch
deleted file mode 100644
index 2256325c9c..0000000000
--- a/target/linux/mediatek/patches-4.9/0043-net-next-mediatek-enable-special-tag-indication-for-.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 53e3d9af39805a7e1ba81a047a9ab433be0e82f5 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Wed, 9 Aug 2017 14:56:53 +0200
-Subject: [PATCH 43/57] net-next: mediatek: enable special tag indication for
- PDMA
-
-The Ingress special tag indication was only enabled for QDMA and not PDMA.
-Properly initialize the STAG bit. This broke HW NAT and Qos from working
-for traffic coming in via a DSA device. The PPE failed to properly parse
-the traffic as it was not expecting the special tag.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 ++
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++++
- 2 files changed, 6 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1894,6 +1894,8 @@ static int mtk_hw_init(struct mtk_eth *e
- */
- val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
- mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
-+ val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
-+ mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
-
- /* Enable RX VLan Offloading */
- if (MTK_HW_FEATURES & NETIF_F_HW_VLAN_CTAG_RX)
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -76,6 +76,10 @@
- #define MTK_CDMQ_IG_CTRL 0x1400
- #define MTK_CDMQ_STAG_EN BIT(0)
-
-+/* CDMP Ingress Control Register */
-+#define MTK_CDMP_IG_CTRL 0x400
-+#define MTK_CDMP_STAG_EN BIT(0)
-+
- /* CDMP Exgress Control Register */
- #define MTK_CDMP_EG_CTRL 0x404
-
diff --git a/target/linux/mediatek/patches-4.9/0044-net-next-dsa-mediatek-tell-GDMA-when-we-are-turning-.patch b/target/linux/mediatek/patches-4.9/0044-net-next-dsa-mediatek-tell-GDMA-when-we-are-turning-.patch
deleted file mode 100644
index 51204d4001..0000000000
--- a/target/linux/mediatek/patches-4.9/0044-net-next-dsa-mediatek-tell-GDMA-when-we-are-turning-.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 6a5932028a4f3217ed7c9d602f269611d95dd8ca Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Wed, 9 Aug 2017 15:13:19 +0200
-Subject: [PATCH 44/57] net-next: dsa: mediatek: tell GDMA when we are turning
- on the special tag
-
-Enabling this bit will make the RX DMA descriptor enable the SP bit for all
-ingress traffic inside the return descriptor. The PPE needs this to know
-that a SP is present.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/dsa/mt7530.c | 5 +++++
- drivers/net/dsa/mt7530.h | 4 ++++
- 2 files changed, 9 insertions(+)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -742,6 +742,11 @@ mt7530_cpu_port_enable(struct mt7530_pri
- mt7530_write(priv, MT7530_PVC_P(port),
- PORT_SPEC_TAG);
-
-+ /* Enable Mediatek header mode on the GMAC that the cpu port
-+ * connects to */
-+ regmap_write_bits(priv->ethernet, MTK_GDMA_FWD_CFG(port),
-+ GDMA_SPEC_TAG, GDMA_SPEC_TAG);
-+
- /* Setup the MAC by default for the cpu port */
- mt7530_write(priv, MT7530_PMCR_P(port), PMCR_CPUP_LINK);
-
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -22,6 +22,10 @@
-
- #define TRGMII_BASE(x) (0x10000 + (x))
-
-+/* Registers for GDMA configuration access */
-+#define MTK_GDMA_FWD_CFG(x) (0x500 + (x * 0x1000))
-+#define GDMA_SPEC_TAG BIT(24)
-+
- /* Registers to ethsys access */
- #define ETHSYS_CLKCFG0 0x2c
- #define ETHSYS_TRGMII_CLK_SEL362_5 BIT(11)
diff --git a/target/linux/mediatek/patches-4.9/0045-net-dsa-mediatek-turn-into-platform-driver.patch b/target/linux/mediatek/patches-4.9/0045-net-dsa-mediatek-turn-into-platform-driver.patch
deleted file mode 100644
index c263b07952..0000000000
--- a/target/linux/mediatek/patches-4.9/0045-net-dsa-mediatek-turn-into-platform-driver.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From 1e33784f665cb95c2af5481d3e776d2d3099921b Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 15:57:17 +0200
-Subject: [PATCH 45/57] net: dsa: mediatek: turn into platform driver
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/dsa/mt7530.c | 23 +++++++++++++++--------
- 1 file changed, 15 insertions(+), 8 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -1035,10 +1035,10 @@ static struct dsa_switch_ops mt7530_swit
- };
-
- static int
--mt7530_probe(struct mdio_device *mdiodev)
-+mt7530_probe(struct platform_device *mdiodev)
- {
- struct mt7530_priv *priv;
-- struct device_node *dn;
-+ struct device_node *dn, *mdio;
-
- dn = mdiodev->dev.of_node;
-
-@@ -1086,7 +1086,12 @@ mt7530_probe(struct mdio_device *mdiodev
- }
- }
-
-- priv->bus = mdiodev->bus;
-+ mdio = of_parse_phandle(dn, "dsa,mii-bus", 0);
-+ if (!mdio)
-+ return -EINVAL;
-+ priv->bus = of_mdio_find_bus(mdio);
-+ if (!priv->bus)
-+ return -EPROBE_DEFER;
- priv->dev = &mdiodev->dev;
- priv->ds->priv = priv;
- priv->ds->dev = &mdiodev->dev;
-@@ -1098,8 +1103,8 @@ mt7530_probe(struct mdio_device *mdiodev
- return dsa_register_switch(priv->ds, priv->ds->dev->of_node);
- }
-
--static void
--mt7530_remove(struct mdio_device *mdiodev)
-+static int
-+mt7530_remove(struct platform_device *mdiodev)
- {
- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
- int ret = 0;
-@@ -1116,6 +1121,8 @@ mt7530_remove(struct mdio_device *mdiode
-
- dsa_unregister_switch(priv->ds);
- mutex_destroy(&priv->reg_mutex);
-+
-+ return 0;
- }
-
- static const struct of_device_id mt7530_of_match[] = {
-@@ -1123,16 +1130,16 @@ static const struct of_device_id mt7530_
- { /* sentinel */ },
- };
-
--static struct mdio_driver mt7530_mdio_driver = {
-+static struct platform_driver mtk_mt7530_driver = {
- .probe = mt7530_probe,
- .remove = mt7530_remove,
-- .mdiodrv.driver = {
-+ .driver = {
- .name = "mt7530",
- .of_match_table = mt7530_of_match,
- },
- };
-+module_platform_driver(mtk_mt7530_driver);
-
--mdio_module_driver(mt7530_mdio_driver);
-
- MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
- MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch");
diff --git a/target/linux/mediatek/patches-4.9/0046-net-mediatek-add-irq-delay.patch b/target/linux/mediatek/patches-4.9/0046-net-mediatek-add-irq-delay.patch
deleted file mode 100644
index 47c3980a6c..0000000000
--- a/target/linux/mediatek/patches-4.9/0046-net-mediatek-add-irq-delay.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From 6e081074df96bf3762c2e6438c383f11a56b0a7e Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 15:58:04 +0200
-Subject: [PATCH 46/57] net: mediatek: add irq delay
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 ++++++-
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +++++++-
- 2 files changed, 13 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1904,8 +1904,13 @@ static int mtk_hw_init(struct mtk_eth *e
- mtk_w32(eth, 0, MTK_CDMP_EG_CTRL);
-
- /* disable delay and normal interrupt */
-- mtk_w32(eth, 0, MTK_QDMA_DELAY_INT);
-+#ifdef MTK_IRQ_DLY
-+ mtk_w32(eth, 0x84048404, MTK_PDMA_DELAY_INT);
-+ mtk_w32(eth, 0x84048404, MTK_QDMA_DELAY_INT);
-+#else
- mtk_w32(eth, 0, MTK_PDMA_DELAY_INT);
-+ mtk_w32(eth, 0, MTK_QDMA_DELAY_INT);
-+#endif
- mtk_irq_disable(eth, MTK_QDMA_INT_MASK, ~0);
- mtk_irq_disable(eth, MTK_PDMA_INT_MASK, ~0);
- mtk_w32(eth, RST_GL_PSE, MTK_RST_GL);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -12,6 +12,8 @@
- * Copyright (C) 2013-2016 Michael Lee <igvtee@gmail.com>
- */
-
-+#define MTK_IRQ_DLY
-+
- #ifndef MTK_ETH_H
- #define MTK_ETH_H
-
-@@ -220,11 +222,15 @@
- #define MTK_TX_DONE_INT2 BIT(2)
- #define MTK_TX_DONE_INT1 BIT(1)
- #define MTK_TX_DONE_INT0 BIT(0)
-+#ifdef MTK_IRQ_DLY
-+#define MTK_RX_DONE_INT BIT(30)
-+#define MTK_TX_DONE_INT BIT(28)
-+#else
- #define MTK_RX_DONE_INT (MTK_RX_DONE_INT0 | MTK_RX_DONE_INT1 | \
- MTK_RX_DONE_INT2 | MTK_RX_DONE_INT3)
- #define MTK_TX_DONE_INT (MTK_TX_DONE_INT0 | MTK_TX_DONE_INT1 | \
- MTK_TX_DONE_INT2 | MTK_TX_DONE_INT3)
--
-+#endif
- /* QDMA Interrupt grouping registers */
- #define MTK_QDMA_INT_GRP1 0x1a20
- #define MTK_QDMA_INT_GRP2 0x1a24
diff --git a/target/linux/mediatek/patches-4.9/0047-net-next-mediatek-split-IRQ-register-locking-into-TX.patch b/target/linux/mediatek/patches-4.9/0047-net-next-mediatek-split-IRQ-register-locking-into-TX.patch
deleted file mode 100644
index 27a78a63b0..0000000000
--- a/target/linux/mediatek/patches-4.9/0047-net-next-mediatek-split-IRQ-register-locking-into-TX.patch
+++ /dev/null
@@ -1,208 +0,0 @@
-From 5afceece38fa30e3c71e7ed9ac62aa70ba8cfbb1 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Fri, 16 Jun 2017 10:00:30 +0200
-Subject: [PATCH 47/57] net-next: mediatek: split IRQ register locking into TX
- and RX
-
-Originally the driver only utilized the new QDMA engine. The current code
-still assumes this is the case when locking the IRQ mask register. Since
-RX now runs on the old style PDMA engine we can add a second lock. This
-patch reduces the IRQ latency as the TX and RX path no longer need to wait
-on each other under heavy load.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 79 ++++++++++++++++++-----------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 5 +-
- 2 files changed, 54 insertions(+), 30 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -372,28 +372,48 @@ static void mtk_mdio_cleanup(struct mtk_
- mdiobus_unregister(eth->mii_bus);
- }
-
--static inline void mtk_irq_disable(struct mtk_eth *eth,
-- unsigned reg, u32 mask)
-+static inline void mtk_tx_irq_disable(struct mtk_eth *eth, u32 mask)
- {
- unsigned long flags;
- u32 val;
-
-- spin_lock_irqsave(&eth->irq_lock, flags);
-- val = mtk_r32(eth, reg);
-- mtk_w32(eth, val & ~mask, reg);
-- spin_unlock_irqrestore(&eth->irq_lock, flags);
-+ spin_lock_irqsave(&eth->tx_irq_lock, flags);
-+ val = mtk_r32(eth, MTK_QDMA_INT_MASK);
-+ mtk_w32(eth, val & ~mask, MTK_QDMA_INT_MASK);
-+ spin_unlock_irqrestore(&eth->tx_irq_lock, flags);
- }
-
--static inline void mtk_irq_enable(struct mtk_eth *eth,
-- unsigned reg, u32 mask)
-+static inline void mtk_tx_irq_enable(struct mtk_eth *eth, u32 mask)
- {
- unsigned long flags;
- u32 val;
-
-- spin_lock_irqsave(&eth->irq_lock, flags);
-- val = mtk_r32(eth, reg);
-- mtk_w32(eth, val | mask, reg);
-- spin_unlock_irqrestore(&eth->irq_lock, flags);
-+ spin_lock_irqsave(&eth->tx_irq_lock, flags);
-+ val = mtk_r32(eth, MTK_QDMA_INT_MASK);
-+ mtk_w32(eth, val | mask, MTK_QDMA_INT_MASK);
-+ spin_unlock_irqrestore(&eth->tx_irq_lock, flags);
-+}
-+
-+static inline void mtk_rx_irq_disable(struct mtk_eth *eth, u32 mask)
-+{
-+ unsigned long flags;
-+ u32 val;
-+
-+ spin_lock_irqsave(&eth->rx_irq_lock, flags);
-+ val = mtk_r32(eth, MTK_PDMA_INT_MASK);
-+ mtk_w32(eth, val & ~mask, MTK_PDMA_INT_MASK);
-+ spin_unlock_irqrestore(&eth->rx_irq_lock, flags);
-+}
-+
-+static inline void mtk_rx_irq_enable(struct mtk_eth *eth, u32 mask)
-+{
-+ unsigned long flags;
-+ u32 val;
-+
-+ spin_lock_irqsave(&eth->rx_irq_lock, flags);
-+ val = mtk_r32(eth, MTK_PDMA_INT_MASK);
-+ mtk_w32(eth, val | mask, MTK_PDMA_INT_MASK);
-+ spin_unlock_irqrestore(&eth->rx_irq_lock, flags);
- }
-
- static int mtk_set_mac_address(struct net_device *dev, void *p)
-@@ -1116,7 +1136,7 @@ static int mtk_napi_tx(struct napi_struc
- return budget;
-
- napi_complete(napi);
-- mtk_irq_enable(eth, MTK_QDMA_INT_MASK, MTK_TX_DONE_INT);
-+ mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
-
- return tx_done;
- }
-@@ -1150,7 +1170,7 @@ poll_again:
- goto poll_again;
- }
- napi_complete(napi);
-- mtk_irq_enable(eth, MTK_PDMA_INT_MASK, MTK_RX_DONE_INT);
-+ mtk_rx_irq_enable(eth, MTK_RX_DONE_INT);
-
- return rx_done + budget - remain_budget;
- }
-@@ -1699,7 +1719,7 @@ static irqreturn_t mtk_handle_irq_rx(int
-
- if (likely(napi_schedule_prep(&eth->rx_napi))) {
- __napi_schedule(&eth->rx_napi);
-- mtk_irq_disable(eth, MTK_PDMA_INT_MASK, MTK_RX_DONE_INT);
-+ mtk_rx_irq_disable(eth, MTK_RX_DONE_INT);
- }
-
- return IRQ_HANDLED;
-@@ -1711,7 +1731,7 @@ static irqreturn_t mtk_handle_irq_tx(int
-
- if (likely(napi_schedule_prep(&eth->tx_napi))) {
- __napi_schedule(&eth->tx_napi);
-- mtk_irq_disable(eth, MTK_QDMA_INT_MASK, MTK_TX_DONE_INT);
-+ mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
- }
-
- return IRQ_HANDLED;
-@@ -1723,11 +1743,11 @@ static void mtk_poll_controller(struct n
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
-
-- mtk_irq_disable(eth, MTK_QDMA_INT_MASK, MTK_TX_DONE_INT);
-- mtk_irq_disable(eth, MTK_PDMA_INT_MASK, MTK_RX_DONE_INT);
-+ mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
-+ mtk_rx_irq_disable(eth, MTK_RX_DONE_INT);
- mtk_handle_irq_rx(eth->irq[2], dev);
-- mtk_irq_enable(eth, MTK_QDMA_INT_MASK, MTK_TX_DONE_INT);
-- mtk_irq_enable(eth, MTK_PDMA_INT_MASK, MTK_RX_DONE_INT);
-+ mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
-+ mtk_rx_irq_enable(eth, MTK_RX_DONE_INT);
- }
- #endif
-
-@@ -1770,8 +1790,8 @@ static int mtk_open(struct net_device *d
-
- napi_enable(&eth->tx_napi);
- napi_enable(&eth->rx_napi);
-- mtk_irq_enable(eth, MTK_QDMA_INT_MASK, MTK_TX_DONE_INT);
-- mtk_irq_enable(eth, MTK_PDMA_INT_MASK, MTK_RX_DONE_INT);
-+ mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
-+ mtk_rx_irq_enable(eth, MTK_RX_DONE_INT);
- }
- atomic_inc(&eth->dma_refcnt);
-
-@@ -1816,8 +1836,8 @@ static int mtk_stop(struct net_device *d
- if (!atomic_dec_and_test(&eth->dma_refcnt))
- return 0;
-
-- mtk_irq_disable(eth, MTK_QDMA_INT_MASK, MTK_TX_DONE_INT);
-- mtk_irq_disable(eth, MTK_PDMA_INT_MASK, MTK_RX_DONE_INT);
-+ mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
-+ mtk_rx_irq_disable(eth, MTK_RX_DONE_INT);
- napi_disable(&eth->tx_napi);
- napi_disable(&eth->rx_napi);
-
-@@ -1911,8 +1931,8 @@ static int mtk_hw_init(struct mtk_eth *e
- mtk_w32(eth, 0, MTK_PDMA_DELAY_INT);
- mtk_w32(eth, 0, MTK_QDMA_DELAY_INT);
- #endif
-- mtk_irq_disable(eth, MTK_QDMA_INT_MASK, ~0);
-- mtk_irq_disable(eth, MTK_PDMA_INT_MASK, ~0);
-+ mtk_tx_irq_disable(eth, ~0);
-+ mtk_rx_irq_disable(eth, ~0);
- mtk_w32(eth, RST_GL_PSE, MTK_RST_GL);
- mtk_w32(eth, 0, MTK_RST_GL);
-
-@@ -1983,8 +2003,8 @@ static void mtk_uninit(struct net_device
- phy_disconnect(dev->phydev);
- if (of_phy_is_fixed_link(mac->of_node))
- of_phy_deregister_fixed_link(mac->of_node);
-- mtk_irq_disable(eth, MTK_QDMA_INT_MASK, ~0);
-- mtk_irq_disable(eth, MTK_PDMA_INT_MASK, ~0);
-+ mtk_tx_irq_disable(eth, ~0);
-+ mtk_rx_irq_disable(eth, ~0);
- }
-
- static int mtk_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-@@ -2442,7 +2462,8 @@ static int mtk_probe(struct platform_dev
- return PTR_ERR(eth->base);
-
- spin_lock_init(&eth->page_lock);
-- spin_lock_init(&eth->irq_lock);
-+ spin_lock_init(&eth->tx_irq_lock);
-+ spin_lock_init(&eth->rx_irq_lock);
-
- eth->ethsys = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
- "mediatek,ethsys");
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -526,6 +526,8 @@ struct mtk_rx_ring {
- * @dev: The device pointer
- * @base: The mapped register i/o base
- * @page_lock: Make sure that register operations are atomic
-+ * @tx_irq__lock: Make sure that IRQ register operations are atomic
-+ * @rx_irq__lock: Make sure that IRQ register operations are atomic
- * @dummy_dev: we run 2 netdevs on 1 physical DMA ring and need a
- * dummy for NAPI to work
- * @netdev: The netdev instances
-@@ -555,7 +557,8 @@ struct mtk_eth {
- struct device *dev;
- void __iomem *base;
- spinlock_t page_lock;
-- spinlock_t irq_lock;
-+ spinlock_t tx_irq_lock;
-+ spinlock_t rx_irq_lock;
- struct net_device dummy_dev;
- struct net_device *netdev[MTK_MAX_DEVS];
- struct mtk_mac *mac[MTK_MAX_DEVS];
diff --git a/target/linux/mediatek/patches-4.9/0048-net-core-add-RPS-balancer.patch b/target/linux/mediatek/patches-4.9/0048-net-core-add-RPS-balancer.patch
deleted file mode 100644
index aeb81e14bf..0000000000
--- a/target/linux/mediatek/patches-4.9/0048-net-core-add-RPS-balancer.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 3e969c9695b45e1a052d43b367096ec99f2f0aac Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 15:58:29 +0200
-Subject: [PATCH 48/57] net: core: add RPS balancer
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- net/core/dev.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 56 insertions(+), 1 deletion(-)
-
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -3551,6 +3551,58 @@ set_rps_cpu(struct net_device *dev, stru
- return rflow;
- }
-
-+#define RPS_TBL_SIZE_SHIFT 10
-+#define RPS_TBL_SIZE (1 << RPS_TBL_SIZE_SHIFT)
-+struct rps_table {
-+ int core;
-+ struct timer_list expire;
-+};
-+static struct rps_table rps_table[RPS_TBL_SIZE];
-+static int rps_table_last_core;
-+
-+static void rps_table_expire(unsigned long data)
-+{
-+ struct rps_table *entry = (struct rps_table *) data;
-+
-+ entry->core = -1;
-+}
-+
-+static int rps_table_core(struct rps_map *map)
-+{
-+ int i;
-+
-+ for (i = 0; i < map->len; i++) {
-+ int cpu = map->cpus[(rps_table_last_core + i + 1) % map->len];
-+ if (cpu_online(cpu)) {
-+ rps_table_last_core = cpu;
-+ return cpu;
-+ }
-+ }
-+ return map->cpus[0];
-+}
-+
-+static int rps_table_lookup(struct rps_map *map, u32 hash)
-+{
-+ int bucket = hash & 0x3ff;
-+
-+ if (rps_table[bucket].core < 0)
-+ rps_table[bucket].core = rps_table_core(map);
-+ mod_timer(&rps_table[bucket].expire, jiffies + HZ);
-+
-+ return rps_table[bucket].core;
-+}
-+
-+static void rps_table_init(void)
-+{
-+ int i;
-+
-+ for (i = 0; i < RPS_TBL_SIZE; i++) {
-+ rps_table[i].core = -1;
-+ setup_timer(&rps_table[i].expire, rps_table_expire,
-+ (unsigned long) &rps_table[i]);
-+ }
-+}
-+
- /*
- * get_rps_cpu is called from netif_receive_skb and returns the target
- * CPU from the RPS map of the receiving queue for a given skb.
-@@ -3640,7 +3692,7 @@ static int get_rps_cpu(struct net_device
- try_rps:
-
- if (map) {
-- tcpu = map->cpus[reciprocal_scale(hash, map->len)];
-+ tcpu = rps_table_lookup(map, hash);
- if (cpu_online(tcpu)) {
- cpu = tcpu;
- goto done;
-@@ -8431,6 +8483,9 @@ static int __init net_dev_init(void)
- sd->backlog.weight = weight_p;
- }
-
-+ if (IS_ENABLED(CONFIG_RPS))
-+ rps_table_init();
-+
- dev_boot_phase = 0;
-
- /* The loopback device is special if any other network devices
diff --git a/target/linux/mediatek/patches-4.9/0049-net-mediatek-add-rx-queue.patch b/target/linux/mediatek/patches-4.9/0049-net-mediatek-add-rx-queue.patch
deleted file mode 100644
index 0146a9dd5c..0000000000
--- a/target/linux/mediatek/patches-4.9/0049-net-mediatek-add-rx-queue.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From 066b30a76a0d13cbd2c0d463f9a1e87efc352679 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 15:58:46 +0200
-Subject: [PATCH 49/57] net: mediatek: add rx queue
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1009,6 +1009,7 @@ static int mtk_poll_rx(struct napi_struc
- RX_DMA_VID(trxd.rxd3))
- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
- RX_DMA_VID(trxd.rxd3));
-+ skb_record_rx_queue(skb, 0);
- napi_gro_receive(napi, skb);
-
- ring->data[idx] = new_data;
diff --git a/target/linux/mediatek/patches-4.9/0050-net-mediatek-add-trgmii-clock.patch b/target/linux/mediatek/patches-4.9/0050-net-mediatek-add-trgmii-clock.patch
deleted file mode 100644
index 3d7df70bb3..0000000000
--- a/target/linux/mediatek/patches-4.9/0050-net-mediatek-add-trgmii-clock.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From 67c4af99af02d86b627a8cde2e99cc4c9699d2ce Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 15:59:08 +0200
-Subject: [PATCH 50/57] net: mediatek: add trgmii clock
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1873,6 +1873,8 @@ static int mtk_hw_init(struct mtk_eth *e
- pm_runtime_enable(eth->dev);
- pm_runtime_get_sync(eth->dev);
-
-+ clk_set_rate(eth->clks[MTK_CLK_TRGPLL], 250000000);
-+
- clk_prepare_enable(eth->clks[MTK_CLK_ETHIF]);
- clk_prepare_enable(eth->clks[MTK_CLK_ESW]);
- clk_prepare_enable(eth->clks[MTK_CLK_GP1]);
diff --git a/target/linux/mediatek/patches-4.9/0051-net-mediatek-increase-tx_timeout.patch b/target/linux/mediatek/patches-4.9/0051-net-mediatek-increase-tx_timeout.patch
deleted file mode 100644
index 3de3e7343b..0000000000
--- a/target/linux/mediatek/patches-4.9/0051-net-mediatek-increase-tx_timeout.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From 5cbf53c7e5eac5bacc409461888789accdaf8eec Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 16:00:06 +0200
-Subject: [PATCH 51/57] net: mediatek: increase tx_timeout
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2384,7 +2384,7 @@ static int mtk_add_mac(struct mtk_eth *e
- mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
-
- SET_NETDEV_DEV(eth->netdev[id], eth->dev);
-- eth->netdev[id]->watchdog_timeo = 5 * HZ;
-+ eth->netdev[id]->watchdog_timeo = 30 * HZ;
- eth->netdev[id]->netdev_ops = &mtk_netdev_ops;
- eth->netdev[id]->base_addr = (unsigned long)eth->base;
-
diff --git a/target/linux/mediatek/patches-4.9/0052-net-phy-add-FC.patch b/target/linux/mediatek/patches-4.9/0052-net-phy-add-FC.patch
deleted file mode 100644
index 32d516ce4d..0000000000
--- a/target/linux/mediatek/patches-4.9/0052-net-phy-add-FC.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From 18b2169d84b47a3414164e5e40f23fb7e875707c Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 16:00:28 +0200
-Subject: [PATCH 52/57] net: phy: add FC
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/phy/phy_device.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -1804,7 +1804,7 @@ static struct phy_driver genphy_driver[]
- .config_init = genphy_config_init,
- .features = PHY_GBIT_FEATURES | SUPPORTED_MII |
- SUPPORTED_AUI | SUPPORTED_FIBRE |
-- SUPPORTED_BNC,
-+ SUPPORTED_BNC | SUPPORTED_Pause | SUPPORTED_Asym_Pause,
- .config_aneg = genphy_config_aneg,
- .aneg_done = genphy_aneg_done,
- .read_status = genphy_read_status,
diff --git a/target/linux/mediatek/patches-4.9/0053-net-dsa-mediatek-add-software-phy-polling.patch b/target/linux/mediatek/patches-4.9/0053-net-dsa-mediatek-add-software-phy-polling.patch
deleted file mode 100644
index a41bcb0262..0000000000
--- a/target/linux/mediatek/patches-4.9/0053-net-dsa-mediatek-add-software-phy-polling.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 53eec2c3580e63fdebfc25ae324f30cd8aa4403b Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 16:00:46 +0200
-Subject: [PATCH 53/57] net: dsa: mediatek: add software phy polling
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/dsa/mt7530.c | 38 ++++++++++++++++++++++++++++++++++++++
- drivers/net/dsa/mt7530.h | 1 +
- 2 files changed, 39 insertions(+)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -728,6 +728,44 @@ static void mt7530_adjust_link(struct ds
- * all finished.
- */
- mt7623_pad_clk_setup(ds);
-+ } else {
-+ u16 lcl_adv = 0, rmt_adv = 0;
-+ u8 flowctrl;
-+ u32 mcr = PMCR_USERP_LINK | PMCR_FORCE_MODE;
-+
-+ switch (phydev->speed) {
-+ case SPEED_1000:
-+ mcr |= PMCR_FORCE_SPEED_1000;
-+ break;
-+ case SPEED_100:
-+ mcr |= PMCR_FORCE_SPEED_100;
-+ break;
-+ };
-+
-+ if (phydev->link)
-+ mcr |= PMCR_FORCE_LNK;
-+
-+ if (phydev->duplex) {
-+ mcr |= PMCR_FORCE_FDX;
-+
-+ if (phydev->pause)
-+ rmt_adv = LPA_PAUSE_CAP;
-+ if (phydev->asym_pause)
-+ rmt_adv |= LPA_PAUSE_ASYM;
-+
-+ if (phydev->advertising & ADVERTISED_Pause)
-+ lcl_adv |= ADVERTISE_PAUSE_CAP;
-+ if (phydev->advertising & ADVERTISED_Asym_Pause)
-+ lcl_adv |= ADVERTISE_PAUSE_ASYM;
-+
-+ flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
-+
-+ if (flowctrl & FLOW_CTRL_TX)
-+ mcr |= PMCR_TX_FC_EN;
-+ if (flowctrl & FLOW_CTRL_RX)
-+ mcr |= PMCR_RX_FC_EN;
-+ }
-+ mt7530_write(priv, MT7530_PMCR_P(port), mcr);
- }
- }
-
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -155,6 +155,7 @@ enum mt7530_stp_state {
- #define PMCR_TX_FC_EN BIT(5)
- #define PMCR_RX_FC_EN BIT(4)
- #define PMCR_FORCE_SPEED_1000 BIT(3)
-+#define PMCR_FORCE_SPEED_100 BIT(2)
- #define PMCR_FORCE_FDX BIT(1)
- #define PMCR_FORCE_LNK BIT(0)
- #define PMCR_COMMON_LINK (PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | \
diff --git a/target/linux/mediatek/patches-4.9/0054-net-ethernet-mediatek-fixed-deadlock-captured-by-loc.patch b/target/linux/mediatek/patches-4.9/0054-net-ethernet-mediatek-fixed-deadlock-captured-by-loc.patch
deleted file mode 100644
index 29005316ee..0000000000
--- a/target/linux/mediatek/patches-4.9/0054-net-ethernet-mediatek-fixed-deadlock-captured-by-loc.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From 746bf1c3e561aba396cd40e6540245646461117d Mon Sep 17 00:00:00 2001
-From: Sean Wang <sean.wang@mediatek.com>
-Date: Tue, 4 Jul 2017 11:17:36 +0800
-Subject: [PATCH 54/57] net: ethernet: mediatek: fixed deadlock captured by
- lockdep
-
-Lockdep found an inconsistent lock state when mtk_get_stats64 is called
-in user context while NAPI updates MAC statistics in softirq.
-
-Use spin_trylock_bh/spin_unlock_bh fix following lockdep warning.
-
-[ 81.321030] WARNING: inconsistent lock state
-[ 81.325266] 4.12.0-rc1-00035-gd9dda65 #32 Not tainted
-[ 81.330273] --------------------------------
-[ 81.334505] inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
-[ 81.340464] ksoftirqd/0/7 [HC0[0]:SC1[1]:HE1:SE0] takes:
-[ 81.345731] (&syncp->seq#2){+.?...}, at: [<c054ba3c>] mtk_handle_status_irq.part.6+0x70/0x84
-[ 81.354219] {SOFTIRQ-ON-W} state was registered at:
-[ 81.359062] lock_acquire+0xfc/0x2b0
-[ 81.362696] mtk_stats_update_mac+0x60/0x2c0
-[ 81.367017] mtk_get_stats64+0x17c/0x18c
-[ 81.370995] dev_get_stats+0x48/0xbc
-[ 81.374628] rtnl_fill_stats+0x48/0x128
-[ 81.378520] rtnl_fill_ifinfo+0x4ac/0xd1c
-[ 81.382584] rtmsg_ifinfo_build_skb+0x7c/0xe0
-[ 81.386991] rtmsg_ifinfo.part.5+0x24/0x54
-[ 81.391139] rtmsg_ifinfo+0x24/0x28
-[ 81.394685] __dev_notify_flags+0xa4/0xac
-[ 81.398749] dev_change_flags+0x50/0x58
-[ 81.402640] devinet_ioctl+0x768/0x85c
-[ 81.406444] inet_ioctl+0x1a4/0x1d0
-[ 81.409990] sock_ioctl+0x16c/0x33c
-[ 81.413538] do_vfs_ioctl+0xb4/0xa34
-[ 81.417169] SyS_ioctl+0x44/0x6c
-[ 81.420458] ret_fast_syscall+0x0/0x1c
-[ 81.424260] irq event stamp: 3354692
-[ 81.427806] hardirqs last enabled at (3354692): [<c0678168>] net_rx_action+0xc0/0x504
-[ 81.435660] hardirqs last disabled at (3354691): [<c0678134>] net_rx_action+0x8c/0x504
-[ 81.443515] softirqs last enabled at (3354106): [<c0101944>] __do_softirq+0x4b4/0x614
-[ 81.451370] softirqs last disabled at (3354109): [<c012f0c4>] run_ksoftirqd+0x44/0x80
-[ 81.459134]
-[ 81.459134] other info that might help us debug this:
-[ 81.465608] Possible unsafe locking scenario:
-[ 81.465608]
-[ 81.471478] CPU0
-[ 81.473900] ----
-[ 81.476321] lock(&syncp->seq#2);
-[ 81.479701] <Interrupt>
-[ 81.482294] lock(&syncp->seq#2);
-[ 81.485847]
-[ 81.485847] *** DEADLOCK ***
-[ 81.485847]
-[ 81.491720] 1 lock held by ksoftirqd/0/7:
-[ 81.495693] #0: (&(&mac->hw_stats->stats_lock)->rlock){+.+...}, at: [<c054ba14>] mtk_handle_status_irq.part.6+0x48/0x84
-[ 81.506579]
-[ 81.506579] stack backtrace:
-[ 81.510904] CPU: 0 PID: 7 Comm: ksoftirqd/0 Not tainted 4.12.0-rc1-00035-gd9dda65 #32
-[ 81.518668] Hardware name: Mediatek Cortex-A7 (Device Tree)
-[ 81.524208] [<c0113dc4>] (unwind_backtrace) from [<c010e3f0>] (show_stack+0x20/0x24)
-[ 81.531899] [<c010e3f0>] (show_stack) from [<c03f9c64>] (dump_stack+0xb4/0xe0)
-[ 81.539072] [<c03f9c64>] (dump_stack) from [<c017e970>] (print_usage_bug+0x234/0x2e0)
-[ 81.546846] [<c017e970>] (print_usage_bug) from [<c017f058>] (mark_lock+0x63c/0x7bc)
-[ 81.554532] [<c017f058>] (mark_lock) from [<c017fe90>] (__lock_acquire+0x654/0x1bfc)
-[ 81.562217] [<c017fe90>] (__lock_acquire) from [<c0181d04>] (lock_acquire+0xfc/0x2b0)
-[ 81.569990] [<c0181d04>] (lock_acquire) from [<c054b76c>] (mtk_stats_update_mac+0x60/0x2c0)
-[ 81.578283] [<c054b76c>] (mtk_stats_update_mac) from [<c054ba3c>] (mtk_handle_status_irq.part.6+0x70/0x84)
-[ 81.587865] [<c054ba3c>] (mtk_handle_status_irq.part.6) from [<c054c2b8>] (mtk_napi_tx+0x358/0x37c)
-[ 81.596845] [<c054c2b8>] (mtk_napi_tx) from [<c06782ec>] (net_rx_action+0x244/0x504)
-[ 81.604533] [<c06782ec>] (net_rx_action) from [<c01015c4>] (__do_softirq+0x134/0x614)
-[ 81.612306] [<c01015c4>] (__do_softirq) from [<c012f0c4>] (run_ksoftirqd+0x44/0x80)
-[ 81.619907] [<c012f0c4>] (run_ksoftirqd) from [<c0154680>] (smpboot_thread_fn+0x14c/0x25c)
-[ 81.628110] [<c0154680>] (smpboot_thread_fn) from [<c014f8cc>] (kthread+0x150/0x180)
-[ 81.635798] [<c014f8cc>] (kthread) from [<c0109290>] (ret_from_fork+0x14/0x24)
-
-Signed-off-by: Sean Wang <sean.wang@mediatek.com>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -493,9 +493,9 @@ static struct rtnl_link_stats64 * mtk_ge
- unsigned int start;
-
- if (netif_running(dev) && netif_device_present(dev)) {
-- if (spin_trylock(&hw_stats->stats_lock)) {
-+ if (spin_trylock_bh(&hw_stats->stats_lock)) {
- mtk_stats_update_mac(mac);
-- spin_unlock(&hw_stats->stats_lock);
-+ spin_unlock_bh(&hw_stats->stats_lock);
- }
- }
-
-@@ -2229,9 +2229,9 @@ static void mtk_get_ethtool_stats(struct
- return;
-
- if (netif_running(dev) && netif_device_present(dev)) {
-- if (spin_trylock(&hwstats->stats_lock)) {
-+ if (spin_trylock_bh(&hwstats->stats_lock)) {
- mtk_stats_update_mac(mac);
-- spin_unlock(&hwstats->stats_lock);
-+ spin_unlock_bh(&hwstats->stats_lock);
- }
- }
-
diff --git a/target/linux/mediatek/patches-4.9/0055-net-ethernet-mediatek-avoid-potential-invalid-memory.patch b/target/linux/mediatek/patches-4.9/0055-net-ethernet-mediatek-avoid-potential-invalid-memory.patch
deleted file mode 100644
index 6598e8208c..0000000000
--- a/target/linux/mediatek/patches-4.9/0055-net-ethernet-mediatek-avoid-potential-invalid-memory.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From a3360b3543b9fb833ba691019e396e72293a313f Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 16:31:45 +0200
-Subject: [PATCH 55/57] net: ethernet: mediatek: avoid potential invalid memory
- access
-
-Potential dangerous invalid memory might be accessed if invalid mac value
-reflected from the forward port field in rxd4 caused by possible potential
-hardware defects. So added a simple sanity checker to avoid the kind of
-situation happening.
-
-Signed-off-by: Sean Wang <sean.wang@mediatek.com>
-Acked-by: John Crispin <john@phrozen.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -964,6 +964,10 @@ static int mtk_poll_rx(struct napi_struc
- mac--;
- }
-
-+ if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
-+ !eth->netdev[mac]))
-+ goto release_desc;
-+
- netdev = eth->netdev[mac];
-
- if (unlikely(test_bit(MTK_RESETTING, &eth->state)))
diff --git a/target/linux/mediatek/patches-4.9/0056-net-mediatek-add-hw-nat-support.patch b/target/linux/mediatek/patches-4.9/0056-net-mediatek-add-hw-nat-support.patch
deleted file mode 100644
index d1d6ed473b..0000000000
--- a/target/linux/mediatek/patches-4.9/0056-net-mediatek-add-hw-nat-support.patch
+++ /dev/null
@@ -1,119 +0,0 @@
-From 043efc0e619e04661be2b1889382db2fdd378145 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 16:34:36 +0200
-Subject: [PATCH 56/57] net: mediatek: add hw nat support
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/Kconfig | 7 +++++++
- drivers/net/ethernet/mediatek/Makefile | 1 +
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 13 +++++++++++++
- net/netfilter/nf_conntrack_proto_tcp.c | 19 +++++++++++++++++++
- 4 files changed, 40 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/Kconfig
-+++ b/drivers/net/ethernet/mediatek/Kconfig
-@@ -14,4 +14,11 @@ config NET_MEDIATEK_SOC
- This driver supports the gigabit ethernet MACs in the
- MediaTek MT2701/MT7623 chipset family.
-
-+config NET_MEDIATEK_HNAT
-+ tristate "MediaTek MT7623 hardware NAT support"
-+ depends on NET_MEDIATEK_SOC && NF_CONNTRACK && NF_CONNTRACK_IPV4 && IP_NF_NAT && IP_NF_TARGET_MASQUERADE
-+ ---help---
-+ This driver supports the hardwaer NAT in the
-+ MediaTek MT2701/MT7623 chipset family.
-+
- endif #NET_VENDOR_MEDIATEK
---- a/drivers/net/ethernet/mediatek/Makefile
-+++ b/drivers/net/ethernet/mediatek/Makefile
-@@ -3,3 +3,4 @@
- #
-
- obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth_soc.o
-+obj-$(CONFIG_NET_MEDIATEK_HNAT) += mtk_hnat/
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -23,6 +23,10 @@
- #include <linux/reset.h>
- #include <linux/tcp.h>
-
-+#if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE)
-+#include "mtk_hnat/nf_hnat_mtk.h"
-+#endif
-+
- #include "mtk_eth_soc.h"
-
- static int mtk_msg_level = -1;
-@@ -649,6 +653,11 @@ static int mtk_tx_map(struct sk_buff *sk
- return -ENOMEM;
-
- /* set the forward port */
-+#if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE)
-+ if (HNAT_SKB_CB2(skb)->magic == 0x78681415)
-+ fport |= 0x4 << TX_DMA_FPORT_SHIFT;
-+ else
-+#endif
- fport = (mac->id + 1) << TX_DMA_FPORT_SHIFT;
- txd4 |= fport;
-
-@@ -1013,6 +1022,10 @@ static int mtk_poll_rx(struct napi_struc
- RX_DMA_VID(trxd.rxd3))
- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
- RX_DMA_VID(trxd.rxd3));
-+#if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE)
-+ *(u32 *)(skb->head) = trxd.rxd4;
-+ skb_hnat_alg(skb) = 0;
-+#endif
- skb_record_rx_queue(skb, 0);
- napi_gro_receive(napi, skb);
-
---- a/net/netfilter/nf_conntrack_proto_tcp.c
-+++ b/net/netfilter/nf_conntrack_proto_tcp.c
-@@ -11,6 +11,7 @@
- #include <linux/types.h>
- #include <linux/timer.h>
- #include <linux/module.h>
-+#include <linux/inetdevice.h>
- #include <linux/in.h>
- #include <linux/tcp.h>
- #include <linux/spinlock.h>
-@@ -19,6 +20,7 @@
- #include <net/ip6_checksum.h>
- #include <asm/unaligned.h>
-
-+#include <net/ip.h>
- #include <net/tcp.h>
-
- #include <linux/netfilter.h>
-@@ -53,6 +55,11 @@ static int nf_ct_tcp_max_retrans __read_
- /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
- closely. They're more complex. --RR */
-
-+#ifndef IPV4_DEVCONF_DFLT
-+ #define IPV4_DEVCONF_DFLT(net, attr) \
-+ IPV4_DEVCONF((*net->ipv4.devconf_dflt), attr)
-+#endif
-+
- static const char *const tcp_conntrack_names[] = {
- "NONE",
- "SYN_SENT",
-@@ -519,6 +526,18 @@ static bool tcp_in_window(const struct n
- if (nf_ct_tcp_no_window_check)
- return true;
-
-+ if (net) {
-+ if ((net->ipv4.devconf_all && net->ipv4.devconf_dflt && net->ipv6.devconf_all) &&
-+ net->ipv6.devconf_dflt) {
-+ if ((IPV4_DEVCONF_DFLT(net, FORWARDING) ||
-+ IPV4_DEVCONF_ALL(net, FORWARDING)) ||
-+ (net->ipv6.devconf_all->forwarding ||
-+ net->ipv6.devconf_dflt->forwarding)) {
-+ return true;
-+ }
-+ }
-+ }
-+
- /*
- * Get the required data from the packet.
- */
diff --git a/target/linux/mediatek/patches-4.9/0057-net-mediatek-add-HW-QoS-support.patch b/target/linux/mediatek/patches-4.9/0057-net-mediatek-add-HW-QoS-support.patch
deleted file mode 100644
index f6284583a4..0000000000
--- a/target/linux/mediatek/patches-4.9/0057-net-mediatek-add-HW-QoS-support.patch
+++ /dev/null
@@ -1,121 +0,0 @@
-From 660c13dfbacbf37f090a66a2b14f0c5ce7cbec81 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 10 Aug 2017 16:38:27 +0200
-Subject: [PATCH 57/57] net: mediatek: add HW QoS support
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/Kconfig | 7 ++++
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 60 ++++++++++++++++++++++++++++-
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +-
- 3 files changed, 66 insertions(+), 3 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/Kconfig
-+++ b/drivers/net/ethernet/mediatek/Kconfig
-@@ -21,4 +21,11 @@ config NET_MEDIATEK_HNAT
- This driver supports the hardwaer NAT in the
- MediaTek MT2701/MT7623 chipset family.
-
-+config NET_MEDIATEK_HW_QOS
-+ tristate "MediaTek MT7623 hardware QoS support"
-+ depends on NET_MEDIATEK_SOC
-+ ---help---
-+ This driver supports the hardware QoS in the
-+ MediaTek MT2701/MT7623 chipset family.
-+
- endif #NET_VENDOR_MEDIATEK
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -23,6 +23,17 @@
- #include <linux/reset.h>
- #include <linux/tcp.h>
-
-+#if defined(CONFIG_NET_MEDIATEK_HW_QOS)
-+struct mtk_ioctl_reg {
-+ unsigned int off;
-+ unsigned int val;
-+};
-+
-+#define REG_HQOS_MAX 0x3FFF
-+#define RAETH_QDMA_REG_READ 0x89F8
-+#define RAETH_QDMA_REG_WRITE 0x89F9
-+#endif
-+
- #if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE)
- #include "mtk_hnat/nf_hnat_mtk.h"
- #endif
-@@ -646,7 +657,7 @@ static int mtk_tx_map(struct sk_buff *sk
- dma_addr_t mapped_addr;
- unsigned int nr_frags;
- int i, n_desc = 1;
-- u32 txd4 = 0, fport;
-+ u32 txd3 = 0, txd4 = 0, fport;
-
- itxd = ring->next_free;
- if (itxd == ring->last_free)
-@@ -675,6 +686,12 @@ static int mtk_tx_map(struct sk_buff *sk
- // if (skb_vlan_tag_present(skb))
- // txd4 |= TX_DMA_INS_VLAN | skb_vlan_tag_get(skb);
-
-+#ifdef CONFIG_NET_MEDIATEK_HW_QOS
-+ txd3 |= skb->mark & 0x7;
-+ if (mac->id)
-+ txd3 += 8;
-+#endif
-+
- mapped_addr = dma_map_single(eth->dev, skb->data,
- skb_headlen(skb), DMA_TO_DEVICE);
- if (unlikely(dma_mapping_error(eth->dev, mapped_addr)))
-@@ -718,7 +735,8 @@ static int mtk_tx_map(struct sk_buff *sk
- WRITE_ONCE(txd->txd1, mapped_addr);
- WRITE_ONCE(txd->txd3, (TX_DMA_SWC |
- TX_DMA_PLEN0(frag_map_size) |
-- last_frag * TX_DMA_LS0));
-+ last_frag * TX_DMA_LS0 |
-+ txd3));
- WRITE_ONCE(txd->txd4, fport);
-
- tx_buf = mtk_desc_to_tx_buf(ring, txd);
-@@ -2029,7 +2047,31 @@ static void mtk_uninit(struct net_device
-
- static int mtk_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
- {
-+#if defined(CONFIG_NET_MEDIATEK_HW_QOS)
-+ struct mtk_mac *mac = netdev_priv(dev);
-+ struct mtk_eth *eth = mac->hw;
-+ struct mtk_ioctl_reg reg;
-+#endif
-+
- switch (cmd) {
-+#if defined(CONFIG_NET_MEDIATEK_HW_QOS)
-+ case RAETH_QDMA_REG_READ:
-+ copy_from_user(&reg, ifr->ifr_data, sizeof(reg));
-+ if (reg.off > REG_HQOS_MAX)
-+ return -EINVAL;
-+ reg.val = mtk_r32(eth, 0x1800 + reg.off);
-+// printk("read reg off:%x val:%x\n", reg.off, reg.val);
-+ copy_to_user(ifr->ifr_data, &reg, sizeof(reg));
-+ return 0;
-+
-+ case RAETH_QDMA_REG_WRITE:
-+ copy_from_user(&reg, ifr->ifr_data, sizeof(reg));
-+ if (reg.off > REG_HQOS_MAX)
-+ return -EINVAL;
-+ mtk_w32(eth, reg.val, 0x1800 + reg.off);
-+// printk("write reg off:%x val:%x\n", reg.off, reg.val);
-+ return 0;
-+#endif
- case SIOCGMIIPHY:
- case SIOCGMIIREG:
- case SIOCSMIIREG:
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -20,7 +20,7 @@
- #define MTK_QDMA_PAGE_SIZE 2048
- #define MTK_MAX_RX_LENGTH 1536
- #define MTK_TX_DMA_BUF_LEN 0x3fff
--#define MTK_DMA_SIZE 256
-+#define MTK_DMA_SIZE 2048
- #define MTK_NAPI_WEIGHT 64
- #define MTK_MAC_COUNT 2
- #define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)
diff --git a/target/linux/mediatek/patches-4.9/0058-pinctrl-update.patch b/target/linux/mediatek/patches-4.9/0058-pinctrl-update.patch
deleted file mode 100644
index 3174b805e2..0000000000
--- a/target/linux/mediatek/patches-4.9/0058-pinctrl-update.patch
+++ /dev/null
@@ -1,470 +0,0 @@
---- a/drivers/pinctrl/mediatek/Kconfig
-+++ b/drivers/pinctrl/mediatek/Kconfig
-@@ -15,12 +15,6 @@ config PINCTRL_MT2701
- default MACH_MT2701
- select PINCTRL_MTK
-
--config PINCTRL_MT7623
-- bool "Mediatek MT7623 pin control" if COMPILE_TEST && !MACH_MT7623
-- depends on OF
-- default MACH_MT7623
-- select PINCTRL_MTK_COMMON
--
- config PINCTRL_MT8135
- bool "Mediatek MT8135 pin control" if COMPILE_TEST && !MACH_MT8135
- depends on OF
---- a/drivers/pinctrl/mediatek/Makefile
-+++ b/drivers/pinctrl/mediatek/Makefile
-@@ -3,7 +3,6 @@ obj-y += pinctrl-mtk-common.o
-
- # SoC Drivers
- obj-$(CONFIG_PINCTRL_MT2701) += pinctrl-mt2701.o
--obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o
- obj-$(CONFIG_PINCTRL_MT8135) += pinctrl-mt8135.o
- obj-$(CONFIG_PINCTRL_MT8127) += pinctrl-mt8127.o
- obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o
---- a/drivers/pinctrl/mediatek/pinctrl-mt2701.c
-+++ b/drivers/pinctrl/mediatek/pinctrl-mt2701.c
-@@ -565,6 +565,7 @@ static int mt2701_pinctrl_probe(struct p
-
- static const struct of_device_id mt2701_pctrl_match[] = {
- { .compatible = "mediatek,mt2701-pinctrl", },
-+ { .compatible = "mediatek,mt7623-pinctrl", },
- {}
- };
- MODULE_DEVICE_TABLE(of, mt2701_pctrl_match);
---- a/drivers/pinctrl/mediatek/pinctrl-mt7623.c
-+++ /dev/null
-@@ -1,379 +0,0 @@
--/*
-- * Copyright (c) 2016 John Crispin <blogic@openwrt.org>
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 as
-- * published by the Free Software Foundation.
-- *
-- * This program is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- * GNU General Public License for more details.
-- */
--
--#include <dt-bindings/pinctrl/mt65xx.h>
--#include <linux/module.h>
--#include <linux/of.h>
--#include <linux/of_device.h>
--#include <linux/platform_device.h>
--#include <linux/pinctrl/pinctrl.h>
--#include <linux/regmap.h>
--
--#include "pinctrl-mtk-common.h"
--#include "pinctrl-mtk-mt7623.h"
--
--static const struct mtk_drv_group_desc mt7623_drv_grp[] = {
-- /* 0E4E8SR 4/8/12/16 */
-- MTK_DRV_GRP(4, 16, 1, 2, 4),
-- /* 0E2E4SR 2/4/6/8 */
-- MTK_DRV_GRP(2, 8, 1, 2, 2),
-- /* E8E4E2 2/4/6/8/10/12/14/16 */
-- MTK_DRV_GRP(2, 16, 0, 2, 2)
--};
--
--#define DRV_SEL0 0xf50
--#define DRV_SEL1 0xf60
--#define DRV_SEL2 0xf70
--#define DRV_SEL3 0xf80
--#define DRV_SEL4 0xf90
--#define DRV_SEL5 0xfa0
--#define DRV_SEL6 0xfb0
--#define DRV_SEL7 0xfe0
--#define DRV_SEL8 0xfd0
--#define DRV_SEL9 0xff0
--#define DRV_SEL10 0xf00
--
--#define MSDC0_CTRL0 0xcc0
--#define MSDC0_CTRL1 0xcd0
--#define MSDC0_CTRL2 0xce0
--#define MSDC0_CTRL3 0xcf0
--#define MSDC0_CTRL4 0xd00
--#define MSDC0_CTRL5 0xd10
--#define MSDC0_CTRL6 0xd20
--#define MSDC1_CTRL0 0xd30
--#define MSDC1_CTRL1 0xd40
--#define MSDC1_CTRL2 0xd50
--#define MSDC1_CTRL3 0xd60
--#define MSDC1_CTRL4 0xd70
--#define MSDC1_CTRL5 0xd80
--#define MSDC1_CTRL6 0xd90
--
--#define IES_EN0 0xb20
--#define IES_EN1 0xb30
--#define IES_EN2 0xb40
--
--#define SMT_EN0 0xb50
--#define SMT_EN1 0xb60
--#define SMT_EN2 0xb70
--
--static const struct mtk_pin_drv_grp mt7623_pin_drv[] = {
-- MTK_PIN_DRV_GRP(0, DRV_SEL0, 0, 1),
-- MTK_PIN_DRV_GRP(1, DRV_SEL0, 0, 1),
-- MTK_PIN_DRV_GRP(2, DRV_SEL0, 0, 1),
-- MTK_PIN_DRV_GRP(3, DRV_SEL0, 0, 1),
-- MTK_PIN_DRV_GRP(4, DRV_SEL0, 0, 1),
-- MTK_PIN_DRV_GRP(5, DRV_SEL0, 0, 1),
-- MTK_PIN_DRV_GRP(6, DRV_SEL0, 0, 1),
-- MTK_PIN_DRV_GRP(7, DRV_SEL0, 4, 1),
-- MTK_PIN_DRV_GRP(8, DRV_SEL0, 4, 1),
-- MTK_PIN_DRV_GRP(9, DRV_SEL0, 4, 1),
-- MTK_PIN_DRV_GRP(10, DRV_SEL0, 8, 1),
-- MTK_PIN_DRV_GRP(11, DRV_SEL0, 8, 1),
-- MTK_PIN_DRV_GRP(12, DRV_SEL0, 8, 1),
-- MTK_PIN_DRV_GRP(13, DRV_SEL0, 8, 1),
-- MTK_PIN_DRV_GRP(14, DRV_SEL0, 12, 0),
-- MTK_PIN_DRV_GRP(15, DRV_SEL0, 12, 0),
-- MTK_PIN_DRV_GRP(18, DRV_SEL1, 4, 0),
-- MTK_PIN_DRV_GRP(19, DRV_SEL1, 4, 0),
-- MTK_PIN_DRV_GRP(20, DRV_SEL1, 4, 0),
-- MTK_PIN_DRV_GRP(21, DRV_SEL1, 4, 0),
-- MTK_PIN_DRV_GRP(22, DRV_SEL1, 8, 0),
-- MTK_PIN_DRV_GRP(23, DRV_SEL1, 8, 0),
-- MTK_PIN_DRV_GRP(24, DRV_SEL1, 8, 0),
-- MTK_PIN_DRV_GRP(25, DRV_SEL1, 8, 0),
-- MTK_PIN_DRV_GRP(26, DRV_SEL1, 8, 0),
-- MTK_PIN_DRV_GRP(27, DRV_SEL1, 12, 0),
-- MTK_PIN_DRV_GRP(28, DRV_SEL1, 12, 0),
-- MTK_PIN_DRV_GRP(29, DRV_SEL1, 12, 0),
-- MTK_PIN_DRV_GRP(33, DRV_SEL2, 0, 0),
-- MTK_PIN_DRV_GRP(34, DRV_SEL2, 0, 0),
-- MTK_PIN_DRV_GRP(35, DRV_SEL2, 0, 0),
-- MTK_PIN_DRV_GRP(36, DRV_SEL2, 0, 0),
-- MTK_PIN_DRV_GRP(37, DRV_SEL2, 0, 0),
-- MTK_PIN_DRV_GRP(39, DRV_SEL2, 8, 1),
-- MTK_PIN_DRV_GRP(40, DRV_SEL2, 8, 1),
-- MTK_PIN_DRV_GRP(41, DRV_SEL2, 8, 1),
-- MTK_PIN_DRV_GRP(42, DRV_SEL2, 8, 1),
-- MTK_PIN_DRV_GRP(43, DRV_SEL2, 12, 0),
-- MTK_PIN_DRV_GRP(44, DRV_SEL2, 12, 0),
-- MTK_PIN_DRV_GRP(45, DRV_SEL2, 12, 0),
-- MTK_PIN_DRV_GRP(47, DRV_SEL3, 0, 0),
-- MTK_PIN_DRV_GRP(48, DRV_SEL3, 0, 0),
-- MTK_PIN_DRV_GRP(49, DRV_SEL3, 4, 0),
-- MTK_PIN_DRV_GRP(53, DRV_SEL3, 12, 0),
-- MTK_PIN_DRV_GRP(54, DRV_SEL3, 12, 0),
-- MTK_PIN_DRV_GRP(55, DRV_SEL3, 12, 0),
-- MTK_PIN_DRV_GRP(56, DRV_SEL3, 12, 0),
-- MTK_PIN_DRV_GRP(60, DRV_SEL4, 8, 1),
-- MTK_PIN_DRV_GRP(61, DRV_SEL4, 8, 1),
-- MTK_PIN_DRV_GRP(62, DRV_SEL4, 8, 1),
-- MTK_PIN_DRV_GRP(63, DRV_SEL4, 12, 1),
-- MTK_PIN_DRV_GRP(64, DRV_SEL4, 12, 1),
-- MTK_PIN_DRV_GRP(65, DRV_SEL4, 12, 1),
-- MTK_PIN_DRV_GRP(66, DRV_SEL5, 0, 1),
-- MTK_PIN_DRV_GRP(67, DRV_SEL5, 0, 1),
-- MTK_PIN_DRV_GRP(68, DRV_SEL5, 0, 1),
-- MTK_PIN_DRV_GRP(69, DRV_SEL5, 0, 1),
-- MTK_PIN_DRV_GRP(70, DRV_SEL5, 0, 1),
-- MTK_PIN_DRV_GRP(71, DRV_SEL5, 0, 1),
-- MTK_PIN_DRV_GRP(72, DRV_SEL3, 4, 0),
-- MTK_PIN_DRV_GRP(73, DRV_SEL3, 4, 0),
-- MTK_PIN_DRV_GRP(74, DRV_SEL3, 4, 0),
-- MTK_PIN_DRV_GRP(83, DRV_SEL5, 0, 1),
-- MTK_PIN_DRV_GRP(84, DRV_SEL5, 0, 1),
-- MTK_PIN_DRV_GRP(105, MSDC1_CTRL1, 0, 1),
-- MTK_PIN_DRV_GRP(106, MSDC1_CTRL0, 0, 1),
-- MTK_PIN_DRV_GRP(107, MSDC1_CTRL2, 0, 1),
-- MTK_PIN_DRV_GRP(108, MSDC1_CTRL2, 0, 1),
-- MTK_PIN_DRV_GRP(109, MSDC1_CTRL2, 0, 1),
-- MTK_PIN_DRV_GRP(110, MSDC1_CTRL2, 0, 1),
-- MTK_PIN_DRV_GRP(111, MSDC0_CTRL2, 0, 1),
-- MTK_PIN_DRV_GRP(112, MSDC0_CTRL2, 0, 1),
-- MTK_PIN_DRV_GRP(113, MSDC0_CTRL2, 0, 1),
-- MTK_PIN_DRV_GRP(114, MSDC0_CTRL2, 0, 1),
-- MTK_PIN_DRV_GRP(115, MSDC0_CTRL2, 0, 1),
-- MTK_PIN_DRV_GRP(116, MSDC0_CTRL1, 0, 1),
-- MTK_PIN_DRV_GRP(117, MSDC0_CTRL0, 0, 1),
-- MTK_PIN_DRV_GRP(118, MSDC0_CTRL2, 0, 1),
-- MTK_PIN_DRV_GRP(119, MSDC0_CTRL2, 0, 1),
-- MTK_PIN_DRV_GRP(120, MSDC0_CTRL2, 0, 1),
-- MTK_PIN_DRV_GRP(121, MSDC0_CTRL2, 0, 1),
-- MTK_PIN_DRV_GRP(126, DRV_SEL3, 4, 0),
-- MTK_PIN_DRV_GRP(199, DRV_SEL0, 4, 1),
-- MTK_PIN_DRV_GRP(200, DRV_SEL8, 0, 0),
-- MTK_PIN_DRV_GRP(201, DRV_SEL8, 0, 0),
-- MTK_PIN_DRV_GRP(203, DRV_SEL8, 4, 0),
-- MTK_PIN_DRV_GRP(204, DRV_SEL8, 4, 0),
-- MTK_PIN_DRV_GRP(205, DRV_SEL8, 4, 0),
-- MTK_PIN_DRV_GRP(206, DRV_SEL8, 4, 0),
-- MTK_PIN_DRV_GRP(207, DRV_SEL8, 4, 0),
-- MTK_PIN_DRV_GRP(208, DRV_SEL8, 8, 0),
-- MTK_PIN_DRV_GRP(209, DRV_SEL8, 8, 0),
-- MTK_PIN_DRV_GRP(236, DRV_SEL9, 4, 0),
-- MTK_PIN_DRV_GRP(237, DRV_SEL9, 4, 0),
-- MTK_PIN_DRV_GRP(238, DRV_SEL9, 4, 0),
-- MTK_PIN_DRV_GRP(239, DRV_SEL9, 4, 0),
-- MTK_PIN_DRV_GRP(240, DRV_SEL9, 4, 0),
-- MTK_PIN_DRV_GRP(241, DRV_SEL9, 4, 0),
-- MTK_PIN_DRV_GRP(242, DRV_SEL9, 8, 0),
-- MTK_PIN_DRV_GRP(243, DRV_SEL9, 8, 0),
-- MTK_PIN_DRV_GRP(257, MSDC0_CTRL2, 0, 1),
-- MTK_PIN_DRV_GRP(261, MSDC1_CTRL2, 0, 1),
-- MTK_PIN_DRV_GRP(262, DRV_SEL10, 8, 0),
-- MTK_PIN_DRV_GRP(263, DRV_SEL10, 8, 0),
-- MTK_PIN_DRV_GRP(264, DRV_SEL10, 8, 0),
-- MTK_PIN_DRV_GRP(265, DRV_SEL10, 8, 0),
-- MTK_PIN_DRV_GRP(266, DRV_SEL10, 8, 0),
-- MTK_PIN_DRV_GRP(267, DRV_SEL10, 8, 0),
-- MTK_PIN_DRV_GRP(268, DRV_SEL10, 8, 0),
-- MTK_PIN_DRV_GRP(269, DRV_SEL10, 8, 0),
-- MTK_PIN_DRV_GRP(270, DRV_SEL10, 8, 0),
-- MTK_PIN_DRV_GRP(271, DRV_SEL10, 8, 0),
-- MTK_PIN_DRV_GRP(272, DRV_SEL10, 8, 0),
-- MTK_PIN_DRV_GRP(274, DRV_SEL10, 8, 0),
-- MTK_PIN_DRV_GRP(275, DRV_SEL10, 8, 0),
-- MTK_PIN_DRV_GRP(276, DRV_SEL10, 8, 0),
-- MTK_PIN_DRV_GRP(278, DRV_SEL2, 8, 1),
--};
--
--static const struct mtk_pin_spec_pupd_set_samereg mt7623_spec_pupd[] = {
-- MTK_PIN_PUPD_SPEC_SR(105, MSDC1_CTRL1, 8, 9, 10),
-- MTK_PIN_PUPD_SPEC_SR(106, MSDC1_CTRL0, 8, 9, 10),
-- MTK_PIN_PUPD_SPEC_SR(107, MSDC1_CTRL3, 0, 1, 2),
-- MTK_PIN_PUPD_SPEC_SR(108, MSDC1_CTRL3, 4, 5, 6),
-- MTK_PIN_PUPD_SPEC_SR(109, MSDC1_CTRL3, 8, 9, 10),
-- MTK_PIN_PUPD_SPEC_SR(110, MSDC1_CTRL3, 12, 13, 14),
-- MTK_PIN_PUPD_SPEC_SR(111, MSDC0_CTRL4, 12, 13, 14),
-- MTK_PIN_PUPD_SPEC_SR(112, MSDC0_CTRL4, 8, 9, 10),
-- MTK_PIN_PUPD_SPEC_SR(113, MSDC0_CTRL4, 4, 5, 6),
-- MTK_PIN_PUPD_SPEC_SR(114, MSDC0_CTRL4, 0, 1, 2),
-- MTK_PIN_PUPD_SPEC_SR(115, MSDC0_CTRL5, 0, 1, 2),
-- MTK_PIN_PUPD_SPEC_SR(116, MSDC0_CTRL1, 8, 9, 10),
-- MTK_PIN_PUPD_SPEC_SR(117, MSDC0_CTRL0, 8, 9, 10),
-- MTK_PIN_PUPD_SPEC_SR(118, MSDC0_CTRL3, 12, 13, 14),
-- MTK_PIN_PUPD_SPEC_SR(119, MSDC0_CTRL3, 8, 9, 10),
-- MTK_PIN_PUPD_SPEC_SR(120, MSDC0_CTRL3, 4, 5, 6),
-- MTK_PIN_PUPD_SPEC_SR(121, MSDC0_CTRL3, 0, 1, 2),
--};
--
--static int mt7623_spec_pull_set(struct regmap *regmap, unsigned int pin,
-- unsigned char align, bool isup, unsigned int r1r0)
--{
-- return mtk_pctrl_spec_pull_set_samereg(regmap, mt7623_spec_pupd,
-- ARRAY_SIZE(mt7623_spec_pupd), pin, align, isup, r1r0);
--}
--
--static const struct mtk_pin_ies_smt_set mt7623_ies_set[] = {
-- MTK_PIN_IES_SMT_SPEC(0, 6, IES_EN0, 0),
-- MTK_PIN_IES_SMT_SPEC(7, 9, IES_EN0, 1),
-- MTK_PIN_IES_SMT_SPEC(10, 13, IES_EN0, 2),
-- MTK_PIN_IES_SMT_SPEC(14, 15, IES_EN0, 3),
-- MTK_PIN_IES_SMT_SPEC(18, 21, IES_EN0, 5),
-- MTK_PIN_IES_SMT_SPEC(22, 26, IES_EN0, 6),
-- MTK_PIN_IES_SMT_SPEC(27, 29, IES_EN0, 7),
-- MTK_PIN_IES_SMT_SPEC(33, 37, IES_EN0, 8),
-- MTK_PIN_IES_SMT_SPEC(39, 42, IES_EN0, 9),
-- MTK_PIN_IES_SMT_SPEC(43, 45, IES_EN0, 10),
-- MTK_PIN_IES_SMT_SPEC(47, 48, IES_EN0, 11),
-- MTK_PIN_IES_SMT_SPEC(49, 49, IES_EN0, 12),
-- MTK_PIN_IES_SMT_SPEC(53, 56, IES_EN0, 14),
-- MTK_PIN_IES_SMT_SPEC(60, 62, IES_EN1, 0),
-- MTK_PIN_IES_SMT_SPEC(63, 65, IES_EN1, 1),
-- MTK_PIN_IES_SMT_SPEC(66, 71, IES_EN1, 2),
-- MTK_PIN_IES_SMT_SPEC(72, 74, IES_EN0, 12),
-- MTK_PIN_IES_SMT_SPEC(75, 76, IES_EN1, 3),
-- MTK_PIN_IES_SMT_SPEC(83, 84, IES_EN1, 2),
-- MTK_PIN_IES_SMT_SPEC(105, 121, MSDC1_CTRL1, 4),
-- MTK_PIN_IES_SMT_SPEC(122, 125, IES_EN1, 7),
-- MTK_PIN_IES_SMT_SPEC(126, 126, IES_EN0, 12),
-- MTK_PIN_IES_SMT_SPEC(199, 201, IES_EN0, 1),
-- MTK_PIN_IES_SMT_SPEC(203, 207, IES_EN2, 2),
-- MTK_PIN_IES_SMT_SPEC(208, 209, IES_EN2, 3),
-- MTK_PIN_IES_SMT_SPEC(236, 241, IES_EN2, 6),
-- MTK_PIN_IES_SMT_SPEC(242, 243, IES_EN2, 7),
-- MTK_PIN_IES_SMT_SPEC(261, 261, MSDC1_CTRL2, 4),
-- MTK_PIN_IES_SMT_SPEC(262, 272, IES_EN2, 12),
-- MTK_PIN_IES_SMT_SPEC(274, 276, IES_EN2, 12),
-- MTK_PIN_IES_SMT_SPEC(278, 278, IES_EN2, 13),
--};
--
--static const struct mtk_pin_ies_smt_set mt7623_smt_set[] = {
-- MTK_PIN_IES_SMT_SPEC(0, 6, SMT_EN0, 0),
-- MTK_PIN_IES_SMT_SPEC(7, 9, SMT_EN0, 1),
-- MTK_PIN_IES_SMT_SPEC(10, 13, SMT_EN0, 2),
-- MTK_PIN_IES_SMT_SPEC(14, 15, SMT_EN0, 3),
-- MTK_PIN_IES_SMT_SPEC(18, 21, SMT_EN0, 5),
-- MTK_PIN_IES_SMT_SPEC(22, 26, SMT_EN0, 6),
-- MTK_PIN_IES_SMT_SPEC(27, 29, SMT_EN0, 7),
-- MTK_PIN_IES_SMT_SPEC(33, 37, SMT_EN0, 8),
-- MTK_PIN_IES_SMT_SPEC(39, 42, SMT_EN0, 9),
-- MTK_PIN_IES_SMT_SPEC(43, 45, SMT_EN0, 10),
-- MTK_PIN_IES_SMT_SPEC(47, 48, SMT_EN0, 11),
-- MTK_PIN_IES_SMT_SPEC(49, 49, SMT_EN0, 12),
-- MTK_PIN_IES_SMT_SPEC(53, 56, SMT_EN0, 14),
-- MTK_PIN_IES_SMT_SPEC(60, 62, SMT_EN1, 0),
-- MTK_PIN_IES_SMT_SPEC(63, 65, SMT_EN1, 1),
-- MTK_PIN_IES_SMT_SPEC(66, 71, SMT_EN1, 2),
-- MTK_PIN_IES_SMT_SPEC(72, 74, SMT_EN0, 12),
-- MTK_PIN_IES_SMT_SPEC(75, 76, SMT_EN1, 3),
-- MTK_PIN_IES_SMT_SPEC(83, 84, SMT_EN1, 2),
-- MTK_PIN_IES_SMT_SPEC(105, 106, MSDC1_CTRL1, 11),
-- MTK_PIN_IES_SMT_SPEC(107, 107, MSDC1_CTRL3, 3),
-- MTK_PIN_IES_SMT_SPEC(108, 108, MSDC1_CTRL3, 7),
-- MTK_PIN_IES_SMT_SPEC(109, 109, MSDC1_CTRL3, 11),
-- MTK_PIN_IES_SMT_SPEC(110, 111, MSDC1_CTRL3, 15),
-- MTK_PIN_IES_SMT_SPEC(112, 112, MSDC0_CTRL4, 11),
-- MTK_PIN_IES_SMT_SPEC(113, 113, MSDC0_CTRL4, 7),
-- MTK_PIN_IES_SMT_SPEC(114, 115, MSDC0_CTRL4, 3),
-- MTK_PIN_IES_SMT_SPEC(116, 117, MSDC0_CTRL1, 11),
-- MTK_PIN_IES_SMT_SPEC(118, 118, MSDC0_CTRL3, 15),
-- MTK_PIN_IES_SMT_SPEC(119, 119, MSDC0_CTRL3, 11),
-- MTK_PIN_IES_SMT_SPEC(120, 120, MSDC0_CTRL3, 7),
-- MTK_PIN_IES_SMT_SPEC(121, 121, MSDC0_CTRL3, 3),
-- MTK_PIN_IES_SMT_SPEC(122, 125, SMT_EN1, 7),
-- MTK_PIN_IES_SMT_SPEC(126, 126, SMT_EN0, 12),
-- MTK_PIN_IES_SMT_SPEC(199, 201, SMT_EN0, 1),
-- MTK_PIN_IES_SMT_SPEC(203, 207, SMT_EN2, 2),
-- MTK_PIN_IES_SMT_SPEC(208, 209, SMT_EN2, 3),
-- MTK_PIN_IES_SMT_SPEC(236, 241, SMT_EN2, 6),
-- MTK_PIN_IES_SMT_SPEC(242, 243, SMT_EN2, 7),
-- MTK_PIN_IES_SMT_SPEC(261, 261, MSDC1_CTRL6, 3),
-- MTK_PIN_IES_SMT_SPEC(262, 272, SMT_EN2, 12),
-- MTK_PIN_IES_SMT_SPEC(274, 276, SMT_EN2, 12),
-- MTK_PIN_IES_SMT_SPEC(278, 278, SMT_EN2, 13),
--};
--
--static int mt7623_ies_smt_set(struct regmap *regmap, unsigned int pin,
-- unsigned char align, int value, enum pin_config_param arg)
--{
-- if (arg == PIN_CONFIG_INPUT_ENABLE)
-- return mtk_pconf_spec_set_ies_smt_range(regmap, mt7623_ies_set,
-- ARRAY_SIZE(mt7623_ies_set), pin, align, value);
-- else if (arg == PIN_CONFIG_INPUT_SCHMITT_ENABLE)
-- return mtk_pconf_spec_set_ies_smt_range(regmap, mt7623_smt_set,
-- ARRAY_SIZE(mt7623_smt_set), pin, align, value);
-- return -EINVAL;
--}
--
--static const struct mtk_pinctrl_devdata mt7623_pinctrl_data = {
-- .pins = mtk_pins_mt7623,
-- .npins = ARRAY_SIZE(mtk_pins_mt7623),
-- .grp_desc = mt7623_drv_grp,
-- .n_grp_cls = ARRAY_SIZE(mt7623_drv_grp),
-- .pin_drv_grp = mt7623_pin_drv,
-- .n_pin_drv_grps = ARRAY_SIZE(mt7623_pin_drv),
-- .spec_pull_set = mt7623_spec_pull_set,
-- .spec_ies_smt_set = mt7623_ies_smt_set,
-- .dir_offset = 0x0000,
-- .pullen_offset = 0x0150,
-- .pullsel_offset = 0x0280,
-- .dout_offset = 0x0500,
-- .din_offset = 0x0630,
-- .pinmux_offset = 0x0760,
-- .type1_start = 280,
-- .type1_end = 280,
-- .port_shf = 4,
-- .port_mask = 0x1f,
-- .port_align = 4,
-- .eint_offsets = {
-- .name = "mt7623_eint",
-- .stat = 0x000,
-- .ack = 0x040,
-- .mask = 0x080,
-- .mask_set = 0x0c0,
-- .mask_clr = 0x100,
-- .sens = 0x140,
-- .sens_set = 0x180,
-- .sens_clr = 0x1c0,
-- .soft = 0x200,
-- .soft_set = 0x240,
-- .soft_clr = 0x280,
-- .pol = 0x300,
-- .pol_set = 0x340,
-- .pol_clr = 0x380,
-- .dom_en = 0x400,
-- .dbnc_ctrl = 0x500,
-- .dbnc_set = 0x600,
-- .dbnc_clr = 0x700,
-- .port_mask = 6,
-- .ports = 6,
-- },
-- .ap_num = 169,
-- .db_cnt = 16,
--};
--
--static int mt7623_pinctrl_probe(struct platform_device *pdev)
--{
-- return mtk_pctrl_init(pdev, &mt7623_pinctrl_data, NULL);
--}
--
--static const struct of_device_id mt7623_pctrl_match[] = {
-- { .compatible = "mediatek,mt7623-pinctrl", },
-- {}
--};
--MODULE_DEVICE_TABLE(of, mt7623_pctrl_match);
--
--static struct platform_driver mtk_pinctrl_driver = {
-- .probe = mt7623_pinctrl_probe,
-- .driver = {
-- .name = "mediatek-mt7623-pinctrl",
-- .of_match_table = mt7623_pctrl_match,
-- },
--};
--
--static int __init mtk_pinctrl_init(void)
--{
-- return platform_driver_register(&mtk_pinctrl_driver);
--}
--
--arch_initcall(mtk_pinctrl_init);
---- a/include/dt-bindings/pinctrl/mt7623-pinfunc.h
-+++ b/include/dt-bindings/pinctrl/mt7623-pinfunc.h
-@@ -185,6 +185,12 @@
- #define MT7623_PIN_56_SPI0_MO_FUNC_SPI0_MO (MTK_PIN_NO(56) | 1)
- #define MT7623_PIN_56_SPI0_MO_FUNC_SPI0_MI (MTK_PIN_NO(56) | 2)
-
-+#define MT7623_PIN_57_SDA1_FUNC_GPIO57 (MTK_PIN_NO(57) | 0)
-+#define MT7623_PIN_57_SDA1_FUNC_SDA1 (MTK_PIN_NO(57) | 1)
-+
-+#define MT7623_PIN_58_SCL1_FUNC_GPIO58 (MTK_PIN_NO(58) | 0)
-+#define MT7623_PIN_58_SCL1_FUNC_SCL1 (MTK_PIN_NO(58) | 1)
-+
- #define MT7623_PIN_60_WB_RSTB_FUNC_GPIO60 (MTK_PIN_NO(60) | 0)
- #define MT7623_PIN_60_WB_RSTB_FUNC_WB_RSTB (MTK_PIN_NO(60) | 1)
-
-@@ -244,6 +250,22 @@
- #define MT7623_PIN_76_SCL0_FUNC_GPIO76 (MTK_PIN_NO(76) | 0)
- #define MT7623_PIN_76_SCL0_FUNC_SCL0 (MTK_PIN_NO(76) | 1)
-
-+#define MT7623_PIN_79_URXD0_FUNC_GPIO79 (MTK_PIN_NO(79) | 0)
-+#define MT7623_PIN_79_URXD0_FUNC_URXD0 (MTK_PIN_NO(79) | 1)
-+#define MT7623_PIN_79_URXD0_FUNC_UTXD0 (MTK_PIN_NO(79) | 2)
-+
-+#define MT7623_PIN_80_UTXD0_FUNC_GPIO80 (MTK_PIN_NO(80) | 0)
-+#define MT7623_PIN_80_UTXD0_FUNC_UTXD0 (MTK_PIN_NO(80) | 1)
-+#define MT7623_PIN_80_UTXD0_FUNC_URXD0 (MTK_PIN_NO(80) | 2)
-+
-+#define MT7623_PIN_81_URXD1_FUNC_GPIO81 (MTK_PIN_NO(81) | 0)
-+#define MT7623_PIN_81_URXD1_FUNC_URXD1 (MTK_PIN_NO(81) | 1)
-+#define MT7623_PIN_81_URXD1_FUNC_UTXD1 (MTK_PIN_NO(81) | 2)
-+
-+#define MT7623_PIN_82_UTXD1_FUNC_GPIO82 (MTK_PIN_NO(82) | 0)
-+#define MT7623_PIN_82_UTXD1_FUNC_UTXD1 (MTK_PIN_NO(82) | 1)
-+#define MT7623_PIN_82_UTXD1_FUNC_URXD1 (MTK_PIN_NO(82) | 2)
-+
- #define MT7623_PIN_83_LCM_RST_FUNC_GPIO83 (MTK_PIN_NO(83) | 0)
- #define MT7623_PIN_83_LCM_RST_FUNC_LCM_RST (MTK_PIN_NO(83) | 1)
-
-@@ -351,10 +373,10 @@
- #define MT7623_PIN_122_GPIO122_FUNC_SDA2 (MTK_PIN_NO(122) | 4)
- #define MT7623_PIN_122_GPIO122_FUNC_URXD0 (MTK_PIN_NO(122) | 5)
-
--#define MT7623_PIN_123_GPIO123_FUNC_GPIO123 (MTK_PIN_NO(123) | 0)
--#define MT7623_PIN_123_GPIO123_FUNC_TEST (MTK_PIN_NO(123) | 1)
--#define MT7623_PIN_123_GPIO123_FUNC_SCL2 (MTK_PIN_NO(123) | 4)
--#define MT7623_PIN_123_GPIO123_FUNC_UTXD0 (MTK_PIN_NO(123) | 5)
-+#define MT7623_PIN_123_HTPLG_FUNC_GPIO123 (MTK_PIN_NO(123) | 0)
-+#define MT7623_PIN_123_HTPLG_FUNC_HTPLG (MTK_PIN_NO(123) | 1)
-+#define MT7623_PIN_123_HTPLG_FUNC_SCL2 (MTK_PIN_NO(123) | 4)
-+#define MT7623_PIN_123_HTPLG_FUNC_UTXD0 (MTK_PIN_NO(123) | 5)
-
- #define MT7623_PIN_124_GPIO124_FUNC_GPIO124 (MTK_PIN_NO(124) | 0)
- #define MT7623_PIN_124_GPIO124_FUNC_TEST (MTK_PIN_NO(124) | 1)
diff --git a/target/linux/mediatek/patches-4.9/0059-eth-fixes.patch b/target/linux/mediatek/patches-4.9/0059-eth-fixes.patch
deleted file mode 100644
index c155961862..0000000000
--- a/target/linux/mediatek/patches-4.9/0059-eth-fixes.patch
+++ /dev/null
@@ -1,511 +0,0 @@
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -24,6 +24,7 @@
- #include <linux/tcp.h>
-
- #if defined(CONFIG_NET_MEDIATEK_HW_QOS)
-+
- struct mtk_ioctl_reg {
- unsigned int off;
- unsigned int val;
-@@ -32,6 +33,13 @@ struct mtk_ioctl_reg {
- #define REG_HQOS_MAX 0x3FFF
- #define RAETH_QDMA_REG_READ 0x89F8
- #define RAETH_QDMA_REG_WRITE 0x89F9
-+#define RAETH_QDMA_QUEUE_MAPPING 0x89FA
-+
-+unsigned int M2Q_table[16] = {0};
-+unsigned int lan_wan_separate = 0;
-+
-+EXPORT_SYMBOL_GPL(M2Q_table);
-+
- #endif
-
- #if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE)
-@@ -225,7 +233,7 @@ static void mtk_phy_link_adjust(struct n
- if (flowctrl & FLOW_CTRL_RX)
- mcr |= MAC_MCR_FORCE_RX_FC;
-
-- netif_dbg(mac->hw, link, dev, "rx pause %s, tx pause %s\n",
-+ netif_info(mac->hw, link, dev, "rx pause %s, tx pause %s\n",
- flowctrl & FLOW_CTRL_RX ? "enabled" : "disabled",
- flowctrl & FLOW_CTRL_TX ? "enabled" : "disabled");
- }
-@@ -508,9 +516,9 @@ static struct rtnl_link_stats64 * mtk_ge
- unsigned int start;
-
- if (netif_running(dev) && netif_device_present(dev)) {
-- if (spin_trylock_bh(&hw_stats->stats_lock)) {
-+ if (spin_trylock(&hw_stats->stats_lock)) {
- mtk_stats_update_mac(mac);
-- spin_unlock_bh(&hw_stats->stats_lock);
-+ spin_unlock(&hw_stats->stats_lock);
- }
- }
-
-@@ -690,6 +698,7 @@ static int mtk_tx_map(struct sk_buff *sk
- txd3 |= skb->mark & 0x7;
- if (mac->id)
- txd3 += 8;
-+ txd3 = 0;
- #endif
-
- mapped_addr = dma_map_single(eth->dev, skb->data,
-@@ -760,16 +769,7 @@ static int mtk_tx_map(struct sk_buff *sk
- WRITE_ONCE(itxd->txd3, (TX_DMA_SWC | TX_DMA_PLEN0(skb_headlen(skb)) |
- (!nr_frags * TX_DMA_LS0)));
-
-- /* we have a single DMA ring so BQL needs to be updated for all devices
-- * sitting on this ring
-- */
-- for (i = 0; i < MTK_MAC_COUNT; i++) {
-- if (!eth->netdev[i])
-- continue;
--
-- netdev_sent_queue(eth->netdev[i], skb->len);
-- }
--
-+ netdev_sent_queue(dev, skb->len);
- skb_tx_timestamp(skb);
-
- ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2);
-@@ -980,20 +980,9 @@ static int mtk_poll_rx(struct napi_struc
- if (!(trxd.rxd2 & RX_DMA_DONE))
- break;
-
-- /* find out which mac the packet comes from. If the special tag is
-- * we can assume that the traffic is coming from the builtin mt7530
-- * and the DSA driver has loaded. FPORT will be the physical switch
-- * port in this case rather than the FE forward port id. */
-- if (!(trxd.rxd4 & RX_DMA_SP_TAG)) {
-- /* values start at 1 */
-- mac = (trxd.rxd4 >> RX_DMA_FPORT_SHIFT) &
-- RX_DMA_FPORT_MASK;
-- mac--;
-- }
--
-- if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
-- !eth->netdev[mac]))
-- goto release_desc;
-+ /* find out which mac the packet come from. values start at 1 */
-+ mac = (trxd.rxd4 >> 22) & 0x1;
-+ mac = (mac + 1) % 2;
-
- netdev = eth->netdev[mac];
-
-@@ -1017,6 +1006,9 @@ static int mtk_poll_rx(struct napi_struc
- }
-
- /* receive data */
-+ if (mac < 0 || mac > 2)
-+ mac = 0;
-+
- skb = build_skb(data, ring->frag_size);
- if (unlikely(!skb)) {
- skb_free_frag(new_data);
-@@ -1076,18 +1068,21 @@ static int mtk_poll_tx(struct mtk_eth *e
- struct mtk_tx_dma *desc;
- struct sk_buff *skb;
- struct mtk_tx_buf *tx_buf;
-- int total = 0, done = 0;
-- unsigned int bytes = 0;
-+ unsigned int done[MTK_MAX_DEVS];
-+ unsigned int bytes[MTK_MAX_DEVS];
- u32 cpu, dma;
- static int condition;
-- int i;
-+ int total = 0, i;
-+
-+ memset(done, 0, sizeof(done));
-+ memset(bytes, 0, sizeof(bytes));
-
- cpu = mtk_r32(eth, MTK_QTX_CRX_PTR);
- dma = mtk_r32(eth, MTK_QTX_DRX_PTR);
-
- desc = mtk_qdma_phys_to_virt(ring, cpu);
-
-- while ((cpu != dma) && done < budget) {
-+ while ((cpu != dma) && budget) {
- u32 next_cpu = desc->txd2;
- int mac = 0;
-
-@@ -1106,8 +1101,9 @@ static int mtk_poll_tx(struct mtk_eth *e
- }
-
- if (skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC) {
-- bytes += skb->len;
-- done++;
-+ bytes[mac] += skb->len;
-+ done[mac]++;
-+ budget--;
- }
- mtk_tx_unmap(eth, tx_buf);
-
-@@ -1119,13 +1115,11 @@ static int mtk_poll_tx(struct mtk_eth *e
-
- mtk_w32(eth, cpu, MTK_QTX_CRX_PTR);
-
-- /* we have a single DMA ring so BQL needs to be updated for all devices
-- * sitting on this ring
-- */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
-- if (!eth->netdev[i])
-+ if (!eth->netdev[i] || !done[i])
- continue;
-- netdev_completed_queue(eth->netdev[i], done, bytes);
-+ netdev_completed_queue(eth->netdev[i], done[i], bytes[i]);
-+ total += done[i];
- }
-
- if (mtk_queue_stopped(eth) &&
-@@ -1286,21 +1280,11 @@ static void mtk_tx_clean(struct mtk_eth
-
- static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
- {
-- struct mtk_rx_ring *ring;
-+ struct mtk_rx_ring *ring = &eth->rx_ring[ring_no];
- int rx_data_len, rx_dma_size;
- int i;
-- u32 offset = 0;
--
-- if (rx_flag & MTK_RX_FLAGS_QDMA) {
-- if (ring_no)
-- return -EINVAL;
-- ring = &eth->rx_ring_qdma;
-- offset = 0x1000;
-- } else {
-- ring = &eth->rx_ring[ring_no];
-- }
-
-- if (rx_flag & MTK_RX_FLAGS_HWLRO) {
-+ if (rx_flag == MTK_RX_FLAGS_HWLRO) {
- rx_data_len = MTK_MAX_LRO_RX_LENGTH;
- rx_dma_size = MTK_HW_LRO_DMA_SIZE;
- } else {
-@@ -1348,16 +1332,104 @@ static int mtk_rx_alloc(struct mtk_eth *
- */
- wmb();
-
-- mtk_w32(eth, ring->phys, MTK_PRX_BASE_PTR_CFG(ring_no) + offset);
-- mtk_w32(eth, rx_dma_size, MTK_PRX_MAX_CNT_CFG(ring_no) + offset);
-- mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg + offset);
-- mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), MTK_PDMA_RST_IDX + offset);
-+ mtk_w32(eth, ring->phys, MTK_PRX_BASE_PTR_CFG(ring_no));
-+ mtk_w32(eth, rx_dma_size, MTK_PRX_MAX_CNT_CFG(ring_no));
-+ mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg);
-+ mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), MTK_PDMA_RST_IDX);
-
- return 0;
- }
-
--static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring)
-+static int mtk_rx_alloc_qdma(struct mtk_eth *eth, int rx_flag)
- {
-+ struct mtk_rx_ring *ring = &eth->rx_ring_qdma;
-+ int rx_data_len, rx_dma_size;
-+ int i;
-+
-+ rx_data_len = ETH_DATA_LEN;
-+ rx_dma_size = MTK_DMA_SIZE;
-+
-+ ring->frag_size = mtk_max_frag_size(rx_data_len);
-+ ring->buf_size = mtk_max_buf_size(ring->frag_size);
-+ ring->data = kcalloc(rx_dma_size, sizeof(*ring->data),
-+ GFP_KERNEL);
-+ if (!ring->data)
-+ return -ENOMEM;
-+
-+ for (i = 0; i < rx_dma_size; i++) {
-+ ring->data[i] = netdev_alloc_frag(ring->frag_size);
-+ if (!ring->data[i])
-+ return -ENOMEM;
-+ }
-+
-+ ring->dma = dma_alloc_coherent(eth->dev,
-+ rx_dma_size * sizeof(*ring->dma),
-+ &ring->phys,
-+ GFP_ATOMIC | __GFP_ZERO);
-+ if (!ring->dma)
-+ return -ENOMEM;
-+
-+ for (i = 0; i < rx_dma_size; i++) {
-+ dma_addr_t dma_addr = dma_map_single(eth->dev,
-+ ring->data[i] + NET_SKB_PAD,
-+ ring->buf_size,
-+ DMA_FROM_DEVICE);
-+ if (unlikely(dma_mapping_error(eth->dev, dma_addr)))
-+ return -ENOMEM;
-+ ring->dma[i].rxd1 = (unsigned int)dma_addr;
-+
-+ ring->dma[i].rxd2 = RX_DMA_PLEN0(ring->buf_size);
-+ }
-+ ring->dma_size = rx_dma_size;
-+ ring->calc_idx_update = false;
-+ ring->calc_idx = rx_dma_size - 1;
-+ ring->crx_idx_reg = MTK_QRX_CRX_IDX_CFG(0);
-+ /* make sure that all changes to the dma ring are flushed before we
-+ * continue
-+ */
-+ wmb();
-+
-+ mtk_w32(eth, ring->phys, MTK_QRX_BASE_PTR_CFG(0));
-+ mtk_w32(eth, rx_dma_size, MTK_QRX_MAX_CNT_CFG(0));
-+ mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg);
-+ mtk_w32(eth, MTK_PST_DRX_IDX_CFG(0), MTK_QDMA_RST_IDX);
-+
-+ return 0;
-+}
-+
-+static void mtk_rx_clean(struct mtk_eth *eth, int ring_no)
-+{
-+ struct mtk_rx_ring *ring = &eth->rx_ring[ring_no];
-+ int i;
-+
-+ if (ring->data && ring->dma) {
-+ for (i = 0; i < ring->dma_size; i++) {
-+ if (!ring->data[i])
-+ continue;
-+ if (!ring->dma[i].rxd1)
-+ continue;
-+ dma_unmap_single(eth->dev,
-+ ring->dma[i].rxd1,
-+ ring->buf_size,
-+ DMA_FROM_DEVICE);
-+ skb_free_frag(ring->data[i]);
-+ }
-+ kfree(ring->data);
-+ ring->data = NULL;
-+ }
-+
-+ if (ring->dma) {
-+ dma_free_coherent(eth->dev,
-+ ring->dma_size * sizeof(*ring->dma),
-+ ring->dma,
-+ ring->phys);
-+ ring->dma = NULL;
-+ }
-+}
-+
-+static void mtk_rx_clean_qdma(struct mtk_eth *eth)
-+{
-+ struct mtk_rx_ring *ring = &eth->rx_ring_qdma;
- int i;
-
- if (ring->data && ring->dma) {
-@@ -1683,7 +1755,7 @@ static int mtk_dma_init(struct mtk_eth *
- if (err)
- return err;
-
-- err = mtk_rx_alloc(eth, 0, MTK_RX_FLAGS_QDMA);
-+ err = mtk_rx_alloc_qdma(eth, MTK_RX_FLAGS_NORMAL);
- if (err)
- return err;
-
-@@ -1702,6 +1774,7 @@ static int mtk_dma_init(struct mtk_eth *
- return err;
- }
-
-+
- /* Enable random early drop and set drop threshold automatically */
- mtk_w32(eth, FC_THRES_DROP_MODE | FC_THRES_DROP_EN | FC_THRES_MIN,
- MTK_QDMA_FC_THRES);
-@@ -1726,13 +1799,13 @@ static void mtk_dma_free(struct mtk_eth
- eth->phy_scratch_ring = 0;
- }
- mtk_tx_clean(eth);
-- mtk_rx_clean(eth, &eth->rx_ring[0]);
-- mtk_rx_clean(eth, &eth->rx_ring_qdma);
-+ mtk_rx_clean(eth, 0);
-+ mtk_rx_clean_qdma(eth);
-
- if (eth->hwlro) {
- mtk_hwlro_rx_uninit(eth);
- for (i = 1; i < MTK_MAX_RX_RING_NUM; i++)
-- mtk_rx_clean(eth, &eth->rx_ring[i]);
-+ mtk_rx_clean(eth, i);
- }
-
- kfree(eth->scratch_head);
-@@ -1947,20 +2020,14 @@ static int mtk_hw_init(struct mtk_eth *e
- val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
- mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
-
-- /* Indicates CDM to parse the MTK special tag from CPU
-- * which also is working out for untag packets.
-- */
-- val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
-- mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
-- val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
-- mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
--
- /* Enable RX VLan Offloading */
- if (MTK_HW_FEATURES & NETIF_F_HW_VLAN_CTAG_RX)
- mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
- else
- mtk_w32(eth, 0, MTK_CDMP_EG_CTRL);
-
-+ mtk_w32(eth, 0x81000001, MTK_CDMP_IG_CTRL);
-+
- /* disable delay and normal interrupt */
- #ifdef MTK_IRQ_DLY
- mtk_w32(eth, 0x84048404, MTK_PDMA_DELAY_INT);
-@@ -1990,6 +2057,9 @@ static int mtk_hw_init(struct mtk_eth *e
- /* Enable RX checksum */
- val |= MTK_GDMA_ICS_EN | MTK_GDMA_TCS_EN | MTK_GDMA_UCS_EN;
-
-+ if (!i)
-+ val |= BIT(24);
-+
- /* setup the mac dma */
- mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
- }
-@@ -2069,7 +2139,18 @@ static int mtk_do_ioctl(struct net_devic
- if (reg.off > REG_HQOS_MAX)
- return -EINVAL;
- mtk_w32(eth, reg.val, 0x1800 + reg.off);
--// printk("write reg off:%x val:%x\n", reg.off, reg.val);
-+ printk("write reg off:%x val:%x\n", reg.off, reg.val);
-+ return 0;
-+
-+ case RAETH_QDMA_QUEUE_MAPPING:
-+ copy_from_user(&reg, ifr->ifr_data, sizeof(reg));
-+ if ((reg.off & 0x100) == 0x100) {
-+ lan_wan_separate = 1;
-+ reg.off &= 0xff;
-+ } else {
-+ lan_wan_separate = 0;
-+ }
-+ M2Q_table[reg.off] = reg.val;
- return 0;
- #endif
- case SIOCGMIIPHY:
-@@ -2288,9 +2369,9 @@ static void mtk_get_ethtool_stats(struct
- return;
-
- if (netif_running(dev) && netif_device_present(dev)) {
-- if (spin_trylock_bh(&hwstats->stats_lock)) {
-+ if (spin_trylock(&hwstats->stats_lock)) {
- mtk_stats_update_mac(mac);
-- spin_unlock_bh(&hwstats->stats_lock);
-+ spin_unlock(&hwstats->stats_lock);
- }
- }
-
-@@ -2443,7 +2524,7 @@ static int mtk_add_mac(struct mtk_eth *e
- mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
-
- SET_NETDEV_DEV(eth->netdev[id], eth->dev);
-- eth->netdev[id]->watchdog_timeo = 30 * HZ;
-+ eth->netdev[id]->watchdog_timeo = 15 * HZ;
- eth->netdev[id]->netdev_ops = &mtk_netdev_ops;
- eth->netdev[id]->base_addr = (unsigned long)eth->base;
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -80,7 +80,6 @@
-
- /* CDMP Ingress Control Register */
- #define MTK_CDMP_IG_CTRL 0x400
--#define MTK_CDMP_STAG_EN BIT(0)
-
- /* CDMP Exgress Control Register */
- #define MTK_CDMP_EG_CTRL 0x404
-@@ -91,12 +90,27 @@
- #define MTK_GDMA_TCS_EN BIT(21)
- #define MTK_GDMA_UCS_EN BIT(20)
-
-+/* GDMA Ingress Control Register */
-+#define MTK_GDMA1_IG_CTRL(x) (0x500 + (x * 0x1000))
-+
- /* Unicast Filter MAC Address Register - Low */
- #define MTK_GDMA_MAC_ADRL(x) (0x508 + (x * 0x1000))
-
- /* Unicast Filter MAC Address Register - High */
- #define MTK_GDMA_MAC_ADRH(x) (0x50C + (x * 0x1000))
-
-+/* QDMA RX Base Pointer Register */
-+#define MTK_QRX_BASE_PTR0 0x1900
-+#define MTK_QRX_BASE_PTR_CFG(x) (MTK_QRX_BASE_PTR0 + (x * 0x10))
-+
-+/* QDMA RX Maximum Count Register */
-+#define MTK_QRX_MAX_CNT0 0x1904
-+#define MTK_QRX_MAX_CNT_CFG(x) (MTK_QRX_MAX_CNT0 + (x * 0x10))
-+
-+/* QDMA RX CPU Pointer Register */
-+#define MTK_QRX_CRX_IDX0 0x1908
-+#define MTK_QRX_CRX_IDX_CFG(x) (MTK_QRX_CRX_IDX0 + (x * 0x10))
-+
- /* PDMA RX Base Pointer Register */
- #define MTK_PRX_BASE_PTR0 0x900
- #define MTK_PRX_BASE_PTR_CFG(x) (MTK_PRX_BASE_PTR0 + (x * 0x10))
-@@ -240,7 +254,10 @@
- #define MTK_QDMA_INT_MASK 0x1A1C
-
- /* QDMA Interrupt Mask Register */
-+#define MTK_QDMA_HRED1 0x1A40
- #define MTK_QDMA_HRED2 0x1A44
-+#define MTK_QDMA_SRED1 0x1A48
-+#define MTK_QDMA_SRED2 0x1A4c
-
- /* QDMA TX Forward CPU Pointer Register */
- #define MTK_QTX_CTX_PTR 0x1B00
-@@ -275,6 +292,7 @@
- #define TX_DMA_TSO BIT(28)
- #define TX_DMA_FPORT_SHIFT 25
- #define TX_DMA_FPORT_MASK 0x7
-+#define TX_DMA_VQID0 BIT(17)
- #define TX_DMA_INS_VLAN BIT(16)
-
- /* QDMA descriptor txd3 */
-@@ -294,7 +312,6 @@
-
- /* QDMA descriptor rxd4 */
- #define RX_DMA_L4_VALID BIT(24)
--#define RX_DMA_SP_TAG BIT(22)
- #define RX_DMA_FPORT_SHIFT 19
- #define RX_DMA_FPORT_MASK 0x7
-
-@@ -310,6 +327,7 @@
-
- /* Mac control registers */
- #define MTK_MAC_MCR(x) (0x10100 + (x * 0x100))
-+#define MTK_MAC_MSR(x) (0x10108 + (x * 0x100))
- #define MAC_MCR_MAX_RX_1536 BIT(24)
- #define MAC_MCR_IPG_CFG (BIT(18) | BIT(16))
- #define MAC_MCR_FORCE_MODE BIT(15)
-@@ -495,7 +513,6 @@ struct mtk_tx_ring {
- enum mtk_rx_flags {
- MTK_RX_FLAGS_NORMAL = 0,
- MTK_RX_FLAGS_HWLRO,
-- MTK_RX_FLAGS_QDMA,
- };
-
- /* struct mtk_rx_ring - This struct holds info describing a RX ring
-@@ -539,9 +556,9 @@ struct mtk_rx_ring {
- * @pctl: The register map pointing at the range used to setup
- * GMAC port drive/slew values
- * @dma_refcnt: track how many netdevs are using the DMA engine
-- * @tx_ring: Pointer to the memory holding info about the TX ring
-- * @rx_ring: Pointer to the memory holding info about the RX ring
-- * @rx_ring_qdma: Pointer to the memory holding info about the QDMA RX ring
-+ * @tx_ring: Pointer to the memore holding info about the TX ring
-+ * @rx_ring: Pointer to the memore holding info about the RX ring
-+ * @rx_ring_qdma: Pointer to the memore holding info about the RX ring (QDMA)
- * @tx_napi: The TX NAPI struct
- * @rx_napi: The RX NAPI struct
- * @scratch_ring: Newer SoCs need memory for a second HW managed TX ring
-@@ -563,6 +580,7 @@ struct mtk_eth {
- struct net_device *netdev[MTK_MAX_DEVS];
- struct mtk_mac *mac[MTK_MAX_DEVS];
- int irq[3];
-+ cpumask_t affinity_mask[3];
- u32 msg_enable;
- unsigned long sysclk;
- struct regmap *ethsys;
-@@ -615,4 +633,6 @@ void mtk_stats_update_mac(struct mtk_mac
- void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg);
- u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
-
-+extern unsigned int M2Q_table[16];
-+
- #endif /* MTK_ETH_H */
diff --git a/target/linux/mediatek/patches-4.9/0060-eth-debug.patch b/target/linux/mediatek/patches-4.9/0060-eth-debug.patch
deleted file mode 100644
index 902a72ed8e..0000000000
--- a/target/linux/mediatek/patches-4.9/0060-eth-debug.patch
+++ /dev/null
@@ -1,69 +0,0 @@
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -851,6 +851,7 @@ static void mtk_stop_queue(struct mtk_et
- continue;
- netif_stop_queue(eth->netdev[i]);
- }
-+ mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
- }
-
- static int mtk_start_xmit(struct sk_buff *skb, struct net_device *dev)
-@@ -1885,6 +1886,19 @@ static int mtk_start_dma(struct mtk_eth
- return 0;
- }
-
-+#define NAPI_TIMER_EXPIRE HZ
-+
-+static void napi_timer_handler(unsigned long priv)
-+{
-+ struct mtk_eth *eth = (struct mtk_eth*) priv;
-+
-+ mtk_wake_queue(eth);
-+ mtk_handle_irq_rx(0, eth);
-+ mtk_handle_irq_tx(0, eth);
-+
-+ mod_timer(&eth->napi_timer, jiffies + NAPI_TIMER_EXPIRE);
-+}
-+
- static int mtk_open(struct net_device *dev)
- {
- struct mtk_mac *mac = netdev_priv(dev);
-@@ -1901,6 +1915,9 @@ static int mtk_open(struct net_device *d
- napi_enable(&eth->rx_napi);
- mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
- mtk_rx_irq_enable(eth, MTK_RX_DONE_INT);
-+
-+ setup_timer(&eth->napi_timer, napi_timer_handler, (unsigned long) eth);
-+ mod_timer(&eth->napi_timer, jiffies + NAPI_TIMER_EXPIRE);
- }
- atomic_inc(&eth->dma_refcnt);
-
-@@ -1945,6 +1962,8 @@ static int mtk_stop(struct net_device *d
- if (!atomic_dec_and_test(&eth->dma_refcnt))
- return 0;
-
-+ del_timer(&eth->napi_timer);
-+
- mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
- mtk_rx_irq_disable(eth, MTK_RX_DONE_INT);
- napi_disable(&eth->tx_napi);
-@@ -2524,7 +2543,7 @@ static int mtk_add_mac(struct mtk_eth *e
- mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
-
- SET_NETDEV_DEV(eth->netdev[id], eth->dev);
-- eth->netdev[id]->watchdog_timeo = 15 * HZ;
-+ eth->netdev[id]->watchdog_timeo = 30 * HZ;
- eth->netdev[id]->netdev_ops = &mtk_netdev_ops;
- eth->netdev[id]->base_addr = (unsigned long)eth->base;
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -601,6 +601,8 @@ struct mtk_eth {
- struct mii_bus *mii_bus;
- struct work_struct pending_work;
- unsigned long state;
-+
-+ struct timer_list napi_timer;
- };
-
- /* struct mtk_mac - the structure that holds the info about the MACs of the
diff --git a/target/linux/mediatek/patches-4.9/0061-eth-up_down_lock.patch b/target/linux/mediatek/patches-4.9/0061-eth-up_down_lock.patch
deleted file mode 100644
index e6f1cf69d6..0000000000
--- a/target/linux/mediatek/patches-4.9/0061-eth-up_down_lock.patch
+++ /dev/null
@@ -1,72 +0,0 @@
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1904,12 +1904,16 @@ static int mtk_open(struct net_device *d
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
-
-+ spin_lock(&eth->iface_lock);
-+
- /* we run 2 netdevs on the same dma ring so we only bring it up once */
- if (!atomic_read(&eth->dma_refcnt)) {
- int err = mtk_start_dma(eth);
-
-- if (err)
-+ if (err) {
-+ spin_unlock(&eth->iface_lock);
- return err;
-+ }
-
- napi_enable(&eth->tx_napi);
- napi_enable(&eth->rx_napi);
-@@ -1923,6 +1927,7 @@ static int mtk_open(struct net_device *d
-
- phy_start(dev->phydev);
- netif_start_queue(dev);
-+ spin_unlock(&eth->iface_lock);
-
- return 0;
- }
-@@ -1955,12 +1960,15 @@ static int mtk_stop(struct net_device *d
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
-
-+ spin_lock(&eth->iface_lock);
- netif_tx_disable(dev);
- phy_stop(dev->phydev);
-
- /* only shutdown DMA if this is the last user */
-- if (!atomic_dec_and_test(&eth->dma_refcnt))
-+ if (!atomic_dec_and_test(&eth->dma_refcnt)) {
-+ spin_unlock(&eth->iface_lock);
- return 0;
-+ }
-
- del_timer(&eth->napi_timer);
-
-@@ -1974,6 +1982,8 @@ static int mtk_stop(struct net_device *d
-
- mtk_dma_free(eth);
-
-+ spin_unlock(&eth->iface_lock);
-+
- return 0;
- }
-
-@@ -2623,6 +2633,7 @@ static int mtk_probe(struct platform_dev
- if (IS_ERR(eth->base))
- return PTR_ERR(eth->base);
-
-+ spin_lock_init(&eth->iface_lock);
- spin_lock_init(&eth->page_lock);
- spin_lock_init(&eth->tx_irq_lock);
- spin_lock_init(&eth->rx_irq_lock);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -573,6 +573,7 @@ struct mtk_rx_ring {
- struct mtk_eth {
- struct device *dev;
- void __iomem *base;
-+ spinlock_t iface_lock;
- spinlock_t page_lock;
- spinlock_t tx_irq_lock;
- spinlock_t rx_irq_lock;
diff --git a/target/linux/mediatek/patches-4.9/0062-mdio-atomic.patch b/target/linux/mediatek/patches-4.9/0062-mdio-atomic.patch
deleted file mode 100644
index 96e7072a33..0000000000
--- a/target/linux/mediatek/patches-4.9/0062-mdio-atomic.patch
+++ /dev/null
@@ -1,14 +0,0 @@
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -97,7 +97,10 @@ static int mtk_mdio_busy_wait(struct mtk
- return 0;
- if (time_after(jiffies, t_start + PHY_IAC_TIMEOUT))
- break;
-- usleep_range(10, 20);
-+ if (in_atomic())
-+ udelay(10);
-+ else
-+ usleep_range(10, 20);
- }
-
- dev_err(eth->dev, "mdio: MDIO timeout\n");
diff --git a/target/linux/mediatek/patches-4.9/0063-atomic-sleep.patch b/target/linux/mediatek/patches-4.9/0063-atomic-sleep.patch
deleted file mode 100644
index 095ce74a4f..0000000000
--- a/target/linux/mediatek/patches-4.9/0063-atomic-sleep.patch
+++ /dev/null
@@ -1,38 +0,0 @@
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1533,7 +1533,10 @@ static void mtk_hwlro_rx_uninit(struct m
- for (i = 0; i < 10; i++) {
- val = mtk_r32(eth, MTK_PDMA_LRO_CTRL_DW0);
- if (val & MTK_LRO_RING_RELINQUISH_DONE) {
-- msleep(20);
-+ if (in_atomic())
-+ mdelay(20);
-+ else
-+ msleep(20);
- continue;
- }
- break;
-@@ -1951,7 +1954,10 @@ static void mtk_stop_dma(struct mtk_eth
- for (i = 0; i < 10; i++) {
- val = mtk_r32(eth, glo_cfg);
- if (val & (MTK_TX_DMA_BUSY | MTK_RX_DMA_BUSY)) {
-- msleep(20);
-+ if (in_atomic())
-+ mdelay(20);
-+ else
-+ msleep(20);
- continue;
- }
- break;
-@@ -1996,7 +2002,10 @@ static void ethsys_reset(struct mtk_eth
- reset_bits,
- reset_bits);
-
-- usleep_range(1000, 1100);
-+ if (in_atomic())
-+ udelay(1000);
-+ else
-+ usleep_range(1000, 1100);
- regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL,
- reset_bits,
- ~reset_bits);