ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/target/linux/layerscape/patches-5.4/701-net-0259-net-mscc-ocelot-separate-the-implementation-of-switc.patch b/target/linux/layerscape/patches-5.4/701-net-0259-net-mscc-ocelot-separate-the-implementation-of-switc.patch
new file mode 100644
index 0000000..3a8e9d6
--- /dev/null
+++ b/target/linux/layerscape/patches-5.4/701-net-0259-net-mscc-ocelot-separate-the-implementation-of-switc.patch
@@ -0,0 +1,109 @@
+From c96a1cff5d03a56f380ce761aec9d11fcf61c7f1 Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Thu, 14 Nov 2019 17:03:26 +0200
+Subject: [PATCH] net: mscc: ocelot: separate the implementation of switch
+ reset
+
+The Felix switch has a different reset procedure, so a function pointer
+needs to be created and added to the ocelot_ops structure.
+
+The reset procedure has been moved into ocelot_init.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/mscc/ocelot.c       |  8 +++++++
+ drivers/net/ethernet/mscc/ocelot.h       |  1 +
+ drivers/net/ethernet/mscc/ocelot_board.c | 37 +++++++++++++++++++++-----------
+ 3 files changed, 33 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/ethernet/mscc/ocelot.c
++++ b/drivers/net/ethernet/mscc/ocelot.c
+@@ -2268,6 +2268,14 @@ int ocelot_init(struct ocelot *ocelot)
+ 	int i, ret;
+ 	u32 port;
+ 
++	if (ocelot->ops->reset) {
++		ret = ocelot->ops->reset(ocelot);
++		if (ret) {
++			dev_err(ocelot->dev, "Switch reset failed\n");
++			return ret;
++		}
++	}
++
+ 	ocelot->lags = devm_kcalloc(ocelot->dev, ocelot->num_phys_ports,
+ 				    sizeof(u32), GFP_KERNEL);
+ 	if (!ocelot->lags)
+--- a/drivers/net/ethernet/mscc/ocelot.h
++++ b/drivers/net/ethernet/mscc/ocelot.h
+@@ -446,6 +446,7 @@ struct ocelot_stat_layout {
+ 
+ struct ocelot_ops {
+ 	void (*pcs_init)(struct ocelot *ocelot, int port);
++	int (*reset)(struct ocelot *ocelot);
+ };
+ 
+ struct ocelot {
+--- a/drivers/net/ethernet/mscc/ocelot_board.c
++++ b/drivers/net/ethernet/mscc/ocelot_board.c
+@@ -285,8 +285,32 @@ static void ocelot_port_pcs_init(struct
+ 	ocelot_port_writel(ocelot_port, 0, PCS1G_LB_CFG);
+ }
+ 
++static int ocelot_reset(struct ocelot *ocelot)
++{
++	int retries = 100;
++	u32 val;
++
++	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1);
++	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
++
++	do {
++		msleep(1);
++		regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT],
++				  &val);
++	} while (val && --retries);
++
++	if (!retries)
++		return -ETIMEDOUT;
++
++	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
++	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1);
++
++	return 0;
++}
++
+ static const struct ocelot_ops ocelot_ops = {
+ 	.pcs_init		= ocelot_port_pcs_init,
++	.reset			= ocelot_reset,
+ };
+ 
+ static int mscc_ocelot_probe(struct platform_device *pdev)
+@@ -297,7 +321,6 @@ static int mscc_ocelot_probe(struct plat
+ 	struct ocelot *ocelot;
+ 	struct regmap *hsio;
+ 	unsigned int i;
+-	u32 val;
+ 
+ 	struct {
+ 		enum ocelot_target id;
+@@ -377,18 +400,6 @@ static int mscc_ocelot_probe(struct plat
+ 		ocelot->ptp = 1;
+ 	}
+ 
+-	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1);
+-	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
+-
+-	do {
+-		msleep(1);
+-		regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT],
+-				  &val);
+-	} while (val);
+-
+-	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
+-	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1);
+-
+ 	ocelot->num_cpu_ports = 1; /* 1 port on the switch, two groups */
+ 
+ 	ports = of_get_child_by_name(np, "ethernet-ports");