All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea
@ 2013-08-02  8:33 Peter Chen
  2013-08-02  8:33 ` [PATCH v14 01/12] usb: chipidea: move vbus regulator operation to core Peter Chen
                   ` (12 more replies)
  0 siblings, 13 replies; 23+ messages in thread
From: Peter Chen @ 2013-08-02  8:33 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset adds tested otg id switch function and vbus connect
and disconnect detection for chipidea driver. And fix kinds of 
bugs found at chipidea drivers after enabling id and vbus detection.

This patch are fully tested at imx6 sabresd and imx28evk platform by me.
Besides, marek tested it on two STMP3780-based boards (not yet mainline)
and two MX28-based boards.

My chipidea repo: https://github.com/hzpeterchen/linux-usb.git

Changes for v14:
- This patchset is based on below recent chipidea patches and newest
usb-next, it can decrease rebase effort.

Fabio Estevam (3):
  chipidea: ci_hdrc_imx: Remove unused variable 'res'
  chipidea: core: Move hw_phymode_configure() into probe
  chipidea: Remove previous MODULE_ALIAS

Lothar Wa??mann (3):
  usb: chipidea: improve kconfig 2.0
  usb: chipidea: don't clobber return value of ci_role_start()
  usb: chipidea: ci_hdrc_imx: remove an unsolicited module_put() call
    from ci_hdrc_imx_remove()

Peter Chen (1):
  usb: chipidea: fix the build error with randconfig

- [Michael comments]: move vbus operation to core, and squash two vbus
patches. [1/12], [2/12]
- [Michael comments]: move out non vbus and non id related patches. [14/14 at v13]

Chagnes for v13:
- Add Tested-by: Marek Vasut <marex@denx.de>
- [Sascha's comments]: Add return value check for devm_regulator_get. [3/14]
- [Marc's comments]: Change timeout usage at hw_wait_reg. [11/14]
- [Alex's comments]: Using platdata flag to indicate dual role but not 
OTG controller. [7/14]

Changes for v12:
- Rebased greg's usb-next tree (3.10.0-rc7+)
- Split more small patches for single function and fix.

Peter Chen (12):
  usb: chipidea: move vbus regulator operation to core
  usb: chipidea: host: add vbus regulator control
  usb: chipidea: udc: otg_set_peripheral is useless for some chipidea
    users
  usb: chipidea: otg: Add otg file used to access otgsc
  usb: chipidea: Add role init and destory APIs
  usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG
  usb: chipidea: disable all interrupts and clear all interrupts status
  usb: chipidea: move otg relate things to otg file
  usb: chipidea: add vbus interrupt handler
  usb: chipidea: add wait vbus lower than OTGSC_BSV before role starts
  usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and
    CI_HDRC_PULLUP_ON_VBUS
  usb: chipidea: udc: .pullup is valid when vbus is on at
    CI_HDRC_PULLUP_ON_VBUS

 drivers/usb/chipidea/Makefile      |    2 +-
 drivers/usb/chipidea/bits.h        |   10 ++
 drivers/usb/chipidea/ci.h          |    8 ++
 drivers/usb/chipidea/ci_hdrc_imx.c |   26 +-----
 drivers/usb/chipidea/core.c        |  184 +++++++++++++++++++++++++-----------
 drivers/usb/chipidea/host.c        |   30 ++++++-
 drivers/usb/chipidea/host.h        |    6 +
 drivers/usb/chipidea/otg.c         |  135 ++++++++++++++++++++++++++
 drivers/usb/chipidea/otg.h         |   22 +++++
 drivers/usb/chipidea/udc.c         |   59 +++++++++---
 drivers/usb/chipidea/udc.h         |    6 +
 include/linux/usb/chipidea.h       |    6 +
 12 files changed, 401 insertions(+), 93 deletions(-)
 create mode 100644 drivers/usb/chipidea/otg.c
 create mode 100644 drivers/usb/chipidea/otg.h

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v14 01/12] usb: chipidea: move vbus regulator operation to core
  2013-08-02  8:33 [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea Peter Chen
@ 2013-08-02  8:33 ` Peter Chen
  2013-08-02  8:33 ` [PATCH v14 02/12] usb: chipidea: host: add vbus regulator control Peter Chen
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Peter Chen @ 2013-08-02  8:33 UTC (permalink / raw)
  To: linux-arm-kernel

The vbus regulator is a common element for USB vbus operation,
So, move it from glue layer to core.

Tested-by: Marek Vasut <marex@denx.de>
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/ci_hdrc_imx.c |   26 ++------------------------
 drivers/usb/chipidea/core.c        |   23 +++++++++++++++++++++++
 include/linux/usb/chipidea.h       |    1 +
 3 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index e04611f..b886998 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -19,7 +19,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/usb/chipidea.h>
 #include <linux/clk.h>
-#include <linux/regulator/consumer.h>
 
 #include "ci.h"
 #include "ci_hdrc_imx.h"
@@ -31,7 +30,6 @@ struct ci_hdrc_imx_data {
 	struct usb_phy *phy;
 	struct platform_device *ci_pdev;
 	struct clk *clk;
-	struct regulator *reg_vbus;
 };
 
 static const struct usbmisc_ops *usbmisc_ops;
@@ -134,20 +132,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
 		goto err_clk;
 	}
 
-	/* we only support host now, so enable vbus here */
-	data->reg_vbus = devm_regulator_get(&pdev->dev, "vbus");
-	if (!IS_ERR(data->reg_vbus)) {
-		ret = regulator_enable(data->reg_vbus);
-		if (ret) {
-			dev_err(&pdev->dev,
-				"Failed to enable vbus regulator, err=%d\n",
-				ret);
-			goto err_clk;
-		}
-	} else {
-		data->reg_vbus = NULL;
-	}
-
 	pdata.phy = data->phy;
 
 	if (!pdev->dev.dma_mask)
@@ -160,7 +144,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
 		if (ret) {
 			dev_err(&pdev->dev,
 				"usbmisc init failed, ret=%d\n", ret);
-			goto err;
+			goto err_clk;
 		}
 	}
 
@@ -172,7 +156,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev,
 			"Can't register ci_hdrc platform device, err=%d\n",
 			ret);
-		goto err;
+		goto err_clk;
 	}
 
 	if (usbmisc_ops && usbmisc_ops->post) {
@@ -193,9 +177,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
 
 disable_device:
 	ci_hdrc_remove_device(data->ci_pdev);
-err:
-	if (data->reg_vbus)
-		regulator_disable(data->reg_vbus);
 err_clk:
 	clk_disable_unprepare(data->clk);
 	return ret;
@@ -208,9 +189,6 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev)
 	pm_runtime_disable(&pdev->dev);
 	ci_hdrc_remove_device(data->ci_pdev);
 
-	if (data->reg_vbus)
-		regulator_disable(data->reg_vbus);
-
 	if (data->phy)
 		usb_phy_shutdown(data->phy);
 
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 3126c03..26f6599 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -65,6 +65,7 @@
 #include <linux/usb/chipidea.h>
 #include <linux/usb/of.h>
 #include <linux/phy.h>
+#include <linux/regulator/consumer.h>
 
 #include "ci.h"
 #include "udc.h"
@@ -342,6 +343,24 @@ static irqreturn_t ci_irq(int irq, void *data)
 	return ret;
 }
 
+static int ci_get_platdata(struct device *dev,
+		struct ci_hdrc_platform_data *platdata)
+{
+	/* Get the vbus regulator */
+	platdata->reg_vbus = devm_regulator_get(dev, "vbus");
+	if (PTR_ERR(platdata->reg_vbus) == -EPROBE_DEFER) {
+		return -EPROBE_DEFER;
+	} else if (PTR_ERR(platdata->reg_vbus) == -ENODEV) {
+		platdata->reg_vbus = NULL; /* no vbus regualator is needed */
+	} else if (IS_ERR(platdata->reg_vbus)) {
+		dev_err(dev, "Getting regulator error: %ld\n",
+			PTR_ERR(platdata->reg_vbus));
+		return PTR_ERR(platdata->reg_vbus);
+	}
+
+	return 0;
+}
+
 static DEFINE_IDA(ci_ida);
 
 struct platform_device *ci_hdrc_add_device(struct device *dev,
@@ -351,6 +370,10 @@ struct platform_device *ci_hdrc_add_device(struct device *dev,
 	struct platform_device *pdev;
 	int id, ret;
 
+	ret = ci_get_platdata(dev, platdata);
+	if (ret)
+		return ERR_PTR(ret);
+
 	id = ida_simple_get(&ci_ida, 0, 0, GFP_KERNEL);
 	if (id < 0)
 		return ERR_PTR(id);
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 2562994..ce4e1aa 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -24,6 +24,7 @@ struct ci_hdrc_platform_data {
 #define CI_HDRC_CONTROLLER_RESET_EVENT		0
 #define CI_HDRC_CONTROLLER_STOPPED_EVENT	1
 	void	(*notify_event) (struct ci_hdrc *ci, unsigned event);
+	struct regulator	*reg_vbus;
 };
 
 /* Default offset of capability registers */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v14 02/12] usb: chipidea: host: add vbus regulator control
  2013-08-02  8:33 [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea Peter Chen
  2013-08-02  8:33 ` [PATCH v14 01/12] usb: chipidea: move vbus regulator operation to core Peter Chen
@ 2013-08-02  8:33 ` Peter Chen
  2013-08-02  8:33 ` [PATCH v14 03/12] usb: chipidea: udc: otg_set_peripheral is useless for some chipidea users Peter Chen
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Peter Chen @ 2013-08-02  8:33 UTC (permalink / raw)
  To: linux-arm-kernel

For boards which have board level vbus control (eg, through gpio), we
need to vbus operation according to below rules:
- For host, we need open vbus before start hcd, and close it
after remove hcd.
- For otg, the vbus needs to be on/off when usb role switches.
When the host roles begins, it opens vbus; when the host role
finishes, it closes vbus.

We put vbus operation to host as host is the only vbus user,
When we are at host mode, the vbus is on, when we are not at
host mode, vbus should be off.

Tested-by: Marek Vasut <marex@denx.de>
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/host.c |   23 ++++++++++++++++++++++-
 1 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 40d0fda..e94e52b 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -24,6 +24,7 @@
 #include <linux/usb.h>
 #include <linux/usb/hcd.h>
 #include <linux/usb/chipidea.h>
+#include <linux/regulator/consumer.h>
 
 #include "../host/ehci.h"
 
@@ -64,9 +65,19 @@ static int host_start(struct ci_hdrc *ci)
 	ehci->caps = ci->hw_bank.cap;
 	ehci->has_hostpc = ci->hw_bank.lpm;
 
+	if (ci->platdata->reg_vbus) {
+		ret = regulator_enable(ci->platdata->reg_vbus);
+		if (ret) {
+			dev_err(ci->dev,
+				"Failed to enable vbus regulator, ret=%d\n",
+				ret);
+			goto put_hcd;
+		}
+	}
+
 	ret = usb_add_hcd(hcd, 0, 0);
 	if (ret)
-		usb_put_hcd(hcd);
+		goto disable_reg;
 	else
 		ci->hcd = hcd;
 
@@ -74,6 +85,14 @@ static int host_start(struct ci_hdrc *ci)
 		hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
 
 	return ret;
+
+disable_reg:
+	regulator_disable(ci->platdata->reg_vbus);
+
+put_hcd:
+	usb_put_hcd(hcd);
+
+	return ret;
 }
 
 static void host_stop(struct ci_hdrc *ci)
@@ -82,6 +101,8 @@ static void host_stop(struct ci_hdrc *ci)
 
 	usb_remove_hcd(hcd);
 	usb_put_hcd(hcd);
+	if (ci->platdata->reg_vbus)
+		regulator_disable(ci->platdata->reg_vbus);
 }
 
 int ci_hdrc_host_init(struct ci_hdrc *ci)
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v14 03/12] usb: chipidea: udc: otg_set_peripheral is useless for some chipidea users
  2013-08-02  8:33 [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea Peter Chen
  2013-08-02  8:33 ` [PATCH v14 01/12] usb: chipidea: move vbus regulator operation to core Peter Chen
  2013-08-02  8:33 ` [PATCH v14 02/12] usb: chipidea: host: add vbus regulator control Peter Chen
@ 2013-08-02  8:33 ` Peter Chen
  2013-08-02  8:33 ` [PATCH v14 04/12] usb: chipidea: otg: Add otg file used to access otgsc Peter Chen
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Peter Chen @ 2013-08-02  8:33 UTC (permalink / raw)
  To: linux-arm-kernel

It is useless at below cases:
- If we implement both usb host and device at chipidea driver.
- If we don't need phy->otg.

Tested-by: Marek Vasut <marex@denx.de>
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/udc.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index e475fcd..116c762 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1805,7 +1805,12 @@ static int udc_start(struct ci_hdrc *ci)
 	if (ci->transceiver) {
 		retval = otg_set_peripheral(ci->transceiver->otg,
 						&ci->gadget);
-		if (retval)
+		/*
+		 * If we implement all USB functions using chipidea drivers,
+		 * it doesn't need to call above API, meanwhile, if we only
+		 * use gadget function, calling above API is useless.
+		 */
+		if (retval && retval != -ENOTSUPP)
 			goto put_transceiver;
 	}
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v14 04/12] usb: chipidea: otg: Add otg file used to access otgsc
  2013-08-02  8:33 [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea Peter Chen
                   ` (2 preceding siblings ...)
  2013-08-02  8:33 ` [PATCH v14 03/12] usb: chipidea: udc: otg_set_peripheral is useless for some chipidea users Peter Chen
@ 2013-08-02  8:33 ` Peter Chen
  2013-08-09 13:00   ` Alexander Shishkin
  2013-08-02  8:33 ` [PATCH v14 05/12] usb: chipidea: Add role init and destory APIs Peter Chen
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 23+ messages in thread
From: Peter Chen @ 2013-08-02  8:33 UTC (permalink / raw)
  To: linux-arm-kernel

This file is mainly used to access otgsc currently, it may
add otg related things in the future.

Tested-by: Marek Vasut <marex@denx.de>
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/Makefile |    2 +-
 drivers/usb/chipidea/bits.h   |   10 ++++++++
 drivers/usb/chipidea/core.c   |    3 +-
 drivers/usb/chipidea/otg.c    |   50 +++++++++++++++++++++++++++++++++++++++++
 drivers/usb/chipidea/otg.h    |   19 +++++++++++++++
 5 files changed, 82 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile
index 6cf5f68..a99d980 100644
--- a/drivers/usb/chipidea/Makefile
+++ b/drivers/usb/chipidea/Makefile
@@ -2,7 +2,7 @@ ccflags-$(CONFIG_USB_CHIPIDEA_DEBUG) := -DDEBUG
 
 obj-$(CONFIG_USB_CHIPIDEA)		+= ci_hdrc.o
 
-ci_hdrc-y				:= core.o
+ci_hdrc-y				:= core.o otg.o
 ci_hdrc-$(CONFIG_USB_CHIPIDEA_UDC)	+= udc.o
 ci_hdrc-$(CONFIG_USB_CHIPIDEA_HOST)	+= host.o
 ci_hdrc-$(CONFIG_USB_CHIPIDEA_DEBUG)	+= debug.o
diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h
index aefa026..dd0cf9e 100644
--- a/drivers/usb/chipidea/bits.h
+++ b/drivers/usb/chipidea/bits.h
@@ -79,11 +79,21 @@
 #define OTGSC_ASVIS	      BIT(18)
 #define OTGSC_BSVIS	      BIT(19)
 #define OTGSC_BSEIS	      BIT(20)
+#define OTGSC_1MSIS	      BIT(21)
+#define OTGSC_DPIS	      BIT(22)
 #define OTGSC_IDIE	      BIT(24)
 #define OTGSC_AVVIE	      BIT(25)
 #define OTGSC_ASVIE	      BIT(26)
 #define OTGSC_BSVIE	      BIT(27)
 #define OTGSC_BSEIE	      BIT(28)
+#define OTGSC_1MSIE	      BIT(29)
+#define OTGSC_DPIE	      BIT(30)
+#define OTGSC_INT_EN_BITS	(OTGSC_IDIE | OTGSC_AVVIE | OTGSC_ASVIE \
+				| OTGSC_BSVIE | OTGSC_BSEIE | OTGSC_1MSIE \
+				| OTGSC_DPIE)
+#define OTGSC_INT_STATUS_BITS	(OTGSC_IDIS | OTGSC_AVVIS | OTGSC_ASVIS	\
+				| OTGSC_BSVIS | OTGSC_BSEIS | OTGSC_1MSIS \
+				| OTGSC_DPIS)
 
 /* USBMODE */
 #define USBMODE_CM            (0x03UL <<  0)
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 26f6599..a4be8a5 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -72,6 +72,7 @@
 #include "bits.h"
 #include "host.h"
 #include "debug.h"
