From 4625c9b5a4122f21b2415a32f930d58dbd74686b Mon Sep 17 00:00:00 2001
From: Gabor Juhos <juhosg@openwrt.org>
Date: Sat, 21 Jan 2012 22:44:09 +0000
Subject: [PATCH] generic: rtl8366: add rtl8366_smi_write_reg_noack helper

After issuing a soft reset on the RT8366{S,RB}
switch, waiting for the last acknowlegement fails
in rtl8366_smi_write_reg. Add a _noack version of
the function and use that for issuing a soft reset.

SVN-Revision: 29844
---
 .../files/drivers/net/phy/rtl8366_smi.c       | 25 +++++++++++++++++--
 .../files/drivers/net/phy/rtl8366_smi.h       |  1 +
 .../generic/files/drivers/net/phy/rtl8366rb.c |  4 +--
 .../generic/files/drivers/net/phy/rtl8366s.c  |  4 +--
 4 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c
index 971c95f83d..e48ca99ce8 100644
--- a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c
+++ b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c
@@ -157,6 +157,12 @@ static int rtl8366_smi_write_byte(struct rtl8366_smi *smi, u8 data)
 	return rtl8366_smi_wait_for_ack(smi);
 }
 
+static int rtl8366_smi_write_byte_noack(struct rtl8366_smi *smi, u8 data)
+{
+	rtl8366_smi_write_bits(smi, data, 8);
+	return 0;
+}
+
 static int rtl8366_smi_read_byte0(struct rtl8366_smi *smi, u8 *data)
 {
 	u32 t;
@@ -228,7 +234,8 @@ int rtl8366_smi_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data)
 }
 EXPORT_SYMBOL_GPL(rtl8366_smi_read_reg);
 
-int rtl8366_smi_write_reg(struct rtl8366_smi *smi, u32 addr, u32 data)
+static int __rtl8366_smi_write_reg(struct rtl8366_smi *smi,
+				   u32 addr, u32 data, bool ack)
 {
 	unsigned long flags;
 	int ret;
@@ -258,7 +265,10 @@ int rtl8366_smi_write_reg(struct rtl8366_smi *smi, u32 addr, u32 data)
 		goto out;
 
 	/* write DATA[15:8] */
-	ret = rtl8366_smi_write_byte(smi, data >> 8);
+	if (ack)
+		ret = rtl8366_smi_write_byte(smi, data >> 8);
+	else
+		ret = rtl8366_smi_write_byte_noack(smi, data >> 8);
 	if (ret)
 		goto out;
 
@@ -270,8 +280,19 @@ int rtl8366_smi_write_reg(struct rtl8366_smi *smi, u32 addr, u32 data)
 
 	return ret;
 }
+
+int rtl8366_smi_write_reg(struct rtl8366_smi *smi, u32 addr, u32 data)
+{
+	return __rtl8366_smi_write_reg(smi, addr, data, true);
+}
 EXPORT_SYMBOL_GPL(rtl8366_smi_write_reg);
 
+int rtl8366_smi_write_reg_noack(struct rtl8366_smi *smi, u32 addr, u32 data)
+{
+	return __rtl8366_smi_write_reg(smi, addr, data, false);
+}
+EXPORT_SYMBOL_GPL(rtl8366_smi_write_reg_noack);
+
 int rtl8366_smi_rmwr(struct rtl8366_smi *smi, u32 addr, u32 mask, u32 data)
 {
 	u32 t;
diff --git a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h
index 9db2576c88..8b1a70dca8 100644
--- a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h
+++ b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h
@@ -103,6 +103,7 @@ struct rtl8366_smi *rtl8366_smi_alloc(struct device *parent);
 int rtl8366_smi_init(struct rtl8366_smi *smi);
 void rtl8366_smi_cleanup(struct rtl8366_smi *smi);
 int rtl8366_smi_write_reg(struct rtl8366_smi *smi, u32 addr, u32 data);
+int rtl8366_smi_write_reg_noack(struct rtl8366_smi *smi, u32 addr, u32 data);
 int rtl8366_smi_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data);
 int rtl8366_smi_rmwr(struct rtl8366_smi *smi, u32 addr, u32 mask, u32 data);
 
diff --git a/target/linux/generic/files/drivers/net/phy/rtl8366rb.c b/target/linux/generic/files/drivers/net/phy/rtl8366rb.c
index 49dd03e274..d6a9ece36f 100644
--- a/target/linux/generic/files/drivers/net/phy/rtl8366rb.c
+++ b/target/linux/generic/files/drivers/net/phy/rtl8366rb.c
@@ -246,8 +246,8 @@ static int rtl8366rb_reset_chip(struct rtl8366_smi *smi)
 	int timeout = 10;
 	u32 data;
 
-	rtl8366_smi_write_reg(smi, RTL8366RB_RESET_CTRL_REG,
-			      RTL8366RB_CHIP_CTRL_RESET_HW);
+	rtl8366_smi_write_reg_noack(smi, RTL8366RB_RESET_CTRL_REG,
+			 	    RTL8366RB_CHIP_CTRL_RESET_HW);
 	do {
 		msleep(1);
 		if (rtl8366_smi_read_reg(smi, RTL8366RB_RESET_CTRL_REG, &data))
diff --git a/target/linux/generic/files/drivers/net/phy/rtl8366s.c b/target/linux/generic/files/drivers/net/phy/rtl8366s.c
index 27e9aa45e4..4300872c3e 100644
--- a/target/linux/generic/files/drivers/net/phy/rtl8366s.c
+++ b/target/linux/generic/files/drivers/net/phy/rtl8366s.c
@@ -229,8 +229,8 @@ static int rtl8366s_reset_chip(struct rtl8366_smi *smi)
 	int timeout = 10;
 	u32 data;
 
-	rtl8366_smi_write_reg(smi, RTL8366S_RESET_CTRL_REG,
-			      RTL8366S_CHIP_CTRL_RESET_HW);
+	rtl8366_smi_write_reg_noack(smi, RTL8366S_RESET_CTRL_REG,
+				    RTL8366S_CHIP_CTRL_RESET_HW);
 	do {
 		msleep(1);
 		if (rtl8366_smi_read_reg(smi, RTL8366S_RESET_CTRL_REG, &data))
-- 
2.30.2