[RFC/PATCH v4] usb: dwc3: Introduce OTG driver for dwc3

2012-08-06 Thread Ido Shayevitz
This is first release of otg driver for the dwc3 Synopsys USB3 core.
The otg driver implements the otg final state machine and control the
activation of the device controller or host controller.

In this first implementation, only simple DRD mode is implemented,
determine if A or B device according to the ID pin as reflected in the
OSTS.ConIDSts field.

Signed-off-by: Ido Shayevitz i...@codeaurora.org

---
 drivers/usb/dwc3/Makefile|2 +
 drivers/usb/dwc3/core.c  |   15 +-
 drivers/usb/dwc3/core.h  |   55 -
 drivers/usb/dwc3/dwc3_otg.c  |  537 ++
 drivers/usb/dwc3/dwc3_otg.h  |   59 +
 drivers/usb/dwc3/gadget.c|   63 +
 drivers/usb/host/xhci-plat.c |   21 ++
 drivers/usb/host/xhci.c  |   13 +-
 8 files changed, 755 insertions(+), 10 deletions(-)
 create mode 100644 drivers/usb/dwc3/dwc3_otg.c
 create mode 100644 drivers/usb/dwc3/dwc3_otg.h

diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index d441fe4..ffb3f55 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -1,11 +1,13 @@
 ccflags-$(CONFIG_USB_DWC3_DEBUG)   := -DDEBUG
 ccflags-$(CONFIG_USB_DWC3_VERBOSE) += -DVERBOSE_DEBUG
+ccflags-y += -Idrivers/usb/host
 
 obj-$(CONFIG_USB_DWC3) += dwc3.o
 
 dwc3-y := core.o
 dwc3-y += host.o
 dwc3-y += gadget.o ep0.o
+dwc3-y += dwc3_otg.o
 
 ifneq ($(CONFIG_DEBUG_FS),)
dwc3-y  += debugfs.o
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index c34452a..5343e39 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -517,15 +517,24 @@ static int __devinit dwc3_probe(struct platform_device 
*pdev)
break;
case DWC3_MODE_DRD:
dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
+   ret = dwc3_otg_init(dwc);
+   if (ret) {
+   dev_err(dev, failed to initialize otg\n);
+   goto err1;
+   }
+
ret = dwc3_host_init(dwc);
if (ret) {
dev_err(dev, failed to initialize host\n);
+   dwc3_otg_exit(dwc);
goto err1;
}
 
ret = dwc3_gadget_init(dwc);
if (ret) {
dev_err(dev, failed to initialize gadget\n);
+   dwc3_host_exit(dwc);
+   dwc3_otg_exit(dwc);
goto err1;
}
break;
@@ -554,8 +563,9 @@ err2:
dwc3_host_exit(dwc);
break;
case DWC3_MODE_DRD:
-   dwc3_host_exit(dwc);
dwc3_gadget_exit(dwc);
+   dwc3_host_exit(dwc);
+   dwc3_otg_exit(dwc);
break;
default:
/* do nothing */
@@ -588,8 +598,9 @@ static int __devexit dwc3_remove(struct platform_device 
*pdev)
dwc3_host_exit(dwc);
break;
case DWC3_MODE_DRD:
-   dwc3_host_exit(dwc);
dwc3_gadget_exit(dwc);
+   dwc3_host_exit(dwc);
+   dwc3_otg_exit(dwc);
break;
default:
/* do nothing */
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index c611d80..c2521ba 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -50,6 +50,8 @@
 #include linux/usb/ch9.h
 #include linux/usb/gadget.h
 
+#include dwc3_otg.h
+
 /* Global constants */
 #define DWC3_EP0_BOUNCE_SIZE   512
 #define DWC3_ENDPOINTS_NUM 32
@@ -152,8 +154,9 @@
 /* OTG Registers */
 #define DWC3_OCFG  0xcc00
 #define DWC3_OCTL  0xcc04
-#define DWC3_OEVTEN0xcc08
-#define DWC3_OSTS  0xcc0C
+#define DWC3_OEVT  0xcc08
+#define DWC3_OEVTEN0xcc0c
+#define DWC3_OSTS  0xcc10
 
 /* Bit fields */
 
@@ -203,6 +206,9 @@
 #define DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(n)   (((n)  (0x0f  13))  13)
 #define DWC3_MAX_HIBER_SCRATCHBUFS 15
 
+/* Global HWPARAMS6 Register */
+#define DWC3_GHWPARAMS6_SRP_SUPPORT(1  10)
+
 /* Device Configuration Register */
 #define DWC3_DCFG_LPM_CAP  (1  22)
 #define DWC3_DCFG_DEVADDR(addr)((addr)  3)
@@ -358,6 +364,38 @@
 #define DWC3_DEPCMD_TYPE_BULK  2
 #define DWC3_DEPCMD_TYPE_INTR  3
 
+/* OTG Events Register */
+#define DWC3_OEVT_DEVICEMODE   (1  31)
+#define DWC3_OEVT_CLEAR_ALL(~DWC3_OEVT_DEVICEMODE)
+#define DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT(1  24)
+#define DWC3_OEVTEN_OTGADEVBHOSTENDEVNT(1  20)
+#define DWC3_OEVTEN_OTGADEVHOSTEVNT(1  19)
+#define DWC3_OEVTEN_OTGADEVHNPCHNGEVNT (1  18)
+#define DWC3_OEVTEN_OTGADEVSRPDETEVNT

