Refresh patches. Remove upstreamed patch: generic/pending/181-net-usb-add-lte-modem-wistron-neweb-d18q1.patch Update patches that no longer applies: generic/hack/901-debloat_sock_diag.patch Compile-tested on: x86/64. Runtime-tested on: x86/64. Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
		
			
				
	
	
		
			275 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			275 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From 6c4995c9a8ba8841ba640201636954c84f494587 Mon Sep 17 00:00:00 2001
 | 
						|
From: Chunfeng Yun <chunfeng.yun@mediatek.com>
 | 
						|
Date: Fri, 13 Oct 2017 17:10:42 +0800
 | 
						|
Subject: [PATCH 108/224] usb: mtu3: use FORCE/RG_IDDIG to implement manual DRD
 | 
						|
 switch
 | 
						|
 | 
						|
In order to keep manual DRD switch independent on IDDIG interrupt,
 | 
						|
make use of FORCE/RG_IDDIG instead of IDDIG EINT interrupt to
 | 
						|
implement manual DRD switch function.
 | 
						|
 | 
						|
Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
 | 
						|
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
 | 
						|
---
 | 
						|
 drivers/usb/mtu3/mtu3.h         | 18 ++++++++----
 | 
						|
 drivers/usb/mtu3/mtu3_dr.c      | 61 ++++++++++++++++++++++++++++++-----------
 | 
						|
 drivers/usb/mtu3/mtu3_dr.h      |  6 ++++
 | 
						|
 drivers/usb/mtu3/mtu3_host.c    |  5 ++++
 | 
						|
 drivers/usb/mtu3/mtu3_hw_regs.h |  2 ++
 | 
						|
 drivers/usb/mtu3/mtu3_plat.c    | 38 ++-----------------------
 | 
						|
 6 files changed, 74 insertions(+), 56 deletions(-)
 | 
						|
 | 
						|
--- a/drivers/usb/mtu3/mtu3.h
 | 
						|
+++ b/drivers/usb/mtu3/mtu3.h
 | 
						|
@@ -115,6 +115,19 @@ enum mtu3_g_ep0_state {
 | 
						|
 };
 | 
						|
 
 | 
						|
 /**
 | 
						|
+ * MTU3_DR_FORCE_NONE: automatically switch host and periperal mode
 | 
						|
+ *		by IDPIN signal.
 | 
						|
+ * MTU3_DR_FORCE_HOST: force to enter host mode and override OTG
 | 
						|
+ *		IDPIN signal.
 | 
						|
+ * MTU3_DR_FORCE_DEVICE: force to enter peripheral mode.
 | 
						|
+ */
 | 
						|
+enum mtu3_dr_force_mode {
 | 
						|
+	MTU3_DR_FORCE_NONE = 0,
 | 
						|
+	MTU3_DR_FORCE_HOST,
 | 
						|
+	MTU3_DR_FORCE_DEVICE,
 | 
						|
+};
 | 
						|
+
 | 
						|
+/**
 | 
						|
  * @base: the base address of fifo
 | 
						|
  * @limit: the bitmap size in bits
 | 
						|
  * @bitmap: fifo bitmap in unit of @MTU3_EP_FIFO_UNIT
 | 
						|
@@ -196,7 +209,6 @@ struct mtu3_gpd_ring {
 | 
						|
 *		xHCI driver initialization, it's necessary for system bootup
 | 
						|
 *		as device.
 | 
						|
 * @is_u3_drd: whether port0 supports usb3.0 dual-role device or not
 | 
						|
-* @id_*: used to maually switch between host and device modes by idpin
 | 
						|
 * @manual_drd_enabled: it's true when supports dual-role device by debugfs
 | 
						|
 *		to switch host/device modes depending on user input.
 | 
						|
 */
 | 
						|
@@ -207,10 +219,6 @@ struct otg_switch_mtk {
 | 
						|
 	struct notifier_block id_nb;
 | 
						|
 	struct delayed_work extcon_reg_dwork;
 | 
						|
 	bool is_u3_drd;
 | 
						|
-	/* dual-role switch by debugfs */
 | 
						|
-	struct pinctrl *id_pinctrl;
 | 
						|
-	struct pinctrl_state *id_float;
 | 
						|
-	struct pinctrl_state *id_ground;
 | 
						|
 	bool manual_drd_enabled;
 | 
						|
 };
 | 
						|
 
 | 
						|
--- a/drivers/usb/mtu3/mtu3_dr.c
 | 
						|
