phy: sun4i-usb: Add a sunxi specific function for setting squelch-detect

The sunxi otg phy has a bug where it wrongly detects a high speed squelch
when reset on the root port gets de-asserted with a lo-speed device.

The workaround for this is to disable squelch detect before de-asserting
reset, and re-enabling it after the reset de-assert is done. Add a sunxi
specific phy function to allow the sunxi-musb glue to do this.

Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
Acked-by: Jun Nie <jun.nie@linaro.org>
diff --git a/drivers/usb/musb-new/musb_core.h b/drivers/usb/musb-new/musb_core.h
index fa4cf86..821d0e0 100644
--- a/drivers/usb/musb-new/musb_core.h
+++ b/drivers/usb/musb-new/musb_core.h
@@ -200,6 +200,8 @@
  * @vbus_status: returns vbus status if possible
  * @set_vbus:	forces vbus status
  * @adjust_channel_params: pre check for standard dma channel_program func
+ * @pre_root_reset_end: called before the root usb port reset flag gets cleared
+ * @post_root_reset_end: called after the root usb port reset flag gets cleared
  */
 struct musb_platform_ops {
 	int	(*init)(struct musb *musb);
@@ -221,6 +223,8 @@
 	int	(*adjust_channel_params)(struct dma_channel *channel,
 				u16 packet_sz, u8 *mode,
 				dma_addr_t *dma_addr, u32 *len);
+	void	(*pre_root_reset_end)(struct musb *musb);
+	void	(*post_root_reset_end)(struct musb *musb);
 };
 
 /*
diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c
index 8662c0f..48242c0 100644
--- a/drivers/usb/musb-new/musb_uboot.c
+++ b/drivers/usb/musb-new/musb_uboot.c
@@ -193,19 +193,16 @@
 	power &= 0xf0;
 	musb_writeb(mbase, MUSB_POWER, MUSB_POWER_RESET | power);
 	mdelay(50);
-#ifdef CONFIG_ARCH_SUNXI
-	/*
-	 * sunxi phy has a bug and it will wrongly detect high speed squelch
-	 * when clearing reset on low-speed devices, temporary disable
-	 * squelch detection to work around this.
-	 */
-	sunxi_usb_phy_enable_squelch_detect(0, 0);
-#endif
+
+	if (host->host->ops->pre_root_reset_end)
+		host->host->ops->pre_root_reset_end(host->host);
+
 	power = musb_readb(mbase, MUSB_POWER);
 	musb_writeb(mbase, MUSB_POWER, ~MUSB_POWER_RESET & power);
-#ifdef CONFIG_ARCH_SUNXI
-	sunxi_usb_phy_enable_squelch_detect(0, 1);
-#endif
+
+	if (host->host->ops->post_root_reset_end)
+		host->host->ops->post_root_reset_end(host->host);
+
 	host->host->isr(0, host->host);
 	host->host_speed = (musb_readb(mbase, MUSB_POWER) & MUSB_POWER_HSMODE) ?
 			USB_SPEED_HIGH :
diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c
index a33ebe5..5728a3f 100644
--- a/drivers/usb/musb-new/sunxi.c
+++ b/drivers/usb/musb-new/sunxi.c
@@ -304,10 +304,26 @@
 	return 0;
 }
 
+static void sunxi_musb_pre_root_reset_end(struct musb *musb)
+{
+	struct sunxi_glue *glue = to_sunxi_glue(musb->controller);
+
+	sun4i_usb_phy_set_squelch_detect(glue->phy, false);
+}
+
+static void sunxi_musb_post_root_reset_end(struct musb *musb)
+{
+	struct sunxi_glue *glue = to_sunxi_glue(musb->controller);
+
+	sun4i_usb_phy_set_squelch_detect(glue->phy, true);
+}
+
 static const struct musb_platform_ops sunxi_musb_ops = {
 	.init		= sunxi_musb_init,
 	.enable		= sunxi_musb_enable,
 	.disable	= sunxi_musb_disable,
+	.pre_root_reset_end = sunxi_musb_pre_root_reset_end,
+	.post_root_reset_end = sunxi_musb_post_root_reset_end,
 };
 
 /* Allwinner OTG supports up to 5 endpoints */