+#include "otg.h"
 
 /* Controller register map */
 static uintptr_t ci_regs_nolpm[] = {
@@ -530,7 +531,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 		goto stop;
 
 	if (ci->is_otg)
-		hw_write(ci, OP_OTGSC, OTGSC_IDIE, OTGSC_IDIE);
+		ci_hdrc_otg_init(ci);
 
 	ret = dbg_create_files(ci);
 	if (!ret)
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
new file mode 100644
index 0000000..abefb4d
--- /dev/null
+++ b/drivers/usb/chipidea/otg.c
@@ -0,0 +1,50 @@
+/*
+ * otg.c - ChipIdea USB IP core OTG driver
+ *
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * Author: Peter Chen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * This file mainly handles otgsc register, it may include OTG operation
+ * in the future.
+ */
+
+#include <linux/usb/otg.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/chipidea.h>
+
+#include "ci.h"
+#include "bits.h"
+
+void ci_clear_otg_interrupt(struct ci_hdrc *ci, u32 bits)
+{
+	/* Only clear request bits */
+	hw_write(ci, OP_OTGSC, OTGSC_INT_STATUS_BITS, bits);
+}
+
+void ci_enable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
+{
+	hw_write(ci, OP_OTGSC, bits, bits);
+}
+
+void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
+{
+	hw_write(ci, OP_OTGSC, bits, 0);
+}
+
+/**
+ * ci_hdrc_otg_init - initialize otgsc bits
+ * ci: the controller
+ */
+int ci_hdrc_otg_init(struct ci_hdrc *ci)
+{
+	ci_enable_otg_interrupt(ci, OTGSC_IDIE);
+
+	return 0;
+}
diff --git a/drivers/usb/chipidea/otg.h b/drivers/usb/chipidea/otg.h
new file mode 100644
index 0000000..f24ec37
--- /dev/null
+++ b/drivers/usb/chipidea/otg.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * Author: Peter Chen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __DRIVERS_USB_CHIPIDEA_OTG_H
+#define __DRIVERS_USB_CHIPIDEA_OTG_H
+
+int ci_hdrc_otg_init(struct ci_hdrc *ci);
+void ci_clear_otg_interrupt(struct ci_hdrc *ci, u32 bits);
+void ci_enable_otg_interrupt(struct ci_hdrc *ci, u32 bits);
+void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits);
+
+#endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v14 05/12] usb: chipidea: Add role init and destory APIs
  2013-08-02  8:33 [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea Peter Chen
                   ` (3 preceding siblings ...)
  2013-08-02  8:33 ` [PATCH v14 04/12] usb: chipidea: otg: Add otg file used to access otgsc Peter Chen
@ 2013-08-02  8:33 ` Peter Chen
  2013-08-02  8:33 ` [PATCH v14 06/12] usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG Peter Chen
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Peter Chen @ 2013-08-02  8:33 UTC (permalink / raw)
  To: linux-arm-kernel

- The role's init will be called at probe procedure.
- The role's destory will be called at fail patch
at probe and driver's removal.
- The role's start/stop will be called when specific
role has started.

Tested-by: Marek Vasut <marex@denx.de>
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/core.c |   10 ++++++++--
 drivers/usb/chipidea/host.c |    7 +++++++
 drivers/usb/chipidea/host.h |    6 ++++++
 drivers/usb/chipidea/udc.c  |   36 +++++++++++++++++++++++++++---------
 drivers/usb/chipidea/udc.h  |    6 ++++++
 5 files changed, 54 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index a4be8a5..bfc9aef 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -420,6 +420,12 @@ void ci_hdrc_remove_device(struct platform_device *pdev)
 }
 EXPORT_SYMBOL_GPL(ci_hdrc_remove_device);
 
+static inline void ci_role_destroy(struct ci_hdrc *ci)
+{
+	ci_hdrc_gadget_destroy(ci);
+	ci_hdrc_host_destroy(ci);
+}
+
 static int ci_hdrc_probe(struct platform_device *pdev)
 {
 	struct device	*dev = &pdev->dev;
@@ -539,7 +545,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 
 	free_irq(ci->irq, ci);
 stop:
-	ci_role_stop(ci);
+	ci_role_destroy(ci);
 rm_wq:
 	flush_workqueue(ci->wq);
 	destroy_workqueue(ci->wq);
@@ -555,7 +561,7 @@ static int ci_hdrc_remove(struct platform_device *pdev)
 	flush_workqueue(ci->wq);
 	destroy_workqueue(ci->wq);
 	free_irq(ci->irq, ci);
-	ci_role_stop(ci);
+	ci_role_destroy(ci);
 
 	return 0;
 }
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index e94e52b..382be5b 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -105,6 +105,13 @@ static void host_stop(struct ci_hdrc *ci)
 		regulator_disable(ci->platdata->reg_vbus);
 }
 
+
+void ci_hdrc_host_destroy(struct ci_hdrc *ci)
+{
+	if (ci->role == CI_ROLE_HOST)
+		host_stop(ci);
+}
+
 int ci_hdrc_host_init(struct ci_hdrc *ci)
 {
 	struct ci_role_driver *rdrv;
diff --git a/drivers/usb/chipidea/host.h b/drivers/usb/chipidea/host.h
index 058875c..5707bf3 100644
--- a/drivers/usb/chipidea/host.h
+++ b/drivers/usb/chipidea/host.h
@@ -4,6 +4,7 @@
 #ifdef CONFIG_USB_CHIPIDEA_HOST
 
 int ci_hdrc_host_init(struct ci_hdrc *ci);
+void ci_hdrc_host_destroy(struct ci_hdrc *ci);
 
 #else
 
@@ -12,6 +13,11 @@ static inline int ci_hdrc_host_init(struct ci_hdrc *ci)
 	return -ENXIO;
 }
 
+static inline void ci_hdrc_host_destroy(struct ci_hdrc *ci)
+{
+
+}
+
 #endif
 
 #endif /* __DRIVERS_USB_CHIPIDEA_HOST_H */
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 116c762..24a100d 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -27,6 +27,7 @@
 #include "udc.h"
 #include "bits.h"
 #include "debug.h"
+#include "otg.h"
 
 /* control endpoint description */
 static const struct usb_endpoint_descriptor
@@ -1844,13 +1845,13 @@ free_qh_pool:
 }
 
 /**
- * udc_remove: parent remove must call this to remove UDC
+ * ci_hdrc_gadget_destroy: parent remove must call this to remove UDC
  *
  * No interrupts active, the IRQ has been released
  */
-static void udc_stop(struct ci_hdrc *ci)
+void ci_hdrc_gadget_destroy(struct ci_hdrc *ci)
 {
-	if (ci == NULL)
+	if (!ci->roles[CI_ROLE_GADGET])
 		return;
 
 	usb_del_gadget_udc(&ci->gadget);
@@ -1865,15 +1866,32 @@ static void udc_stop(struct ci_hdrc *ci)
 		if (ci->global_phy)
 			usb_put_phy(ci->transceiver);
 	}
-	/* my kobject is dynamic, I swear! */
-	memset(&ci->gadget, 0, sizeof(ci->gadget));
+}
+
+static int udc_id_switch_for_device(struct ci_hdrc *ci)
+{
+	if (ci->is_otg) {
+		ci_clear_otg_interrupt(ci, OTGSC_BSVIS);
+		ci_enable_otg_interrupt(ci, OTGSC_BSVIE);
+	}
+
+	return 0;
+}
+
+static void udc_id_switch_for_host(struct ci_hdrc *ci)
+{
+	if (ci->is_otg) {
+		/* host doesn't care B_SESSION_VALID event */
+		ci_clear_otg_interrupt(ci, OTGSC_BSVIS);
+		ci_disable_otg_interrupt(ci, OTGSC_BSVIE);
+	}
 }
 
 /**
  * ci_hdrc_gadget_init - initialize device related bits
  * ci: the controller
  *
- * This function enables the gadget role, if the device is "device capable".
+ * This function initializes the gadget, if the device is "device capable".
  */
 int ci_hdrc_gadget_init(struct ci_hdrc *ci)
 {
@@ -1886,11 +1904,11 @@ int ci_hdrc_gadget_init(struct ci_hdrc *ci)
 	if (!rdrv)
 		return -ENOMEM;
 
-	rdrv->start	= udc_start;
-	rdrv->stop	= udc_stop;
+	rdrv->start	= udc_id_switch_for_device;
+	rdrv->stop	= udc_id_switch_for_host;
 	rdrv->irq	= udc_irq;
 	rdrv->name	= "gadget";
 	ci->roles[CI_ROLE_GADGET] = rdrv;
 
-	return 0;
+	return udc_start(ci);
 }
