aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ipq806x/patches-4.1/701-stmmac_update_to_4.3.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/ipq806x/patches-4.1/701-stmmac_update_to_4.3.patch')
-rw-r--r--target/linux/ipq806x/patches-4.1/701-stmmac_update_to_4.3.patch2355
1 files changed, 0 insertions, 2355 deletions
diff --git a/target/linux/ipq806x/patches-4.1/701-stmmac_update_to_4.3.patch b/target/linux/ipq806x/patches-4.1/701-stmmac_update_to_4.3.patch
deleted file mode 100644
index 22450d4bbe..0000000000
--- a/target/linux/ipq806x/patches-4.1/701-stmmac_update_to_4.3.patch
+++ /dev/null
@@ -1,2355 +0,0 @@
---- a/drivers/net/ethernet/stmicro/Kconfig
-+++ b/drivers/net/ethernet/stmicro/Kconfig
-@@ -7,9 +7,7 @@ config NET_VENDOR_STMICRO
- default y
- depends on HAS_IOMEM
- ---help---
-- If you have a network (Ethernet) card belonging to this class, say Y
-- and read the Ethernet-HOWTO, available from
-- <http://www.tldp.org/docs.html#howto>.
-+ If you have a network (Ethernet) card belonging to this class, say Y.
-
- Note that the answer to this question doesn't directly affect the
- kernel: saying N will just cause the configurator to skip all
---- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
-+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
-@@ -16,6 +16,7 @@ if STMMAC_ETH
- config STMMAC_PLATFORM
- tristate "STMMAC Platform bus support"
- depends on STMMAC_ETH
-+ select MFD_SYSCON
- default y
- ---help---
- This selects the platform specific bus support for the stmmac driver.
-@@ -26,6 +27,95 @@ config STMMAC_PLATFORM
-
- If unsure, say N.
-
-+if STMMAC_PLATFORM
-+
-+config DWMAC_GENERIC
-+ tristate "Generic driver for DWMAC"
-+ default STMMAC_PLATFORM
-+ ---help---
-+ Generic DWMAC driver for platforms that don't require any
-+ platform specific code to function or is using platform
-+ data for setup.
-+
-+config DWMAC_IPQ806X
-+ tristate "QCA IPQ806x DWMAC support"
-+ default ARCH_QCOM
-+ depends on OF
-+ select MFD_SYSCON
-+ help
-+ Support for QCA IPQ806X DWMAC Ethernet.
-+
-+ This selects the IPQ806x SoC glue layer support for the stmmac
-+ device driver. This driver does not use any of the hardware
-+ acceleration features available on this SoC. Network devices
-+ will behave like standard non-accelerated ethernet interfaces.
-+
-+config DWMAC_LPC18XX
-+ tristate "NXP LPC18xx/43xx DWMAC support"
-+ default ARCH_LPC18XX
-+ depends on OF
-+ select MFD_SYSCON
-+ ---help---
-+ Support for NXP LPC18xx/43xx DWMAC Ethernet.
-+
-+config DWMAC_MESON
-+ tristate "Amlogic Meson dwmac support"
-+ default ARCH_MESON
-+ depends on OF
-+ help
-+ Support for Ethernet controller on Amlogic Meson SoCs.
-+
-+ This selects the Amlogic Meson SoC glue layer support for
-+ the stmmac device driver. This driver is used for Meson6 and
-+ Meson8 SoCs.
-+
-+config DWMAC_ROCKCHIP
-+ tristate "Rockchip dwmac support"
-+ default ARCH_ROCKCHIP
-+ depends on OF
-+ select MFD_SYSCON
-+ help
-+ Support for Ethernet controller on Rockchip RK3288 SoC.
-+
-+ This selects the Rockchip RK3288 SoC glue layer support for
-+ the stmmac device driver.
-+
-+config DWMAC_SOCFPGA
-+ tristate "SOCFPGA dwmac support"
-+ default ARCH_SOCFPGA
-+ depends on OF
-+ select MFD_SYSCON
-+ help
-+ Support for ethernet controller on Altera SOCFPGA
-+
-+ This selects the Altera SOCFPGA SoC glue layer support
-+ for the stmmac device driver. This driver is used for
-+ arria5 and cyclone5 FPGA SoCs.
-+
-+config DWMAC_STI
-+ tristate "STi GMAC support"
-+ default ARCH_STI
-+ depends on OF
-+ select MFD_SYSCON
-+ ---help---
-+ Support for ethernet controller on STi SOCs.
-+
-+ This selects STi SoC glue layer support for the stmmac
-+ device driver. This driver is used on for the STi series
-+ SOCs GMAC ethernet controller.
-+
-+config DWMAC_SUNXI
-+ tristate "Allwinner GMAC support"
-+ default ARCH_SUNXI
-+ depends on OF
-+ ---help---
-+ Support for Allwinner A20/A31 GMAC ethernet controllers.
-+
-+ This selects Allwinner SoC glue layer support for the
-+ stmmac device driver. This driver is used for A20/A31
-+ GMAC ethernet controller.
-+endif
-+
- config STMMAC_PCI
- tristate "STMMAC PCI bus support"
- depends on STMMAC_ETH && PCI
---- a/drivers/net/ethernet/stmicro/stmmac/Makefile
-+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
-@@ -4,9 +4,17 @@ stmmac-objs:= stmmac_main.o stmmac_ethto
- dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
- mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o $(stmmac-y)
-
--obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
--stmmac-platform-objs:= stmmac_platform.o dwmac-meson.o dwmac-sunxi.o \
-- dwmac-sti.o dwmac-socfpga.o dwmac-rk.o
-+# Ordering matters. Generic driver must be last.
-+obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
-+obj-$(CONFIG_DWMAC_IPQ806X) += dwmac-ipq806x.o
-+obj-$(CONFIG_DWMAC_LPC18XX) += dwmac-lpc18xx.o
-+obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o
-+obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o
-+obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-socfpga.o
-+obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o
-+obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
-+obj-$(CONFIG_DWMAC_GENERIC) += dwmac-generic.o
-+stmmac-platform-objs:= stmmac_platform.o
-
- obj-$(CONFIG_STMMAC_PCI) += stmmac-pci.o
- stmmac-pci-objs:= stmmac_pci.o
---- /dev/null
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
-@@ -0,0 +1,81 @@
-+/*
-+ * Generic DWMAC platform driver
-+ *
-+ * Copyright (C) 2007-2011 STMicroelectronics Ltd
-+ * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
-+ *
-+ * 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/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+
-+#include "stmmac.h"
-+#include "stmmac_platform.h"
-+
-+static int dwmac_generic_probe(struct platform_device *pdev)
-+{
-+ struct plat_stmmacenet_data *plat_dat;
-+ struct stmmac_resources stmmac_res;
-+ int ret;
-+
-+ ret = stmmac_get_platform_resources(pdev, &stmmac_res);
-+ if (ret)
-+ return ret;
-+
-+ if (pdev->dev.of_node) {
-+ plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+ if (IS_ERR(plat_dat)) {
-+ dev_err(&pdev->dev, "dt configuration failed\n");
-+ return PTR_ERR(plat_dat);
-+ }
-+ } else {
-+ plat_dat = dev_get_platdata(&pdev->dev);
-+ if (!plat_dat) {
-+ dev_err(&pdev->dev, "no platform data provided\n");
-+ return -EINVAL;
-+ }
-+
-+ /* Set default value for multicast hash bins */
-+ plat_dat->multicast_filter_bins = HASH_TABLE_SIZE;
-+
-+ /* Set default value for unicast filter entries */
-+ plat_dat->unicast_filter_entries = 1;
-+ }
-+
-+ /* Custom initialisation (if needed) */
-+ if (plat_dat->init) {
-+ ret = plat_dat->init(pdev, plat_dat->bsp_priv);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-+}
-+
-+static const struct of_device_id dwmac_generic_match[] = {
-+ { .compatible = "st,spear600-gmac"},
-+ { .compatible = "snps,dwmac-3.610"},
-+ { .compatible = "snps,dwmac-3.70a"},
-+ { .compatible = "snps,dwmac-3.710"},
-+ { .compatible = "snps,dwmac"},
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, dwmac_generic_match);
-+
-+static struct platform_driver dwmac_generic_driver = {
-+ .probe = dwmac_generic_probe,
-+ .remove = stmmac_pltfr_remove,
-+ .driver = {
-+ .name = STMMAC_RESOURCE_NAME,
-+ .pm = &stmmac_pltfr_pm_ops,
-+ .of_match_table = of_match_ptr(dwmac_generic_match),
-+ },
-+};
-+module_platform_driver(dwmac_generic_driver);
-+
-+MODULE_DESCRIPTION("Generic dwmac driver");
-+MODULE_LICENSE("GPL v2");
---- /dev/null
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
-@@ -0,0 +1,373 @@
-+/*
-+ * Qualcomm Atheros IPQ806x GMAC glue layer
-+ *
-+ * Copyright (C) 2015 The Linux Foundation
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/platform_device.h>
-+#include <linux/phy.h>
-+#include <linux/regmap.h>
-+#include <linux/clk.h>
-+#include <linux/reset.h>
-+#include <linux/of_net.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/stmmac.h>
-+#include <linux/of_mdio.h>
-+#include <linux/module.h>
-+
-+#include "stmmac_platform.h"
-+
-+#define NSS_COMMON_CLK_GATE 0x8
-+#define NSS_COMMON_CLK_GATE_PTP_EN(x) BIT(0x10 + x)
-+#define NSS_COMMON_CLK_GATE_RGMII_RX_EN(x) BIT(0x9 + (x * 2))
-+#define NSS_COMMON_CLK_GATE_RGMII_TX_EN(x) BIT(0x8 + (x * 2))
-+#define NSS_COMMON_CLK_GATE_GMII_RX_EN(x) BIT(0x4 + x)
-+#define NSS_COMMON_CLK_GATE_GMII_TX_EN(x) BIT(0x0 + x)
-+
-+#define NSS_COMMON_CLK_DIV0 0xC
-+#define NSS_COMMON_CLK_DIV_OFFSET(x) (x * 8)
-+#define NSS_COMMON_CLK_DIV_MASK 0x7f
-+
-+#define NSS_COMMON_CLK_SRC_CTRL 0x14
-+#define NSS_COMMON_CLK_SRC_CTRL_OFFSET(x) (x)
-+/* Mode is coded on 1 bit but is different depending on the MAC ID:
-+ * MAC0: QSGMII=0 RGMII=1
-+ * MAC1: QSGMII=0 SGMII=0 RGMII=1
-+ * MAC2 & MAC3: QSGMII=0 SGMII=1
-+ */
-+#define NSS_COMMON_CLK_SRC_CTRL_RGMII(x) 1
-+#define NSS_COMMON_CLK_SRC_CTRL_SGMII(x) ((x >= 2) ? 1 : 0)
-+
-+#define NSS_COMMON_MACSEC_CTL 0x28
-+#define NSS_COMMON_MACSEC_CTL_EXT_BYPASS_EN(x) (1 << x)
-+
-+#define NSS_COMMON_GMAC_CTL(x) (0x30 + (x * 4))
-+#define NSS_COMMON_GMAC_CTL_CSYS_REQ BIT(19)
-+#define NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL BIT(16)
-+#define NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET 8
-+#define NSS_COMMON_GMAC_CTL_IFG_OFFSET 0
-+#define NSS_COMMON_GMAC_CTL_IFG_MASK 0x3f
-+
-+#define NSS_COMMON_CLK_DIV_RGMII_1000 1
-+#define NSS_COMMON_CLK_DIV_RGMII_100 9
-+#define NSS_COMMON_CLK_DIV_RGMII_10 99
-+#define NSS_COMMON_CLK_DIV_SGMII_1000 0
-+#define NSS_COMMON_CLK_DIV_SGMII_100 4
-+#define NSS_COMMON_CLK_DIV_SGMII_10 49
-+
-+#define QSGMII_PCS_MODE_CTL 0x68
-+#define QSGMII_PCS_MODE_CTL_AUTONEG_EN(x) BIT((x * 8) + 7)
-+
-+#define QSGMII_PCS_CAL_LCKDT_CTL 0x120
-+#define QSGMII_PCS_CAL_LCKDT_CTL_RST BIT(19)
-+
-+/* Only GMAC1/2/3 support SGMII and their CTL register are not contiguous */
-+#define QSGMII_PHY_SGMII_CTL(x) ((x == 1) ? 0x134 : \
-+ (0x13c + (4 * (x - 2))))
-+#define QSGMII_PHY_CDR_EN BIT(0)
-+#define QSGMII_PHY_RX_FRONT_EN BIT(1)
-+#define QSGMII_PHY_RX_SIGNAL_DETECT_EN BIT(2)
-+#define QSGMII_PHY_TX_DRIVER_EN BIT(3)
-+#define QSGMII_PHY_QSGMII_EN BIT(7)
-+#define QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET 12
-+#define QSGMII_PHY_PHASE_LOOP_GAIN_MASK 0x7
-+#define QSGMII_PHY_RX_DC_BIAS_OFFSET 18
-+#define QSGMII_PHY_RX_DC_BIAS_MASK 0x3
-+#define QSGMII_PHY_RX_INPUT_EQU_OFFSET 20
-+#define QSGMII_PHY_RX_INPUT_EQU_MASK 0x3
-+#define QSGMII_PHY_CDR_PI_SLEW_OFFSET 22
-+#define QSGMII_PHY_CDR_PI_SLEW_MASK 0x3
-+#define QSGMII_PHY_TX_DRV_AMP_OFFSET 28
-+#define QSGMII_PHY_TX_DRV_AMP_MASK 0xf
-+
-+struct ipq806x_gmac {
-+ struct platform_device *pdev;
-+ struct regmap *nss_common;
-+ struct regmap *qsgmii_csr;
-+ uint32_t id;
-+ struct clk *core_clk;
-+ phy_interface_t phy_mode;
-+};
-+
-+static int get_clk_div_sgmii(struct ipq806x_gmac *gmac, unsigned int speed)
-+{
-+ struct device *dev = &gmac->pdev->dev;
-+ int div;
-+
-+ switch (speed) {
-+ case SPEED_1000:
-+ div = NSS_COMMON_CLK_DIV_SGMII_1000;
-+ break;
-+
-+ case SPEED_100:
-+ div = NSS_COMMON_CLK_DIV_SGMII_100;
-+ break;
-+
-+ case SPEED_10:
-+ div = NSS_COMMON_CLK_DIV_SGMII_10;
-+ break;
-+
-+ default:
-+ dev_err(dev, "Speed %dMbps not supported in SGMII\n", speed);
-+ return -EINVAL;
-+ }
-+
-+ return div;
-+}
-+
-+static int get_clk_div_rgmii(struct ipq806x_gmac *gmac, unsigned int speed)
-+{
-+ struct device *dev = &gmac->pdev->dev;
-+ int div;
-+
-+ switch (speed) {
-+ case SPEED_1000:
-+ div = NSS_COMMON_CLK_DIV_RGMII_1000;
-+ break;
-+
-+ case SPEED_100:
-+ div = NSS_COMMON_CLK_DIV_RGMII_100;
-+ break;
-+
-+ case SPEED_10:
-+ div = NSS_COMMON_CLK_DIV_RGMII_10;
-+ break;
-+
-+ default:
-+ dev_err(dev, "Speed %dMbps not supported in RGMII\n", speed);
-+ return -EINVAL;
-+ }
-+
-+ return div;
-+}
-+
-+static int ipq806x_gmac_set_speed(struct ipq806x_gmac *gmac, unsigned int speed)
-+{
-+ uint32_t clk_bits, val;
-+ int div;
-+
-+ switch (gmac->phy_mode) {
-+ case PHY_INTERFACE_MODE_RGMII:
-+ div = get_clk_div_rgmii(gmac, speed);
-+ clk_bits = NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) |
-+ NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id);
-+ break;
-+
-+ case PHY_INTERFACE_MODE_SGMII:
-+ div = get_clk_div_sgmii(gmac, speed);
-+ clk_bits = NSS_COMMON_CLK_GATE_GMII_RX_EN(gmac->id) |
-+ NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id);
-+ break;
-+
-+ default:
-+ dev_err(&gmac->pdev->dev, "Unsupported PHY mode: \"%s\"\n",
-+ phy_modes(gmac->phy_mode));
-+ return -EINVAL;
-+ }
-+
-+ /* Disable the clocks */
-+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
-+ val &= ~clk_bits;
-+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
-+
-+ /* Set the divider */
-+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_DIV0, &val);
-+ val &= ~(NSS_COMMON_CLK_DIV_MASK
-+ << NSS_COMMON_CLK_DIV_OFFSET(gmac->id));
-+ val |= div << NSS_COMMON_CLK_DIV_OFFSET(gmac->id);
-+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_DIV0, val);
-+
-+ /* Enable the clock back */
-+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
-+ val |= clk_bits;
-+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
-+
-+ return 0;
-+}
-+
-+static void *ipq806x_gmac_of_parse(struct ipq806x_gmac *gmac)
-+{
-+ struct device *dev = &gmac->pdev->dev;
-+
-+ gmac->phy_mode = of_get_phy_mode(dev->of_node);
-+ if (gmac->phy_mode < 0) {
-+ dev_err(dev, "missing phy mode property\n");
-+ return ERR_PTR(-EINVAL);
-+ }
-+
-+ if (of_property_read_u32(dev->of_node, "qcom,id", &gmac->id) < 0) {
-+ dev_err(dev, "missing qcom id property\n");
-+ return ERR_PTR(-EINVAL);
-+ }
-+
-+ /* The GMACs are called 1 to 4 in the documentation, but to simplify the
-+ * code and keep it consistent with the Linux convention, we'll number
-+ * them from 0 to 3 here.
-+ */
-+ if (gmac->id < 0 || gmac->id > 3) {
-+ dev_err(dev, "invalid gmac id\n");
-+ return ERR_PTR(-EINVAL);
-+ }
-+
-+ gmac->core_clk = devm_clk_get(dev, "stmmaceth");
-+ if (IS_ERR(gmac->core_clk)) {
-+ dev_err(dev, "missing stmmaceth clk property\n");
-+ return gmac->core_clk;
-+ }
-+ clk_set_rate(gmac->core_clk, 266000000);
-+
-+ /* Setup the register map for the nss common registers */
-+ gmac->nss_common = syscon_regmap_lookup_by_phandle(dev->of_node,
-+ "qcom,nss-common");
-+ if (IS_ERR(gmac->nss_common)) {
-+ dev_err(dev, "missing nss-common node\n");
-+ return gmac->nss_common;
-+ }
-+
-+ /* Setup the register map for the qsgmii csr registers */
-+ gmac->qsgmii_csr = syscon_regmap_lookup_by_phandle(dev->of_node,
-+ "qcom,qsgmii-csr");
-+ if (IS_ERR(gmac->qsgmii_csr)) {
-+ dev_err(dev, "missing qsgmii-csr node\n");
-+ return gmac->qsgmii_csr;
-+ }
-+
-+ return NULL;
-+}
-+
-+static void ipq806x_gmac_fix_mac_speed(void *priv, unsigned int speed)
-+{
-+ struct ipq806x_gmac *gmac = priv;
-+
-+ ipq806x_gmac_set_speed(gmac, speed);
-+}
-+
-+static int ipq806x_gmac_probe(struct platform_device *pdev)
-+{
-+ struct plat_stmmacenet_data *plat_dat;
-+ struct stmmac_resources stmmac_res;
-+ struct device *dev = &pdev->dev;
-+ struct ipq806x_gmac *gmac;
-+ int val;
-+ void *err;
-+
-+ val = stmmac_get_platform_resources(pdev, &stmmac_res);
-+ if (val)
-+ return val;
-+
-+ plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+ if (IS_ERR(plat_dat))
-+ return PTR_ERR(plat_dat);
-+
-+ gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
-+ if (!gmac)
-+ return -ENOMEM;
-+
-+ gmac->pdev = pdev;
-+
-+ err = ipq806x_gmac_of_parse(gmac);
-+ if (IS_ERR(err)) {
-+ dev_err(dev, "device tree parsing error\n");
-+ return PTR_ERR(err);
-+ }
-+
-+ regmap_write(gmac->qsgmii_csr, QSGMII_PCS_CAL_LCKDT_CTL,
-+ QSGMII_PCS_CAL_LCKDT_CTL_RST);
-+
-+ /* Inter frame gap is set to 12 */
-+ val = 12 << NSS_COMMON_GMAC_CTL_IFG_OFFSET |
-+ 12 << NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET;
-+ /* We also initiate an AXI low power exit request */
-+ val |= NSS_COMMON_GMAC_CTL_CSYS_REQ;
-+ switch (gmac->phy_mode) {
-+ case PHY_INTERFACE_MODE_RGMII:
-+ val |= NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
-+ break;
-+ case PHY_INTERFACE_MODE_SGMII:
-+ val &= ~NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
-+ break;
-+ default:
-+ dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
-+ phy_modes(gmac->phy_mode));
-+ return -EINVAL;
-+ }
-+ regmap_write(gmac->nss_common, NSS_COMMON_GMAC_CTL(gmac->id), val);
-+
-+ /* Configure the clock src according to the mode */
-+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, &val);
-+ val &= ~(1 << NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id));
-+ switch (gmac->phy_mode) {
-+ case PHY_INTERFACE_MODE_RGMII:
-+ val |= NSS_COMMON_CLK_SRC_CTRL_RGMII(gmac->id) <<
-+ NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
-+ break;
-+ case PHY_INTERFACE_MODE_SGMII:
-+ val |= NSS_COMMON_CLK_SRC_CTRL_SGMII(gmac->id) <<
-+ NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
-+ break;
-+ default:
-+ dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
-+ phy_modes(gmac->phy_mode));
-+ return -EINVAL;
-+ }
-+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, val);
-+
-+ /* Enable PTP clock */
-+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
-+ val |= NSS_COMMON_CLK_GATE_PTP_EN(gmac->id);
-+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
-+
-+ if (gmac->phy_mode == PHY_INTERFACE_MODE_SGMII) {
-+ regmap_write(gmac->qsgmii_csr, QSGMII_PHY_SGMII_CTL(gmac->id),
-+ QSGMII_PHY_CDR_EN |
-+ QSGMII_PHY_RX_FRONT_EN |
-+ QSGMII_PHY_RX_SIGNAL_DETECT_EN |
-+ QSGMII_PHY_TX_DRIVER_EN |
-+ QSGMII_PHY_QSGMII_EN |
-+ 0x4 << QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET |
-+ 0x3 << QSGMII_PHY_RX_DC_BIAS_OFFSET |
-+ 0x1 << QSGMII_PHY_RX_INPUT_EQU_OFFSET |
-+ 0x2 << QSGMII_PHY_CDR_PI_SLEW_OFFSET |
-+ 0xC << QSGMII_PHY_TX_DRV_AMP_OFFSET);
-+ }
-+
-+ plat_dat->has_gmac = true;
-+ plat_dat->bsp_priv = gmac;
-+ plat_dat->fix_mac_speed = ipq806x_gmac_fix_mac_speed;
-+
-+ return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-+}
-+
-+static const struct of_device_id ipq806x_gmac_dwmac_match[] = {
-+ { .compatible = "qcom,ipq806x-gmac" },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, ipq806x_gmac_dwmac_match);
-+
-+static struct platform_driver ipq806x_gmac_dwmac_driver = {
-+ .probe = ipq806x_gmac_probe,
-+ .remove = stmmac_pltfr_remove,
-+ .driver = {
-+ .name = "ipq806x-gmac-dwmac",
-+ .pm = &stmmac_pltfr_pm_ops,
-+ .of_match_table = ipq806x_gmac_dwmac_match,
-+ },
-+};
-+module_platform_driver(ipq806x_gmac_dwmac_driver);
-+
-+MODULE_AUTHOR("Mathieu Olivari <mathieu@codeaurora.org>");
-+MODULE_DESCRIPTION("Qualcomm Atheros IPQ806x DWMAC specific glue layer");
-+MODULE_LICENSE("Dual BSD/GPL");
---- /dev/null
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
-@@ -0,0 +1,86 @@
-+/*
-+ * DWMAC glue for NXP LPC18xx/LPC43xx Ethernet
-+ *
-+ * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
-+ *
-+ * 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/mfd/syscon.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_net.h>
-+#include <linux/phy.h>
-+#include <linux/platform_device.h>
-+#include <linux/regmap.h>
-+#include <linux/stmmac.h>
-+
-+#include "stmmac_platform.h"
-+
-+/* Register defines for CREG syscon */
-+#define LPC18XX_CREG_CREG6 0x12c
-+# define LPC18XX_CREG_CREG6_ETHMODE_MASK 0x7
-+# define LPC18XX_CREG_CREG6_ETHMODE_MII 0x0
-+# define LPC18XX_CREG_CREG6_ETHMODE_RMII 0x4
-+
-+static int lpc18xx_dwmac_probe(struct platform_device *pdev)
-+{
-+ struct plat_stmmacenet_data *plat_dat;
-+ struct stmmac_resources stmmac_res;
-+ struct regmap *reg;
-+ u8 ethmode;
-+ int ret;
-+
-+ ret = stmmac_get_platform_resources(pdev, &stmmac_res);
-+ if (ret)
-+ return ret;
-+
-+ plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+ if (IS_ERR(plat_dat))
-+ return PTR_ERR(plat_dat);
-+
-+ plat_dat->has_gmac = true;
-+
-+ reg = syscon_regmap_lookup_by_compatible("nxp,lpc1850-creg");
-+ if (IS_ERR(reg)) {
-+ dev_err(&pdev->dev, "syscon lookup failed\n");
-+ return PTR_ERR(reg);
-+ }
-+
-+ if (plat_dat->interface == PHY_INTERFACE_MODE_MII) {
-+ ethmode = LPC18XX_CREG_CREG6_ETHMODE_MII;
-+ } else if (plat_dat->interface == PHY_INTERFACE_MODE_RMII) {
-+ ethmode = LPC18XX_CREG_CREG6_ETHMODE_RMII;
-+ } else {
-+ dev_err(&pdev->dev, "Only MII and RMII mode supported\n");
-+ return -EINVAL;
-+ }
-+
-+ regmap_update_bits(reg, LPC18XX_CREG_CREG6,
-+ LPC18XX_CREG_CREG6_ETHMODE_MASK, ethmode);
-+
-+ return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-+}
-+
-+static const struct of_device_id lpc18xx_dwmac_match[] = {
-+ { .compatible = "nxp,lpc1850-dwmac" },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, lpc18xx_dwmac_match);
-+
-+static struct platform_driver lpc18xx_dwmac_driver = {
-+ .probe = lpc18xx_dwmac_probe,
-+ .remove = stmmac_pltfr_remove,
-+ .driver = {
-+ .name = "lpc18xx-dwmac",
-+ .pm = &stmmac_pltfr_pm_ops,
-+ .of_match_table = lpc18xx_dwmac_match,
-+ },
-+};
-+module_platform_driver(lpc18xx_dwmac_driver);
-+
-+MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>");
-+MODULE_DESCRIPTION("DWMAC glue for LPC18xx/43xx Ethernet");
-+MODULE_LICENSE("GPL v2");
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
-@@ -15,6 +15,7 @@
- #include <linux/ethtool.h>
- #include <linux/io.h>
- #include <linux/ioport.h>
-+#include <linux/module.h>
- #include <linux/platform_device.h>
- #include <linux/stmmac.h>
-
-@@ -46,24 +47,54 @@ static void meson6_dwmac_fix_mac_speed(v
- writel(val, dwmac->reg);
- }
-
--static void *meson6_dwmac_setup(struct platform_device *pdev)
-+static int meson6_dwmac_probe(struct platform_device *pdev)
- {
-+ struct plat_stmmacenet_data *plat_dat;
-+ struct stmmac_resources stmmac_res;
- struct meson_dwmac *dwmac;
- struct resource *res;
-+ int ret;
-+
-+ ret = stmmac_get_platform_resources(pdev, &stmmac_res);
-+ if (ret)
-+ return ret;
-+
-+ plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+ if (IS_ERR(plat_dat))
-+ return PTR_ERR(plat_dat);
-
- dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
- if (!dwmac)
-- return ERR_PTR(-ENOMEM);
-+ return -ENOMEM;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- dwmac->reg = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(dwmac->reg))
-- return ERR_CAST(dwmac->reg);
-+ return PTR_ERR(dwmac->reg);
-+
-+ plat_dat->bsp_priv = dwmac;
-+ plat_dat->fix_mac_speed = meson6_dwmac_fix_mac_speed;
-
-- return dwmac;
-+ return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
- }
-
--const struct stmmac_of_data meson6_dwmac_data = {
-- .setup = meson6_dwmac_setup,
-- .fix_mac_speed = meson6_dwmac_fix_mac_speed,
-+static const struct of_device_id meson6_dwmac_match[] = {
-+ { .compatible = "amlogic,meson6-dwmac" },
-+ { }
- };
-+MODULE_DEVICE_TABLE(of, meson6_dwmac_match);
-+
-+static struct platform_driver meson6_dwmac_driver = {
-+ .probe = meson6_dwmac_probe,
-+ .remove = stmmac_pltfr_remove,
-+ .driver = {
-+ .name = "meson6-dwmac",
-+ .pm = &stmmac_pltfr_pm_ops,
-+ .of_match_table = meson6_dwmac_match,
-+ },
-+};
-+module_platform_driver(meson6_dwmac_driver);
-+
-+MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>");
-+MODULE_DESCRIPTION("Amlogic Meson DWMAC glue layer");
-+MODULE_LICENSE("GPL v2");
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
-@@ -22,17 +22,31 @@
- #include <linux/phy.h>
- #include <linux/of_net.h>
- #include <linux/gpio.h>
-+#include <linux/module.h>
- #include <linux/of_gpio.h>
- #include <linux/of_device.h>
-+#include <linux/platform_device.h>
- #include <linux/regulator/consumer.h>
- #include <linux/delay.h>
- #include <linux/mfd/syscon.h>
- #include <linux/regmap.h>
-
-+#include "stmmac_platform.h"
-+
-+struct rk_priv_data;
-+struct rk_gmac_ops {
-+ void (*set_to_rgmii)(struct rk_priv_data *bsp_priv,
-+ int tx_delay, int rx_delay);
-+ void (*set_to_rmii)(struct rk_priv_data *bsp_priv);
-+ void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
-+ void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
-+};
-+
- struct rk_priv_data {
- struct platform_device *pdev;
- int phy_iface;
- struct regulator *regulator;
-+ const struct rk_gmac_ops *ops;
-
- bool clk_enabled;
- bool clock_input;
-@@ -60,103 +74,228 @@ struct rk_priv_data {
-
- #define RK3288_GRF_SOC_CON1 0x0248
- #define RK3288_GRF_SOC_CON3 0x0250
--#define RK3288_GRF_GPIO3D_E 0x01ec
--#define RK3288_GRF_GPIO4A_E 0x01f0
--#define RK3288_GRF_GPIO4B_E 0x01f4
-
- /*RK3288_GRF_SOC_CON1*/
--#define GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8))
--#define GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8))
--#define GMAC_FLOW_CTRL GRF_BIT(9)
--#define GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9)
--#define GMAC_SPEED_10M GRF_CLR_BIT(10)
--#define GMAC_SPEED_100M GRF_BIT(10)
--#define GMAC_RMII_CLK_25M GRF_BIT(11)
--#define GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11)
--#define GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
--#define GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13))
--#define GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13))
--#define GMAC_RMII_MODE GRF_BIT(14)
--#define GMAC_RMII_MODE_CLR GRF_CLR_BIT(14)
-+#define RK3288_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(6) | GRF_CLR_BIT(7) | \
-+ GRF_CLR_BIT(8))
-+#define RK3288_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \
-+ GRF_BIT(8))
-+#define RK3288_GMAC_FLOW_CTRL GRF_BIT(9)
-+#define RK3288_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9)
-+#define RK3288_GMAC_SPEED_10M GRF_CLR_BIT(10)
-+#define RK3288_GMAC_SPEED_100M GRF_BIT(10)
-+#define RK3288_GMAC_RMII_CLK_25M GRF_BIT(11)
-+#define RK3288_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11)
-+#define RK3288_GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
-+#define RK3288_GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13))
-+#define RK3288_GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13))
-+#define RK3288_GMAC_RMII_MODE GRF_BIT(14)
-+#define RK3288_GMAC_RMII_MODE_CLR GRF_CLR_BIT(14)
-
- /*RK3288_GRF_SOC_CON3*/
--#define GMAC_TXCLK_DLY_ENABLE GRF_BIT(14)
--#define GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14)
--#define GMAC_RXCLK_DLY_ENABLE GRF_BIT(15)
--#define GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15)
--#define GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
--#define GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
-+#define RK3288_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14)
-+#define RK3288_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14)
-+#define RK3288_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15)
-+#define RK3288_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15)
-+#define RK3288_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
-+#define RK3288_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
-
--static void set_to_rgmii(struct rk_priv_data *bsp_priv,
-- int tx_delay, int rx_delay)
-+static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv,
-+ int tx_delay, int rx_delay)
- {
- struct device *dev = &bsp_priv->pdev->dev;
-
- if (IS_ERR(bsp_priv->grf)) {
-- dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
-+ dev_err(dev, "Missing rockchip,grf property\n");
- return;
- }
-
- regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
-- GMAC_PHY_INTF_SEL_RGMII | GMAC_RMII_MODE_CLR);
-+ RK3288_GMAC_PHY_INTF_SEL_RGMII |
-+ RK3288_GMAC_RMII_MODE_CLR);
- regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3,
-- GMAC_RXCLK_DLY_ENABLE | GMAC_TXCLK_DLY_ENABLE |
-- GMAC_CLK_RX_DL_CFG(rx_delay) |
-- GMAC_CLK_TX_DL_CFG(tx_delay));
-+ RK3288_GMAC_RXCLK_DLY_ENABLE |
-+ RK3288_GMAC_TXCLK_DLY_ENABLE |
-+ RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) |
-+ RK3288_GMAC_CLK_TX_DL_CFG(tx_delay));
- }
-
--static void set_to_rmii(struct rk_priv_data *bsp_priv)
-+static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv)
- {
- struct device *dev = &bsp_priv->pdev->dev;
-
- if (IS_ERR(bsp_priv->grf)) {
-- dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
-+ dev_err(dev, "Missing rockchip,grf property\n");
- return;
- }
-
- regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
-- GMAC_PHY_INTF_SEL_RMII | GMAC_RMII_MODE);
-+ RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE);
- }
-
--static void set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
-+static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
- {
- struct device *dev = &bsp_priv->pdev->dev;
-
- if (IS_ERR(bsp_priv->grf)) {
-- dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
-+ dev_err(dev, "Missing rockchip,grf property\n");
- return;
- }
-
- if (speed == 10)
-- regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, GMAC_CLK_2_5M);
-+ regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
-+ RK3288_GMAC_CLK_2_5M);
- else if (speed == 100)
-- regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, GMAC_CLK_25M);
-+ regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
-+ RK3288_GMAC_CLK_25M);
- else if (speed == 1000)
-- regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, GMAC_CLK_125M);
-+ regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
-+ RK3288_GMAC_CLK_125M);
- else
- dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
- }
-
--static void set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
-+static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
- {
- struct device *dev = &bsp_priv->pdev->dev;
-
- if (IS_ERR(bsp_priv->grf)) {
-- dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
-+ dev_err(dev, "Missing rockchip,grf property\n");
- return;
- }
-
- if (speed == 10) {
- regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
-- GMAC_RMII_CLK_2_5M | GMAC_SPEED_10M);
-+ RK3288_GMAC_RMII_CLK_2_5M |
-+ RK3288_GMAC_SPEED_10M);
- } else if (speed == 100) {
- regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
-- GMAC_RMII_CLK_25M | GMAC_SPEED_100M);
-+ RK3288_GMAC_RMII_CLK_25M |
-+ RK3288_GMAC_SPEED_100M);
-+ } else {
-+ dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
-+ }
-+}
-+
-+static const struct rk_gmac_ops rk3288_ops = {
-+ .set_to_rgmii = rk3288_set_to_rgmii,
-+ .set_to_rmii = rk3288_set_to_rmii,
-+ .set_rgmii_speed = rk3288_set_rgmii_speed,
-+ .set_rmii_speed = rk3288_set_rmii_speed,
-+};
-+
-+#define RK3368_GRF_SOC_CON15 0x043c
-+#define RK3368_GRF_SOC_CON16 0x0440
-+
-+/* RK3368_GRF_SOC_CON15 */
-+#define RK3368_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \
-+ GRF_CLR_BIT(11))
-+#define RK3368_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
-+ GRF_BIT(11))
-+#define RK3368_GMAC_FLOW_CTRL GRF_BIT(8)
-+#define RK3368_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8)
-+#define RK3368_GMAC_SPEED_10M GRF_CLR_BIT(7)
-+#define RK3368_GMAC_SPEED_100M GRF_BIT(7)
-+#define RK3368_GMAC_RMII_CLK_25M GRF_BIT(3)
-+#define RK3368_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3)
-+#define RK3368_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
-+#define RK3368_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5))
-+#define RK3368_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5))
-+#define RK3368_GMAC_RMII_MODE GRF_BIT(6)
-+#define RK3368_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6)
-+
-+/* RK3368_GRF_SOC_CON16 */
-+#define RK3368_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7)
-+#define RK3368_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7)
-+#define RK3368_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15)
-+#define RK3368_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15)
-+#define RK3368_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8)
-+#define RK3368_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
-+
-+static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv,
-+ int tx_delay, int rx_delay)
-+{
-+ struct device *dev = &bsp_priv->pdev->dev;
-+
-+ if (IS_ERR(bsp_priv->grf)) {
-+ dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
-+ return;
-+ }
-+
-+ regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
-+ RK3368_GMAC_PHY_INTF_SEL_RGMII |
-+ RK3368_GMAC_RMII_MODE_CLR);
-+ regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16,
-+ RK3368_GMAC_RXCLK_DLY_ENABLE |
-+ RK3368_GMAC_TXCLK_DLY_ENABLE |
-+ RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) |
-+ RK3368_GMAC_CLK_TX_DL_CFG(tx_delay));
-+}
-+
-+static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv)
-+{
-+ struct device *dev = &bsp_priv->pdev->dev;
-+
-+ if (IS_ERR(bsp_priv->grf)) {
-+ dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
-+ return;
-+ }
-+
-+ regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
-+ RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE);
-+}
-+
-+static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
-+{
-+ struct device *dev = &bsp_priv->pdev->dev;
-+
-+ if (IS_ERR(bsp_priv->grf)) {
-+ dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
-+ return;
-+ }
-+
-+ if (speed == 10)
-+ regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
-+ RK3368_GMAC_CLK_2_5M);
-+ else if (speed == 100)
-+ regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
-+ RK3368_GMAC_CLK_25M);
-+ else if (speed == 1000)
-+ regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
-+ RK3368_GMAC_CLK_125M);
-+ else
-+ dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
-+}
-+
-+static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
-+{
-+ struct device *dev = &bsp_priv->pdev->dev;
-+
-+ if (IS_ERR(bsp_priv->grf)) {
-+ dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
-+ return;
-+ }
-+
-+ if (speed == 10) {
-+ regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
-+ RK3368_GMAC_RMII_CLK_2_5M |
-+ RK3368_GMAC_SPEED_10M);
-+ } else if (speed == 100) {
-+ regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
-+ RK3368_GMAC_RMII_CLK_25M |
-+ RK3368_GMAC_SPEED_100M);
- } else {
- dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
- }
- }
-
-+static const struct rk_gmac_ops rk3368_ops = {
-+ .set_to_rgmii = rk3368_set_to_rgmii,
-+ .set_to_rmii = rk3368_set_to_rmii,
-+ .set_rgmii_speed = rk3368_set_rgmii_speed,
-+ .set_rmii_speed = rk3368_set_rmii_speed,
-+};
-+
- static int gmac_clk_init(struct rk_priv_data *bsp_priv)
- {
- struct device *dev = &bsp_priv->pdev->dev;
-@@ -165,46 +304,46 @@ static int gmac_clk_init(struct rk_priv_
-
- bsp_priv->mac_clk_rx = devm_clk_get(dev, "mac_clk_rx");
- if (IS_ERR(bsp_priv->mac_clk_rx))
-- dev_err(dev, "%s: cannot get clock %s\n",
-- __func__, "mac_clk_rx");
-+ dev_err(dev, "cannot get clock %s\n",
-+ "mac_clk_rx");
-
- bsp_priv->mac_clk_tx = devm_clk_get(dev, "mac_clk_tx");
- if (IS_ERR(bsp_priv->mac_clk_tx))
-- dev_err(dev, "%s: cannot get clock %s\n",
-- __func__, "mac_clk_tx");
-+ dev_err(dev, "cannot get clock %s\n",
-+ "mac_clk_tx");
-
- bsp_priv->aclk_mac = devm_clk_get(dev, "aclk_mac");
- if (IS_ERR(bsp_priv->aclk_mac))
-- dev_err(dev, "%s: cannot get clock %s\n",
-- __func__, "aclk_mac");
-+ dev_err(dev, "cannot get clock %s\n",
-+ "aclk_mac");
-
- bsp_priv->pclk_mac = devm_clk_get(dev, "pclk_mac");
- if (IS_ERR(bsp_priv->pclk_mac))
-- dev_err(dev, "%s: cannot get clock %s\n",
-- __func__, "pclk_mac");
-+ dev_err(dev, "cannot get clock %s\n",
-+ "pclk_mac");
-
- bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth");
- if (IS_ERR(bsp_priv->clk_mac))
-- dev_err(dev, "%s: cannot get clock %s\n",
-- __func__, "stmmaceth");
-+ dev_err(dev, "cannot get clock %s\n",
-+ "stmmaceth");
-
- if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
- bsp_priv->clk_mac_ref = devm_clk_get(dev, "clk_mac_ref");
- if (IS_ERR(bsp_priv->clk_mac_ref))
-- dev_err(dev, "%s: cannot get clock %s\n",
-- __func__, "clk_mac_ref");
-+ dev_err(dev, "cannot get clock %s\n",
-+ "clk_mac_ref");
-
- if (!bsp_priv->clock_input) {
- bsp_priv->clk_mac_refout =
- devm_clk_get(dev, "clk_mac_refout");
- if (IS_ERR(bsp_priv->clk_mac_refout))
-- dev_err(dev, "%s: cannot get clock %s\n",
-- __func__, "clk_mac_refout");
-+ dev_err(dev, "cannot get clock %s\n",
-+ "clk_mac_refout");
- }
- }
-
- if (bsp_priv->clock_input) {
-- dev_info(dev, "%s: clock input from PHY\n", __func__);
-+ dev_info(dev, "clock input from PHY\n");
- } else {
- if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
- clk_set_rate(bsp_priv->clk_mac, 50000000);
-@@ -291,26 +430,25 @@ static int phy_power_on(struct rk_priv_d
- struct device *dev = &bsp_priv->pdev->dev;
-
- if (!ldo) {
-- dev_err(dev, "%s: no regulator found\n", __func__);
-+ dev_err(dev, "no regulator found\n");
- return -1;
- }
-
- if (enable) {
- ret = regulator_enable(ldo);
- if (ret)
-- dev_err(dev, "%s: fail to enable phy-supply\n",
-- __func__);
-+ dev_err(dev, "fail to enable phy-supply\n");
- } else {
- ret = regulator_disable(ldo);
- if (ret)
-- dev_err(dev, "%s: fail to disable phy-supply\n",
-- __func__);
-+ dev_err(dev, "fail to disable phy-supply\n");
- }
-
- return 0;
- }
-
--static void *rk_gmac_setup(struct platform_device *pdev)
-+static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
-+ const struct rk_gmac_ops *ops)
- {
- struct rk_priv_data *bsp_priv;
- struct device *dev = &pdev->dev;
-@@ -323,6 +461,7 @@ static void *rk_gmac_setup(struct platfo
- return ERR_PTR(-ENOMEM);
-
- bsp_priv->phy_iface = of_get_phy_mode(dev->of_node);
-+ bsp_priv->ops = ops;
-
- bsp_priv->regulator = devm_regulator_get_optional(dev, "phy");
- if (IS_ERR(bsp_priv->regulator)) {
-@@ -336,12 +475,11 @@ static void *rk_gmac_setup(struct platfo
-
- ret = of_property_read_string(dev->of_node, "clock_in_out", &strings);
- if (ret) {
-- dev_err(dev, "%s: Can not read property: clock_in_out.\n",
-- __func__);
-+ dev_err(dev, "Can not read property: clock_in_out.\n");
- bsp_priv->clock_input = true;
- } else {
-- dev_info(dev, "%s: clock input or output? (%s).\n",
-- __func__, strings);
-+ dev_info(dev, "clock input or output? (%s).\n",
-+ strings);
- if (!strcmp(strings, "input"))
- bsp_priv->clock_input = true;
- else
-@@ -351,22 +489,22 @@ static void *rk_gmac_setup(struct platfo
- ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
- if (ret) {
- bsp_priv->tx_delay = 0x30;
-- dev_err(dev, "%s: Can not read property: tx_delay.", __func__);
-- dev_err(dev, "%s: set tx_delay to 0x%x\n",
-- __func__, bsp_priv->tx_delay);
-+ dev_err(dev, "Can not read property: tx_delay.");
-+ dev_err(dev, "set tx_delay to 0x%x\n",
-+ bsp_priv->tx_delay);
- } else {
-- dev_info(dev, "%s: TX delay(0x%x).\n", __func__, value);
-+ dev_info(dev, "TX delay(0x%x).\n", value);
- bsp_priv->tx_delay = value;
- }
-
- ret = of_property_read_u32(dev->of_node, "rx_delay", &value);
- if (ret) {
- bsp_priv->rx_delay = 0x10;
-- dev_err(dev, "%s: Can not read property: rx_delay.", __func__);
-- dev_err(dev, "%s: set rx_delay to 0x%x\n",
-- __func__, bsp_priv->rx_delay);
-+ dev_err(dev, "Can not read property: rx_delay.");
-+ dev_err(dev, "set rx_delay to 0x%x\n",
-+ bsp_priv->rx_delay);
- } else {
-- dev_info(dev, "%s: RX delay(0x%x).\n", __func__, value);
-+ dev_info(dev, "RX delay(0x%x).\n", value);
- bsp_priv->rx_delay = value;
- }
-
-@@ -376,13 +514,14 @@ static void *rk_gmac_setup(struct platfo
-
- /*rmii or rgmii*/
- if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII) {
-- dev_info(dev, "%s: init for RGMII\n", __func__);
-- set_to_rgmii(bsp_priv, bsp_priv->tx_delay, bsp_priv->rx_delay);
-+ dev_info(dev, "init for RGMII\n");
-+ bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay,
-+ bsp_priv->rx_delay);
- } else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
-- dev_info(dev, "%s: init for RMII\n", __func__);
-- set_to_rmii(bsp_priv);
-+ dev_info(dev, "init for RMII\n");
-+ bsp_priv->ops->set_to_rmii(bsp_priv);
- } else {
-- dev_err(dev, "%s: NO interface defined!\n", __func__);
-+ dev_err(dev, "NO interface defined!\n");
- }
-
- gmac_clk_init(bsp_priv);
-@@ -420,17 +559,68 @@ static void rk_fix_speed(void *priv, uns
- struct device *dev = &bsp_priv->pdev->dev;
-
- if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII)
-- set_rgmii_speed(bsp_priv, speed);
-+ bsp_priv->ops->set_rgmii_speed(bsp_priv, speed);
- else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
-- set_rmii_speed(bsp_priv, speed);
-+ bsp_priv->ops->set_rmii_speed(bsp_priv, speed);
- else
- dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface);
- }
-
--const struct stmmac_of_data rk3288_gmac_data = {
-- .has_gmac = 1,
-- .fix_mac_speed = rk_fix_speed,
-- .setup = rk_gmac_setup,
-- .init = rk_gmac_init,
-- .exit = rk_gmac_exit,
-+static int rk_gmac_probe(struct platform_device *pdev)
-+{
-+ struct plat_stmmacenet_data *plat_dat;
-+ struct stmmac_resources stmmac_res;
-+ const struct rk_gmac_ops *data;
-+ int ret;
-+
-+ data = of_device_get_match_data(&pdev->dev);
-+ if (!data) {
-+ dev_err(&pdev->dev, "no of match data provided\n");
-+ return -EINVAL;
-+ }
-+
-+ ret = stmmac_get_platform_resources(pdev, &stmmac_res);
-+ if (ret)
-+ return ret;
-+
-+ plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+ if (IS_ERR(plat_dat))
-+ return PTR_ERR(plat_dat);
-+
-+ plat_dat->has_gmac = true;
-+ plat_dat->init = rk_gmac_init;
-+ plat_dat->exit = rk_gmac_exit;
-+ plat_dat->fix_mac_speed = rk_fix_speed;
-+
-+ plat_dat->bsp_priv = rk_gmac_setup(pdev, data);
-+ if (IS_ERR(plat_dat->bsp_priv))
-+ return PTR_ERR(plat_dat->bsp_priv);
-+
-+ ret = rk_gmac_init(pdev, plat_dat->bsp_priv);
-+ if (ret)
-+ return ret;
-+
-+ return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-+}
-+
-+static const struct of_device_id rk_gmac_dwmac_match[] = {
-+ { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops },
-+ { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops },
-+ { }
- };
-+MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match);
-+
-+static struct platform_driver rk_gmac_dwmac_driver = {
-+ .probe = rk_gmac_probe,
-+ .remove = stmmac_pltfr_remove,
-+ .driver = {
-+ .name = "rk_gmac-dwmac",
-+ .pm = &stmmac_pltfr_pm_ops,
-+ .of_match_table = rk_gmac_dwmac_match,
-+ },
-+};
-+module_platform_driver(rk_gmac_dwmac_driver);
-+
-+MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>");
-+MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer");
-+MODULE_LICENSE("GPL");
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
-@@ -175,31 +175,6 @@ static int socfpga_dwmac_setup(struct so
- return 0;
- }
-
--static void *socfpga_dwmac_probe(struct platform_device *pdev)
--{
-- struct device *dev = &pdev->dev;
-- int ret;
-- struct socfpga_dwmac *dwmac;
--
-- dwmac = devm_kzalloc(dev, sizeof(*dwmac), GFP_KERNEL);
-- if (!dwmac)
-- return ERR_PTR(-ENOMEM);
--
-- ret = socfpga_dwmac_parse_data(dwmac, dev);
-- if (ret) {
-- dev_err(dev, "Unable to parse OF data\n");
-- return ERR_PTR(ret);
-- }
--
-- ret = socfpga_dwmac_setup(dwmac);
-- if (ret) {
-- dev_err(dev, "couldn't setup SoC glue (%d)\n", ret);
-- return ERR_PTR(ret);
-- }
--
-- return dwmac;
--}
--
- static void socfpga_dwmac_exit(struct platform_device *pdev, void *priv)
- {
- struct socfpga_dwmac *dwmac = priv;
-@@ -257,9 +232,65 @@ static int socfpga_dwmac_init(struct pla
- return ret;
- }
-
--const struct stmmac_of_data socfpga_gmac_data = {
-- .setup = socfpga_dwmac_probe,
-- .init = socfpga_dwmac_init,
-- .exit = socfpga_dwmac_exit,
-- .fix_mac_speed = socfpga_dwmac_fix_mac_speed,
-+static int socfpga_dwmac_probe(struct platform_device *pdev)
-+{
-+ struct plat_stmmacenet_data *plat_dat;
-+ struct stmmac_resources stmmac_res;
-+ struct device *dev = &pdev->dev;
-+ int ret;
-+ struct socfpga_dwmac *dwmac;
-+
-+ ret = stmmac_get_platform_resources(pdev, &stmmac_res);
-+ if (ret)
-+ return ret;
-+
-+ plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+ if (IS_ERR(plat_dat))
-+ return PTR_ERR(plat_dat);
-+
-+ dwmac = devm_kzalloc(dev, sizeof(*dwmac), GFP_KERNEL);
-+ if (!dwmac)
-+ return -ENOMEM;
-+
-+ ret = socfpga_dwmac_parse_data(dwmac, dev);
-+ if (ret) {
-+ dev_err(dev, "Unable to parse OF data\n");
-+ return ret;
-+ }
-+
-+ ret = socfpga_dwmac_setup(dwmac);
-+ if (ret) {
-+ dev_err(dev, "couldn't setup SoC glue (%d)\n", ret);
-+ return ret;
-+ }
-+
-+ plat_dat->bsp_priv = dwmac;
-+ plat_dat->init = socfpga_dwmac_init;
-+ plat_dat->exit = socfpga_dwmac_exit;
-+ plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed;
-+
-+ ret = socfpga_dwmac_init(pdev, plat_dat->bsp_priv);
-+ if (ret)
-+ return ret;
-+
-+ return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-+}
-+
-+static const struct of_device_id socfpga_dwmac_match[] = {
-+ { .compatible = "altr,socfpga-stmmac" },
-+ { }
- };
-+MODULE_DEVICE_TABLE(of, socfpga_dwmac_match);
-+
-+static struct platform_driver socfpga_dwmac_driver = {
-+ .probe = socfpga_dwmac_probe,
-+ .remove = stmmac_pltfr_remove,
-+ .driver = {
-+ .name = "socfpga-dwmac",
-+ .pm = &stmmac_pltfr_pm_ops,
-+ .of_match_table = socfpga_dwmac_match,
-+ },
-+};
-+module_platform_driver(socfpga_dwmac_driver);
-+
-+MODULE_LICENSE("GPL v2");
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
-@@ -17,9 +17,11 @@
- #include <linux/stmmac.h>
- #include <linux/phy.h>
- #include <linux/mfd/syscon.h>
-+#include <linux/module.h>
- #include <linux/regmap.h>
- #include <linux/clk.h>
- #include <linux/of.h>
-+#include <linux/of_device.h>
- #include <linux/of_net.h>
-
- #include "stmmac_platform.h"
-@@ -127,6 +129,11 @@ struct sti_dwmac {
- struct device *dev;
- struct regmap *regmap;
- u32 speed;
-+ void (*fix_retime_src)(void *priv, unsigned int speed);
-+};
-+
-+struct sti_dwmac_of_data {
-+ void (*fix_retime_src)(void *priv, unsigned int speed);
- };
-
- static u32 phy_intf_sels[] = {
-@@ -221,8 +228,9 @@ static void stid127_fix_retime_src(void
- regmap_update_bits(dwmac->regmap, reg, STID127_RETIME_SRC_MASK, val);
- }
-
--static void sti_dwmac_ctrl_init(struct sti_dwmac *dwmac)
-+static int sti_dwmac_init(struct platform_device *pdev, void *priv)
- {
-+ struct sti_dwmac *dwmac = priv;
- struct regmap *regmap = dwmac->regmap;
- int iface = dwmac->interface;
- struct device *dev = dwmac->dev;
-@@ -240,28 +248,8 @@ static void sti_dwmac_ctrl_init(struct s
-
- val = (iface == PHY_INTERFACE_MODE_REVMII) ? 0 : ENMII;
- regmap_update_bits(regmap, reg, ENMII_MASK, val);
--}
--
--static int stix4xx_init(struct platform_device *pdev, void *priv)
--{
-- struct sti_dwmac *dwmac = priv;
-- u32 spd = dwmac->speed;
-
-- sti_dwmac_ctrl_init(dwmac);
--
-- stih4xx_fix_retime_src(priv, spd);
--
-- return 0;
--}
--
--static int stid127_init(struct platform_device *pdev, void *priv)
--{
-- struct sti_dwmac *dwmac = priv;
-- u32 spd = dwmac->speed;
--
-- sti_dwmac_ctrl_init(dwmac);
--
-- stid127_fix_retime_src(priv, spd);
-+ dwmac->fix_retime_src(priv, dwmac->speed);
-
- return 0;
- }
-@@ -333,34 +321,80 @@ static int sti_dwmac_parse_data(struct s
- return 0;
- }
-
--static void *sti_dwmac_setup(struct platform_device *pdev)
-+static int sti_dwmac_probe(struct platform_device *pdev)
- {
-+ struct plat_stmmacenet_data *plat_dat;
-+ const struct sti_dwmac_of_data *data;
-+ struct stmmac_resources stmmac_res;
- struct sti_dwmac *dwmac;
- int ret;
-
-+ data = of_device_get_match_data(&pdev->dev);
-+ if (!data) {
-+ dev_err(&pdev->dev, "No OF match data provided\n");
-+ return -EINVAL;
-+ }
-+
-+ ret = stmmac_get_platform_resources(pdev, &stmmac_res);
-+ if (ret)
-+ return ret;
-+
-+ plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+ if (IS_ERR(plat_dat))
-+ return PTR_ERR(plat_dat);
-+
- dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
- if (!dwmac)
-- return ERR_PTR(-ENOMEM);
-+ return -ENOMEM;
-
- ret = sti_dwmac_parse_data(dwmac, pdev);
- if (ret) {
- dev_err(&pdev->dev, "Unable to parse OF data\n");
-- return ERR_PTR(ret);
-+ return ret;
- }
-
-- return dwmac;
-+ dwmac->fix_retime_src = data->fix_retime_src;
-+
-+ plat_dat->bsp_priv = dwmac;
-+ plat_dat->init = sti_dwmac_init;
-+ plat_dat->exit = sti_dwmac_exit;
-+ plat_dat->fix_mac_speed = data->fix_retime_src;
-+
-+ ret = sti_dwmac_init(pdev, plat_dat->bsp_priv);
-+ if (ret)
-+ return ret;
-+
-+ return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
- }
-
--const struct stmmac_of_data stih4xx_dwmac_data = {
-- .fix_mac_speed = stih4xx_fix_retime_src,
-- .setup = sti_dwmac_setup,
-- .init = stix4xx_init,
-- .exit = sti_dwmac_exit,
-+static const struct sti_dwmac_of_data stih4xx_dwmac_data = {
-+ .fix_retime_src = stih4xx_fix_retime_src,
-+};
-+
-+static const struct sti_dwmac_of_data stid127_dwmac_data = {
-+ .fix_retime_src = stid127_fix_retime_src,
- };
-
--const struct stmmac_of_data stid127_dwmac_data = {
-- .fix_mac_speed = stid127_fix_retime_src,
-- .setup = sti_dwmac_setup,
-- .init = stid127_init,
-- .exit = sti_dwmac_exit,
-+static const struct of_device_id sti_dwmac_match[] = {
-+ { .compatible = "st,stih415-dwmac", .data = &stih4xx_dwmac_data},
-+ { .compatible = "st,stih416-dwmac", .data = &stih4xx_dwmac_data},
-+ { .compatible = "st,stid127-dwmac", .data = &stid127_dwmac_data},
-+ { .compatible = "st,stih407-dwmac", .data = &stih4xx_dwmac_data},
-+ { }
- };
-+MODULE_DEVICE_TABLE(of, sti_dwmac_match);
-+
-+static struct platform_driver sti_dwmac_driver = {
-+ .probe = sti_dwmac_probe,
-+ .remove = stmmac_pltfr_remove,
-+ .driver = {
-+ .name = "sti-dwmac",
-+ .pm = &stmmac_pltfr_pm_ops,
-+ .of_match_table = sti_dwmac_match,
-+ },
-+};
-+module_platform_driver(sti_dwmac_driver);
-+
-+MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@st.com>");
-+MODULE_DESCRIPTION("STMicroelectronics DWMAC Specific Glue layer");
-+MODULE_LICENSE("GPL");
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
-@@ -18,7 +18,9 @@
-
- #include <linux/stmmac.h>
- #include <linux/clk.h>
-+#include <linux/module.h>
- #include <linux/phy.h>
-+#include <linux/platform_device.h>
- #include <linux/of_net.h>
- #include <linux/regulator/consumer.h>
-
-@@ -31,35 +33,6 @@ struct sunxi_priv_data {
- struct regulator *regulator;
- };
-
--static void *sun7i_gmac_setup(struct platform_device *pdev)
--{
-- struct sunxi_priv_data *gmac;
-- struct device *dev = &pdev->dev;
--
-- gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
-- if (!gmac)
-- return ERR_PTR(-ENOMEM);
--
-- gmac->interface = of_get_phy_mode(dev->of_node);
--
-- gmac->tx_clk = devm_clk_get(dev, "allwinner_gmac_tx");
-- if (IS_ERR(gmac->tx_clk)) {
-- dev_err(dev, "could not get tx clock\n");
-- return gmac->tx_clk;
-- }
--
-- /* Optional regulator for PHY */
-- gmac->regulator = devm_regulator_get_optional(dev, "phy");
-- if (IS_ERR(gmac->regulator)) {
-- if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER)
-- return ERR_PTR(-EPROBE_DEFER);
-- dev_info(dev, "no regulator found\n");
-- gmac->regulator = NULL;
-- }
--
-- return gmac;
--}
--
- #define SUN7I_GMAC_GMII_RGMII_RATE 125000000
- #define SUN7I_GMAC_MII_RATE 25000000
-
-@@ -130,13 +103,76 @@ static void sun7i_fix_speed(void *priv,
- }
- }
-
--/* of_data specifying hardware features and callbacks.
-- * hardware features were copied from Allwinner drivers. */
--const struct stmmac_of_data sun7i_gmac_data = {
-- .has_gmac = 1,
-- .tx_coe = 1,
-- .fix_mac_speed = sun7i_fix_speed,
-- .setup = sun7i_gmac_setup,
-- .init = sun7i_gmac_init,
-- .exit = sun7i_gmac_exit,
-+static int sun7i_gmac_probe(struct platform_device *pdev)
-+{
-+ struct plat_stmmacenet_data *plat_dat;
-+ struct stmmac_resources stmmac_res;
-+ struct sunxi_priv_data *gmac;
-+ struct device *dev = &pdev->dev;
-+ int ret;
-+
-+ ret = stmmac_get_platform_resources(pdev, &stmmac_res);
-+ if (ret)
-+ return ret;
-+
-+ plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+ if (IS_ERR(plat_dat))
-+ return PTR_ERR(plat_dat);
-+
-+ gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
-+ if (!gmac)
-+ return -ENOMEM;
-+
-+ gmac->interface = of_get_phy_mode(dev->of_node);
-+
-+ gmac->tx_clk = devm_clk_get(dev, "allwinner_gmac_tx");
-+ if (IS_ERR(gmac->tx_clk)) {
-+ dev_err(dev, "could not get tx clock\n");
-+ return PTR_ERR(gmac->tx_clk);
-+ }
-+
-+ /* Optional regulator for PHY */
-+ gmac->regulator = devm_regulator_get_optional(dev, "phy");
-+ if (IS_ERR(gmac->regulator)) {
-+ if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER)
-+ return -EPROBE_DEFER;
-+ dev_info(dev, "no regulator found\n");
-+ gmac->regulator = NULL;
-+ }
-+
-+ /* platform data specifying hardware features and callbacks.
-+ * hardware features were copied from Allwinner drivers. */
-+ plat_dat->tx_coe = 1;
-+ plat_dat->has_gmac = true;
-+ plat_dat->bsp_priv = gmac;
-+ plat_dat->init = sun7i_gmac_init;
-+ plat_dat->exit = sun7i_gmac_exit;
-+ plat_dat->fix_mac_speed = sun7i_fix_speed;
-+
-+ ret = sun7i_gmac_init(pdev, plat_dat->bsp_priv);
-+ if (ret)
-+ return ret;
-+
-+ return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-+}
-+
-+static const struct of_device_id sun7i_dwmac_match[] = {
-+ { .compatible = "allwinner,sun7i-a20-gmac" },
-+ { }
- };
-+MODULE_DEVICE_TABLE(of, sun7i_dwmac_match);
-+
-+static struct platform_driver sun7i_dwmac_driver = {
-+ .probe = sun7i_gmac_probe,
-+ .remove = stmmac_pltfr_remove,
-+ .driver = {
-+ .name = "sun7i-dwmac",
-+ .pm = &stmmac_pltfr_pm_ops,
-+ .of_match_table = sun7i_dwmac_match,
-+ },
-+};
-+module_platform_driver(sun7i_dwmac_driver);
-+
-+MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
-+MODULE_DESCRIPTION("Allwinner sunxi DWMAC specific glue layer");
-+MODULE_LICENSE("GPL");
---- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
-@@ -73,7 +73,7 @@
- #define MMC_RX_OCTETCOUNT_G 0x00000188
- #define MMC_RX_BROADCASTFRAME_G 0x0000018c
- #define MMC_RX_MULTICASTFRAME_G 0x00000190
--#define MMC_RX_CRC_ERRROR 0x00000194
-+#define MMC_RX_CRC_ERROR 0x00000194
- #define MMC_RX_ALIGN_ERROR 0x00000198
- #define MMC_RX_RUN_ERROR 0x0000019C
- #define MMC_RX_JABBER_ERROR 0x000001A0
-@@ -196,7 +196,7 @@ void dwmac_mmc_read(void __iomem *ioaddr
- mmc->mmc_rx_octetcount_g += readl(ioaddr + MMC_RX_OCTETCOUNT_G);
- mmc->mmc_rx_broadcastframe_g += readl(ioaddr + MMC_RX_BROADCASTFRAME_G);
- mmc->mmc_rx_multicastframe_g += readl(ioaddr + MMC_RX_MULTICASTFRAME_G);
-- mmc->mmc_rx_crc_error += readl(ioaddr + MMC_RX_CRC_ERRROR);
-+ mmc->mmc_rx_crc_error += readl(ioaddr + MMC_RX_CRC_ERROR);
- mmc->mmc_rx_align_error += readl(ioaddr + MMC_RX_ALIGN_ERROR);
- mmc->mmc_rx_run_error += readl(ioaddr + MMC_RX_RUN_ERROR);
- mmc->mmc_rx_jabber_error += readl(ioaddr + MMC_RX_JABBER_ERROR);
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
-@@ -34,6 +34,14 @@
- #include <linux/ptp_clock_kernel.h>
- #include <linux/reset.h>
-
-+struct stmmac_resources {
-+ void __iomem *addr;
-+ const char *mac;
-+ int wol_irq;
-+ int lpi_irq;
-+ int irq;
-+};
-+
- struct stmmac_tx_info {
- dma_addr_t buf;
- bool map_as_page;
-@@ -135,9 +143,9 @@ void stmmac_ptp_unregister(struct stmmac
- int stmmac_resume(struct net_device *ndev);
- int stmmac_suspend(struct net_device *ndev);
- int stmmac_dvr_remove(struct net_device *ndev);
--struct stmmac_priv *stmmac_dvr_probe(struct device *device,
-- struct plat_stmmacenet_data *plat_dat,
-- void __iomem *addr);
-+int stmmac_dvr_probe(struct device *device,
-+ struct plat_stmmacenet_data *plat_dat,
-+ struct stmmac_resources *res);
- void stmmac_disable_eee_mode(struct stmmac_priv *priv);
- bool stmmac_eee_init(struct stmmac_priv *priv);
-
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -52,6 +52,7 @@
- #include "stmmac_ptp.h"
- #include "stmmac.h"
- #include <linux/reset.h>
-+#include <linux/of_mdio.h>
-
- #define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x)
-
-@@ -816,18 +817,25 @@ static int stmmac_init_phy(struct net_de
- priv->speed = 0;
- priv->oldduplex = -1;
-
-- if (priv->plat->phy_bus_name)
-- snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
-- priv->plat->phy_bus_name, priv->plat->bus_id);
-- else
-- snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
-- priv->plat->bus_id);
-+ if (priv->plat->phy_node) {
-+ phydev = of_phy_connect(dev, priv->plat->phy_node,
-+ &stmmac_adjust_link, 0, interface);
-+ } else {
-+ if (priv->plat->phy_bus_name)
-+ snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
-+ priv->plat->phy_bus_name, priv->plat->bus_id);
-+ else
-+ snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
-+ priv->plat->bus_id);
-
-- snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
-- priv->plat->phy_addr);
-- pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id_fmt);
-+ snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
-+ priv->plat->phy_addr);
-+ pr_debug("stmmac_init_phy: trying to attach to %s\n",
-+ phy_id_fmt);
-
-- phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, interface);
-+ phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link,
-+ interface);
-+ }
-
- if (IS_ERR_OR_NULL(phydev)) {
- pr_err("%s: Could not attach to PHY\n", dev->name);
-@@ -851,7 +859,7 @@ static int stmmac_init_phy(struct net_de
- * device as well.
- * Note: phydev->phy_id is the result of reading the UID PHY registers.
- */
-- if (phydev->phy_id == 0) {
-+ if (!priv->plat->phy_node && phydev->phy_id == 0) {
- phy_disconnect(phydev);
- return -ENODEV;
- }
-@@ -978,13 +986,11 @@ static int stmmac_init_rx_buffers(struct
- {
- struct sk_buff *skb;
-
-- skb = __netdev_alloc_skb(priv->dev, priv->dma_buf_sz + NET_IP_ALIGN,
-- flags);
-+ skb = __netdev_alloc_skb_ip_align(priv->dev, priv->dma_buf_sz, flags);
- if (!skb) {
- pr_err("%s: Rx init fails; skb is NULL\n", __func__);
- return -ENOMEM;
- }
-- skb_reserve(skb, NET_IP_ALIGN);
- priv->rx_skbuff[i] = skb;
- priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data,
- priv->dma_buf_sz,
-@@ -2803,16 +2809,15 @@ static int stmmac_hw_init(struct stmmac_
- * stmmac_dvr_probe
- * @device: device pointer
- * @plat_dat: platform data pointer
-- * @addr: iobase memory address
-+ * @res: stmmac resource pointer
- * Description: this is the main probe function used to
- * call the alloc_etherdev, allocate the priv structure.
- * Return:
-- * on success the new private structure is returned, otherwise the error
-- * pointer.
-+ * returns 0 on success, otherwise errno.
- */
--struct stmmac_priv *stmmac_dvr_probe(struct device *device,
-- struct plat_stmmacenet_data *plat_dat,
-- void __iomem *addr)
-+int stmmac_dvr_probe(struct device *device,
-+ struct plat_stmmacenet_data *plat_dat,
-+ struct stmmac_resources *res)
- {
- int ret = 0;
- struct net_device *ndev = NULL;
-@@ -2820,7 +2825,7 @@ struct stmmac_priv *stmmac_dvr_probe(str
-
- ndev = alloc_etherdev(sizeof(struct stmmac_priv));
- if (!ndev)
-- return ERR_PTR(-ENOMEM);
-+ return -ENOMEM;
-
- SET_NETDEV_DEV(ndev, device);
-
-@@ -2831,8 +2836,17 @@ struct stmmac_priv *stmmac_dvr_probe(str
- stmmac_set_ethtool_ops(ndev);
- priv->pause = pause;
- priv->plat = plat_dat;
-- priv->ioaddr = addr;
-- priv->dev->base_addr = (unsigned long)addr;
-+ priv->ioaddr = res->addr;
-+ priv->dev->base_addr = (unsigned long)res->addr;
-+
-+ priv->dev->irq = res->irq;
-+ priv->wol_irq = res->wol_irq;
-+ priv->lpi_irq = res->lpi_irq;
-+
-+ if (res->mac)
-+ memcpy(priv->dev->dev_addr, res->mac, ETH_ALEN);
-+
-+ dev_set_drvdata(device, priv->dev);
-
- /* Verify driver arguments */
- stmmac_verify_args();
-@@ -2947,7 +2961,7 @@ struct stmmac_priv *stmmac_dvr_probe(str
- }
- }
-
-- return priv;
-+ return 0;
-
- error_mdio_register:
- unregister_netdev(ndev);
-@@ -2960,7 +2974,7 @@ error_pclk_get:
- error_clk_get:
- free_netdev(ndev);
-
-- return ERR_PTR(ret);
-+ return ret;
- }
- EXPORT_SYMBOL_GPL(stmmac_dvr_probe);
-
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
-@@ -161,11 +161,16 @@ int stmmac_mdio_reset(struct mii_bus *bu
-
- if (!gpio_request(reset_gpio, "mdio-reset")) {
- gpio_direction_output(reset_gpio, active_low ? 1 : 0);
-- udelay(data->delays[0]);
-+ if (data->delays[0])
-+ msleep(DIV_ROUND_UP(data->delays[0], 1000));
-+
- gpio_set_value(reset_gpio, active_low ? 0 : 1);
-- udelay(data->delays[1]);
-+ if (data->delays[1])
-+ msleep(DIV_ROUND_UP(data->delays[1], 1000));
-+
- gpio_set_value(reset_gpio, active_low ? 1 : 0);
-- udelay(data->delays[2]);
-+ if (data->delays[2])
-+ msleep(DIV_ROUND_UP(data->delays[2], 1000));
- }
- }
- #endif
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -163,7 +163,7 @@ static int stmmac_pci_probe(struct pci_d
- {
- struct stmmac_pci_info *info = (struct stmmac_pci_info *)id->driver_data;
- struct plat_stmmacenet_data *plat;
-- struct stmmac_priv *priv;
-+ struct stmmac_resources res;
- int i;
- int ret;
-
-@@ -214,19 +214,12 @@ static int stmmac_pci_probe(struct pci_d
-
- pci_enable_msi(pdev);
-
-- priv = stmmac_dvr_probe(&pdev->dev, plat, pcim_iomap_table(pdev)[i]);
-- if (IS_ERR(priv)) {
-- dev_err(&pdev->dev, "%s: main driver probe failed\n", __func__);
-- return PTR_ERR(priv);
-- }
-- priv->dev->irq = pdev->irq;
-- priv->wol_irq = pdev->irq;
--
-- pci_set_drvdata(pdev, priv->dev);
--
-- dev_dbg(&pdev->dev, "STMMAC PCI driver registration completed\n");
-+ memset(&res, 0, sizeof(res));
-+ res.addr = pcim_iomap_table(pdev)[i];
-+ res.wol_irq = pdev->irq;
-+ res.irq = pdev->irq;
-
-- return 0;
-+ return stmmac_dvr_probe(&pdev->dev, plat, &res);
- }
-
- /**
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
-@@ -28,29 +28,11 @@
- #include <linux/of.h>
- #include <linux/of_net.h>
- #include <linux/of_device.h>
-+#include <linux/of_mdio.h>
-
- #include "stmmac.h"
- #include "stmmac_platform.h"
-
--static const struct of_device_id stmmac_dt_ids[] = {
-- /* SoC specific glue layers should come before generic bindings */
-- { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_gmac_data},
-- { .compatible = "amlogic,meson6-dwmac", .data = &meson6_dwmac_data},
-- { .compatible = "allwinner,sun7i-a20-gmac", .data = &sun7i_gmac_data},
-- { .compatible = "st,stih415-dwmac", .data = &stih4xx_dwmac_data},
-- { .compatible = "st,stih416-dwmac", .data = &stih4xx_dwmac_data},
-- { .compatible = "st,stid127-dwmac", .data = &stid127_dwmac_data},
-- { .compatible = "st,stih407-dwmac", .data = &stih4xx_dwmac_data},
-- { .compatible = "altr,socfpga-stmmac", .data = &socfpga_gmac_data },
-- { .compatible = "st,spear600-gmac"},
-- { .compatible = "snps,dwmac-3.610"},
-- { .compatible = "snps,dwmac-3.70a"},
-- { .compatible = "snps,dwmac-3.710"},
-- { .compatible = "snps,dwmac"},
-- { /* sentinel */ }
--};
--MODULE_DEVICE_TABLE(of, stmmac_dt_ids);
--
- #ifdef CONFIG_OF
-
- /**
-@@ -122,37 +104,16 @@ static int dwmac1000_validate_ucast_entr
- * this function is to read the driver parameters from device-tree and
- * set some private fields that will be used by the main at runtime.
- */
--static int stmmac_probe_config_dt(struct platform_device *pdev,
-- struct plat_stmmacenet_data *plat,
-- const char **mac)
-+struct plat_stmmacenet_data *
-+stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
- {
- struct device_node *np = pdev->dev.of_node;
-+ struct plat_stmmacenet_data *plat;
- struct stmmac_dma_cfg *dma_cfg;
-- const struct of_device_id *device;
--
-- if (!np)
-- return -ENODEV;
-
-- device = of_match_device(stmmac_dt_ids, &pdev->dev);
-- if (!device)
-- return -ENODEV;
--
-- if (device->data) {
-- const struct stmmac_of_data *data = device->data;
-- plat->has_gmac = data->has_gmac;
-- plat->enh_desc = data->enh_desc;
-- plat->tx_coe = data->tx_coe;
-- plat->rx_coe = data->rx_coe;
-- plat->bugged_jumbo = data->bugged_jumbo;
-- plat->pmt = data->pmt;
-- plat->riwt_off = data->riwt_off;
-- plat->fix_mac_speed = data->fix_mac_speed;
-- plat->bus_setup = data->bus_setup;
-- plat->setup = data->setup;
-- plat->free = data->free;
-- plat->init = data->init;
-- plat->exit = data->exit;
-- }
-+ plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
-+ if (!plat)
-+ return ERR_PTR(-ENOMEM);
-
- *mac = of_get_mac_address(np);
- plat->interface = of_get_phy_mode(np);
-@@ -168,13 +129,24 @@ static int stmmac_probe_config_dt(struct
- /* Default to phy auto-detection */
- plat->phy_addr = -1;
-
-+ /* If we find a phy-handle property, use it as the PHY */
-+ plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
-+
-+ /* If phy-handle is not specified, check if we have a fixed-phy */
-+ if (!plat->phy_node && of_phy_is_fixed_link(np)) {
-+ if ((of_phy_register_fixed_link(np) < 0))
-+ return ERR_PTR(-ENODEV);
-+
-+ plat->phy_node = of_node_get(np);
-+ }
-+
- /* "snps,phy-addr" is not a standard property. Mark it as deprecated
- * and warn of its use. Remove this when phy node support is added.
- */
- if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0)
- dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
-
-- if (plat->phy_bus_name)
-+ if (plat->phy_node || plat->phy_bus_name)
- plat->mdio_bus_data = NULL;
- else
- plat->mdio_bus_data =
-@@ -194,6 +166,12 @@ static int stmmac_probe_config_dt(struct
- */
- plat->maxmtu = JUMBO_LEN;
-
-+ /* Set default value for multicast hash bins */
-+ plat->multicast_filter_bins = HASH_TABLE_SIZE;
-+
-+ /* Set default value for unicast filter entries */
-+ plat->unicast_filter_entries = 1;
-+
- /*
- * Currently only the properties needed on SPEAr600
- * are provided. All other properties should be added
-@@ -232,8 +210,10 @@ static int stmmac_probe_config_dt(struct
- if (of_find_property(np, "snps,pbl", NULL)) {
- dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
- GFP_KERNEL);
-- if (!dma_cfg)
-- return -ENOMEM;
-+ if (!dma_cfg) {
-+ of_node_put(np);
-+ return ERR_PTR(-ENOMEM);
-+ }
- plat->dma_cfg = dma_cfg;
- of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
- dma_cfg->fixed_burst =
-@@ -250,45 +230,34 @@ static int stmmac_probe_config_dt(struct
- pr_warn("force_sf_dma_mode is ignored if force_thresh_dma_mode is set.");
- }
-
-- return 0;
-+ return plat;
- }
- #else
--static int stmmac_probe_config_dt(struct platform_device *pdev,
-- struct plat_stmmacenet_data *plat,
-- const char **mac)
-+struct plat_stmmacenet_data *
-+stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
- {
-- return -ENOSYS;
-+ return ERR_PTR(-ENOSYS);
- }
- #endif /* CONFIG_OF */
-+EXPORT_SYMBOL_GPL(stmmac_probe_config_dt);
-
--/**
-- * stmmac_pltfr_probe - platform driver probe.
-- * @pdev: platform device pointer
-- * Description: platform_device probe function. It is to allocate
-- * the necessary platform resources, invoke custom helper (if required) and
-- * invoke the main probe function.
-- */
--static int stmmac_pltfr_probe(struct platform_device *pdev)
-+int stmmac_get_platform_resources(struct platform_device *pdev,
-+ struct stmmac_resources *stmmac_res)
- {
-- int ret = 0;
- struct resource *res;
-- struct device *dev = &pdev->dev;
-- void __iomem *addr = NULL;
-- struct stmmac_priv *priv = NULL;
-- struct plat_stmmacenet_data *plat_dat = NULL;
-- const char *mac = NULL;
-- int irq, wol_irq, lpi_irq;
-+
-+ memset(stmmac_res, 0, sizeof(*stmmac_res));
-
- /* Get IRQ information early to have an ability to ask for deferred
- * probe if needed before we went too far with resource allocation.
- */
-- irq = platform_get_irq_byname(pdev, "macirq");
-- if (irq < 0) {
-- if (irq != -EPROBE_DEFER) {
-- dev_err(dev,
-+ stmmac_res->irq = platform_get_irq_byname(pdev, "macirq");
-+ if (stmmac_res->irq < 0) {
-+ if (stmmac_res->irq != -EPROBE_DEFER) {
-+ dev_err(&pdev->dev,
- "MAC IRQ configuration information not found\n");
- }
-- return irq;
-+ return stmmac_res->irq;
- }
-
- /* On some platforms e.g. SPEAr the wake up irq differs from the mac irq
-@@ -298,82 +267,23 @@ static int stmmac_pltfr_probe(struct pla
- * In case the wake up interrupt is not passed from the platform
- * so the driver will continue to use the mac irq (ndev->irq)
- */
-- wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq");
-- if (wol_irq < 0) {
-- if (wol_irq == -EPROBE_DEFER)
-+ stmmac_res->wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq");
-+ if (stmmac_res->wol_irq < 0) {
-+ if (stmmac_res->wol_irq == -EPROBE_DEFER)
- return -EPROBE_DEFER;
-- wol_irq = irq;
-+ stmmac_res->wol_irq = stmmac_res->irq;
- }
-
-- lpi_irq = platform_get_irq_byname(pdev, "eth_lpi");
-- if (lpi_irq == -EPROBE_DEFER)
-+ stmmac_res->lpi_irq = platform_get_irq_byname(pdev, "eth_lpi");
-+ if (stmmac_res->lpi_irq == -EPROBE_DEFER)
- return -EPROBE_DEFER;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- addr = devm_ioremap_resource(dev, res);
-- if (IS_ERR(addr))
-- return PTR_ERR(addr);
--
-- plat_dat = dev_get_platdata(&pdev->dev);
--
-- if (!plat_dat)
-- plat_dat = devm_kzalloc(&pdev->dev,
-- sizeof(struct plat_stmmacenet_data),
-- GFP_KERNEL);
-- if (!plat_dat) {
-- pr_err("%s: ERROR: no memory", __func__);
-- return -ENOMEM;
-- }
--
-- /* Set default value for multicast hash bins */
-- plat_dat->multicast_filter_bins = HASH_TABLE_SIZE;
-+ stmmac_res->addr = devm_ioremap_resource(&pdev->dev, res);
-
-- /* Set default value for unicast filter entries */
-- plat_dat->unicast_filter_entries = 1;
--
-- if (pdev->dev.of_node) {
-- ret = stmmac_probe_config_dt(pdev, plat_dat, &mac);
-- if (ret) {
-- pr_err("%s: main dt probe failed", __func__);
-- return ret;
-- }
-- }
--
-- /* Custom setup (if needed) */
-- if (plat_dat->setup) {
-- plat_dat->bsp_priv = plat_dat->setup(pdev);
-- if (IS_ERR(plat_dat->bsp_priv))
-- return PTR_ERR(plat_dat->bsp_priv);
-- }
--
-- /* Custom initialisation (if needed)*/
-- if (plat_dat->init) {
-- ret = plat_dat->init(pdev, plat_dat->bsp_priv);
-- if (unlikely(ret))
-- return ret;
-- }
--
-- priv = stmmac_dvr_probe(&(pdev->dev), plat_dat, addr);
-- if (IS_ERR(priv)) {
-- pr_err("%s: main driver probe failed", __func__);
-- return PTR_ERR(priv);
-- }
--
-- /* Copy IRQ values to priv structure which is now avaialble */
-- priv->dev->irq = irq;
-- priv->wol_irq = wol_irq;
-- priv->lpi_irq = lpi_irq;
--
-- /* Get MAC address if available (DT) */
-- if (mac)
-- memcpy(priv->dev->dev_addr, mac, ETH_ALEN);
--
-- platform_set_drvdata(pdev, priv->dev);
--
-- pr_debug("STMMAC platform driver registration completed");
--
-- return 0;
-+ return PTR_ERR_OR_ZERO(stmmac_res->addr);
- }
-+EXPORT_SYMBOL_GPL(stmmac_get_platform_resources);
-
- /**
- * stmmac_pltfr_remove
-@@ -381,7 +291,7 @@ static int stmmac_pltfr_probe(struct pla
- * Description: this function calls the main to free the net resources
- * and calls the platforms hook and release the resources (e.g. mem).
- */
--static int stmmac_pltfr_remove(struct platform_device *pdev)
-+int stmmac_pltfr_remove(struct platform_device *pdev)
- {
- struct net_device *ndev = platform_get_drvdata(pdev);
- struct stmmac_priv *priv = netdev_priv(ndev);
-@@ -390,11 +300,9 @@ static int stmmac_pltfr_remove(struct pl
- if (priv->plat->exit)
- priv->plat->exit(pdev, priv->plat->bsp_priv);
-
-- if (priv->plat->free)
-- priv->plat->free(pdev, priv->plat->bsp_priv);
--
- return ret;
- }
-+EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
-
- #ifdef CONFIG_PM_SLEEP
- /**
-@@ -438,21 +346,10 @@ static int stmmac_pltfr_resume(struct de
- }
- #endif /* CONFIG_PM_SLEEP */
-
--static SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops,
-- stmmac_pltfr_suspend, stmmac_pltfr_resume);
--
--static struct platform_driver stmmac_pltfr_driver = {
-- .probe = stmmac_pltfr_probe,
-- .remove = stmmac_pltfr_remove,
-- .driver = {
-- .name = STMMAC_RESOURCE_NAME,
-- .pm = &stmmac_pltfr_pm_ops,
-- .of_match_table = of_match_ptr(stmmac_dt_ids),
-- },
--};
--
--module_platform_driver(stmmac_pltfr_driver);
-+SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops, stmmac_pltfr_suspend,
-+ stmmac_pltfr_resume);
-+EXPORT_SYMBOL_GPL(stmmac_pltfr_pm_ops);
-
--MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PLATFORM driver");
-+MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet platform support");
- MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
- MODULE_LICENSE("GPL");
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
-@@ -19,11 +19,15 @@
- #ifndef __STMMAC_PLATFORM_H__
- #define __STMMAC_PLATFORM_H__
-
--extern const struct stmmac_of_data meson6_dwmac_data;
--extern const struct stmmac_of_data sun7i_gmac_data;
--extern const struct stmmac_of_data stih4xx_dwmac_data;
--extern const struct stmmac_of_data stid127_dwmac_data;
--extern const struct stmmac_of_data socfpga_gmac_data;
--extern const struct stmmac_of_data rk3288_gmac_data;
-+#include "stmmac.h"
-+
-+struct plat_stmmacenet_data *
-+stmmac_probe_config_dt(struct platform_device *pdev, const char **mac);
-+
-+int stmmac_get_platform_resources(struct platform_device *pdev,
-+ struct stmmac_resources *stmmac_res);
-+
-+int stmmac_pltfr_remove(struct platform_device *pdev);
-+extern const struct dev_pm_ops stmmac_pltfr_pm_ops;
-
- #endif /* __STMMAC_PLATFORM_H__ */
---- a/include/linux/stmmac.h
-+++ b/include/linux/stmmac.h
-@@ -99,6 +99,7 @@ struct plat_stmmacenet_data {
- int phy_addr;
- int interface;
- struct stmmac_mdio_bus_data *mdio_bus_data;
-+ struct device_node *phy_node;
- struct stmmac_dma_cfg *dma_cfg;
- int clk_csr;
- int has_gmac;
-@@ -118,30 +119,8 @@ struct plat_stmmacenet_data {
- int rx_fifo_size;
- void (*fix_mac_speed)(void *priv, unsigned int speed);
- void (*bus_setup)(void __iomem *ioaddr);
-- void *(*setup)(struct platform_device *pdev);
-- void (*free)(struct platform_device *pdev, void *priv);
- int (*init)(struct platform_device *pdev, void *priv);
- void (*exit)(struct platform_device *pdev, void *priv);
-- void *custom_cfg;
-- void *custom_data;
- void *bsp_priv;
- };
--
--/* of_data for SoC glue layer device tree bindings */
--
--struct stmmac_of_data {
-- int has_gmac;
-- int enh_desc;
-- int tx_coe;
-- int rx_coe;
-- int bugged_jumbo;
-- int pmt;
-- int riwt_off;
-- void (*fix_mac_speed)(void *priv, unsigned int speed);
-- void (*bus_setup)(void __iomem *ioaddr);
-- void *(*setup)(struct platform_device *pdev);
-- void (*free)(struct platform_device *pdev, void *priv);
-- int (*init)(struct platform_device *pdev, void *priv);
-- void (*exit)(struct platform_device *pdev, void *priv);
--};
- #endif