RE: [RFC/PATCH v3] usb: dwc3: Introduce OTG driver for dwc3

2012-08-01 Thread Ido Shayevitz

Hi Paul,

On Mon, July 30, 2012 12:00 pm, Paul Zimmerman wrote:
 From: Ido Shayevitz [mailto:i...@codeaurora.org]
 Sent: Monday, July 30, 2012 3:15 AM

 On Thu, July 26, 2012 4:38 pm, Paul Zimmerman wrote:
  From: linux-usb-ow...@vger.kernel.org
  [mailto:linux-usb-ow...@vger.kernel.org] On Behalf Of Ido Shayevitz
  Sent: Wednesday, July 25, 2012 5:46 AM
  ---
   drivers/usb/dwc3/Kconfig |6 +-
   drivers/usb/dwc3/Makefile|2 +
   drivers/usb/dwc3/core.c  |   15 +-
   drivers/usb/dwc3/core.h  |   54 +-
   drivers/usb/dwc3/dwc3_otg.c  |  512
  ++
   drivers/usb/dwc3/dwc3_otg.h  |   38 +++
   drivers/usb/dwc3/gadget.c|   63 +
   drivers/usb/host/xhci-plat.c |   21 ++
   drivers/usb/host/xhci.c  |   13 +-
   9 files changed, 711 insertions(+), 13 deletions(-)
   create mode 100644 drivers/usb/dwc3/dwc3_otg.c
   create mode 100644 drivers/usb/dwc3/dwc3_otg.h
 
  diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
  index d13c60f..0cc108d 100644
  --- a/drivers/usb/dwc3/Kconfig
  +++ b/drivers/usb/dwc3/Kconfig
  @@ -1,9 +1,9 @@
   config USB_DWC3
tristate DesignWare USB3 DRD Core Support
  - depends on (USB  USB_GADGET)
  + depends on (USB || USB_GADGET)
 
  Are you sure this is correct? How can a dual-role device work unless
 both
  USB and USB_GADGET are set?

 If the USB_DWC3 is not selected then even dwc3/core.c is not being built
 and core.c supports also non DRD cores (depends on DWC3_MODE), so we
 want
 to build the DWC3 if there is at least host support or a gadget support.
 In case that the DWC_MODE is DRD but USB is not on, then dwc3/host.c
 will
 add the xHCI device, but will be no xHCI driver (xhci-plat) that will
 probe on this device.

 I just tried compiling this without USB_GADGET defined, and I get
 these errors:

   HOSTCC  arch/x86/boot/compressed/mkpiggy
 ERROR: usb_gadget_map_request [drivers/usb/dwc3/dwc3.ko] undefined!
 ERROR: usb_del_gadget_udc [drivers/usb/dwc3/dwc3.ko] undefined!
 ERROR: usb_gadget_unmap_request [drivers/usb/dwc3/dwc3.ko] undefined!
 ERROR: usb_add_gadget_udc [drivers/usb/dwc3/dwc3.ko] undefined!


Yes, you are totally right.
So we have two options: The first is, if you agree with my reasoning:
and core.c supports also non DRD cores (depends on DWC3_MODE), so we want
to build the DWC3 if there is at least host support or a gadget support.
Then we may want to build gadget.c and ep0.c only if USB_GADGET is
selected and this requires also changes in core.c or core.h (providing
empty prototype for dwc3_gadget_init() ?)

The second option is indeed to keep it as it is, means USB  USB_GADGET.
It means that kernel image size will have to include xHCI driver and dwc3
gadget driver, nevertheless if the controller is DRD or not.
Basically I am ok with that too.

Please let me know what you and Felipe decide...

  diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
  index c34452a..5343e39 100644
  --- a/drivers/usb/dwc3/core.c
  +++ b/drivers/usb/dwc3/core.c
  @@ -517,15 +517,24 @@ static int __devinit dwc3_probe(struct
  platform_device *pdev)
break;
case DWC3_MODE_DRD:
dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
  + ret = dwc3_otg_init(dwc);
  + if (ret) {
  + dev_err(dev, failed to initialize otg\n);
  + goto err1;
  + }
  +
 
  You should follow the existing pattern for error handling in this
  function. If there is an error, jump to the error exit, and put your
  exit function there, instead of here.

 I think I followed the pattern for error handling in this function.
 Please see that it is the same as case DWC3_MODE_HOST or case
 DWC3_MODE_DEVICE