diff --git a/drivers/usb/chipidea/udc.h b/drivers/usb/chipidea/udc.h
index 455ac21..e66df00 100644
--- a/drivers/usb/chipidea/udc.h
+++ b/drivers/usb/chipidea/udc.h
@@ -84,6 +84,7 @@ struct ci_hw_req {
 #ifdef CONFIG_USB_CHIPIDEA_UDC
 
 int ci_hdrc_gadget_init(struct ci_hdrc *ci);
+void ci_hdrc_gadget_destroy(struct ci_hdrc *ci);
 
 #else
 
@@ -92,6 +93,11 @@ static inline int ci_hdrc_gadget_init(struct ci_hdrc *ci)
 	return -ENXIO;
 }
 
+static inline void ci_hdrc_gadget_destroy(struct ci_hdrc *ci)
+{
+
+}
+
 #endif
 
 #endif /* __DRIVERS_USB_CHIPIDEA_UDC_H */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v14 06/12] usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG
  2013-08-02  8:33 [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea Peter Chen
                   ` (4 preceding siblings ...)
  2013-08-02  8:33 ` [PATCH v14 05/12] usb: chipidea: Add role init and destory APIs Peter Chen
@ 2013-08-02  8:33 ` Peter Chen
  2013-08-09 12:55   ` Alexander Shishkin
  2013-08-02  8:34 ` [PATCH v14 07/12] usb: chipidea: disable all interrupts and clear all interrupts status Peter Chen
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 23+ messages in thread
From: Peter Chen @ 2013-08-02  8:33 UTC (permalink / raw)
  To: linux-arm-kernel

Since we need otgsc to know vbus's status at some chipidea
controllers even it is peripheral-only mode. Besides, some
SoCs (eg, AR9331 SoC) don't have otgsc register even
the DCCPARAMS_DC and DCCPARAMS_HC are both 1 at CAP_DCCPARAMS.

We inroduce flag CI_HDRC_DUAL_ROLE_NOT_OTG to indicate if the
controller is dual role, but not supports OTG. If this flag is
not set, we follow the rule that if DCCPARAMS_DC and DCCPARAMS_HC
are both 1 at CAP_DCCPARAMS, then this controller is otg capable.

Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/core.c  |   38 +++++++++++++++++++++++++++++++-------
 include/linux/usb/chipidea.h |    5 +++++
 2 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index bfc9aef..2ae18fd 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -426,6 +426,18 @@ static inline void ci_role_destroy(struct ci_hdrc *ci)
 	ci_hdrc_host_destroy(ci);
 }
 
+static void ci_get_otg_capable(struct ci_hdrc *ci)
+{
+	if (ci->platdata->flags & CI_HDRC_DUAL_ROLE_NOT_OTG)
+		ci->is_otg = false;
+	else
+		ci->is_otg = (hw_read(ci, CAP_DCCPARAMS,
+				DCCPARAMS_DC | DCCPARAMS_HC)
+					== (DCCPARAMS_DC | DCCPARAMS_HC));
+	if (ci->is_otg)
+		dev_dbg(ci->dev, "It is OTG capable controller\n");
+}
+
 static int ci_hdrc_probe(struct platform_device *pdev)
 {
 	struct device	*dev = &pdev->dev;
@@ -482,6 +494,9 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	/* To know if controller is OTG capable or not */
+	ci_get_otg_capable(ci);
+
 	if (!ci->platdata->phy_mode)
 		ci->platdata->phy_mode = of_usb_get_phy_mode(dev->of_node);
 
@@ -514,10 +529,22 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 	}
 
 	if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) {
-		ci->is_otg = true;
-		/* ID pin needs 1ms debouce time, we delay 2ms for safe */
-		mdelay(2);
-		ci->role = ci_otg_role(ci);
+		if (ci->is_otg) {
+			/*
+			 * ID pin needs 1ms debouce time,
+			 * we delay 2ms for safe.
+			 */
+			mdelay(2);
+			ci->role = ci_otg_role(ci);
+			ci_hdrc_otg_init(ci);
+		} else {
+			/*
+			 * If the controller is not OTG capable, but support
+			 * role switch, the defalt role is gadget, and the
+			 * user can switch it through debugfs (proc in future?)
+			 */
+			ci->role = CI_ROLE_GADGET;
+		}
 	} else {
 		ci->role = ci->roles[CI_ROLE_HOST]
 			? CI_ROLE_HOST
@@ -536,9 +563,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 	if (ret)
 		goto stop;
 
-	if (ci->is_otg)
-		ci_hdrc_otg_init(ci);
-
 	ret = dbg_create_files(ci);
 	if (!ret)
 		return 0;
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index ce4e1aa..10a607c 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -20,6 +20,11 @@ struct ci_hdrc_platform_data {
 #define CI_HDRC_REQUIRE_TRANSCEIVER	BIT(1)
 #define CI_HDRC_PULLUP_ON_VBUS		BIT(2)
 #define CI_HDRC_DISABLE_STREAMING	BIT(3)
+	/*
+	 * Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1,
+	 * but otg is not supported (no register otgsc).
+	 */
+#define CI_HDRC_DUAL_ROLE_NOT_OTG	BIT(4)
 	enum usb_dr_mode	dr_mode;
 #define CI_HDRC_CONTROLLER_RESET_EVENT		0
 #define CI_HDRC_CONTROLLER_STOPPED_EVENT	1
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v14 07/12] usb: chipidea: disable all interrupts and clear all interrupts status
  2013-08-02  8:33 [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea Peter Chen
                   ` (5 preceding siblings ...)
  2013-08-02  8:33 ` [PATCH v14 06/12] usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG Peter Chen
@ 2013-08-02  8:34 ` Peter Chen
  2013-08-02  8:34 ` [PATCH v14 08/12] usb: chipidea: move otg relate things to otg file Peter Chen
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Peter Chen @ 2013-08-02  8:34 UTC (permalink / raw)
  To: linux-arm-kernel

During the initialization, it needs to disable all interrupts
enable bit as well as clear all interrupts status bits to avoid
exceptional interrupt.

Tested-by: Marek Vasut <marex@denx.de>
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/core.c |   11 ++++++++++-
 1 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 2ae18fd..2223954 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -199,6 +199,12 @@ static int hw_device_init(struct ci_hdrc *ci, void __iomem *base)
 	if (ci->hw_ep_max > ENDPT_MAX)
 		return -ENODEV;
 
+	/* Disable all interrupts bits */
+	hw_write(ci, OP_USBINTR, 0xffffffff, 0);
+
+	/* Clear all interrupts status bits*/
+	hw_write(ci, OP_USBSTS, 0xffffffff, 0xffffffff);
+
 	dev_dbg(ci->dev, "ChipIdea HDRC found, lpm: %d; cap: %p op: %p\n",
 		ci->hw_bank.lpm, ci->hw_bank.cap, ci->hw_bank.op);
 
@@ -434,8 +440,11 @@ static void ci_get_otg_capable(struct ci_hdrc *ci)
 		ci->is_otg = (hw_read(ci, CAP_DCCPARAMS,
 				DCCPARAMS_DC | DCCPARAMS_HC)
 					== (DCCPARAMS_DC | DCCPARAMS_HC));
-	if (ci->is_otg)
+	if (ci->is_otg) {
 		dev_dbg(ci->dev, "It is OTG capable controller\n");
+		ci_disable_otg_interrupt(ci, OTGSC_INT_EN_BITS);
+		ci_clear_otg_interrupt(ci, OTGSC_INT_STATUS_BITS);
+	}
 }
 
 static int ci_hdrc_probe(struct platform_device *pdev)
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v14 08/12] usb: chipidea: move otg relate things to otg file
  2013-08-02  8:33 [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea Peter Chen
                   ` (6 preceding siblings ...)
  2013-08-02  8:34 ` [PATCH v14 07/12] usb: chipidea: disable all interrupts and clear all interrupts status Peter Chen
@ 2013-08-02  8:34 ` Peter Chen
  2013-08-09 13:09   ` Alexander Shishkin
  2013-08-02  8:34 ` [PATCH v14 09/12] usb: chipidea: add vbus interrupt handler Peter Chen
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 23+ messages in thread
From: Peter Chen @ 2013-08-02  8:34 UTC (permalink / raw)
  To: linux-arm-kernel

Move otg relate things to otg file.

Tested-by: Marek Vasut <marex@denx.de>
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/core.c |   63 +++++++++----------------------------------
 drivers/usb/chipidea/otg.c  |   57 +++++++++++++++++++++++++++++++++++++-
 drivers/usb/chipidea/otg.h  |    2 +
 3 files changed, 70 insertions(+), 52 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 2223954..30be811 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -294,40 +294,6 @@ int hw_device_reset(struct ci_hdrc *ci, u32 mode)
 	return 0;
 }
 
-/**
- * ci_otg_role - pick role based on ID pin state
- * @ci: the controller
- */
-static enum ci_role ci_otg_role(struct ci_hdrc *ci)
-{
-	u32 sts = hw_read(ci, OP_OTGSC, ~0);
-	enum ci_role role = sts & OTGSC_ID
-		? CI_ROLE_GADGET
-		: CI_ROLE_HOST;
-
-	return role;
-}
-
-/**
- * ci_role_work - perform role changing based on ID pin
- * @work: work struct
- */
-static void ci_role_work(struct work_struct *work)
-{
-	struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
-	enum ci_role role = ci_otg_role(ci);
-
-	if (role != ci->role) {
-		dev_dbg(ci->dev, "switching from %s to %s\n",
-			ci_role(ci)->name, ci->roles[role]->name);
-
-		ci_role_stop(ci);
-		ci_role_start(ci, role);
-	}
-
-	enable_irq(ci->irq);
-}
-
 static irqreturn_t ci_irq(int irq, void *data)
 {
 	struct ci_hdrc *ci = data;
@@ -430,6 +396,8 @@ static inline void ci_role_destroy(struct ci_hdrc *ci)
 {
 	ci_hdrc_gadget_destroy(ci);
 	ci_hdrc_host_destroy(ci);
+	if (ci->is_otg)
+		ci_hdrc_otg_destory(ci);
 }
 
 static void ci_get_otg_capable(struct ci_hdrc *ci)
@@ -496,13 +464,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	INIT_WORK(&ci->work, ci_role_work);
-	ci->wq = create_singlethread_workqueue("ci_otg");
-	if (!ci->wq) {
-		dev_err(dev, "can't create workqueue\n");
-		return -ENODEV;
-	}
-
 	/* To know if controller is OTG capable or not */
 	ci_get_otg_capable(ci);
 
@@ -533,8 +494,15 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 
 	if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) {
 		dev_err(dev, "no supported roles\n");
-		ret = -ENODEV;
-		goto rm_wq;
+		return -ENODEV;
+	}
+
+	if (ci->is_otg) {
+		ret = ci_hdrc_otg_init(ci);
+		if (ret) {
+			dev_err(dev, "init otg fails, ret = %d\n", ret);
+			goto stop;
+		}
 	}
 
 	if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) {
@@ -545,7 +513,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 			 */
 			mdelay(2);
 			ci->role = ci_otg_role(ci);
-			ci_hdrc_otg_init(ci);
+			ci_enable_otg_interrupt(ci, OTGSC_IDIE);
 		} else {
 			/*
 			 * If the controller is not OTG capable, but support
@@ -563,7 +531,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 	ret = ci_role_start(ci, ci->role);
 	if (ret) {
 		dev_err(dev, "can't start %s role\n", ci_role(ci)->name);
-		goto rm_wq;
+		goto stop;
 	}
 
 	platform_set_drvdata(pdev, ci);
@@ -579,9 +547,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 	free_irq(ci->irq, ci);
 stop:
 	ci_role_destroy(ci);
-rm_wq:
-	flush_workqueue(ci->wq);
-	destroy_workqueue(ci->wq);
 
 	return ret;
 }
@@ -591,8 +556,6 @@ static int ci_hdrc_remove(struct platform_device *pdev)
 	struct ci_hdrc *ci = platform_get_drvdata(pdev);
 
 	dbg_remove_files(ci);
-	flush_workqueue(ci->wq);
-	destroy_workqueue(ci->wq);
 	free_irq(ci->irq, ci);
 	ci_role_destroy(ci);
 
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index abefb4d..68f2faf 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -39,12 +39,65 @@ void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
 }
 
 /**
- * ci_hdrc_otg_init - initialize otgsc bits
+ * ci_otg_role - pick role based on ID pin state
+ * @ci: the controller
+ */
+enum ci_role ci_otg_role(struct ci_hdrc *ci)
+{
+	u32 sts = hw_read(ci, OP_OTGSC, ~0);
+	enum ci_role role = sts & OTGSC_ID
+		? CI_ROLE_GADGET
+		: CI_ROLE_HOST;
+
+	return role;
+}
+
+/**
+ * ci_role_work - perform role changing based on ID pin
+ * @work: work struct
+ */
+static void ci_role_work(struct work_struct *work)
+{
+	struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
+	enum ci_role role = ci_otg_role(ci);
+
+	if (role != ci->role) {
+		dev_dbg(ci->dev, "switching from %s to %s\n",
+			ci_role(ci)->name, ci->roles[role]->name);
+
+		ci_role_stop(ci);
+		ci_role_start(ci, role);
+	}
+
+	enable_irq(ci->irq);
+}
+
+/**
+ * ci_hdrc_otg_init - initialize otg struct
  * ci: the controller
  */
 int ci_hdrc_otg_init(struct ci_hdrc *ci)
 {
-	ci_enable_otg_interrupt(ci, OTGSC_IDIE);
+	INIT_WORK(&ci->work, ci_role_work);
+	ci->wq = create_singlethread_workqueue("ci_otg");
+	if (!ci->wq) {
+		dev_err(ci->dev, "can't create workqueue\n");
+		return -ENODEV;
+	}
 
 	return 0;
 }
+
+/**
+ * ci_hdrc_otg_destroy - destory otg struct
+ * ci: the controller
+ */
+void ci_hdrc_otg_destory(struct ci_hdrc *ci)
+{
+	if (ci->wq) {
+		flush_workqueue(ci->wq);
+		destroy_workqueue(ci->wq);
+	}
+	ci_disable_otg_interrupt(ci, OTGSC_INT_EN_BITS);
+	ci_clear_otg_interrupt(ci, OTGSC_INT_STATUS_BITS);
+}
diff --git a/drivers/usb/chipidea/otg.h b/drivers/usb/chipidea/otg.h
index f24ec37..8913062 100644
--- a/drivers/usb/chipidea/otg.h
+++ b/drivers/usb/chipidea/otg.h
@@ -15,5 +15,7 @@ int ci_hdrc_otg_init(struct ci_hdrc *ci);
 void ci_clear_otg_interrupt(struct ci_hdrc *ci, u32 bits);
 void ci_enable_otg_interrupt(struct ci_hdrc *ci, u32 bits);
 void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits);