+++ b/drivers/usb/mtu3/mtu3_dr.c
 | 
						|
@@ -261,21 +261,22 @@ static void extcon_register_dwork(struct
 | 
						|
  * depending on user input.
 | 
						|
  * This is useful in special cases, such as uses TYPE-A receptacle but also
 | 
						|
  * wants to support dual-role mode.
 | 
						|
- * It generates cable state changes by pulling up/down IDPIN and
 | 
						|
- * notifies driver to switch mode by "extcon-usb-gpio".
 | 
						|
- * NOTE: when use MICRO receptacle, should not enable this interface.
 | 
						|
  */
 | 
						|
 static void ssusb_mode_manual_switch(struct ssusb_mtk *ssusb, int to_host)
 | 
						|
 {
 | 
						|
 	struct otg_switch_mtk *otg_sx = &ssusb->otg_switch;
 | 
						|
 
 | 
						|
-	if (to_host)
 | 
						|
-		pinctrl_select_state(otg_sx->id_pinctrl, otg_sx->id_ground);
 | 
						|
-	else
 | 
						|
-		pinctrl_select_state(otg_sx->id_pinctrl, otg_sx->id_float);
 | 
						|
+	if (to_host) {
 | 
						|
+		ssusb_set_force_mode(ssusb, MTU3_DR_FORCE_HOST);
 | 
						|
+		ssusb_set_mailbox(otg_sx, MTU3_VBUS_OFF);
 | 
						|
+		ssusb_set_mailbox(otg_sx, MTU3_ID_GROUND);
 | 
						|
+	} else {
 | 
						|
+		ssusb_set_force_mode(ssusb, MTU3_DR_FORCE_DEVICE);
 | 
						|
+		ssusb_set_mailbox(otg_sx, MTU3_ID_FLOAT);
 | 
						|
+		ssusb_set_mailbox(otg_sx, MTU3_VBUS_VALID);
 | 
						|
+	}
 | 
						|
 }
 | 
						|
 
 | 
						|
-
 | 
						|
 static int ssusb_mode_show(struct seq_file *sf, void *unused)
 | 
						|
 {
 | 
						|
 	struct ssusb_mtk *ssusb = sf->private;
 | 
						|
@@ -388,17 +389,45 @@ static void ssusb_debugfs_exit(struct ss
 | 
						|
 	debugfs_remove_recursive(ssusb->dbgfs_root);
 | 
						|
 }
 | 
						|
 
 | 
						|
+void ssusb_set_force_mode(struct ssusb_mtk *ssusb,
 | 
						|
+			  enum mtu3_dr_force_mode mode)
 | 
						|
+{
 | 
						|
+	u32 value;
 | 
						|
+
 | 
						|
+	value = mtu3_readl(ssusb->ippc_base, SSUSB_U2_CTRL(0));
 | 
						|
+	switch (mode) {
 | 
						|
+	case MTU3_DR_FORCE_DEVICE:
 | 
						|
+		value |= SSUSB_U2_PORT_FORCE_IDDIG | SSUSB_U2_PORT_RG_IDDIG;
 | 
						|
+		break;
 | 
						|
+	case MTU3_DR_FORCE_HOST:
 | 
						|
+		value |= SSUSB_U2_PORT_FORCE_IDDIG;
 | 
						|
+		value &= ~SSUSB_U2_PORT_RG_IDDIG;
 | 
						|
+		break;
 | 
						|
+	case MTU3_DR_FORCE_NONE:
 | 
						|
+		value &= ~(SSUSB_U2_PORT_FORCE_IDDIG | SSUSB_U2_PORT_RG_IDDIG);
 | 
						|
+		break;
 | 
						|
+	default:
 | 
						|
+		return;
 | 
						|
+	}
 | 
						|
+	mtu3_writel(ssusb->ippc_base, SSUSB_U2_CTRL(0), value);
 | 
						|
+}
 | 
						|
+
 | 
						|
 int ssusb_otg_switch_init(struct ssusb_mtk *ssusb)
 | 
						|
 {
 | 
						|
 	struct otg_switch_mtk *otg_sx = &ssusb->otg_switch;
 | 
						|
 
 | 
						|
-	INIT_DELAYED_WORK(&otg_sx->extcon_reg_dwork, extcon_register_dwork);
 | 
						|
-
 | 
						|
-	if (otg_sx->manual_drd_enabled)
 | 
						|
+	if (otg_sx->manual_drd_enabled) {
 | 
						|
 		ssusb_debugfs_init(ssusb);
 | 
						|
+	} else {
 | 
						|
+		INIT_DELAYED_WORK(&otg_sx->extcon_reg_dwork,
 | 
						|
+				  extcon_register_dwork);
 | 
						|
 
 | 
						|
-	/* It is enough to delay 1s for waiting for host initialization */
 | 
						|
-	schedule_delayed_work(&otg_sx->extcon_reg_dwork, HZ);
 | 
						|
+		/*
 | 
						|
+		 * It is enough to delay 1s for waiting for
 | 
						|
+		 * host initialization
 | 
						|
+		 */
 | 
						|
+		schedule_delayed_work(&otg_sx->extcon_reg_dwork, HZ);
 | 
						|
+	}
 | 
						|
 
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
@@ -407,8 +436,8 @@ void ssusb_otg_switch_exit(struct ssusb_
 | 
						|
 {
 | 
						|
 	struct otg_switch_mtk *otg_sx = &ssusb->otg_switch;
 | 
						|
 
 | 
						|
-	cancel_delayed_work(&otg_sx->extcon_reg_dwork);
 | 
						|
-
 | 
						|
 	if (otg_sx->manual_drd_enabled)
 | 
						|
 		ssusb_debugfs_exit(ssusb);
 | 
						|
+	else
 | 
						|
+		cancel_delayed_work(&otg_sx->extcon_reg_dwork);
 | 
						|
 }
 | 
						|
--- a/drivers/usb/mtu3/mtu3_dr.h
 | 
						|
+++ b/drivers/usb/mtu3/mtu3_dr.h
 | 
						|
@@ -87,6 +87,8 @@ static inline void ssusb_gadget_exit(str
 | 
						|
 int ssusb_otg_switch_init(struct ssusb_mtk *ssusb);
 | 
						|
 void ssusb_otg_switch_exit(struct ssusb_mtk *ssusb);
 | 
						|
 int ssusb_set_vbus(struct otg_switch_mtk *otg_sx, int is_on);
 | 
						|
+void ssusb_set_force_mode(struct ssusb_mtk *ssusb,
 | 
						|
+			  enum mtu3_dr_force_mode mode);
 | 
						|
 
 | 
						|
 #else
 | 
						|
 
 | 
						|
@@ -103,6 +105,10 @@ static inline int ssusb_set_vbus(struct
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
+static inline void
 | 
						|
+ssusb_set_force_mode(struct ssusb_mtk *ssusb, enum mtu3_dr_force_mode mode)
 | 
						|
+{}
 | 
						|
+
 | 
						|
 #endif
 | 
						|
 
 | 
						|
 #endif		/* _MTU3_DR_H_ */
 | 
						|
--- a/drivers/usb/mtu3/mtu3_host.c
 | 
						|
+++ b/drivers/usb/mtu3/mtu3_host.c
 | 
						|
@@ -189,6 +189,8 @@ int ssusb_host_disable(struct ssusb_mtk
 | 
						|
 
 | 
						|
 static void ssusb_host_setup(struct ssusb_mtk *ssusb)
 | 
						|
 {
 | 
						|
+	struct otg_switch_mtk *otg_sx = &ssusb->otg_switch;
 | 
						|
+
 | 
						|
 	host_ports_num_get(ssusb);
 | 
						|
 
 | 
						|
 	/*
 | 
						|
@@ -197,6 +199,9 @@ static void ssusb_host_setup(struct ssus
 | 
						|
 	 */
 | 
						|
 	ssusb_host_enable(ssusb);
 | 
						|
 
 | 
						|
+	if (otg_sx->manual_drd_enabled)
 | 
						|
+		ssusb_set_force_mode(ssusb, MTU3_DR_FORCE_HOST);
 | 
						|
+
 | 
						|
 	/* if port0 supports dual-role, works as host mode by default */
 | 
						|
 	ssusb_set_vbus(&ssusb->otg_switch, 1);
 | 
						|
 }
 | 
						|
--- a/drivers/usb/mtu3/mtu3_hw_regs.h
 | 
						|
+++ b/drivers/usb/mtu3/mtu3_hw_regs.h
 | 
						|
@@ -472,6 +472,8 @@
 | 
						|
 #define SSUSB_U3_PORT_DIS		BIT(0)
 | 
						|
 
 | 
						|
 /* U3D_SSUSB_U2_CTRL_0P */
 | 
						|
+#define SSUSB_U2_PORT_RG_IDDIG		BIT(12)
 | 
						|
+#define SSUSB_U2_PORT_FORCE_IDDIG	BIT(11)
 | 
						|
 #define SSUSB_U2_PORT_VBUSVALID	BIT(9)
 | 
						|
 #define SSUSB_U2_PORT_OTG_SEL		BIT(7)
 | 
						|
 #define SSUSB_U2_PORT_HOST		BIT(2)
 | 
						|
--- a/drivers/usb/mtu3/mtu3_plat.c
 | 
						|
+++ b/drivers/usb/mtu3/mtu3_plat.c
 | 
						|
@@ -21,7 +21,6 @@
 | 
						|
 #include <linux/module.h>
 | 
						|
 #include <linux/of_address.h>
 | 
						|
 #include <linux/of_irq.h>
 | 
						|
-#include <linux/pinctrl/consumer.h>
 | 
						|
 #include <linux/platform_device.h>
 | 
						|
 
 | 
						|
 #include "mtu3.h"
 | 
						|
@@ -212,33 +211,6 @@ static void ssusb_ip_sw_reset(struct ssu
 | 
						|
 	mtu3_clrbits(ssusb->ippc_base, U3D_SSUSB_IP_PW_CTRL0, SSUSB_IP_SW_RST);
 | 
						|
 }
 | 
						|
 
 | 
						|
-static int get_iddig_pinctrl(struct ssusb_mtk *ssusb)
 | 
						|
-{
 | 
						|
-	struct otg_switch_mtk *otg_sx = &ssusb->otg_switch;
 | 
						|
-
 | 
						|
-	otg_sx->id_pinctrl = devm_pinctrl_get(ssusb->dev);
 | 
						|
-	if (IS_ERR(otg_sx->id_pinctrl)) {
 | 
						|
-		dev_err(ssusb->dev, "Cannot find id pinctrl!\n");
 | 
						|
-		return PTR_ERR(otg_sx->id_pinctrl);
 | 
						|
-	}
 | 
						|
-
 | 
						|
-	otg_sx->id_float =
 | 
						|
-		pinctrl_lookup_state(otg_sx->id_pinctrl, "id_float");
 | 
						|
-	if (IS_ERR(otg_sx->id_float)) {
 | 
						|
-		dev_err(ssusb->dev, "Cannot find pinctrl id_float!\n");
 | 
						|
-		return PTR_ERR(otg_sx->id_float);
 | 
						|
-	}
 | 
						|
-
 | 
						|
-	otg_sx->id_ground =
 | 
						|
-		pinctrl_lookup_state(otg_sx->id_pinctrl, "id_ground");
 | 
						|
-	if (IS_ERR(otg_sx->id_ground)) {
 | 
						|
-		dev_err(ssusb->dev, "Cannot find pinctrl id_ground!\n");
 | 
						|
-		return PTR_ERR(otg_sx->id_ground);
 | 
						|
-	}
 | 
						|
-
 | 
						|
-	return 0;
 | 
						|
-}
 | 
						|
-
 | 
						|
 /* ignore the error if the clock does not exist */
 | 
						|
 static struct clk *get_optional_clk(struct device *dev, const char *id)
 | 
						|
 {
 | 
						|
@@ -349,15 +321,11 @@ static int get_ssusb_rscs(struct platfor
 | 
						|
 			dev_err(ssusb->dev, "couldn't get extcon device\n");
 | 
						|
 			return -EPROBE_DEFER;
 | 
						|
 		}
 | 
						|
-		if (otg_sx->manual_drd_enabled) {
 | 
						|
-			ret = get_iddig_pinctrl(ssusb);
 | 
						|
-			if (ret)
 | 
						|
-				return ret;
 | 
						|
-		}
 | 
						|
 	}
 | 
						|
 
 | 
						|
-	dev_info(dev, "dr_mode: %d, is_u3_dr: %d, u3p_dis_msk:%x\n",
 | 
						|
-		ssusb->dr_mode, otg_sx->is_u3_drd, ssusb->u3p_dis_msk);
 | 
						|
+	dev_info(dev, "dr_mode: %d, is_u3_dr: %d, u3p_dis_msk: %x, drd: %s\n",
 | 
						|
+		ssusb->dr_mode, otg_sx->is_u3_drd, ssusb->u3p_dis_msk,
 | 
						|
+		otg_sx->manual_drd_enabled ? "manual" : "auto");
 | 
						|
 
 | 
						|
 	return 0;
 | 
						|
 }
 |