ret = dwc3_host_init(dwc);
if (ret) {
dev_err(dev, failed to initialize host\n);
  + dwc3_otg_exit(dwc);
 
  Same here.

 Here I was thinking of moving dwc3_otg_exit() to the error handling
 section, but I think it will make the error handling section too clumsy
 since eventhough the mode is DWC3_MODE_DRD, in this point I want to exit
 only the otg and not the host or gadget. So this should have a new error
 label that will be located between err1 and err2. On the other hand if
 the
 error will happen later, as the goto err2 statement below in this
 function, then if the mode is DRD I will want to activate the exit
 function of also the host and gadget but not doing the otg exit again
 (the
 new label) and then do err1... So it becomes clumsy.

 Yes, I see now that the error handling for DRD in that function was
 broken before your patch, and your patch fixes it. So it's up to
 Felipe to decide if the way you did it is acceptable.

 --
 Paul

 --
 To unsubscribe from this list: send the line unsubscribe linux-usb in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html


Ido
-- 
Consultant for Qualcomm Innovation

RE: [RFC/PATCH v3] usb: dwc3: Introduce OTG driver for dwc3

2012-08-01 Thread Ido Shayevitz

Hi Anton,

On Tue, July 31, 2012 11:27 pm, Anton Tikhomirov wrote:
 Hi Ido,

 -Original Message-
 From: linux-usb-ow...@vger.kernel.org [mailto:linux-usb-
 ow...@vger.kernel.org] On Behalf Of Ido Shayevitz
 Sent: Monday, July 30, 2012 10:16 PM
 To: Anton Tikhomirov
 Cc: 'Ido Shayevitz'; 'Felipe Balbi'; linux-usb@vger.kernel.org
 Subject: RE: [RFC/PATCH v3] usb: dwc3: Introduce OTG driver for dwc3

 Hi Anton,

 On Mon, July 30, 2012 5:25 am, Anton Tikhomirov wrote:
  Hi Ido,
 
  
   You activate sm only if gadget and host are ready. At the same
 time,
   in dwc3_otg_interrupt() you schedule work if interrupt happens. In
   situation
   when host is not set yet, but cable is plugged, we will have
 unwanted
  sm
   activation
   (in interrupt handler) and, as a consequence, repeating error
 unable
  to
   start A-device\n
   in dwc3_otg_sm_work().
 
  Host and gadget should set themselves to the otg on drivers probe, in
  boot
  time. So cable connect happens later.
  If the scenario you describe does happen it means that the xHCI
 driver
  was
  not loaded into the kernel, but cable with micro-A was plugged into
 your
  device, so need add host support to the menuconfig.
  It should be enough to select in the menuconfig CONFIG_USB and
  CONFIG_USB_XHCI_HCD.
 
  Agree. But what if my controller supports DRD mode, but I _want_ to
 keep
  this
  option (XHCI support) off, for any reason. By the way, it seems we
 will
  have
  similar effect when micro-A cable is plugged after
 otg_set_host(phy-otg,
  NULL)
  call. Of course such situations are rare.
 

 OK, so I will avoid the re-schedule of the sm_work after this error will
 be printed (so will be printed once...)
 Thanks...

 One more thing. Currently the work is first time scheduled in two cases:
 when
 interrupt happens or both, peripheral and host, were set. If host is not
 set
 (and probably won't be) the work will _not_ be scheduled (and peripheral
 will
 not start) till we connect and then disconnect micro-A cable. In other
 words:
 we should be able to use peripheral even if host is not supported (and
 vice
 versa?). What's your opinion?

The idea behind schedule the work after both are set, is that we don't
want a case that we scheduled the work after only the gadget was set but
the ID pin is zero. In this case we will get wasted run of work state
machine.
If host is not set, we will start the peripheral on cable connect, as you
said, and if ID pin is 1. When we start the peripheral we actually just
turn on the run stop bit, while the dwc3 gadget driver was already up and
allocated its needed memory, so there shouldn't be problem to wait until
cable connect...


  But if your controller DWC_MODE (see core.c) does not support DRD, or
  the
  cable plugged in is micro-B then this error should not be printed
  eventhough the host was not set.
 
+   } else {
+   if (otg-phy-state == OTG_STATE_A_HOST) {
+   dwc3_otg_start_host(otg, 0);
+   otg-host = NULL;
+   otg-phy-state = OTG_STATE_UNDEFINED;
+   schedule_work(dotg-sm_work);
+   } else {
+   otg-host = NULL;
+   }
+   }
+
+   return 0;
+}
+
+/**
+ * dwc3_otg_start_peripheral -  bind/unbind the peripheral
   controller.
+ *
+ * @otg: Pointer to the otg_transceiver structure.
+ * @gadget: pointer to the usb_gadget structure.
   
This comment doesn't match the function definition (@on, not
  @gadget).
   
+ *
+ * Returns 0 on success otherwise negative errno.
+ */
+static int dwc3_otg_start_peripheral(struct usb_otg *otg, int
 on)
+{
+   struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg,
  otg);
+
+   if (!otg-gadget)
+   return -EINVAL;
+
+   if (on) {
+   dev_dbg(otg-phy-dev, %s: turn on gadget %s\n,
+   __func__,
  otg-gadget-name);
+   dwc3_otg_set_peripheral_regs(dotg);
+   usb_gadget_vbus_connect(otg-gadget);
+   } else {
+   dev_dbg(otg-phy-dev, %s: turn off gadget %s\n,
+   __func__,
  otg-gadget-name);
+   usb_gadget_vbus_disconnect(otg-gadget);
+   }
+
+   return 0;
+}
+
+/**
+ * dwc3_otg_set_peripheral -  bind/unbind the peripheral
  controller
driver.
+ *
+ * @otg: Pointer to the otg_transceiver structure.
+ * @gadget: pointer to the usb_gadget structure.
+ *
+ * Returns 0 on success otherwise negative errno.
+ */
+static int dwc3_otg_set_peripheral(struct usb_otg *otg,
+   struct usb_gadget *gadget)
+{
+   struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg,
  otg);