+void ci_hdrc_otg_destory(struct ci_hdrc *ci);
+enum ci_role ci_otg_role(struct ci_hdrc *ci);
 
 #endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v14 09/12] usb: chipidea: add vbus interrupt handler
  2013-08-02  8:33 [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea Peter Chen
                   ` (7 preceding siblings ...)
  2013-08-02  8:34 ` [PATCH v14 08/12] usb: chipidea: move otg relate things to otg file Peter Chen
@ 2013-08-02  8:34 ` Peter Chen
  2013-08-02  8:34 ` [PATCH v14 10/12] usb: chipidea: add wait vbus lower than OTGSC_BSV before role starts Peter Chen
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Peter Chen @ 2013-08-02  8:34 UTC (permalink / raw)
  To: linux-arm-kernel

We add vbus interrupt handler at ci_otg_work, it uses OTGSC_BSV(at otgsc)
to know it is connect or disconnet event.
Meanwhile, we introduce two flags id_event and b_sess_valid_event to
indicate it is an id interrupt or a vbus interrupt.

Tested-by: Marek Vasut <marex@denx.de>
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/ci.h   |    5 +++++
 drivers/usb/chipidea/core.c |   28 +++++++++++++++++++++++-----
 drivers/usb/chipidea/otg.c  |   42 +++++++++++++++++++++++++++++++++++-------
 drivers/usb/chipidea/otg.h  |    1 +
 drivers/usb/chipidea/udc.c  |    7 +++++++
 5 files changed, 71 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 33cb29f..3160363 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -132,6 +132,9 @@ struct hw_bank {
  * @transceiver: pointer to USB PHY, if any
  * @hcd: pointer to usb_hcd for ehci host driver
  * @debugfs: root dentry for this controller in debugfs
+ * @id_event: indicates there is an id event, and handled at ci_otg_work
+ * @b_sess_valid_event: indicates there is a vbus event, and handled
+ * at ci_otg_work
  */
 struct ci_hdrc {
 	struct device			*dev;
@@ -168,6 +171,8 @@ struct ci_hdrc {
 	struct usb_phy			*transceiver;
 	struct usb_hcd			*hcd;
 	struct dentry			*debugfs;
+	bool				id_event;
+	bool				b_sess_valid_event;
 };
 
 static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci)
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 30be811..0e69282 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -303,16 +303,34 @@ static irqreturn_t ci_irq(int irq, void *data)
 	if (ci->is_otg)
 		otgsc = hw_read(ci, OP_OTGSC, ~0);
 
-	if (ci->role != CI_ROLE_END)
-		ret = ci_role(ci)->irq(ci);
+	/*
+	 * Handle id change interrupt, it indicates device/host function
+	 * switch.
+	 */
+	if (ci->is_otg && (otgsc & OTGSC_IDIE) && (otgsc & OTGSC_IDIS)) {
+		ci->id_event = true;
+		ci_clear_otg_interrupt(ci, OTGSC_IDIS);
+		disable_irq_nosync(ci->irq);
+		queue_work(ci->wq, &ci->work);
+		return IRQ_HANDLED;
+	}
 
-	if (ci->is_otg && (otgsc & OTGSC_IDIS)) {
-		hw_write(ci, OP_OTGSC, OTGSC_IDIS, OTGSC_IDIS);
+	/*
+	 * Handle vbus change interrupt, it indicates device connection
+	 * and disconnection events.
+	 */
+	if (ci->is_otg && (otgsc & OTGSC_BSVIE) && (otgsc & OTGSC_BSVIS)) {
+		ci->b_sess_valid_event = true;
+		ci_clear_otg_interrupt(ci, OTGSC_BSVIS);
 		disable_irq_nosync(ci->irq);
 		queue_work(ci->wq, &ci->work);
-		ret = IRQ_HANDLED;
+		return IRQ_HANDLED;
 	}
 
+	/* Handle device/host interrupt */
+	if (ci->role != CI_ROLE_END)
+		ret = ci_role(ci)->irq(ci);
+
 	return ret;
 }
 
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index 68f2faf..c74194d 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -52,13 +52,23 @@ enum ci_role ci_otg_role(struct ci_hdrc *ci)
 	return role;
 }
 
-/**
- * ci_role_work - perform role changing based on ID pin
- * @work: work struct
- */
-static void ci_role_work(struct work_struct *work)
+void ci_handle_vbus_change(struct ci_hdrc *ci)
+{
+	u32 otgsc;
+
+	if (!ci->is_otg)
+		return;
+
+	otgsc = hw_read(ci, OP_OTGSC, ~0);
+
+	if (otgsc & OTGSC_BSV)
+		usb_gadget_vbus_connect(&ci->gadget);
+	else
+		usb_gadget_vbus_disconnect(&ci->gadget);
+}
+
+static void ci_handle_id_switch(struct ci_hdrc *ci)
 {
-	struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
 	enum ci_role role = ci_otg_role(ci);
 
 	if (role != ci->role) {
@@ -68,17 +78,35 @@ static void ci_role_work(struct work_struct *work)
 		ci_role_stop(ci);
 		ci_role_start(ci, role);
 	}
+}
+/**
+ * ci_otg_work - perform otg (vbus/id) event handle
+ * @work: work struct
+ */
+static void ci_otg_work(struct work_struct *work)
+{
+	struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
+
+	if (ci->id_event) {
+		ci->id_event = false;
+		ci_handle_id_switch(ci);
+	} else if (ci->b_sess_valid_event) {
+		ci->b_sess_valid_event = false;
+		ci_handle_vbus_change(ci);
+	} else
+		dev_err(ci->dev, "unexpected event occurs at %s\n", __func__);
 
 	enable_irq(ci->irq);
 }
 
+
 /**
  * ci_hdrc_otg_init - initialize otg struct
  * ci: the controller
  */
 int ci_hdrc_otg_init(struct ci_hdrc *ci)
 {
-	INIT_WORK(&ci->work, ci_role_work);
+	INIT_WORK(&ci->work, ci_otg_work);
 	ci->wq = create_singlethread_workqueue("ci_otg");
 	if (!ci->wq) {
 		dev_err(ci->dev, "can't create workqueue\n");
diff --git a/drivers/usb/chipidea/otg.h b/drivers/usb/chipidea/otg.h
index 8913062..b8d5c05 100644
--- a/drivers/usb/chipidea/otg.h
+++ b/drivers/usb/chipidea/otg.h
@@ -17,5 +17,6 @@ void ci_enable_otg_interrupt(struct ci_hdrc *ci, u32 bits);
 void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits);
 void ci_hdrc_otg_destory(struct ci_hdrc *ci);
 enum ci_role ci_otg_role(struct ci_hdrc *ci);
+void ci_handle_vbus_change(struct ci_hdrc *ci);
 
 #endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 24a100d..c70ce38 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -85,8 +85,10 @@ static int hw_device_state(struct ci_hdrc *ci, u32 dma)
 		/* interrupt, error, port change, reset, sleep/suspend */
 		hw_write(ci, OP_USBINTR, ~0,
 			     USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI);
+		hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS);
 	} else {
 		hw_write(ci, OP_USBINTR, ~0, 0);
+		hw_write(ci, OP_USBCMD, USBCMD_RS, 0);
 	}
 	return 0;
 }
@@ -1460,6 +1462,7 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
 			pm_runtime_get_sync(&_gadget->dev);
 			hw_device_reset(ci, USBMODE_CM_DC);
 			hw_device_state(ci, ci->ep0out->qh.dma);
+			dev_dbg(ci->dev, "Connected to host\n");
 		} else {
 			hw_device_state(ci, 0);
 			if (ci->platdata->notify_event)
@@ -1467,6 +1470,7 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
 				CI_HDRC_CONTROLLER_STOPPED_EVENT);
 			_gadget_stop_activity(&ci->gadget);
 			pm_runtime_put_sync(&_gadget->dev);
+			dev_dbg(ci->dev, "Disconnected from host\n");
 		}
 	}
 
@@ -1822,6 +1826,9 @@ static int udc_start(struct ci_hdrc *ci)
 	pm_runtime_no_callbacks(&ci->gadget.dev);
 	pm_runtime_enable(&ci->gadget.dev);
 
+	/* Update ci->vbus_active */
+	ci_handle_vbus_change(ci);
+
 	return retval;
 
 remove_trans:
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v14 10/12] usb: chipidea: add wait vbus lower than OTGSC_BSV before role starts
  2013-08-02  8:33 [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea Peter Chen
                   ` (8 preceding siblings ...)
  2013-08-02  8:34 ` [PATCH v14 09/12] usb: chipidea: add vbus interrupt handler Peter Chen
@ 2013-08-02  8:34 ` Peter Chen
  2013-08-02  8:34 ` [PATCH v14 11/12] usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and CI_HDRC_PULLUP_ON_VBUS Peter Chen
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Peter Chen @ 2013-08-02  8:34 UTC (permalink / raw)
  To: linux-arm-kernel

When the gadget role starts, we need to make sure the vbus is lower
than OTGSC_BSV, or there will be an vbus interrupt since we use
B_SESSION_VALID as vbus interrupt to indicate connect and disconnect.
When the host role starts, it may not be useful to wait vbus to lower
than OTGSC_BSV, but it can indicate some hardware problems like the
vbus is still higher than OTGSC_BSV after we disconnect to host some
time later (5000 milliseconds currently), which is obvious not correct.

Tested-by: Marek Vasut <marex@denx.de>
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/ci.h   |    3 +++
 drivers/usb/chipidea/core.c |   32 ++++++++++++++++++++++++++++++++
 drivers/usb/chipidea/otg.c  |    4 ++++
 3 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 3160363..1c94fc5 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -308,4 +308,7 @@ int hw_port_test_set(struct ci_hdrc *ci, u8 mode);
 
 u8 hw_port_test_get(struct ci_hdrc *ci);
 
+int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
+				u32 value, unsigned int timeout_ms);
+
 #endif	/* __DRIVERS_USB_CHIPIDEA_CI_H */
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 0e69282..f09b4db 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -294,6 +294,38 @@ int hw_device_reset(struct ci_hdrc *ci, u32 mode)
 	return 0;
 }
 
+/**
+ * hw_wait_reg: wait the register value
+ *
+ * Sometimes, it needs to wait register value before going on.
+ * Eg, when switch to device mode, the vbus value should be lower
+ * than OTGSC_BSV before connects to host.
+ *
+ * @ci: the controller
+ * @reg: register index
+ * @mask: mast bit
+ * @value: the bit value to wait
+ * @timeout_ms: timeout in millisecond
+ *
+ * This function returns an error code if timeout
+ */
+int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
+				u32 value, unsigned int timeout_ms)
+{
+	unsigned long elapse = jiffies + msecs_to_jiffies(timeout_ms);
+
+	while (hw_read(ci, reg, mask) != value) {
+		if (time_after(jiffies, elapse)) {
+			dev_err(ci->dev, "timeout waiting for %08x in %d\n",
+					mask, reg);
+			return -ETIMEDOUT;
+		}
+		msleep(20);
+	}
+
+	return 0;
+}
+
 static irqreturn_t ci_irq(int irq, void *data)
 {
 	struct ci_hdrc *ci = data;
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index c74194d..d39cce8 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -67,6 +67,7 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
 		usb_gadget_vbus_disconnect(&ci->gadget);
 }
 
+#define CI_VBUS_STABLE_TIMEOUT_MS 5000
 static void ci_handle_id_switch(struct ci_hdrc *ci)
 {
 	enum ci_role role = ci_otg_role(ci);
@@ -76,6 +77,9 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
 			ci_role(ci)->name, ci->roles[role]->name);
 
 		ci_role_stop(ci);
+		/* wait vbus lower than OTGSC_BSV */
+		hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,
+				CI_VBUS_STABLE_TIMEOUT_MS);
 		ci_role_start(ci, role);
 	}
 }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v14 11/12] usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and CI_HDRC_PULLUP_ON_VBUS
  2013-08-02  8:33 [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea Peter Chen
                   ` (9 preceding siblings ...)
  2013-08-02  8:34 ` [PATCH v14 10/12] usb: chipidea: add wait vbus lower than OTGSC_BSV before role starts Peter Chen
@ 2013-08-02  8:34 ` Peter Chen
  2013-08-09 13:23   ` Alexander Shishkin
  2013-08-02  8:34 ` [PATCH v14 12/12] usb: chipidea: udc: .pullup is valid when vbus is on at CI_HDRC_PULLUP_ON_VBUS Peter Chen
  2013-08-06 12:00 ` [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea Peter Chen
  12 siblings, 1 reply; 23+ messages in thread
From: Peter Chen @ 2013-08-02  8:34 UTC (permalink / raw)
  To: linux-arm-kernel

CI_HDRC_REGS_SHARED stands for the controller registers is shared
with other USB drivers, if all USB drivers are at chipidea/, it doesn't
needed to set.
CI_HDRC_PULLUP_ON_VBUS stands for pullup dp when the vbus is on. This
flag doesn't need to set if the vbus is always on for gadget
since dp has always pulled up after the gadget has initialized.

So, the current code seems to misuse this two flags.
- When the gadget initializes, the controller doesn't need to run if
it depends on vbus (CI_HDRC_PULLUP_ON_VBUS), it does not
relate to shared register.
- When the gadget starts (load one gadget module), the controller
can run if vbus is on (CI_HDRC_PULLUP_ON_VBUS), it also does not
relate to shared register.

Tested-by: Marek Vasut <marex@denx.de>
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/udc.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index c70ce38..45abf4d 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1637,8 +1637,7 @@ static int ci_udc_start(struct usb_gadget *gadget,
 	pm_runtime_get_sync(&ci->gadget.dev);
 	if (ci->platdata->flags & CI_HDRC_PULLUP_ON_VBUS) {
 		if (ci->vbus_active) {
-			if (ci->platdata->flags & CI_HDRC_REGS_SHARED)
-				hw_device_reset(ci, USBMODE_CM_DC);
+			hw_device_reset(ci, USBMODE_CM_DC);
 		} else {
 			pm_runtime_put_sync(&ci->gadget.dev);
 			goto done;
@@ -1801,7 +1800,7 @@ static int udc_start(struct ci_hdrc *ci)
 		}
 	}
 
-	if (!(ci->platdata->flags & CI_HDRC_REGS_SHARED)) {
+	if (!(ci->platdata->flags & CI_HDRC_PULLUP_ON_VBUS)) {
 		retval = hw_device_reset(ci, USBMODE_CM_DC);
 		if (retval)
 			goto put_transceiver;
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v14 12/12] usb: chipidea: udc: .pullup is valid when vbus is on at CI_HDRC_PULLUP_ON_VBUS
  2013-08-02  8:33 [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea Peter Chen
                   ` (10 preceding siblings ...)
  2013-08-02  8:34 ` [PATCH v14 11/12] usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and CI_HDRC_PULLUP_ON_VBUS Peter Chen
@ 2013-08-02  8:34 ` Peter Chen
  2013-08-06 12:00 ` [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea Peter Chen
  12 siblings, 0 replies; 23+ messages in thread
From: Peter Chen @ 2013-08-02  8:34 UTC (permalink / raw)
  To: linux-arm-kernel

When the flag CI_HDRC_PULLUP_ON_VBUS is set, .pullup should only be
called when the vbus is active. When the CI_HDRC_PULLUP_ON_VBUS
is set, the controller only begins to run when the vbus is on,
So, it is only meaningful software set pullup/pulldown after
the controller begins to run.

Tested-by: Marek Vasut <marex@denx.de>
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/udc.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 45abf4d..b7ead5f 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1514,6 +1514,10 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on)
 {
 	struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget);
 
+	if ((ci->platdata->flags & CI_HDRC_PULLUP_ON_VBUS)
+			&& !ci->vbus_active)
+		return -EOPNOTSUPP;
+
 	if (is_on)
 		hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS);
 	else
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea
  2013-08-02  8:33 [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea Peter Chen
                   ` (11 preceding siblings ...)
  2013-08-02  8:34 ` [PATCH v14 12/12] usb: chipidea: udc: .pullup is valid when vbus is on at CI_HDRC_PULLUP_ON_VBUS Peter Chen
@ 2013-08-06 12:00 ` Peter Chen
  12 siblings, 0 replies; 23+ messages in thread
From: Peter Chen @ 2013-08-06 12:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Aug 02, 2013 at 04:33:53PM +0800, Peter Chen wrote:
> This patchset adds tested otg id switch function and vbus connect
> and disconnect detection for chipidea driver. And fix kinds of 
> bugs found at chipidea drivers after enabling id and vbus detection.
> 
> This patch are fully tested at imx6 sabresd and imx28evk platform by me.
> Besides, marek tested it on two STMP3780-based boards (not yet mainline)
> and two MX28-based boards.
> 
> My chipidea repo: https://github.com/hzpeterchen/linux-usb.git
> 
> Changes for v14:
> - This patchset is based on below recent chipidea patches and newest
> usb-next, it can decrease rebase effort.
> 
> Fabio Estevam (3):
>   chipidea: ci_hdrc_imx: Remove unused variable 'res'
>   chipidea: core: Move hw_phymode_configure() into probe
>   chipidea: Remove previous MODULE_ALIAS
> 
> Lothar Wabmann (3):
>   usb: chipidea: improve kconfig 2.0
>   usb: chipidea: don't clobber return value of ci_role_start()
>   usb: chipidea: ci_hdrc_imx: remove an unsolicited module_put() call
>     from ci_hdrc_imx_remove()
> 
> Peter Chen (1):
>   usb: chipidea: fix the build error with randconfig
> 
> - [Michael comments]: move vbus operation to core, and squash two vbus
> patches. [1/12], [2/12]
> - [Michael comments]: move out non vbus and non id related patches. [14/14 at v13]

Hi Alex, any comments?

> 
> Chagnes for v13:
> - Add Tested-by: Marek Vasut <marex@denx.de>
> - [Sascha's comments]: Add return value check for devm_regulator_get. [3/14]
> - [Marc's comments]: Change timeout usage at hw_wait_reg. [11/14]
> - [Alex's comments]: Using platdata flag to indicate dual role but not 
> OTG controller. [7/14]
> 
> Changes for v12:
> - Rebased greg's usb-next tree (3.10.0-rc7+)
> - Split more small patches for single function and fix.
> 
> Peter Chen (12):
>   usb: chipidea: move vbus regulator operation to core
>   usb: chipidea: host: add vbus regulator control
>   usb: chipidea: udc: otg_set_peripheral is useless for some chipidea
>     users
>   usb: chipidea: otg: Add otg file used to access otgsc
>   usb: chipidea: Add role init and destory APIs
>   usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG
>   usb: chipidea: disable all interrupts and clear all interrupts status
>   usb: chipidea: move otg relate things to otg file
>   usb: chipidea: add vbus interrupt handler
>   usb: chipidea: add wait vbus lower than OTGSC_BSV before role starts
>   usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and
>     CI_HDRC_PULLUP_ON_VBUS
>   usb: chipidea: udc: .pullup is valid when vbus is on at
>     CI_HDRC_PULLUP_ON_VBUS
> 
>  drivers/usb/chipidea/Makefile      |    2 +-
>  drivers/usb/chipidea/bits.h        |   10 ++
>  drivers/usb/chipidea/ci.h          |    8 ++
>  drivers/usb/chipidea/ci_hdrc_imx.c |   26 +-----
>  drivers/usb/chipidea/core.c        |  184 +++++++++++++++++++++++++-----------
>  drivers/usb/chipidea/host.c        |   30 ++++++-
>  drivers/usb/chipidea/host.h        |    6 +
>  drivers/usb/chipidea/otg.c         |  135 ++++++++++++++++++++++++++
>  drivers/usb/chipidea/otg.h         |   22 +++++
>  drivers/usb/chipidea/udc.c         |   59 +++++++++---
>  drivers/usb/chipidea/udc.h         |    6 +
>  include/linux/usb/chipidea.h       |    6 +
>  12 files changed, 401 insertions(+), 93 deletions(-)
>  create mode 100644 drivers/usb/chipidea/otg.c
>  create mode 100644 drivers/usb/chipidea/otg.h
> 

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v14 06/12] usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG
  2013-08-09 12:55   ` Alexander Shishkin
@ 2013-08-09 11:13     ` Peter Chen
  2013-08-09 13:21       ` Alexander Shishkin
  0 siblings, 1 reply; 23+ messages in thread
From: Peter Chen @ 2013-08-09 11:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Aug 09, 2013 at 03:55:56PM +0300, Alexander Shishkin wrote:
> Peter Chen <peter.chen@freescale.com> writes:
> 
> > Since we need otgsc to know vbus's status at some chipidea
> > controllers even it is peripheral-only mode. Besides, some
> > SoCs (eg, AR9331 SoC) don't have otgsc register even
> > the DCCPARAMS_DC and DCCPARAMS_HC are both 1 at CAP_DCCPARAMS.
> >
> > We inroduce flag CI_HDRC_DUAL_ROLE_NOT_OTG to indicate if the
> > controller is dual role, but not supports OTG. If this flag is
> > not set, we follow the rule that if DCCPARAMS_DC and DCCPARAMS_HC
> > are both 1 at CAP_DCCPARAMS, then this controller is otg capable.
> >
> > Signed-off-by: Peter Chen <peter.chen@freescale.com>
> > ---
> >  drivers/usb/chipidea/core.c  |   38 +++++++++++++++++++++++++++++++-------
> >  include/linux/usb/chipidea.h |    5 +++++
> >  2 files changed, 36 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> > index bfc9aef..2ae18fd 100644
> > --- a/drivers/usb/chipidea/core.c
> > +++ b/drivers/usb/chipidea/core.c
> > @@ -426,6 +426,18 @@ static inline void ci_role_destroy(struct ci_hdrc *ci)
> >  	ci_hdrc_host_destroy(ci);
> >  }
> >  
> > +static void ci_get_otg_capable(struct ci_hdrc *ci)
> > +{
> > +	if (ci->platdata->flags & CI_HDRC_DUAL_ROLE_NOT_OTG)
> > +		ci->is_otg = false;
> > +	else
> > +		ci->is_otg = (hw_read(ci, CAP_DCCPARAMS,
> > +				DCCPARAMS_DC | DCCPARAMS_HC)
> > +					== (DCCPARAMS_DC | DCCPARAMS_HC));
> > +	if (ci->is_otg)
> > +		dev_dbg(ci->dev, "It is OTG capable controller\n");
> > +}
> > +
> >  static int ci_hdrc_probe(struct platform_device *pdev)
> >  {
> >  	struct device	*dev = &pdev->dev;
> > @@ -482,6 +494,9 @@ static int ci_hdrc_probe(struct platform_device *pdev)
> >  		return -ENODEV;
> >  	}
> >  
> > +	/* To know if controller is OTG capable or not */
> > +	ci_get_otg_capable(ci);
> 
> The comment is redundant.
> 

Will delete

> > +		} else {
> > +			/*
> > +			 * If the controller is not OTG capable, but support
> > +			 * role switch, the defalt role is gadget, and the
> > +			 * user can switch it through debugfs (proc in future?)
> 
> It's not going to be in procfs ever, so that part of the comment can go.
> 

I can delete now, but the role switch does not a debug function, we
may not put it at debugfs, do you think so?

> > +			 */
> > +			ci->role = CI_ROLE_GADGET;
> 
> I think we might need a config option for this in the future, at least.
> 

Yes, we can add CONFIG_CI_DEFAULT_ROLE in the future.

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v14 04/12] usb: chipidea: otg: Add otg file used to access otgsc
  2013-08-09 13:00   ` Alexander Shishkin
@ 2013-08-09 11:18     ` Peter Chen
  0 siblings, 0 replies; 23+ messages in thread
From: Peter Chen @ 2013-08-09 11:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Aug 09, 2013 at 04:00:13PM +0300, Alexander Shishkin wrote:
> Peter Chen <peter.chen@freescale.com> writes:
> 
> > This file is mainly used to access otgsc currently, it may
> > add otg related things in the future.
> >
> > Tested-by: Marek Vasut <marex@denx.de>
> > Signed-off-by: Peter Chen <peter.chen@freescale.com>
> > ---
> >  drivers/usb/chipidea/Makefile |    2 +-
> >  drivers/usb/chipidea/bits.h   |   10 ++++++++
> >  drivers/usb/chipidea/core.c   |    3 +-
> >  drivers/usb/chipidea/otg.c    |   50 +++++++++++++++++++++++++++++++++++++++++
> >  drivers/usb/chipidea/otg.h    |   19 +++++++++++++++
> >  5 files changed, 82 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile
> > index 6cf5f68..a99d980 100644
> > --- a/drivers/usb/chipidea/Makefile
> > +++ b/drivers/usb/chipidea/Makefile
> > @@ -2,7 +2,7 @@ ccflags-$(CONFIG_USB_CHIPIDEA_DEBUG) := -DDEBUG
> >  
> >  obj-$(CONFIG_USB_CHIPIDEA)		+= ci_hdrc.o
> >  
> > -ci_hdrc-y				:= core.o
> > +ci_hdrc-y				:= core.o otg.o
> >  ci_hdrc-$(CONFIG_USB_CHIPIDEA_UDC)	+= udc.o
> >  ci_hdrc-$(CONFIG_USB_CHIPIDEA_HOST)	+= host.o
> >  ci_hdrc-$(CONFIG_USB_CHIPIDEA_DEBUG)	+= debug.o
> > diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h
> > index aefa026..dd0cf9e 100644
> > --- a/drivers/usb/chipidea/bits.h
> > +++ b/drivers/usb/chipidea/bits.h
> > @@ -79,11 +79,21 @@
> >  #define OTGSC_ASVIS	      BIT(18)
> >  #define OTGSC_BSVIS	      BIT(19)
> >  #define OTGSC_BSEIS	      BIT(20)
> > +#define OTGSC_1MSIS	      BIT(21)
> > +#define OTGSC_DPIS	      BIT(22)
> >  #define OTGSC_IDIE	      BIT(24)
> >  #define OTGSC_AVVIE	      BIT(25)
> >  #define OTGSC_ASVIE	      BIT(26)
> >  #define OTGSC_BSVIE	      BIT(27)
> >  #define OTGSC_BSEIE	      BIT(28)
> > +#define OTGSC_1MSIE	      BIT(29)
> > +#define OTGSC_DPIE	      BIT(30)
> > +#define OTGSC_INT_EN_BITS	(OTGSC_IDIE | OTGSC_AVVIE | OTGSC_ASVIE \
> > +				| OTGSC_BSVIE | OTGSC_BSEIE | OTGSC_1MSIE \
> > +				| OTGSC_DPIE)
> > +#define OTGSC_INT_STATUS_BITS	(OTGSC_IDIS | OTGSC_AVVIS | OTGSC_ASVIS	\
> > +				| OTGSC_BSVIS | OTGSC_BSEIS | OTGSC_1MSIS \
> > +				| OTGSC_DPIS)
> >  
> >  /* USBMODE */
> >  #define USBMODE_CM            (0x03UL <<  0)
> > diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> > index 26f6599..a4be8a5 100644
> > --- a/drivers/usb/chipidea/core.c
> > +++ b/drivers/usb/chipidea/core.c
> > @@ -72,6 +72,7 @@
> >  #include "bits.h"
> >  #include "host.h"
> >  #include "debug.h"
> > +#include "otg.h"
> >  
> >  /* Controller register map */
> >  static uintptr_t ci_regs_nolpm[] = {
> > @@ -530,7 +531,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
> >  		goto stop;
> >  
> >  	if (ci->is_otg)
> > -		hw_write(ci, OP_OTGSC, OTGSC_IDIE, OTGSC_IDIE);
> > +		ci_hdrc_otg_init(ci);
> >  
> >  	ret = dbg_create_files(ci);
> >  	if (!ret)
> > diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
> > new file mode 100644
> > index 0000000..abefb4d
> > --- /dev/null
> > +++ b/drivers/usb/chipidea/otg.c
> > @@ -0,0 +1,50 @@
> > +/*
> > + * otg.c - ChipIdea USB IP core OTG driver
> > + *
> > + * Copyright (C) 2013 Freescale Semiconductor, Inc.
> > + *
> > + * Author: Peter Chen
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +/*
> > + * This file mainly handles otgsc register, it may include OTG operation
> > + * in the future.
> > + */
> > +
> > +#include <linux/usb/otg.h>
> > +#include <linux/usb/gadget.h>
> > +#include <linux/usb/chipidea.h>
> > +
> > +#include "ci.h"
> > +#include "bits.h"
> 
> You don't include otg.h here, which makes sparse think that you wanted
> these functions to be static.
> 

Will add

> > +
> > +void ci_clear_otg_interrupt(struct ci_hdrc *ci, u32 bits)
> > +{
> > +	/* Only clear request bits */
> > +	hw_write(ci, OP_OTGSC, OTGSC_INT_STATUS_BITS, bits);
> > +}
> > +
> > +void ci_enable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
> > +{
> > +	hw_write(ci, OP_OTGSC, bits, bits);
> > +}
> > +
> > +void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
> > +{
> > +	hw_write(ci, OP_OTGSC, bits, 0);
> > +}
> 
> These functions look like they would be better off as static inlines in
> otg.h than here.
> 

Will do

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v14 11/12] usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and CI_HDRC_PULLUP_ON_VBUS
  2013-08-09 13:23   ` Alexander Shishkin
@ 2013-08-09 11:46     ` Peter Chen
  2013-08-09 12:16       ` Peter Chen
  0 siblings, 1 reply; 23+ messages in thread
From: Peter Chen @ 2013-08-09 11:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Aug 09, 2013 at 04:23:11PM +0300, Alexander Shishkin wrote:
> Peter Chen <peter.chen@freescale.com> writes:
> 
> > CI_HDRC_REGS_SHARED stands for the controller registers is shared
> > with other USB drivers, if all USB drivers are at chipidea/, it doesn't
> > needed to set.
> 
> We still have the msm driver that uses REGS_SHARED.
> 

Yes, I have considered it. At udc interrupt handler, the REGS_SHARED
is still used. The msm set both CI_HDRC_REGS_SHARED and CI_HDRC_PULLUP_ON_VBUS.

> > CI_HDRC_PULLUP_ON_VBUS stands for pullup dp when the vbus is on. This
> > flag doesn't need to set if the vbus is always on for gadget
> > since dp has always pulled up after the gadget has initialized.
> 
> Didn't we agree at some point to get rid of this flag altogether once we
> have proper VBUS detection?

Yes, we can delete it now, the reason why I haven't remove it is:
I met some use cases that the vbus is always on recently,
no connection/disconnection. Eg, the USB audio device connects
to Apple Sound machine, the vbus is the power of the device system.

I checked the code just now again, we can cover such kind of case.

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v14 11/12] usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and CI_HDRC_PULLUP_ON_VBUS
  2013-08-09 11:46     ` Peter Chen
@ 2013-08-09 12:16       ` Peter Chen
  0 siblings, 0 replies; 23+ messages in thread
From: Peter Chen @ 2013-08-09 12:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Aug 09, 2013 at 07:46:00PM +0800, Peter Chen wrote:
> On Fri, Aug 09, 2013 at 04:23:11PM +0300, Alexander Shishkin wrote:
> > Peter Chen <peter.chen@freescale.com> writes:
> > 
> > > CI_HDRC_REGS_SHARED stands for the controller registers is shared
> > > with other USB drivers, if all USB drivers are at chipidea/, it doesn't
> > > needed to set.
> > 
> > We still have the msm driver that uses REGS_SHARED.
> > 
> 
> Yes, I have considered it. At udc interrupt handler, the REGS_SHARED
> is still used. The msm set both CI_HDRC_REGS_SHARED and CI_HDRC_PULLUP_ON_VBUS.
> 
> > > CI_HDRC_PULLUP_ON_VBUS stands for pullup dp when the vbus is on. This
> > > flag doesn't need to set if the vbus is always on for gadget
> > > since dp has always pulled up after the gadget has initialized.
> > 
> > Didn't we agree at some point to get rid of this flag altogether once we
> > have proper VBUS detection?
> 
> Yes, we can delete it now, the reason why I haven't remove it is:
> I met some use cases that the vbus is always on recently,
> no connection/disconnection. Eg, the USB audio device connects
> to Apple Sound machine, the vbus is the power of the device system.
> 
> I checked the code just now again, we can cover such kind of case.

I will have a patch to delete CI_HDRC_PULLUP_ON_VBUS. If we squash
two patches, the change like below:

diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index bd1fe25..ab3e74a 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -91,7 +91,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
 		.name		= "ci_hdrc_imx",
 		.capoffset	= DEF_CAPOFFSET,
 		.flags		= CI_HDRC_REQUIRE_TRANSCEIVER |
-				  CI_HDRC_PULLUP_ON_VBUS |
 				  CI_HDRC_DISABLE_STREAMING,
 	};
 	int ret;
diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index fb657ef..2d51d85 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -49,7 +49,6 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
 	.name			= "ci_hdrc_msm",
 	.flags			= CI_HDRC_REGS_SHARED |
 				  CI_HDRC_REQUIRE_TRANSCEIVER |
-				  CI_HDRC_PULLUP_ON_VBUS |
 				  CI_HDRC_DISABLE_STREAMING,
 
 	.notify_event		= ci_hdrc_msm_notify_event,
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index c70ce38..f77c904 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1635,14 +1635,11 @@ static int ci_udc_start(struct usb_gadget *gadget,
 
 	ci->driver = driver;
 	pm_runtime_get_sync(&ci->gadget.dev);
-	if (ci->platdata->flags & CI_HDRC_PULLUP_ON_VBUS) {
-		if (ci->vbus_active) {
-			if (ci->platdata->flags & CI_HDRC_REGS_SHARED)
-				hw_device_reset(ci, USBMODE_CM_DC);
-		} else {
-			pm_runtime_put_sync(&ci->gadget.dev);
-			goto done;
-		}
+	if (ci->vbus_active) {
+		hw_device_reset(ci, USBMODE_CM_DC);
+	} else {
+		pm_runtime_put_sync(&ci->gadget.dev);
+		goto done;
 	}
 
 	retval = hw_device_state(ci, ci->ep0out->qh.dma);
@@ -1665,8 +1662,7 @@ static int ci_udc_stop(struct usb_gadget *gadget,
 
 	spin_lock_irqsave(&ci->lock, flags);
 
-	if (!(ci->platdata->flags & CI_HDRC_PULLUP_ON_VBUS) ||
-			ci->vbus_active) {
+	if (ci->vbus_active) {
 		hw_device_state(ci, 0);
 		if (ci->platdata->notify_event)
 			ci->platdata->notify_event(ci,
@@ -1801,12 +1797,6 @@ static int udc_start(struct ci_hdrc *ci)
 		}
 	}
 
-	if (!(ci->platdata->flags & CI_HDRC_REGS_SHARED)) {
-		retval = hw_device_reset(ci, USBMODE_CM_DC);
-		if (retval)
-			goto put_transceiver;
-	}
-
 	if (ci->transceiver) {
 		retval = otg_set_peripheral(ci->transceiver->otg,
 						&ci->gadget);
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 10a607c..7c4ba37 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -18,13 +18,12 @@ struct ci_hdrc_platform_data {
 	unsigned long	 flags;
 #define CI_HDRC_REGS_SHARED		BIT(0)
 #define CI_HDRC_REQUIRE_TRANSCEIVER	BIT(1)
-#define CI_HDRC_PULLUP_ON_VBUS		BIT(2)
-#define CI_HDRC_DISABLE_STREAMING	BIT(3)
+#define CI_HDRC_DISABLE_STREAMING	BIT(2)
 	/*
 	 * Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1,
 	 * but otg is not supported (no register otgsc).
 	 */
-#define CI_HDRC_DUAL_ROLE_NOT_OTG	BIT(4)
+#define CI_HDRC_DUAL_ROLE_NOT_OTG	BIT(3)
 	enum usb_dr_mode	dr_mode;
 #define CI_HDRC_CONTROLLER_RESET_EVENT		0
 #define CI_HDRC_CONTROLLER_STOPPED_EVENT	1

-- 

Best Regards,
Peter Chen

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v14 06/12] usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG
  2013-08-02  8:33 ` [PATCH v14 06/12] usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG Peter Chen
@ 2013-08-09 12:55   ` Alexander Shishkin
  2013-08-09 11:13     ` Peter Chen
  0 siblings, 1 reply; 23+ messages in thread
From: Alexander Shishkin @ 2013-08-09 12:55 UTC (permalink / raw)
  To: linux-arm-kernel

Peter Chen <peter.chen@freescale.com> writes:

> Since we need otgsc to know vbus's status at some chipidea
> controllers even it is peripheral-only mode. Besides, some
> SoCs (eg, AR9331 SoC) don't have otgsc register even
> the DCCPARAMS_DC and DCCPARAMS_HC are both 1 at CAP_DCCPARAMS.
>
> We inroduce flag CI_HDRC_DUAL_ROLE_NOT_OTG to indicate if the
> controller is dual role, but not supports OTG. If this flag is
> not set, we follow the rule that if DCCPARAMS_DC and DCCPARAMS_HC
> are both 1 at CAP_DCCPARAMS, then this controller is otg capable.
>
> Signed-off-by: Peter Chen <peter.chen@freescale.com>
> ---
>  drivers/usb/chipidea/core.c  |   38 +++++++++++++++++++++++++++++++-------
>  include/linux/usb/chipidea.h |    5 +++++
>  2 files changed, 36 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> index bfc9aef..2ae18fd 100644
> --- a/drivers/usb/chipidea/core.c
> +++ b/drivers/usb/chipidea/core.c
> @@ -426,6 +426,18 @@ static inline void ci_role_destroy(struct ci_hdrc *ci)
>  	ci_hdrc_host_destroy(ci);
>  }
>  
> +static void ci_get_otg_capable(struct ci_hdrc *ci)
> +{
> +	if (ci->platdata->flags & CI_HDRC_DUAL_ROLE_NOT_OTG)
> +		ci->is_otg = false;
> +	else
> +		ci->is_otg = (hw_read(ci, CAP_DCCPARAMS,
> +				DCCPARAMS_DC | DCCPARAMS_HC)
> +					== (DCCPARAMS_DC | DCCPARAMS_HC));
> +	if (ci->is_otg)
> +		dev_dbg(ci->dev, "It is OTG capable controller\n");
> +}
> +
>  static int ci_hdrc_probe(struct platform_device *pdev)
>  {
>  	struct device	*dev = &pdev->dev;
> @@ -482,6 +494,9 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>  		return -ENODEV;
>  	}
>  
> +	/* To know if controller is OTG capable or not */
> +	ci_get_otg_capable(ci);