+
+   if (gadget) {
+   dev_dbg(otg-phy-dev, %s: set gadget %s\n,
+   __func__, gadget

RE: [RFC/PATCH v3] usb: dwc3: Introduce OTG driver for dwc3

2012-07-30 Thread Ido Shayevitz
Hi Anton,

On Mon, July 30, 2012 5:25 am, Anton Tikhomirov wrote:
 Hi Ido,

 
  You activate sm only if gadget and host are ready. At the same time,
  in dwc3_otg_interrupt() you schedule work if interrupt happens. In
  situation
  when host is not set yet, but cable is plugged, we will have unwanted
 sm
  activation
  (in interrupt handler) and, as a consequence, repeating error unable
 to
  start A-device\n
  in dwc3_otg_sm_work().

 Host and gadget should set themselves to the otg on drivers probe, in
 boot
 time. So cable connect happens later.
 If the scenario you describe does happen it means that the xHCI driver
 was
 not loaded into the kernel, but cable with micro-A was plugged into your
 device, so need add host support to the menuconfig.
 It should be enough to select in the menuconfig CONFIG_USB and
 CONFIG_USB_XHCI_HCD.

 Agree. But what if my controller supports DRD mode, but I _want_ to keep
 this
 option (XHCI support) off, for any reason. By the way, it seems we will
 have
 similar effect when micro-A cable is plugged after otg_set_host(phy-otg,
 NULL)
 call. Of course such situations are rare.


OK, so I will avoid the re-schedule of the sm_work after this error will
be printed (so will be printed once...)
Thanks...

 But if your controller DWC_MODE (see core.c) does not support DRD, or
 the
 cable plugged in is micro-B then this error should not be printed
 eventhough the host was not set.

   +  } else {
   +  if (otg-phy-state == OTG_STATE_A_HOST) {
   +  dwc3_otg_start_host(otg, 0);
   +  otg-host = NULL;
   +  otg-phy-state = OTG_STATE_UNDEFINED;
   +  schedule_work(dotg-sm_work);
   +  } else {
   +  otg-host = NULL;
   +  }
   +  }
   +
   +  return 0;
   +}
   +
   +/**
   + * dwc3_otg_start_peripheral -  bind/unbind the peripheral
  controller.
   + *
   + * @otg: Pointer to the otg_transceiver structure.
   + * @gadget: pointer to the usb_gadget structure.
  
   This comment doesn't match the function definition (@on, not
 @gadget).
  
   + *
   + * Returns 0 on success otherwise negative errno.
   + */
   +static int dwc3_otg_start_peripheral(struct usb_otg *otg, int on)
   +{
   +  struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg,
 otg);
   +
   +  if (!otg-gadget)
   +  return -EINVAL;
   +
   +  if (on) {
   +  dev_dbg(otg-phy-dev, %s: turn on gadget %s\n,
   +  __func__,
 otg-gadget-name);
   +  dwc3_otg_set_peripheral_regs(dotg);
   +  usb_gadget_vbus_connect(otg-gadget);
   +  } else {
   +  dev_dbg(otg-phy-dev, %s: turn off gadget %s\n,
   +  __func__,
 otg-gadget-name);
   +  usb_gadget_vbus_disconnect(otg-gadget);
   +  }
   +
   +  return 0;
   +}
   +
   +/**
   + * dwc3_otg_set_peripheral -  bind/unbind the peripheral
 controller
   driver.
   + *
   + * @otg: Pointer to the otg_transceiver structure.
   + * @gadget: pointer to the usb_gadget structure.
   + *
   + * Returns 0 on success otherwise negative errno.
   + */
   +static int dwc3_otg_set_peripheral(struct usb_otg *otg,
   +  struct usb_gadget *gadget)
   +{
   +  struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg,
 otg);
   +
   +  if (gadget) {
   +  dev_dbg(otg-phy-dev, %s: set gadget %s\n,
   +  __func__, gadget-name);
   +  otg-gadget = gadget;
   +
   +  /*
   +   * Only after both peripheral and host are set then
 check
   +   * OTG sm. This prevents unnecessary activation of
 the
 sm
   +   * in case the ID is grounded.
   +   */
   +  if (otg-host)
   +  schedule_work(dotg-sm_work);
   +  } else {
   +  if (otg-phy-state == OTG_STATE_B_PERIPHERAL) {
   +  dwc3_otg_start_peripheral(otg, 0);
   +  otg-gadget = NULL;
   +  otg-phy-state = OTG_STATE_UNDEFINED;
   +  schedule_work(dotg-sm_work);
   +  } else {
   +  otg-gadget = NULL;
   +  }
   +  }
   +
   +  return 0;
   +}
   +
   +/**
   + * dwc3_otg_interrupt - interrupt handler for dwc3 otg events.
  
   You forgot about @irq here.
  
   + * @_dotg: Pointer to out controller context structure
   + *
   + * Returns IRQ_HANDLED on success otherwise IRQ_NONE.
   + */
   +static irqreturn_t dwc3_otg_interrupt(int irq, void *_dotg)
   +{
   +  struct dwc3_otg *dotg = (struct dwc3_otg *)_dotg;
   +  u32 oevt_reg;
   +  int ret = IRQ_NONE;
   +  u32 handled_irqs = 0;
   +
   +  oevt_reg = dwc3_readl(dotg-regs, DWC3_OEVT);
   +
   +  if (oevt_reg  

RE: [RFC/PATCH v2] usb: dwc3: Introduce OTG driver for dwc3

2012-07-25 Thread Ido Shayevitz

Hi Anton,

On Tue, July 17, 2012 9:27 pm, Anton Tikhomirov wrote:
 Hi,

 -Original Message-
 From: linux-usb-ow...@vger.kernel.org [mailto:linux-usb-
 ow...@vger.kernel.org] On Behalf Of Ido Shayevitz
 Sent: Thursday, July 12, 2012 1:24 AM
 To: ba...@ti.com
 Cc: linux-usb@vger.kernel.org; i...@codeaurora.org
 Subject: [RFC/PATCH v2] usb: dwc3: Introduce OTG driver for dwc3

 This is first release of otg driver for the dwc3 Synopsys USB3 core.
 The otg driver implements the otg final state machine and control the
 activation of the device controller or host controller.

 In this first implementation, only simple DRD mode is implemented,
 determine if A or B device according to the ID pin as reflected in the
 OSTS.ConIDSts field.

 Signed-off-by: Ido Shayevitz i...@codeaurora.org

 ---
  drivers/usb/dwc3/Kconfig |6 +-
  drivers/usb/dwc3/Makefile|2 +
  drivers/usb/dwc3/core.c  |   15 +-
  drivers/usb/dwc3/core.h  |   51 -
  drivers/usb/dwc3/dwc3_otg.c  |  512
 ++
  drivers/usb/dwc3/dwc3_otg.h  |   38 +++
  drivers/usb/dwc3/gadget.c|   63 +
  drivers/usb/host/xhci-plat.c |   21 ++
  drivers/usb/host/xhci.c  |   13 +-
  9 files changed, 708 insertions(+), 13 deletions(-)
  create mode 100644 drivers/usb/dwc3/dwc3_otg.c
  create mode 100644 drivers/usb/dwc3/dwc3_otg.h

 diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
 index d13c60f..0cc108d 100644
 --- a/drivers/usb/dwc3/Kconfig
 +++ b/drivers/usb/dwc3/Kconfig
 @@ -1,9 +1,9 @@
  config USB_DWC3
  tristate DesignWare USB3 DRD Core Support
 -depends on (USB  USB_GADGET)
 +depends on (USB || USB_GADGET)
  select USB_OTG_UTILS
 -select USB_GADGET_DUALSPEED
 -select USB_GADGET_SUPERSPEED
 +select USB_GADGET_DUALSPEED if USB_GADGET
 +select USB_GADGET_SUPERSPEED if USB_GADGET
  select USB_XHCI_PLATFORM if USB_SUPPORT  USB_XHCI_HCD
  help
Say Y or M here if your system has a Dual Role SuperSpeed
 diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
 index d441fe4..ffb3f55 100644
 --- a/drivers/usb/dwc3/Makefile
 +++ b/drivers/usb/dwc3/Makefile
 @@ -1,11 +1,13 @@
  ccflags-$(CONFIG_USB_DWC3_DEBUG):= -DDEBUG
  ccflags-$(CONFIG_USB_DWC3_VERBOSE)  += -DVERBOSE_DEBUG
 +ccflags-y += -Idrivers/usb/host

  obj-$(CONFIG_USB_DWC3)  += dwc3.o

  dwc3-y  := core.o
  dwc3-y  += host.o
  dwc3-y  += gadget.o ep0.o
 +dwc3-y  += dwc3_otg.o

  ifneq ($(CONFIG_DEBUG_FS),)
  dwc3-y  += debugfs.o
 diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
 index c34452a..5343e39 100644
 --- a/drivers/usb/dwc3/core.c
 +++ b/drivers/usb/dwc3/core.c
 @@ -517,15 +517,24 @@ static int __devinit dwc3_probe(struct
 platform_device *pdev)
  break;
  case DWC3_MODE_DRD:
  dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
 +ret = dwc3_otg_init(dwc);
 +if (ret) {
 +dev_err(dev, failed to initialize otg\n);
 +goto err1;
 +}
 +
  ret = dwc3_host_init(dwc);
  if (ret) {
  dev_err(dev, failed to initialize host\n);
 +dwc3_otg_exit(dwc);
  goto err1;
  }

  ret = dwc3_gadget_init(dwc);
  if (ret) {
  dev_err(dev, failed to initialize gadget\n);
 +dwc3_host_exit(dwc);
 +dwc3_otg_exit(dwc);
  goto err1;
  }
  break;
 @@ -554,8 +563,9 @@ err2:
  dwc3_host_exit(dwc);
  break;
  case DWC3_MODE_DRD:
 -dwc3_host_exit(dwc);
  dwc3_gadget_exit(dwc);
 +dwc3_host_exit(dwc);
 +dwc3_otg_exit(dwc);
  break;
  default:
  /* do nothing */
 @@ -588,8 +598,9 @@ static int __devexit dwc3_remove(struct
 platform_device *pdev)
  dwc3_host_exit(dwc);
  break;
  case DWC3_MODE_DRD:
 -dwc3_host_exit(dwc);
  dwc3_gadget_exit(dwc);
 +dwc3_host_exit(dwc);
 +dwc3_otg_exit(dwc);
  break;
  default:
  /* do nothing */
 diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
 index 151eca8..793758b 100644
 --- a/drivers/usb/dwc3/core.h
 +++ b/drivers/usb/dwc3/core.h
 @@ -50,6 +50,8 @@
  #include linux/usb/ch9.h
  #include linux/usb/gadget.h

 +#include dwc3_otg.h
 +
  /* Global constants */
  #define DWC3_EP0_BOUNCE_SIZE512
  #define DWC3_ENDPOINTS_NUM  32
 @@ -152,8 +154,9 @@
  /* OTG Registers */
  #define DWC3_OCFG   0xcc00
  #define DWC3_OCTL   0xcc04
 -#define DWC3_OEVTEN 0xcc08
 -#define DWC3_OSTS

[RFC/PATCH v3] usb: dwc3: Introduce OTG driver for dwc3

2012-07-25 Thread Ido Shayevitz
This is first release of otg driver for the dwc3 Synopsys USB3 core.
The otg driver implements the otg final state machine and control the
activation of the device controller or host controller.

In this first implementation, only simple DRD mode is implemented,
determine if A or B device according to the ID pin as reflected in the
OSTS.ConIDSts field.

Signed-off-by: Ido Shayevitz i...@codeaurora.org

---
 drivers/usb/dwc3/Kconfig |6 +-
 drivers/usb/dwc3/Makefile|2 +
 drivers/usb/dwc3/core.c  |   15 +-
 drivers/usb/dwc3/core.h  |   54 +-
 drivers/usb/dwc3/dwc3_otg.c  |  512 ++
 drivers/usb/dwc3/dwc3_otg.h  |   38 +++
 drivers/usb/dwc3/gadget.c|   63 +
 drivers/usb/host/xhci-plat.c |   21 ++
 drivers/usb/host/xhci.c  |   13 +-
 9 files changed, 711 insertions(+), 13 deletions(-)
 create mode 100644 drivers/usb/dwc3/dwc3_otg.c
 create mode 100644 drivers/usb/dwc3/dwc3_otg.h

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index d13c60f..0cc108d 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -1,9 +1,9 @@
 config USB_DWC3
tristate DesignWare USB3 DRD Core Support
-   depends on (USB  USB_GADGET)
+   depends on (USB || USB_GADGET)
select USB_OTG_UTILS
-   select USB_GADGET_DUALSPEED
-   select USB_GADGET_SUPERSPEED
+   select USB_GADGET_DUALSPEED if USB_GADGET
+   select USB_GADGET_SUPERSPEED if USB_GADGET
select USB_XHCI_PLATFORM if USB_SUPPORT  USB_XHCI_HCD
help
  Say Y or M here if your system has a Dual Role SuperSpeed
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index d441fe4..ffb3f55 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -1,11 +1,13 @@
 ccflags-$(CONFIG_USB_DWC3_DEBUG)   := -DDEBUG
 ccflags-$(CONFIG_USB_DWC3_VERBOSE) += -DVERBOSE_DEBUG
+ccflags-y += -Idrivers/usb/host
 
 obj-$(CONFIG_USB_DWC3) += dwc3.o
 
 dwc3-y := core.o
 dwc3-y += host.o
 dwc3-y += gadget.o ep0.o
+dwc3-y += dwc3_otg.o
 
 ifneq ($(CONFIG_DEBUG_FS),)
dwc3-y  += debugfs.o
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index c34452a..5343e39 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -517,15 +517,24 @@ static int __devinit dwc3_probe(struct platform_device 
*pdev)
break;
case DWC3_MODE_DRD:
dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
+   ret = dwc3_otg_init(dwc);
+   if (ret) {
+   dev_err(dev, failed to initialize otg\n);
+   goto err1;
+   }
+
ret = dwc3_host_init(dwc);
if (ret) {
dev_err(dev, failed to initialize host\n);
+   dwc3_otg_exit(dwc);
goto err1;
}
 
ret = dwc3_gadget_init(dwc);
if (ret) {
dev_err(dev, failed to initialize gadget\n);
+   dwc3_host_exit(dwc);
+   dwc3_otg_exit(dwc);
goto err1;
}
break;
@@ -554,8 +563,9 @@ err2:
dwc3_host_exit(dwc);
break;
case DWC3_MODE_DRD:
-   dwc3_host_exit(dwc);
dwc3_gadget_exit(dwc);
+   dwc3_host_exit(dwc);
+   dwc3_otg_exit(dwc);
break;
default:
/* do nothing */
@@ -588,8 +598,9 @@ static int __devexit dwc3_remove(struct platform_device 
*pdev)
dwc3_host_exit(dwc);
break;
case DWC3_MODE_DRD:
-   dwc3_host_exit(dwc);
dwc3_gadget_exit(dwc);
+   dwc3_host_exit(dwc);
+   dwc3_otg_exit(dwc);
break;
default:
/* do nothing */
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index c611d80..29a03e0 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -50,6 +50,8 @@
 #include linux/usb/ch9.h
 #include linux/usb/gadget.h
 
+#include dwc3_otg.h
+
 /* Global constants */
 #define DWC3_EP0_BOUNCE_SIZE   512
 #define DWC3_ENDPOINTS_NUM 32
@@ -152,8 +154,9 @@
 /* OTG Registers */
 #define DWC3_OCFG  0xcc00
 #define DWC3_OCTL  0xcc04
-#define DWC3_OEVTEN0xcc08
-#define DWC3_OSTS  0xcc0C
+#define DWC3_OEVT  0xcc08
+#define DWC3_OEVTEN0xcc0c
+#define DWC3_OSTS  0xcc10
 
 /* Bit fields */
 
@@ -203,6 +206,9 @@
 #define DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(n)   (((n)  (0x0f  13))  13)
 #define DWC3_MAX_HIBER_SCRATCHBUFS 15
 
+/* Global HWPARAMS6 Register */
+#define

[RFC/PATCH] usb: dwc3: Introduce OTG driver for dwc3

2012-07-11 Thread Ido Shayevitz
This is first release of otg driver for the dwc3 Synopsys USB3 core.
The otg driver implements the otg final state machine and control the
activation of the device controller or host controller.

In this first implementation, only simple DRD mode is implemented,
determine if A or B device according to the ID pin as reflected in the
OSTS.ConIDSts field.

Signed-off-by: Ido Shayevitz i...@codeaurora.org

---
 drivers/usb/dwc3/Kconfig |6 +-
 drivers/usb/dwc3/Makefile|2 +
 drivers/usb/dwc3/core.c  |   15 +-
 drivers/usb/dwc3/core.h  |   51 -
 drivers/usb/dwc3/dwc3_otg.c  |  512 ++
 drivers/usb/dwc3/dwc3_otg.h  |   38 +++
 drivers/usb/dwc3/gadget.c|   63 +
 drivers/usb/host/xhci-plat.c |   21 ++
 drivers/usb/host/xhci.c  |   13 +-
 9 files changed, 708 insertions(+), 13 deletions(-)
 create mode 100644 drivers/usb/dwc3/dwc3_otg.c
 create mode 100644 drivers/usb/dwc3/dwc3_otg.h

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index d13c60f..0cc108d 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -1,9 +1,9 @@
 config USB_DWC3
tristate DesignWare USB3 DRD Core Support
-   depends on (USB  USB_GADGET)
+   depends on (USB || USB_GADGET)
select USB_OTG_UTILS
-   select USB_GADGET_DUALSPEED
-   select USB_GADGET_SUPERSPEED
+   select USB_GADGET_DUALSPEED if USB_GADGET
+   select USB_GADGET_SUPERSPEED if USB_GADGET
select USB_XHCI_PLATFORM if USB_SUPPORT  USB_XHCI_HCD
help
  Say Y or M here if your system has a Dual Role SuperSpeed
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index d441fe4..ffb3f55 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -1,11 +1,13 @@
 ccflags-$(CONFIG_USB_DWC3_DEBUG)   := -DDEBUG
 ccflags-$(CONFIG_USB_DWC3_VERBOSE) += -DVERBOSE_DEBUG
+ccflags-y += -Idrivers/usb/host
 
 obj-$(CONFIG_USB_DWC3) += dwc3.o
 
 dwc3-y := core.o
 dwc3-y += host.o
 dwc3-y += gadget.o ep0.o
+dwc3-y += dwc3_otg.o
 
 ifneq ($(CONFIG_DEBUG_FS),)
dwc3-y  += debugfs.o
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index c34452a..5343e39 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -517,15 +517,24 @@ static int __devinit dwc3_probe(struct platform_device 
*pdev)
break;
case DWC3_MODE_DRD:
dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
+   ret = dwc3_otg_init(dwc);
+   if (ret) {
+   dev_err(dev, failed to initialize otg\n);
+   goto err1;
+   }
+
ret = dwc3_host_init(dwc);
if (ret) {
dev_err(dev, failed to initialize host\n);
+   dwc3_otg_exit(dwc);
goto err1;
}
 
ret = dwc3_gadget_init(dwc);
if (ret) {
dev_err(dev, failed to initialize gadget\n);
+   dwc3_host_exit(dwc);
+   dwc3_otg_exit(dwc);
goto err1;
}
break;
@@ -554,8 +563,9 @@ err2:
dwc3_host_exit(dwc);
break;
case DWC3_MODE_DRD:
-   dwc3_host_exit(dwc);
dwc3_gadget_exit(dwc);
+   dwc3_host_exit(dwc);
+   dwc3_otg_exit(dwc);
break;
default:
/* do nothing */
@@ -588,8 +598,9 @@ static int __devexit dwc3_remove(struct platform_device 
*pdev)
dwc3_host_exit(dwc);
break;
case DWC3_MODE_DRD:
-   dwc3_host_exit(dwc);
dwc3_gadget_exit(dwc);
+   dwc3_host_exit(dwc);
+   dwc3_otg_exit(dwc);
break;
default:
/* do nothing */
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 151eca8..793758b 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -50,6 +50,8 @@
 #include linux/usb/ch9.h
 #include linux/usb/gadget.h
 
+#include dwc3_otg.h
+
 /* Global constants */
 #define DWC3_EP0_BOUNCE_SIZE   512
 #define DWC3_ENDPOINTS_NUM 32
@@ -152,8 +154,9 @@
 /* OTG Registers */
 #define DWC3_OCFG  0xcc00
 #define DWC3_OCTL  0xcc04
-#define DWC3_OEVTEN0xcc08
-#define DWC3_OSTS  0xcc0C
+#define DWC3_OEVT  0xcc08
+#define DWC3_OEVTEN0xcc0c
+#define DWC3_OSTS  0xcc10
 
 /* Bit fields */
 
@@ -203,6 +206,9 @@
 #define DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(n)   (((n)  (0x0f  13))  13)
 #define DWC3_MAX_HIBER_SCRATCHBUFS 15
 
+/* Global HWPARAMS6 Register */
+#define

[RFC/PATCH v2] usb: dwc3: Introduce OTG driver for dwc3

2012-07-11 Thread Ido Shayevitz
This is first release of otg driver for the dwc3 Synopsys USB3 core.
The otg driver implements the otg final state machine and control the
activation of the device controller or host controller.

In this first implementation, only simple DRD mode is implemented,
determine if A or B device according to the ID pin as reflected in the
OSTS.ConIDSts field.

Signed-off-by: Ido Shayevitz i...@codeaurora.org

---
 drivers/usb/dwc3/Kconfig |6 +-
 drivers/usb/dwc3/Makefile|2 +
 drivers/usb/dwc3/core.c  |   15 +-
 drivers/usb/dwc3/core.h  |   51 -
 drivers/usb/dwc3/dwc3_otg.c  |  512 ++
 drivers/usb/dwc3/dwc3_otg.h  |   38 +++
 drivers/usb/dwc3/gadget.c|   63 +
 drivers/usb/host/xhci-plat.c |   21 ++
 drivers/usb/host/xhci.c  |   13 +-
 9 files changed, 708 insertions(+), 13 deletions(-)
 create mode 100644 drivers/usb/dwc3/dwc3_otg.c
 create mode 100644 drivers/usb/dwc3/dwc3_otg.h

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index d13c60f..0cc108d 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -1,9 +1,9 @@
 config USB_DWC3
tristate DesignWare USB3 DRD Core Support
-   depends on (USB  USB_GADGET)
+   depends on (USB || USB_GADGET)
select USB_OTG_UTILS
-   select USB_GADGET_DUALSPEED
-   select USB_GADGET_SUPERSPEED
+   select USB_GADGET_DUALSPEED if USB_GADGET
+   select USB_GADGET_SUPERSPEED if USB_GADGET
select USB_XHCI_PLATFORM if USB_SUPPORT  USB_XHCI_HCD
help
  Say Y or M here if your system has a Dual Role SuperSpeed
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index d441fe4..ffb3f55 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -1,11 +1,13 @@
 ccflags-$(CONFIG_USB_DWC3_DEBUG)   := -DDEBUG
 ccflags-$(CONFIG_USB_DWC3_VERBOSE) += -DVERBOSE_DEBUG
+ccflags-y += -Idrivers/usb/host
 
 obj-$(CONFIG_USB_DWC3) += dwc3.o
 
 dwc3-y := core.o
 dwc3-y += host.o
 dwc3-y += gadget.o ep0.o
+dwc3-y += dwc3_otg.o
 
 ifneq ($(CONFIG_DEBUG_FS),)
dwc3-y  += debugfs.o
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index c34452a..5343e39 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -517,15 +517,24 @@ static int __devinit dwc3_probe(struct platform_device 
*pdev)
break;
case DWC3_MODE_DRD:
dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
+   ret = dwc3_otg_init(dwc);
+   if (ret) {
+   dev_err(dev, failed to initialize otg\n);
+   goto err1;
+   }
+
ret = dwc3_host_init(dwc);
if (ret) {
dev_err(dev, failed to initialize host\n);
+   dwc3_otg_exit(dwc);
goto err1;
}
 
ret = dwc3_gadget_init(dwc);
if (ret) {
dev_err(dev, failed to initialize gadget\n);
+   dwc3_host_exit(dwc);
+   dwc3_otg_exit(dwc);
goto err1;
}
break;
@@ -554,8 +563,9 @@ err2:
dwc3_host_exit(dwc);
break;
case DWC3_MODE_DRD:
-   dwc3_host_exit(dwc);
dwc3_gadget_exit(dwc);
+   dwc3_host_exit(dwc);
+   dwc3_otg_exit(dwc);
break;
default:
/* do nothing */
@@ -588,8 +598,9 @@ static int __devexit dwc3_remove(struct platform_device 
*pdev)
dwc3_host_exit(dwc);
break;
case DWC3_MODE_DRD:
-   dwc3_host_exit(dwc);
dwc3_gadget_exit(dwc);
+   dwc3_host_exit(dwc);
+   dwc3_otg_exit(dwc);
break;
default:
/* do nothing */
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 151eca8..793758b 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -50,6 +50,8 @@
 #include linux/usb/ch9.h
 #include linux/usb/gadget.h
 
+#include dwc3_otg.h
+
 /* Global constants */
 #define DWC3_EP0_BOUNCE_SIZE   512
 #define DWC3_ENDPOINTS_NUM 32
@@ -152,8 +154,9 @@
 /* OTG Registers */
 #define DWC3_OCFG  0xcc00
 #define DWC3_OCTL  0xcc04
-#define DWC3_OEVTEN0xcc08
-#define DWC3_OSTS  0xcc0C
+#define DWC3_OEVT  0xcc08
+#define DWC3_OEVTEN0xcc0c
+#define DWC3_OSTS  0xcc10
 
 /* Bit fields */
 
@@ -203,6 +206,9 @@
 #define DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(n)   (((n)  (0x0f  13))  13)
 #define DWC3_MAX_HIBER_SCRATCHBUFS 15
 
+/* Global HWPARAMS6 Register */
+#define