The comment is redundant.

> +
>  	if (!ci->platdata->phy_mode)
>  		ci->platdata->phy_mode = of_usb_get_phy_mode(dev->of_node);
>  
> @@ -514,10 +529,22 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>  	}
>  
>  	if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) {
> -		ci->is_otg = true;
> -		/* ID pin needs 1ms debouce time, we delay 2ms for safe */
> -		mdelay(2);
> -		ci->role = ci_otg_role(ci);
> +		if (ci->is_otg) {
> +			/*
> +			 * ID pin needs 1ms debouce time,
> +			 * we delay 2ms for safe.
> +			 */
> +			mdelay(2);
> +			ci->role = ci_otg_role(ci);
> +			ci_hdrc_otg_init(ci);
> +		} else {
> +			/*
> +			 * If the controller is not OTG capable, but support
> +			 * role switch, the defalt role is gadget, and the
> +			 * user can switch it through debugfs (proc in future?)

It's not going to be in procfs ever, so that part of the comment can go.

> +			 */
> +			ci->role = CI_ROLE_GADGET;

I think we might need a config option for this in the future, at least.

> +		}
>  	} else {
>  		ci->role = ci->roles[CI_ROLE_HOST]
>  			? CI_ROLE_HOST
> @@ -536,9 +563,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>  	if (ret)
>  		goto stop;
>  
> -	if (ci->is_otg)
> -		ci_hdrc_otg_init(ci);
> -
>  	ret = dbg_create_files(ci);
>  	if (!ret)
>  		return 0;
> diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
> index ce4e1aa..10a607c 100644
> --- a/include/linux/usb/chipidea.h
> +++ b/include/linux/usb/chipidea.h
> @@ -20,6 +20,11 @@ struct ci_hdrc_platform_data {
>  #define CI_HDRC_REQUIRE_TRANSCEIVER	BIT(1)
>  #define CI_HDRC_PULLUP_ON_VBUS		BIT(2)
>  #define CI_HDRC_DISABLE_STREAMING	BIT(3)
> +	/*
> +	 * Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1,
> +	 * but otg is not supported (no register otgsc).
> +	 */
> +#define CI_HDRC_DUAL_ROLE_NOT_OTG	BIT(4)
>  	enum usb_dr_mode	dr_mode;
>  #define CI_HDRC_CONTROLLER_RESET_EVENT		0
>  #define CI_HDRC_CONTROLLER_STOPPED_EVENT	1
> -- 
> 1.7.0.4

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v14 04/12] usb: chipidea: otg: Add otg file used to access otgsc
  2013-08-02  8:33 ` [PATCH v14 04/12] usb: chipidea: otg: Add otg file used to access otgsc Peter Chen
@ 2013-08-09 13:00   ` Alexander Shishkin
  2013-08-09 11:18     ` Peter Chen
  0 siblings, 1 reply; 23+ messages in thread
From: Alexander Shishkin @ 2013-08-09 13:00 UTC (permalink / raw)
  To: linux-arm-kernel

Peter Chen <peter.chen@freescale.com> writes:

> This file is mainly used to access otgsc currently, it may
> add otg related things in the future.
>
> Tested-by: Marek Vasut <marex@denx.de>
> Signed-off-by: Peter Chen <peter.chen@freescale.com>
> ---
>  drivers/usb/chipidea/Makefile |    2 +-
>  drivers/usb/chipidea/bits.h   |   10 ++++++++
>  drivers/usb/chipidea/core.c   |    3 +-
>  drivers/usb/chipidea/otg.c    |   50 +++++++++++++++++++++++++++++++++++++++++
>  drivers/usb/chipidea/otg.h    |   19 +++++++++++++++
>  5 files changed, 82 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile
> index 6cf5f68..a99d980 100644
> --- a/drivers/usb/chipidea/Makefile
> +++ b/drivers/usb/chipidea/Makefile
> @@ -2,7 +2,7 @@ ccflags-$(CONFIG_USB_CHIPIDEA_DEBUG) := -DDEBUG
>  
>  obj-$(CONFIG_USB_CHIPIDEA)		+= ci_hdrc.o
>  
> -ci_hdrc-y				:= core.o
> +ci_hdrc-y				:= core.o otg.o
>  ci_hdrc-$(CONFIG_USB_CHIPIDEA_UDC)	+= udc.o
>  ci_hdrc-$(CONFIG_USB_CHIPIDEA_HOST)	+= host.o
>  ci_hdrc-$(CONFIG_USB_CHIPIDEA_DEBUG)	+= debug.o
> diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h
> index aefa026..dd0cf9e 100644
> --- a/drivers/usb/chipidea/bits.h
> +++ b/drivers/usb/chipidea/bits.h
> @@ -79,11 +79,21 @@
>  #define OTGSC_ASVIS	      BIT(18)
>  #define OTGSC_BSVIS	      BIT(19)
>  #define OTGSC_BSEIS	      BIT(20)
> +#define OTGSC_1MSIS	      BIT(21)
> +#define OTGSC_DPIS	      BIT(22)
>  #define OTGSC_IDIE	      BIT(24)
>  #define OTGSC_AVVIE	      BIT(25)
>  #define OTGSC_ASVIE	      BIT(26)
>  #define OTGSC_BSVIE	      BIT(27)
>  #define OTGSC_BSEIE	      BIT(28)
> +#define OTGSC_1MSIE	      BIT(29)
> +#define OTGSC_DPIE	      BIT(30)
> +#define OTGSC_INT_EN_BITS	(OTGSC_IDIE | OTGSC_AVVIE | OTGSC_ASVIE \
> +				| OTGSC_BSVIE | OTGSC_BSEIE | OTGSC_1MSIE \
> +				| OTGSC_DPIE)
> +#define OTGSC_INT_STATUS_BITS	(OTGSC_IDIS | OTGSC_AVVIS | OTGSC_ASVIS	\
> +				| OTGSC_BSVIS | OTGSC_BSEIS | OTGSC_1MSIS \
> +				| OTGSC_DPIS)
>  
>  /* USBMODE */
>  #define USBMODE_CM            (0x03UL <<  0)
> diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> index 26f6599..a4be8a5 100644
> --- a/drivers/usb/chipidea/core.c
> +++ b/drivers/usb/chipidea/core.c
> @@ -72,6 +72,7 @@
>  #include "bits.h"
>  #include "host.h"
>  #include "debug.h"
> +#include "otg.h"
>  
>  /* Controller register map */
>  static uintptr_t ci_regs_nolpm[] = {
> @@ -530,7 +531,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>  		goto stop;
>  
>  	if (ci->is_otg)
> -		hw_write(ci, OP_OTGSC, OTGSC_IDIE, OTGSC_IDIE);
> +		ci_hdrc_otg_init(ci);
>  
>  	ret = dbg_create_files(ci);
>  	if (!ret)
> diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
> new file mode 100644
> index 0000000..abefb4d
> --- /dev/null
> +++ b/drivers/usb/chipidea/otg.c
> @@ -0,0 +1,50 @@
> +/*
> + * otg.c - ChipIdea USB IP core OTG driver
> + *
> + * Copyright (C) 2013 Freescale Semiconductor, Inc.
> + *
> + * Author: Peter Chen
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +/*
> + * This file mainly handles otgsc register, it may include OTG operation
> + * in the future.
> + */
> +
> +#include <linux/usb/otg.h>
> +#include <linux/usb/gadget.h>
> +#include <linux/usb/chipidea.h>
> +
> +#include "ci.h"
> +#include "bits.h"

You don't include otg.h here, which makes sparse think that you wanted
these functions to be static.

> +
> +void ci_clear_otg_interrupt(struct ci_hdrc *ci, u32 bits)
> +{
> +	/* Only clear request bits */
> +	hw_write(ci, OP_OTGSC, OTGSC_INT_STATUS_BITS, bits);
> +}
> +
> +void ci_enable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
> +{
> +	hw_write(ci, OP_OTGSC, bits, bits);
> +}
> +
> +void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
> +{
> +	hw_write(ci, OP_OTGSC, bits, 0);
> +}

These functions look like they would be better off as static inlines in
otg.h than here.

> +
> +/**
> + * ci_hdrc_otg_init - initialize otgsc bits
> + * ci: the controller
> + */
> +int ci_hdrc_otg_init(struct ci_hdrc *ci)
> +{
> +	ci_enable_otg_interrupt(ci, OTGSC_IDIE);
> +
> +	return 0;
> +}
> diff --git a/drivers/usb/chipidea/otg.h b/drivers/usb/chipidea/otg.h
> new file mode 100644
> index 0000000..f24ec37
> --- /dev/null
> +++ b/drivers/usb/chipidea/otg.h
> @@ -0,0 +1,19 @@
> +/*
> + * Copyright (C) 2013 Freescale Semiconductor, Inc.
> + *
> + * Author: Peter Chen
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef __DRIVERS_USB_CHIPIDEA_OTG_H
> +#define __DRIVERS_USB_CHIPIDEA_OTG_H
> +
> +int ci_hdrc_otg_init(struct ci_hdrc *ci);
> +void ci_clear_otg_interrupt(struct ci_hdrc *ci, u32 bits);
> +void ci_enable_otg_interrupt(struct ci_hdrc *ci, u32 bits);
> +void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits);
> +
> +#endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */
> -- 
> 1.7.0.4

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v14 08/12] usb: chipidea: move otg relate things to otg file
  2013-08-02  8:34 ` [PATCH v14 08/12] usb: chipidea: move otg relate things to otg file Peter Chen
@ 2013-08-09 13:09   ` Alexander Shishkin
  0 siblings, 0 replies; 23+ messages in thread
From: Alexander Shishkin @ 2013-08-09 13:09 UTC (permalink / raw)
  To: linux-arm-kernel

Peter Chen <peter.chen@freescale.com> writes:

A few typos:

> Move otg relate things to otg file.

"related"

>
> Tested-by: Marek Vasut <marex@denx.de>
> Signed-off-by: Peter Chen <peter.chen@freescale.com>
> ---
>  drivers/usb/chipidea/core.c |   63 +++++++++----------------------------------
>  drivers/usb/chipidea/otg.c  |   57 +++++++++++++++++++++++++++++++++++++-
>  drivers/usb/chipidea/otg.h  |    2 +
>  3 files changed, 70 insertions(+), 52 deletions(-)
>
> diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> index 2223954..30be811 100644
> --- a/drivers/usb/chipidea/core.c
> +++ b/drivers/usb/chipidea/core.c
> @@ -294,40 +294,6 @@ int hw_device_reset(struct ci_hdrc *ci, u32 mode)
>  	return 0;
>  }
>  
> -/**
> - * ci_otg_role - pick role based on ID pin state
> - * @ci: the controller
> - */
> -static enum ci_role ci_otg_role(struct ci_hdrc *ci)
> -{
> -	u32 sts = hw_read(ci, OP_OTGSC, ~0);
> -	enum ci_role role = sts & OTGSC_ID
> -		? CI_ROLE_GADGET
> -		: CI_ROLE_HOST;
> -
> -	return role;
> -}
> -
> -/**
> - * ci_role_work - perform role changing based on ID pin
> - * @work: work struct
> - */
> -static void ci_role_work(struct work_struct *work)
> -{
> -	struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
> -	enum ci_role role = ci_otg_role(ci);
> -
> -	if (role != ci->role) {
> -		dev_dbg(ci->dev, "switching from %s to %s\n",
> -			ci_role(ci)->name, ci->roles[role]->name);
> -
> -		ci_role_stop(ci);
> -		ci_role_start(ci, role);
> -	}
> -
> -	enable_irq(ci->irq);
> -}
> -
>  static irqreturn_t ci_irq(int irq, void *data)
>  {
>  	struct ci_hdrc *ci = data;
> @@ -430,6 +396,8 @@ static inline void ci_role_destroy(struct ci_hdrc *ci)
>  {
>  	ci_hdrc_gadget_destroy(ci);
>  	ci_hdrc_host_destroy(ci);
> +	if (ci->is_otg)
> +		ci_hdrc_otg_destory(ci);

"destroy"

>  }
>  
>  static void ci_get_otg_capable(struct ci_hdrc *ci)
> @@ -496,13 +464,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>  		return -ENODEV;
>  	}
>  
> -	INIT_WORK(&ci->work, ci_role_work);
> -	ci->wq = create_singlethread_workqueue("ci_otg");
> -	if (!ci->wq) {
> -		dev_err(dev, "can't create workqueue\n");
> -		return -ENODEV;
> -	}
> -
>  	/* To know if controller is OTG capable or not */
>  	ci_get_otg_capable(ci);
>  
> @@ -533,8 +494,15 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>  
>  	if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) {
>  		dev_err(dev, "no supported roles\n");
> -		ret = -ENODEV;
> -		goto rm_wq;
> +		return -ENODEV;
> +	}
> +
> +	if (ci->is_otg) {
> +		ret = ci_hdrc_otg_init(ci);
> +		if (ret) {
> +			dev_err(dev, "init otg fails, ret = %d\n", ret);
> +			goto stop;
> +		}
>  	}
>  
>  	if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) {
> @@ -545,7 +513,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>  			 */
>  			mdelay(2);
>  			ci->role = ci_otg_role(ci);
> -			ci_hdrc_otg_init(ci);
> +			ci_enable_otg_interrupt(ci, OTGSC_IDIE);
>  		} else {
>  			/*
>  			 * If the controller is not OTG capable, but support
> @@ -563,7 +531,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>  	ret = ci_role_start(ci, ci->role);
>  	if (ret) {
>  		dev_err(dev, "can't start %s role\n", ci_role(ci)->name);
> -		goto rm_wq;
> +		goto stop;
>  	}
>  
>  	platform_set_drvdata(pdev, ci);
> @@ -579,9 +547,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>  	free_irq(ci->irq, ci);
>  stop:
>  	ci_role_destroy(ci);
> -rm_wq:
> -	flush_workqueue(ci->wq);
> -	destroy_workqueue(ci->wq);
>  
>  	return ret;
>  }
> @@ -591,8 +556,6 @@ static int ci_hdrc_remove(struct platform_device *pdev)
>  	struct ci_hdrc *ci = platform_get_drvdata(pdev);
>  
>  	dbg_remove_files(ci);
> -	flush_workqueue(ci->wq);
> -	destroy_workqueue(ci->wq);
>  	free_irq(ci->irq, ci);
>  	ci_role_destroy(ci);
>  
> diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
> index abefb4d..68f2faf 100644
> --- a/drivers/usb/chipidea/otg.c
> +++ b/drivers/usb/chipidea/otg.c
> @@ -39,12 +39,65 @@ void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
>  }
>  
>  /**
> - * ci_hdrc_otg_init - initialize otgsc bits
> + * ci_otg_role - pick role based on ID pin state
> + * @ci: the controller
> + */
> +enum ci_role ci_otg_role(struct ci_hdrc *ci)
> +{
> +	u32 sts = hw_read(ci, OP_OTGSC, ~0);
> +	enum ci_role role = sts & OTGSC_ID
> +		? CI_ROLE_GADGET
> +		: CI_ROLE_HOST;
> +
> +	return role;
> +}
> +
> +/**
> + * ci_role_work - perform role changing based on ID pin
> + * @work: work struct
> + */
> +static void ci_role_work(struct work_struct *work)
> +{
> +	struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
> +	enum ci_role role = ci_otg_role(ci);
> +
> +	if (role != ci->role) {
> +		dev_dbg(ci->dev, "switching from %s to %s\n",
> +			ci_role(ci)->name, ci->roles[role]->name);
> +
> +		ci_role_stop(ci);
> +		ci_role_start(ci, role);
> +	}
> +
> +	enable_irq(ci->irq);
> +}
> +
> +/**
> + * ci_hdrc_otg_init - initialize otg struct
>   * ci: the controller
>   */
>  int ci_hdrc_otg_init(struct ci_hdrc *ci)
>  {
> -	ci_enable_otg_interrupt(ci, OTGSC_IDIE);
> +	INIT_WORK(&ci->work, ci_role_work);
> +	ci->wq = create_singlethread_workqueue("ci_otg");
> +	if (!ci->wq) {
> +		dev_err(ci->dev, "can't create workqueue\n");
> +		return -ENODEV;
> +	}
>  
>  	return 0;
>  }
> +
> +/**
> + * ci_hdrc_otg_destroy - destory otg struct

"destroy"

> + * ci: the controller
> + */
> +void ci_hdrc_otg_destory(struct ci_hdrc *ci)

"destroy"

> +{
> +	if (ci->wq) {
> +		flush_workqueue(ci->wq);
> +		destroy_workqueue(ci->wq);
> +	}
> +	ci_disable_otg_interrupt(ci, OTGSC_INT_EN_BITS);
> +	ci_clear_otg_interrupt(ci, OTGSC_INT_STATUS_BITS);
> +}
> diff --git a/drivers/usb/chipidea/otg.h b/drivers/usb/chipidea/otg.h
> index f24ec37..8913062 100644
> --- a/drivers/usb/chipidea/otg.h
> +++ b/drivers/usb/chipidea/otg.h
> @@ -15,5 +15,7 @@ int ci_hdrc_otg_init(struct ci_hdrc *ci);
>  void ci_clear_otg_interrupt(struct ci_hdrc *ci, u32 bits);
>  void ci_enable_otg_interrupt(struct ci_hdrc *ci, u32 bits);
>  void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits);
> +void ci_hdrc_otg_destory(struct ci_hdrc *ci);

"destroy"

> +enum ci_role ci_otg_role(struct ci_hdrc *ci);
>  
>  #endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */
> -- 
> 1.7.0.4

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v14 06/12] usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG
  2013-08-09 11:13     ` Peter Chen
@ 2013-08-09 13:21       ` Alexander Shishkin
  0 siblings, 0 replies; 23+ messages in thread
From: Alexander Shishkin @ 2013-08-09 13:21 UTC (permalink / raw)
  To: linux-arm-kernel

Peter Chen <peter.chen@freescale.com> writes:

> On Fri, Aug 09, 2013 at 03:55:56PM +0300, Alexander Shishkin wrote:
>> > +		} else {
>> > +			/*
>> > +			 * If the controller is not OTG capable, but support
>> > +			 * role switch, the defalt role is gadget, and the
>> > +			 * user can switch it through debugfs (proc in future?)
>> 
>> It's not going to be in procfs ever, so that part of the comment can go.
>> 
>
> I can delete now, but the role switch does not a debug function, we
> may not put it at debugfs, do you think so?

Even if we were to put the role switch elsewhere, it wouldn't be
procfs.

If there is indeed a hardware platform that intentionally allows
software to select the role, then yes. Right now, it is a debugging
feature.

Regards,
--
Alex

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v14 11/12] usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and CI_HDRC_PULLUP_ON_VBUS
  2013-08-02  8:34 ` [PATCH v14 11/12] usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and CI_HDRC_PULLUP_ON_VBUS Peter Chen
@ 2013-08-09 13:23   ` Alexander Shishkin
  2013-08-09 11:46     ` Peter Chen
  0 siblings, 1 reply; 23+ messages in thread
From: Alexander Shishkin @ 2013-08-09 13:23 UTC (permalink / raw)
  To: linux-arm-kernel

Peter Chen <peter.chen@freescale.com> writes:

> CI_HDRC_REGS_SHARED stands for the controller registers is shared
> with other USB drivers, if all USB drivers are at chipidea/, it doesn't
> needed to set.

We still have the msm driver that uses REGS_SHARED.

> CI_HDRC_PULLUP_ON_VBUS stands for pullup dp when the vbus is on. This
> flag doesn't need to set if the vbus is always on for gadget
> since dp has always pulled up after the gadget has initialized.

Didn't we agree at some point to get rid of this flag altogether once we
have proper VBUS detection?

>
> So, the current code seems to misuse this two flags.
> - When the gadget initializes, the controller doesn't need to run if
> it depends on vbus (CI_HDRC_PULLUP_ON_VBUS), it does not
> relate to shared register.
> - When the gadget starts (load one gadget module), the controller
> can run if vbus is on (CI_HDRC_PULLUP_ON_VBUS), it also does not
> relate to shared register.
>
> Tested-by: Marek Vasut <marex@denx.de>
> Signed-off-by: Peter Chen <peter.chen@freescale.com>
> ---
>  drivers/usb/chipidea/udc.c |    5 ++---
>  1 files changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> index c70ce38..45abf4d 100644
> --- a/drivers/usb/chipidea/udc.c
> +++ b/drivers/usb/chipidea/udc.c
> @@ -1637,8 +1637,7 @@ static int ci_udc_start(struct usb_gadget *gadget,
>  	pm_runtime_get_sync(&ci->gadget.dev);
>  	if (ci->platdata->flags & CI_HDRC_PULLUP_ON_VBUS) {
>  		if (ci->vbus_active) {
> -			if (ci->platdata->flags & CI_HDRC_REGS_SHARED)
> -				hw_device_reset(ci, USBMODE_CM_DC);
> +			hw_device_reset(ci, USBMODE_CM_DC);
>  		} else {
>  			pm_runtime_put_sync(&ci->gadget.dev);
>  			goto done;
> @@ -1801,7 +1800,7 @@ static int udc_start(struct ci_hdrc *ci)
>  		}
>  	}
>  
> -	if (!(ci->platdata->flags & CI_HDRC_REGS_SHARED)) {
> +	if (!(ci->platdata->flags & CI_HDRC_PULLUP_ON_VBUS)) {
>  		retval = hw_device_reset(ci, USBMODE_CM_DC);
>  		if (retval)
>  			goto put_transceiver;
> -- 
> 1.7.0.4

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2013-08-09 13:23 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-02  8:33 [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea Peter Chen
2013-08-02  8:33 ` [PATCH v14 01/12] usb: chipidea: move vbus regulator operation to core Peter Chen
2013-08-02  8:33 ` [PATCH v14 02/12] usb: chipidea: host: add vbus regulator control Peter Chen
2013-08-02  8:33 ` [PATCH v14 03/12] usb: chipidea: udc: otg_set_peripheral is useless for some chipidea users Peter Chen
2013-08-02  8:33 ` [PATCH v14 04/12] usb: chipidea: otg: Add otg file used to access otgsc Peter Chen
2013-08-09 13:00   ` Alexander Shishkin
2013-08-09 11:18     ` Peter Chen
2013-08-02  8:33 ` [PATCH v14 05/12] usb: chipidea: Add role init and destory APIs Peter Chen
2013-08-02  8:33 ` [PATCH v14 06/12] usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG Peter Chen
2013-08-09 12:55   ` Alexander Shishkin
2013-08-09 11:13     ` Peter Chen
2013-08-09 13:21       ` Alexander Shishkin
2013-08-02  8:34 ` [PATCH v14 07/12] usb: chipidea: disable all interrupts and clear all interrupts status Peter Chen
2013-08-02  8:34 ` [PATCH v14 08/12] usb: chipidea: move otg relate things to otg file Peter Chen
2013-08-09 13:09   ` Alexander Shishkin
2013-08-02  8:34 ` [PATCH v14 09/12] usb: chipidea: add vbus interrupt handler Peter Chen
2013-08-02  8:34 ` [PATCH v14 10/12] usb: chipidea: add wait vbus lower than OTGSC_BSV before role starts Peter Chen
2013-08-02  8:34 ` [PATCH v14 11/12] usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and CI_HDRC_PULLUP_ON_VBUS Peter Chen
2013-08-09 13:23   ` Alexander Shishkin
2013-08-09 11:46     ` Peter Chen
2013-08-09 12:16       ` Peter Chen
2013-08-02  8:34 ` [PATCH v14 12/12] usb: chipidea: udc: .pullup is valid when vbus is on at CI_HDRC_PULLUP_ON_VBUS Peter Chen
2013-08-06 12:00 ` [PATCH v14 00/12] Add tested id switch and vbus connect detect support for Chipidea Peter Chen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.