Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1417111 > unrolled thread
| Started by | Roger Quadros <rogerq@ti.com> |
|---|---|
| First post | 2016-06-08 11:10 +0200 |
| Last post | 2016-06-09 12:20 +0200 |
| Articles | 13 on this page of 33 — 6 participants |
Back to article view | Back to linux.kernel
[PATCH v9 00/14] USB OTG/dual-role framework Roger Quadros <rogerq@ti.com> - 2016-06-08 11:10 +0200
[PATCH v9 10/14] usb: otg: add hcd companion support Roger Quadros <rogerq@ti.com> - 2016-06-08 11:10 +0200
[PATCH v9 11/14] usb: otg: use dev_dbg() instead of VDBG() Roger Quadros <rogerq@ti.com> - 2016-06-08 11:10 +0200
Re: [PATCH v9 11/14] usb: otg: use dev_dbg() instead of VDBG() Joe Perches <joe@perches.com> - 2016-06-08 17:20 +0200
Re: [PATCH v9 11/14] usb: otg: use dev_dbg() instead of VDBG() Roger Quadros <rogerq@ti.com> - 2016-06-09 09:30 +0200
[PATCH v10 11/14] usb: otg: use dev_dbg() instead of VDBG() Roger Quadros <rogerq@ti.com> - 2016-06-09 10:00 +0200
Re: [PATCH v10 11/14] usb: otg: use dev_dbg() instead of VDBG() Joe Perches <joe@perches.com> - 2016-06-09 17:50 +0200
Re: [PATCH v10 11/14] usb: otg: use dev_dbg() instead of VDBG() Roger Quadros <rogerq@ti.com> - 2016-06-10 09:10 +0200
[PATCH v9 02/14] usb: otg-fsm: Prevent build warning "VDBG" redefined Roger Quadros <rogerq@ti.com> - 2016-06-08 11:10 +0200
[PATCH v9 09/14] usb: of: add an API to get OTG device from USB controller node Roger Quadros <rogerq@ti.com> - 2016-06-08 11:10 +0200
[PATCH v9 14/14] usb: host: xhci-plat: Add otg device to platform data Roger Quadros <rogerq@ti.com> - 2016-06-08 11:10 +0200
[PATCH v9 08/14] usb: otg: add OTG/dual-role core Roger Quadros <rogerq@ti.com> - 2016-06-08 11:10 +0200
Re: [PATCH v9 08/14] usb: otg: add OTG/dual-role core Peter Chen <hzpeterchen@gmail.com> - 2016-06-08 12:00 +0200
Re: [PATCH v9 08/14] usb: otg: add OTG/dual-role core Roger Quadros <rogerq@ti.com> - 2016-06-08 12:20 +0200
Re: [PATCH v9 08/14] usb: otg: add OTG/dual-role core Peter Chen <hzpeterchen@gmail.com> - 2016-06-08 14:50 +0200
Re: [PATCH v9 08/14] usb: otg: add OTG/dual-role core Roger Quadros <rogerq@ti.com> - 2016-06-09 09:30 +0200
[PATCH v10 08/14] usb: otg: add OTG/dual-role core Roger Quadros <rogerq@ti.com> - 2016-06-09 10:00 +0200
Re: [PATCH v10 08/14] usb: otg: add OTG/dual-role core Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> - 2016-06-09 14:40 +0200
Re: [PATCH v10 08/14] usb: otg: add OTG/dual-role core Roger Quadros <rogerq@ti.com> - 2016-06-10 09:10 +0200
Re: [PATCH v10 08/14] usb: otg: add OTG/dual-role core Roger Quadros <rogerq@ti.com> - 2016-06-10 12:20 +0200
Re: [PATCH v10 08/14] usb: otg: add OTG/dual-role core Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> - 2016-06-10 12:50 +0200
Re: [PATCH v10 08/14] usb: otg: add OTG/dual-role core Roger Quadros <rogerq@ti.com> - 2016-06-10 13:00 +0200
Re: [PATCH v10 08/14] usb: otg: add OTG/dual-role core Felipe Balbi <balbi@kernel.org> - 2016-06-10 13:10 +0200
[PATCH v9 13/14] usb: gadget: udc: adapt to OTG core Roger Quadros <rogerq@ti.com> - 2016-06-08 11:10 +0200
RE: [PATCH v9 13/14] usb: gadget: udc: adapt to OTG core Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> - 2016-06-09 12:50 +0200
Re: [PATCH v9 13/14] usb: gadget: udc: adapt to OTG core Roger Quadros <rogerq@ti.com> - 2016-06-10 09:10 +0200
[PATCH v9 07/14] usb: otg: get rid of CONFIG_USB_OTG_FSM in favour of CONFIG_USB_OTG Roger Quadros <rogerq@ti.com> - 2016-06-08 11:20 +0200
[PATCH v9 01/14] usb: hcd: Initialize hcd->flags to 0 Roger Quadros <rogerq@ti.com> - 2016-06-08 11:20 +0200
[PATCH v9 05/14] usb: otg-fsm: move host controller operations into usb_otg->hcd_ops Roger Quadros <rogerq@ti.com> - 2016-06-08 11:20 +0200
[PATCH v9 06/14] usb: gadget.h: Add OTG to gadget interface Roger Quadros <rogerq@ti.com> - 2016-06-08 11:20 +0200
Re: [PATCH v9 00/14] USB OTG/dual-role framework Peter Chen <hzpeterchen@gmail.com> - 2016-06-09 07:30 +0200
Re: [PATCH v9 00/14] USB OTG/dual-role framework Roger Quadros <rogerq@ti.com> - 2016-06-09 09:40 +0200
RE: [PATCH v9 00/14] USB OTG/dual-role framework Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> - 2016-06-09 12:20 +0200
Page 2 of 2 — ← Prev page 1 [2]
| From | Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> |
|---|---|
| Date | 2016-06-10 12:50 +0200 |
| Subject | Re: [PATCH v10 08/14] usb: otg: add OTG/dual-role core |
| Message-ID | <rIsaJ-3sW-11@gated-at.bofh.it> |
| In reply to | #1419198 |
On 6/10/2016 1:19 PM, Roger Quadros wrote:
>>> It provides APIs for the following tasks
>>>
>>> - Registering an OTG/dual-role capable controller
>>> - Registering Host and Gadget controllers to OTG core
>>> - Providing inputs to and kicking the OTG state machine
>>>
>>> Provide a dual-role device (DRD) state machine.
>>> DRD mode is a reduced functionality OTG mode. In this mode
>>> we don't support SRP, HNP and dynamic role-swap.
>>>
>>> In DRD operation, the controller mode (Host or Peripheral)
>>> is decided based on the ID pin status. Once a cable plug (Type-A
>>> or Type-B) is attached the controller selects the state
>>> and doesn't change till the cable in unplugged and a different
>>> cable type is inserted.
>>>
>>> As we don't need most of the complex OTG states and OTG timers
>>> we implement a lean DRD state machine in usb-otg.c.
>>> The DRD state machine is only interested in 2 hardware inputs
>>> 'id' and 'b_sess_vld'.
>>>
>>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>>
>
> <snip>
>
>> [...]
>>> +/**
>>> + * usb_otg_register_gadget - Register the gadget controller to OTG core
>>> + * @gadget: gadget controller
>>
>> We call that USB device controller (UDC). I'm not sure what you meant here...
>> And what about the 2nd arg, 'ops'?
>
> There are 2 data structures representing the Device controller.
>
> struct usb_gadget - represents a usb slave device
> struct usb_udc -struct usb_udc - describes one usb device controller
>
> usb_udc is for private use only. usb_otg_register_gadget() takes struct usb_gadget
> as argument.
>
> Do you want me to refer to struct usb_gadget as UDC?
No.
> What is wrong with calling it gadget controller?
It's not a controller, it's a piece of software AFAIU. Or is my English
just too weak? :-)
> --
> cheers,
> -roger
MBR, Sergei
[toc] | [prev] | [next] | [standalone]
| From | Roger Quadros <rogerq@ti.com> |
|---|---|
| Date | 2016-06-10 13:00 +0200 |
| Subject | Re: [PATCH v10 08/14] usb: otg: add OTG/dual-role core |
| Message-ID | <rIskq-3wi-29@gated-at.bofh.it> |
| In reply to | #1419252 |
On 10/06/16 13:44, Sergei Shtylyov wrote: > On 6/10/2016 1:19 PM, Roger Quadros wrote: > >>>> It provides APIs for the following tasks >>>> >>>> - Registering an OTG/dual-role capable controller >>>> - Registering Host and Gadget controllers to OTG core >>>> - Providing inputs to and kicking the OTG state machine >>>> >>>> Provide a dual-role device (DRD) state machine. >>>> DRD mode is a reduced functionality OTG mode. In this mode >>>> we don't support SRP, HNP and dynamic role-swap. >>>> >>>> In DRD operation, the controller mode (Host or Peripheral) >>>> is decided based on the ID pin status. Once a cable plug (Type-A >>>> or Type-B) is attached the controller selects the state >>>> and doesn't change till the cable in unplugged and a different >>>> cable type is inserted. >>>> >>>> As we don't need most of the complex OTG states and OTG timers >>>> we implement a lean DRD state machine in usb-otg.c. >>>> The DRD state machine is only interested in 2 hardware inputs >>>> 'id' and 'b_sess_vld'. >>>> >>>> Signed-off-by: Roger Quadros <rogerq@ti.com> >>> >> >> <snip> >> >>> [...] >>>> +/** >>>> + * usb_otg_register_gadget - Register the gadget controller to OTG core >>>> + * @gadget: gadget controller >>> >>> We call that USB device controller (UDC). I'm not sure what you meant here... >>> And what about the 2nd arg, 'ops'? >> >> There are 2 data structures representing the Device controller. >> >> struct usb_gadget - represents a usb slave device >> struct usb_udc -struct usb_udc - describes one usb device controller >> >> usb_udc is for private use only. usb_otg_register_gadget() takes struct usb_gadget >> as argument. >> >> Do you want me to refer to struct usb_gadget as UDC? > > No. > >> What is wrong with calling it gadget controller? > > It's not a controller, it's a piece of software AFAIU. Or is my English just too weak? :-) Everything at this point is a piece of software :). struct usb_gadget, represents the gadget controller device not the driver (or software). struct usb_gadget_driver represents the gadget function driver. struct usb_gadget_ops represents the UDC driver ops. -- cheers, -roger
[toc] | [prev] | [next] | [standalone]
| From | Felipe Balbi <balbi@kernel.org> |
|---|---|
| Date | 2016-06-10 13:10 +0200 |
| Subject | Re: [PATCH v10 08/14] usb: otg: add OTG/dual-role core |
| Message-ID | <rIsu5-3Oy-17@gated-at.bofh.it> |
| In reply to | #1419263 |
[Multipart message — attachments visible in raw view] — view raw
Hi, Roger Quadros <rogerq@ti.com> writes: >>> What is wrong with calling it gadget controller? >> >> It's not a controller, it's a piece of software AFAIU. Or is my English just too weak? :-) > > Everything at this point is a piece of software :). > > struct usb_gadget, represents the gadget controller device not the > driver (or software). > > struct usb_gadget_driver represents the gadget function driver. > struct usb_gadget_ops represents the UDC driver ops. right, and usb_udc was added just to have a way of linking usb_gadget with usb_gadget_driver so we could have more than one peripheral port in a system. -- balbi
[toc] | [prev] | [next] | [standalone]
| From | Roger Quadros <rogerq@ti.com> |
|---|---|
| Date | 2016-06-08 11:10 +0200 |
| Subject | [PATCH v9 13/14] usb: gadget: udc: adapt to OTG core |
| Message-ID | <rHHES-6Fd-45@gated-at.bofh.it> |
| In reply to | #1417111 |
The OTG state machine needs a mechanism to start and
stop the gadget controller as well as connect/disconnect
from the bus. Add usb_gadget_start(), usb_gadget_stop()
and usb_gadget_connect_control().
Introduce usb_otg_add_gadget_udc() to allow controller drivers
to register a gadget controller that is part of an OTG instance.
Register with OTG core when UDC is added in usb_add_gadget_udc_release()
and unregister on usb_del_gadget_udc().
Notify the OTG core when gadget function driver is available on
udc_bind_to_driver() and when it is removed in usb_gadget_remove_driver().
We need to unlock the usb_lock mutex before calling
usb_otg_register_gadget() else it will cause a circular
locking dependency.
Ignore softconnect sysfs control when we're in OTG
mode as OTG FSM should care of gadget softconnect using
the b_bus_req mechanism.
Signed-off-by: Roger Quadros <rogerq@ti.com>
---
drivers/usb/gadget/udc/udc-core.c | 202 ++++++++++++++++++++++++++++++++++++--
include/linux/usb/gadget.h | 4 +
2 files changed, 196 insertions(+), 10 deletions(-)
diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
index 6e8300d..a80a6c9 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -28,6 +28,11 @@
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/usb.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/of.h>
+
+#include <linux/of.h>
+#include <linux/of_platform.h>
/**
* struct usb_udc - describes one usb device controller
@@ -337,6 +342,113 @@ static inline void usb_gadget_udc_stop(struct usb_udc *udc)
}
/**
+ * usb_gadget_to_udc - get the UDC owning the gadget
+ *
+ * udc_lock must be held.
+ * Returs NULL if UDC is not found.
+ */
+static struct usb_udc *usb_gadget_to_udc(struct usb_gadget *gadget)
+{
+ struct usb_udc *udc;
+
+ list_for_each_entry(udc, &udc_list, list)
+ if (udc->gadget == gadget)
+ return udc;
+
+ return NULL;
+}
+
+/**
+ * usb_gadget_start - start the usb gadget controller
+ * @gadget: the gadget device to start
+ *
+ * This is external API for use by OTG core.
+ *
+ * Start the usb device controller. Does not connect to the bus.
+ */
+static int usb_gadget_start(struct usb_gadget *gadget)
+{
+ int ret;
+ struct usb_udc *udc;
+
+ mutex_lock(&udc_lock);
+ udc = usb_gadget_to_udc(gadget);
+ if (!udc) {
+ dev_err(gadget->dev.parent, "%s: gadget not registered.\n",
+ __func__);
+ mutex_unlock(&udc_lock);
+ return -EINVAL;
+ }
+
+ ret = usb_gadget_udc_start(udc);
+ if (ret)
+ dev_err(&udc->dev, "USB Device Controller didn't start: %d\n",
+ ret);
+
+ mutex_unlock(&udc_lock);
+
+ return ret;
+}
+
+/**
+ * usb_gadget_stop - stop the usb gadget controller
+ * @gadget: the gadget device we want to stop
+ *
+ * This is external API for use by OTG core.
+ *
+ * Stop the gadget controller. Does not disconnect from the bus.
+ * Caller must ensure that gadget has disconnected from the bus
+ * before calling usb_gadget_stop().
+ */
+static int usb_gadget_stop(struct usb_gadget *gadget)
+{
+ struct usb_udc *udc;
+
+ mutex_lock(&udc_lock);
+ udc = usb_gadget_to_udc(gadget);
+ if (!udc) {
+ dev_err(gadget->dev.parent, "%s: gadget not registered.\n",
+ __func__);
+ mutex_unlock(&udc_lock);
+ return -EINVAL;
+ }
+
+ if (gadget->connected)
+ dev_dbg(gadget->dev.parent,
+ "%s: called while still connected\n", __func__);
+
+ usb_gadget_udc_stop(udc);
+ mutex_unlock(&udc_lock);
+
+ return 0;
+}
+
+static int usb_gadget_connect_control(struct usb_gadget *gadget, bool connect)
+{
+ struct usb_udc *udc;
+
+ mutex_lock(&udc_lock);
+ udc = usb_gadget_to_udc(gadget);
+ if (!udc) {
+ dev_err(gadget->dev.parent, "%s: gadget not registered.\n",
+ __func__);
+ mutex_unlock(&udc_lock);
+ return -EINVAL;
+ }
+
+ if (connect) {
+ usb_gadget_connect(udc->gadget);
+ } else {
+ usb_gadget_disconnect(udc->gadget);
+ udc->driver->disconnect(udc->gadget);
+ }
+
+ mutex_unlock(&udc_lock);
+
+ return 0;
+}
+
+/**
* usb_udc_release - release the usb_udc struct
* @dev: the dev member within usb_udc
*
@@ -359,6 +471,12 @@ static void usb_udc_nop_release(struct device *dev)
dev_vdbg(dev, "%s\n", __func__);
}
+struct otg_gadget_ops otg_gadget_intf = {
+ .start = usb_gadget_start,
+ .stop = usb_gadget_stop,
+ .connect_control = usb_gadget_connect_control,
+};
+
/**
* usb_add_gadget_udc_release - adds a new gadget to the udc class driver list
* @parent: the parent device to this udc. Usually the controller driver's
@@ -414,6 +532,14 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
udc->vbus = true;
+ if (gadget->otg_dev) {
+ mutex_unlock(&udc_lock);
+ ret = usb_otg_register_gadget(gadget, &otg_gadget_intf);
+ mutex_lock(&udc_lock);
+ if (ret)
+ goto err5;
+ }
+
/* pick up one of pending gadget drivers */
list_for_each_entry(driver, &gadget_driver_pending_list, pending) {
if (!driver->udc_name || strcmp(driver->udc_name,
@@ -422,7 +548,7 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
if (ret != -EPROBE_DEFER)
list_del(&driver->pending);
if (ret)
- goto err4;
+ goto err5;
break;
}
}
@@ -431,6 +557,8 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
return 0;
+err5:
+ device_del(&udc->dev);
err4:
list_del(&udc->list);
mutex_unlock(&udc_lock);
@@ -492,6 +620,33 @@ int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget)
}
EXPORT_SYMBOL_GPL(usb_add_gadget_udc);
+/**
+ * usb_otg_add_gadget_udc - adds a new gadget to the udc class driver list
+ * @parent: the parent device to this udc. Usually the controller
+ * driver's device.
+ * @gadget: the gadget to be added to the list
+ * @otg_dev: the OTG controller device
+ *
+ * If otg_dev is NULL then device tree node is checked
+ * for OTG controller via the otg-controller property.
+ * Returns zero on success, negative errno otherwise.
+ */
+int usb_otg_add_gadget_udc(struct device *parent, struct usb_gadget *gadget,
+ struct device *otg_dev)
+{
+ if (!otg_dev) {
+ gadget->otg_dev = of_usb_get_otg(parent->of_node);
+ if (!gadget->otg_dev)
+ return -ENODEV;
+ } else {
+ gadget->otg_dev = otg_dev;
+ }
+
+ return usb_add_gadget_udc_release(parent, gadget, NULL);
+}
+EXPORT_SYMBOL_GPL(usb_otg_add_gadget_udc);
+
+/* udc_lock must be held */
static void usb_gadget_remove_driver(struct usb_udc *udc)
{
dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n",
@@ -499,10 +654,18 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
- usb_gadget_disconnect(udc->gadget);
- udc->driver->disconnect(udc->gadget);
+ /* If OTG/dual-role, the otg core manages UDC start/stop */
+ if (udc->gadget->otg_dev) {
+ mutex_unlock(&udc_lock);
+ usb_otg_gadget_ready(udc->gadget, false);
+ mutex_lock(&udc_lock);
+ } else {
+ usb_gadget_disconnect(udc->gadget);
+ udc->driver->disconnect(udc->gadget);
+ usb_gadget_udc_stop(udc);
+ }
+
udc->driver->unbind(udc->gadget);
- usb_gadget_udc_stop(udc);
udc->driver = NULL;
udc->dev.driver = NULL;
@@ -536,6 +699,9 @@ void usb_del_gadget_udc(struct usb_gadget *gadget)
}
mutex_unlock(&udc_lock);
+ if (gadget->otg_dev)
+ usb_otg_unregister_gadget(gadget);
+
kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE);
flush_work(&gadget->work);
device_unregister(&udc->dev);
@@ -545,6 +711,7 @@ EXPORT_SYMBOL_GPL(usb_del_gadget_udc);
/* ------------------------------------------------------------------------- */
+/* udc_lock must be held */
static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *driver)
{
int ret;
@@ -559,17 +726,26 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri
ret = driver->bind(udc->gadget, driver);
if (ret)
goto err1;
- ret = usb_gadget_udc_start(udc);
- if (ret) {
- driver->unbind(udc->gadget);
- goto err1;
+
+ /* If OTG/dual-role, the otg core manages UDC start/stop */
+ if (udc->gadget->otg_dev) {
+ mutex_unlock(&udc_lock);
+ usb_otg_gadget_ready(udc->gadget, true);
+ mutex_lock(&udc_lock);
+ } else {
+ ret = usb_gadget_udc_start(udc);
+ if (ret) {
+ mutex_unlock(&udc_lock);
+ driver->unbind(udc->gadget);
+ goto err1;
+ }
+ usb_udc_connect_control(udc);
}
- usb_udc_connect_control(udc);
kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
return 0;
err1:
- if (ret != -EISNAM)
+ if ((ret != -EISNAM) && (ret != -EPROBE_DEFER))
dev_err(&udc->dev, "failed to start %s: %d\n",
udc->driver->function, ret);
udc->driver = NULL;
@@ -666,6 +842,12 @@ static ssize_t usb_udc_softconn_store(struct device *dev,
return -EOPNOTSUPP;
}
+ /* In OTG/dual-role mode, soft-connect should be handled by OTG core */
+ if (udc->gadget->otg_dev) {
+ dev_err(dev, "soft-connect not supported in OTG mode\n");
+ return -EOPNOTSUPP;
+ }
+
if (sysfs_streq(buf, "connect")) {
usb_gadget_udc_start(udc);
usb_gadget_connect(udc->gadget);
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 1237f66..698092f 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -1162,6 +1162,10 @@ extern int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget);
extern void usb_del_gadget_udc(struct usb_gadget *gadget);
extern char *usb_get_gadget_udc_name(void);
+extern int usb_otg_add_gadget_udc(struct device *parent,
+ struct usb_gadget *gadget,
+ struct device *otg_dev);
+
/*-------------------------------------------------------------------------*/
/* utility to simplify dealing with string descriptors */
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> |
|---|---|
| Date | 2016-06-09 12:50 +0200 |
| Subject | RE: [PATCH v9 13/14] usb: gadget: udc: adapt to OTG core |
| Message-ID | <rI5Hb-5b7-7@gated-at.bofh.it> |
| In reply to | #1417123 |
Hi Roger, > From: Roger Quadros > Sent: Wednesday, June 08, 2016 6:04 PM > > The OTG state machine needs a mechanism to start and > stop the gadget controller as well as connect/disconnect > from the bus. Add usb_gadget_start(), usb_gadget_stop() > and usb_gadget_connect_control(). > > Introduce usb_otg_add_gadget_udc() to allow controller drivers > to register a gadget controller that is part of an OTG instance. > > Register with OTG core when UDC is added in usb_add_gadget_udc_release() > and unregister on usb_del_gadget_udc(). > > Notify the OTG core when gadget function driver is available on > udc_bind_to_driver() and when it is removed in usb_gadget_remove_driver(). > > We need to unlock the usb_lock mutex before calling > usb_otg_register_gadget() else it will cause a circular > locking dependency. > > Ignore softconnect sysfs control when we're in OTG > mode as OTG FSM should care of gadget softconnect using > the b_bus_req mechanism. > > Signed-off-by: Roger Quadros <rogerq@ti.com> > --- > drivers/usb/gadget/udc/udc-core.c | 202 ++++++++++++++++++++++++++++++++++++-- > include/linux/usb/gadget.h | 4 + > 2 files changed, 196 insertions(+), 10 deletions(-) I tried to apply this patch on the Felipe's usb.git / testing/next branch, but I couldn't apply because the udc-core.c was renamed to core.c. https://git.kernel.org/cgit/linux/kernel/git/balbi/usb.git/commit/?h=testing/next&id=a22b539c7082b6a3046b3a9cebb356a047a2d81d I guess this patch needs rebase for that. Best regards, Yoshihiro Shimoda
[toc] | [prev] | [next] | [standalone]
| From | Roger Quadros <rogerq@ti.com> |
|---|---|
| Date | 2016-06-10 09:10 +0200 |
| Subject | Re: [PATCH v9 13/14] usb: gadget: udc: adapt to OTG core |
| Message-ID | <rIoJP-1vU-11@gated-at.bofh.it> |
| In reply to | #1418234 |
Hi Yoshihiro, On 09/06/16 13:49, Yoshihiro Shimoda wrote: > Hi Roger, > >> From: Roger Quadros >> Sent: Wednesday, June 08, 2016 6:04 PM >> >> The OTG state machine needs a mechanism to start and >> stop the gadget controller as well as connect/disconnect >> from the bus. Add usb_gadget_start(), usb_gadget_stop() >> and usb_gadget_connect_control(). >> >> Introduce usb_otg_add_gadget_udc() to allow controller drivers >> to register a gadget controller that is part of an OTG instance. >> >> Register with OTG core when UDC is added in usb_add_gadget_udc_release() >> and unregister on usb_del_gadget_udc(). >> >> Notify the OTG core when gadget function driver is available on >> udc_bind_to_driver() and when it is removed in usb_gadget_remove_driver(). >> >> We need to unlock the usb_lock mutex before calling >> usb_otg_register_gadget() else it will cause a circular >> locking dependency. >> >> Ignore softconnect sysfs control when we're in OTG >> mode as OTG FSM should care of gadget softconnect using >> the b_bus_req mechanism. >> >> Signed-off-by: Roger Quadros <rogerq@ti.com> >> --- >> drivers/usb/gadget/udc/udc-core.c | 202 ++++++++++++++++++++++++++++++++++++-- >> include/linux/usb/gadget.h | 4 + >> 2 files changed, 196 insertions(+), 10 deletions(-) > > I tried to apply this patch on the Felipe's usb.git / testing/next branch, > but I couldn't apply because the udc-core.c was renamed to core.c. > https://git.kernel.org/cgit/linux/kernel/git/balbi/usb.git/commit/?h=testing/next&id=a22b539c7082b6a3046b3a9cebb356a047a2d81d > > I guess this patch needs rebase for that. OK. I'll respin the whole series on Felipe's usb.git /testing/next. cheers, -roger
[toc] | [prev] | [next] | [standalone]
| From | Roger Quadros <rogerq@ti.com> |
|---|---|
| Date | 2016-06-08 11:20 +0200 |
| Subject | [PATCH v9 07/14] usb: otg: get rid of CONFIG_USB_OTG_FSM in favour of CONFIG_USB_OTG |
| Message-ID | <rHHOx-6Iz-3@gated-at.bofh.it> |
| In reply to | #1417111 |
Let's use CONFIG_USB_OTG as a single config option to enable
USB OTG and the OTG FSM. This makes things a lot less confusing.
Update all users of CONFIG_USB_OTG_FSM to CONFIG_USB_OTG.
Signed-off-by: Roger Quadros <rogerq@ti.com>
Acked-by: Peter Chen <peter.chen@nxp.com>
---
Documentation/usb/chipidea.txt | 2 +-
drivers/usb/chipidea/Makefile | 2 +-
drivers/usb/chipidea/ci.h | 2 +-
drivers/usb/chipidea/otg_fsm.h | 2 +-
drivers/usb/common/Makefile | 3 ++-
drivers/usb/core/Kconfig | 8 --------
drivers/usb/phy/Kconfig | 2 +-
7 files changed, 7 insertions(+), 14 deletions(-)
diff --git a/Documentation/usb/chipidea.txt b/Documentation/usb/chipidea.txt
index edf7cdf..580d157 100644
--- a/Documentation/usb/chipidea.txt
+++ b/Documentation/usb/chipidea.txt
@@ -5,7 +5,7 @@ with 2 Freescale i.MX6Q sabre SD boards.
1.1 How to enable OTG FSM
---------------------------------------
-1.1.1 Select CONFIG_USB_OTG_FSM in menuconfig, rebuild kernel
+1.1.1 Select CONFIG_USB_OTG in menuconfig, rebuild kernel
Image and modules. If you want to check some internal
variables for otg fsm, mount debugfs, there are 2 files
which can show otg fsm variables and some controller registers value:
diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile
index 518e445..45aa24d 100644
--- a/drivers/usb/chipidea/Makefile
+++ b/drivers/usb/chipidea/Makefile
@@ -3,7 +3,7 @@ obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc.o
ci_hdrc-y := core.o otg.o debug.o
ci_hdrc-$(CONFIG_USB_CHIPIDEA_UDC) += udc.o
ci_hdrc-$(CONFIG_USB_CHIPIDEA_HOST) += host.o
-ci_hdrc-$(CONFIG_USB_OTG_FSM) += otg_fsm.o
+ci_hdrc-$(CONFIG_USB_OTG) += otg_fsm.o
# Glue/Bridge layers go here
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index c523975..1a32b8c 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -406,7 +406,7 @@ static inline u32 hw_test_and_write(struct ci_hdrc *ci, enum ci_hw_regs reg,
*/
static inline bool ci_otg_is_fsm_mode(struct ci_hdrc *ci)
{
-#ifdef CONFIG_USB_OTG_FSM
+#ifdef CONFIG_USB_OTG
struct usb_otg_caps *otg_caps = &ci->platdata->ci_otg_caps;
return ci->is_otg && ci->roles[CI_ROLE_HOST] &&
diff --git a/drivers/usb/chipidea/otg_fsm.h b/drivers/usb/chipidea/otg_fsm.h
index 6366fe3..2d451bb 100644
--- a/drivers/usb/chipidea/otg_fsm.h
+++ b/drivers/usb/chipidea/otg_fsm.h
@@ -64,7 +64,7 @@
#define TB_AIDL_BDIS (20) /* 4ms ~ 150ms, section 5.2.1 */
-#if IS_ENABLED(CONFIG_USB_OTG_FSM)
+#if IS_ENABLED(CONFIG_USB_OTG)
int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci);
int ci_otg_fsm_work(struct ci_hdrc *ci);
diff --git a/drivers/usb/common/Makefile b/drivers/usb/common/Makefile
index 6bbb3ec..f8f2c88 100644
--- a/drivers/usb/common/Makefile
+++ b/drivers/usb/common/Makefile
@@ -6,5 +6,6 @@ obj-$(CONFIG_USB_COMMON) += usb-common.o
usb-common-y += common.o
usb-common-$(CONFIG_USB_LED_TRIG) += led.o
-obj-$(CONFIG_USB_OTG_FSM) += usb-otg-fsm.o
obj-$(CONFIG_USB_ULPI_BUS) += ulpi.o
+usbotg-y := usb-otg-fsm.o
+obj-$(CONFIG_USB_OTG) += usbotg.o
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig
index dd28010..ae228d0 100644
--- a/drivers/usb/core/Kconfig
+++ b/drivers/usb/core/Kconfig
@@ -75,14 +75,6 @@ config USB_OTG_BLACKLIST_HUB
and software costs by not supporting external hubs. So
are "Embedded Hosts" that don't offer OTG support.
-config USB_OTG_FSM
- tristate "USB 2.0 OTG FSM implementation"
- depends on USB && USB_OTG
- select USB_PHY
- help
- Implements OTG Finite State Machine as specified in On-The-Go
- and Embedded Host Supplement to the USB Revision 2.0 Specification.
-
config USB_ULPI_BUS
tristate "USB ULPI PHY interface support"
depends on USB_SUPPORT
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index c690474..06794e2 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -20,7 +20,7 @@ config AB8500_USB
config FSL_USB2_OTG
bool "Freescale USB OTG Transceiver Driver"
- depends on USB_EHCI_FSL && USB_FSL_USB2 && USB_OTG_FSM && PM
+ depends on USB_EHCI_FSL && USB_FSL_USB2 && USB_OTG && PM
select USB_PHY
help
Enable this to support Freescale USB OTG transceiver.
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Roger Quadros <rogerq@ti.com> |
|---|---|
| Date | 2016-06-08 11:20 +0200 |
| Subject | [PATCH v9 01/14] usb: hcd: Initialize hcd->flags to 0 |
| Message-ID | <rHHOy-6Iz-23@gated-at.bofh.it> |
| In reply to | #1417111 |
When using the OTG/drd library we can call hcd_add/remove consecutively without calling usb_put_hcd/usb_create_hcd in between so hcd->flags can be stale. If the HC dies due to whatever reason then without this patch we get the below error on next hcd_add. [ 91.494257] xhci-hcd xhci-hcd.0.auto: HC died; cleaning up [ 91.502068] hub 3-0:1.0: state 0 ports 1 chg 0000 evt 0000 [ 91.510240] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller [ 91.516940] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 4 [ 91.529745] usb usb4: We don't know the algorithms for LPM for this host, disabling LPM. [ 91.540637] usb usb4: New USB device found, idVendor=1d6b, idProduct=0003 [ 91.757865] irq 254: nobody cared (try booting with the "irqpoll" option) [ 91.757880] CPU: 0 PID: 68 Comm: kworker/u2:2 Not tainted 4.1.4-00828-g1f0ed8c-dirty #44 [ 91.757885] Hardware name: Generic AM43 (Flattened Device Tree) [ 91.757914] Workqueue: usb_otg usb_otg_work [ 91.757921] Backtrace: [ 91.757954] [<c0012af0>] (dump_backtrace) from [<c0012c8c>] (show_stack+0x18/0x1c) [ 91.757972] r6:c089d4a4 r5:ffffffff r4:00000000 r3:ee440000 [ 91.757991] [<c0012c74>] (show_stack) from [<c05f7c14>] (dump_stack+0x84/0xd0) [ 91.758008] [<c05f7b90>] (dump_stack) from [<c0084b30>] (__report_bad_irq+0x28/0xc8) [ 91.758024] r7:00000000 r6:000000fe r5:00000000 r4:ee514c40 [ 91.758037] [<c0084b08>] (__report_bad_irq) from [<c00850b0>] (note_interrupt+0x24c/0x2ac) [ 91.758052] r6:000000fe r5:00000000 r4:ee514c40 r3:00000000 [ 91.758065] [<c0084e64>] (note_interrupt) from [<c00828fc>] (handle_irq_event_percpu+0xb0/0x158) [ 91.758085] r10:ee514c40 r9:c08ce49a r8:000000fe r7:00000000 r6:00000000 r5:00000000 [ 91.758094] r4:00000000 r3:00000000 [ 91.758105] [<c008284c>] (handle_irq_event_percpu) from [<c00829e8>] (handle_irq_event+0x44/0x64) [ 91.758126] r10:00000001 r9:ee441ab0 r8:ee441bb8 r7:c0858b4c r6:ed174280 r5:ee514ca0 [ 91.758132] r4:ee514c40 [ 91.758144] [<c00829a4>] (handle_irq_event) from [<c0085970>] (handle_fasteoi_irq+0x100/0x1bc) [ 91.758159] r6:c085dba0 r5:ee514ca0 r4:ee514c40 r3:00000000 [ 91.758171] [<c0085870>] (handle_fasteoi_irq) from [<c0082058>] (generic_handle_irq+0x28/0x38) [ 91.758186] r7:c0853d40 r6:c0858b4c r5:000000fe r4:000000fe [ 91.758197] [<c0082030>] (generic_handle_irq) from [<c00821c0>] (__handle_domain_irq+0x98/0x12c) [ 91.758207] r4:c0853d40 r3:00000100 [ 91.758219] [<c0082128>] (__handle_domain_irq) from [<c00094e0>] (gic_handle_irq+0x28/0x68) [ 91.758239] r10:00000001 r9:ee441bb8 r8:fa240100 r7:c0858d70 r6:ee441ab0 r5:000000b8 [ 91.758245] r4:fa24010c [ 91.758264] [<c00094b8>] (gic_handle_irq) from [<c05fd540>] (__irq_svc+0x40/0x74) [ 91.758271] Exception stack(0xee441ab0 to 0xee441af8) [ 91.758280] 1aa0: 00000000 c08d2980 ee441ac0 00000000 [ 91.758292] 1ac0: 00000008 00000089 c0858b4c c0858080 00000000 ee441bb8 00000001 ee441b3c [ 91.758301] 1ae0: 00000101 ee441af8 c02fc418 c0046a1c 20000113 ffffffff [ 91.758321] r8:00000000 r7:ee441ae4 r6:ffffffff r5:20000113 r4:c0046a1c r3:c02fc418 [ 91.758347] [<c00469a0>] (__do_softirq) from [<c0046eac>] (irq_exit+0xb8/0x104) [ 91.758367] r10:00000001 r9:ee441bb8 r8:00000000 r7:c0853d40 r6:c0858b4c r5:00000089 [ 91.758373] r4:00000000 [ 91.758386] [<c0046df4>] (irq_exit) from [<c00821c8>] (__handle_domain_irq+0xa0/0x12c) [ 91.758395] r4:00000000 r3:00000100 [ 91.758406] [<c0082128>] (__handle_domain_irq) from [<c00094e0>] (gic_handle_irq+0x28/0x68) [ 91.758426] r10:c08e3510 r9:20000013 r8:fa240100 r7:c0858d70 r6:ee441bb8 r5:00000039 [ 91.758433] r4:fa24010c [ 91.758445] [<c00094b8>] (gic_handle_irq) from [<c05fd540>] (__irq_svc+0x40/0x74) [ 91.758450] Exception stack(0xee441bb8 to 0xee441c00) [ 91.758457] 1ba0: 00000000 00000001 [ 91.758468] 1bc0: 00000000 ee440000 c08e2524 0000004d 00000274 00000000 00000000 20000013 [ 91.758479] 1be0: c08e3510 ee441c4c ee441b60 ee441c00 c03acfec c0080d4c 60000013 ffffffff [ 91.758499] r8:00000000 r7:ee441bec r6:ffffffff r5:60000013 r4:c0080d4c r3:c03acfec [ 91.758524] [<c0080950>] (console_unlock) from [<c0081670>] (vprintk_emit+0x20c/0x500) [ 91.758544] r10:ee441cc0 r9:c08d3550 r8:c08e3ea0 r7:00000000 r6:00000001 r5:0000003d [ 91.758551] r4:c08d3550 [ 91.758573] [<c0081464>] (vprintk_emit) from [<c03f6f70>] (dev_vprintk_emit+0x104/0x1ac) [ 91.758593] r10:ee441d8c r9:0000000e r8:c07951e0 r7:00000006 r6:ee441cc0 r5:0000000d [ 91.758599] r4:ee731068 [ 91.758612] [<c03f6e6c>] (dev_vprintk_emit) from [<c03f7040>] (dev_printk_emit+0x28/0x30) [ 91.758632] r10:00000001 r9:ee5f8410 r8:ee731000 r7:ed429000 r6:00000006 r5:ee441dc0 [ 91.758638] r4:ee731068 [ 91.758651] [<c03f701c>] (dev_printk_emit) from [<c03f7098>] (__dev_printk+0x50/0x70) [ 91.758660] r3:bf2268cc r2:c07951e0 [ 91.758673] [<c03f7048>] (__dev_printk) from [<c03f70f4>] (_dev_info+0x3c/0x48) [ 91.758686] r6:00000000 r5:ee731068 r4:ee731000 [ 91.758790] [<c03f70bc>] (_dev_info) from [<bf20ec3c>] (usb_new_device+0x11c/0x518 [usbcore]) [ 91.758804] r3:00000003 r2:00001d6b r1:bf225bc4 [ 91.758881] [<bf20eb20>] (usb_new_device [usbcore]) from [<bf213560>] (usb_otg_add_hcd+0x514/0x7f8 [usbcore]) [ 91.758903] r10:00000001 r9:ee5f8410 r8:ee731000 r7:000000fe r6:ed4290c8 r5:00000000 [ 91.758909] r4:ed429000 [ 91.758957] [<bf21304c>] (usb_otg_add_hcd [usbcore]) from [<c047a238>] (usb_otg_start_host+0xb8/0xf8) [ 91.758978] r10:00000000 r9:00000002 r8:00000000 r7:ee02b000 r6:ee452808 r5:ee452808 [ 91.758985] r4:ee452808 [ 91.758997] [<c047a180>] (usb_otg_start_host) from [<c047a020>] (drd_set_protocol+0xac/0xd8) [ 91.759007] r4:00000001 r3:c047a180 [ 91.759018] [<c0479f74>] (drd_set_protocol) from [<c047a2ec>] (drd_set_state+0x74/0x98) [ 91.759027] r5:ee452808 r4:00000009 [ 91.759039] [<c047a278>] (drd_set_state) from [<c047a3dc>] (usb_otg_work+0xcc/0x154) [ 91.759054] r6:ee452808 r5:ee4528b8 r4:ee452968 r3:00000000 [ 91.759072] [<c047a310>] (usb_otg_work) from [<c005754c>] (process_one_work+0x128/0x340) [ 91.759087] r6:ee02ac00 r5:ee452968 r4:ee42b900 r3:c047a310 [ 91.759100] [<c0057424>] (process_one_work) from [<c00578f8>] (worker_thread+0x158/0x49c) [ 91.759120] r10:ee42b900 r9:00000002 r8:ee02ac00 r7:00000088 r6:ee42b918 r5:ee02ac00 [ 91.759127] r4:ee02ac14 [ 91.759145] [<c00577a0>] (worker_thread) from [<c005cc40>] (kthread+0xdc/0xf8) [ 91.759165] r10:00000000 r9:00000000 r8:00000000 r7:c00577a0 r6:ee42b900 r5:ee429940 [ 91.759174] r4:00000000 r3:00000000 [ 91.759190] [<c005cb64>] (kthread) from [<c000fc08>] (ret_from_fork+0x14/0x2c) [ 91.759206] r7:00000000 r6:00000000 r5:c005cb64 r4:ee429940 [ 91.759209] handlers: [ 91.759255] [<bf211b5c>] usb_hcd_irq [usbcore] [ 91.759260] Disabling IRQ #254 Signed-off-by: Roger Quadros <rogerq@ti.com> Reviewed-by: Peter Chen <peter.chen@nxp.com> --- drivers/usb/core/hcd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 34b837a..ae6c76d 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -3021,6 +3021,7 @@ void usb_remove_hcd(struct usb_hcd *hcd) } usb_put_invalidate_rhdev(hcd); + hcd->flags = 0; } EXPORT_SYMBOL_GPL(usb_remove_hcd); -- 2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Roger Quadros <rogerq@ti.com> |
|---|---|
| Date | 2016-06-08 11:20 +0200 |
| Subject | [PATCH v9 05/14] usb: otg-fsm: move host controller operations into usb_otg->hcd_ops |
| Message-ID | <rHHOy-6Iz-39@gated-at.bofh.it> |
| In reply to | #1417111 |
This is to prevent missing symbol build error if OTG is
enabled (built-in) and HCD core (CONFIG_USB) is module.
Signed-off-by: Roger Quadros <rogerq@ti.com>
Acked-by: Peter Chen <peter.chen@nxp.com>
---
drivers/usb/chipidea/otg_fsm.c | 7 +++++++
drivers/usb/common/usb-otg-fsm.c | 15 +++++++++++----
drivers/usb/phy/phy-fsl-usb.c | 7 +++++++
include/linux/usb/otg.h | 2 ++
4 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c
index 1c0c750..2d8d659 100644
--- a/drivers/usb/chipidea/otg_fsm.c
+++ b/drivers/usb/chipidea/otg_fsm.c
@@ -582,6 +582,12 @@ static struct otg_fsm_ops ci_otg_ops = {
.start_gadget = ci_otg_start_gadget,
};
+static struct otg_hcd_ops ci_hcd_ops = {
+ .usb_bus_start_enum = usb_bus_start_enum,
+ .usb_control_msg = usb_control_msg,
+ .usb_hub_find_child = usb_hub_find_child,
+};
+
int ci_otg_fsm_work(struct ci_hdrc *ci)
{
/*
@@ -804,6 +810,7 @@ int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci)
ci->otg.fsm.id = hw_read_otgsc(ci, OTGSC_ID) ? 1 : 0;
ci->otg.state = OTG_STATE_UNDEFINED;
ci->otg.fsm.ops = &ci_otg_ops;
+ ci->otg.hcd_ops = &ci_hcd_ops;
ci->gadget.hnp_polling_support = 1;
ci->otg.fsm.host_req_flag = devm_kzalloc(ci->dev, 1, GFP_KERNEL);
if (!ci->otg.fsm.host_req_flag)
diff --git a/drivers/usb/common/usb-otg-fsm.c b/drivers/usb/common/usb-otg-fsm.c
index 610b5bd6..482d4c9 100644
--- a/drivers/usb/common/usb-otg-fsm.c
+++ b/drivers/usb/common/usb-otg-fsm.c
@@ -141,11 +141,16 @@ static void otg_hnp_polling_work(struct work_struct *work)
enum usb_otg_state state = otg->state;
u8 flag;
int retval;
+ struct otg_hcd_ops *hcd_ops = otg->hcd_ops;
if (state != OTG_STATE_A_HOST && state != OTG_STATE_B_HOST)
return;
- udev = usb_hub_find_child(otg->host->root_hub, 1);
+ if (!hcd_ops || !hcd_ops->usb_control_msg ||
+ !hcd_ops->usb_hub_find_child)
+ return;
+
+ udev = hcd_ops->usb_hub_find_child(otg->host->root_hub, 1);
if (!udev) {
dev_err(otg->host->controller,
"no usb dev connected, can't start HNP polling\n");
@@ -154,7 +159,7 @@ static void otg_hnp_polling_work(struct work_struct *work)
*fsm->host_req_flag = 0;
/* Get host request flag from connected USB device */
- retval = usb_control_msg(udev,
+ retval = hcd_ops->usb_control_msg(udev,
usb_rcvctrlpipe(udev, 0),
USB_REQ_GET_STATUS,
USB_DIR_IN | USB_RECIP_DEVICE,
@@ -183,7 +188,7 @@ static void otg_hnp_polling_work(struct work_struct *work)
if (state == OTG_STATE_A_HOST) {
/* Set b_hnp_enable */
if (!otg->host->b_hnp_enable) {
- retval = usb_control_msg(udev,
+ retval = hcd_ops->usb_control_msg(udev,
usb_sndctrlpipe(udev, 0),
USB_REQ_SET_FEATURE, 0,
USB_DEVICE_B_HNP_ENABLE,
@@ -262,7 +267,9 @@ static int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
otg_loc_conn(otg, 0);
otg_loc_sof(otg, 1);
otg_set_protocol(fsm, PROTO_HOST);
- usb_bus_start_enum(otg->host, otg->host->otg_port);
+ if (otg->hcd_ops && otg->hcd_ops->usb_bus_start_enum)
+ otg->hcd_ops->usb_bus_start_enum(otg->host,
+ otg->host->otg_port);
otg_start_hnp_polling(fsm);
break;
case OTG_STATE_A_IDLE:
diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c
index 3ffa4c6..011d36e 100644
--- a/drivers/usb/phy/phy-fsl-usb.c
+++ b/drivers/usb/phy/phy-fsl-usb.c
@@ -792,6 +792,12 @@ static struct otg_fsm_ops fsl_otg_ops = {
.start_gadget = fsl_otg_start_gadget,
};
+static struct otg_hcd_ops fsl_hcd_ops = {
+ .usb_bus_start_enum = usb_bus_start_enum,
+ .usb_control_msg = usb_control_msg,
+ .usb_hub_find_child = usb_hub_find_child,
+};
+
/* Initialize the global variable fsl_otg_dev and request IRQ for OTG */
static int fsl_otg_conf(struct platform_device *pdev)
{
@@ -820,6 +826,7 @@ static int fsl_otg_conf(struct platform_device *pdev)
/* Set OTG state machine operations */
fsl_otg_tc->otg.fsm.ops = &fsl_otg_ops;
+ fsl_otg_tc->otg.hcd_ops = &fsl_hcd_ops;
/* initialize the otg structure */
fsl_otg_tc->phy.label = DRIVER_DESC;
diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h
index e8a14dc..85b8fb5 100644
--- a/include/linux/usb/otg.h
+++ b/include/linux/usb/otg.h
@@ -12,6 +12,7 @@
#include <linux/phy/phy.h>
#include <linux/usb/phy.h>
#include <linux/usb/otg-fsm.h>
+#include <linux/usb/hcd.h>
struct usb_otg {
u8 default_a;
@@ -24,6 +25,7 @@ struct usb_otg {
enum usb_otg_state state;
struct otg_fsm fsm;
+ struct otg_hcd_ops *hcd_ops;
/* bind/unbind the host controller */
int (*set_host)(struct usb_otg *otg, struct usb_bus *host);
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Roger Quadros <rogerq@ti.com> |
|---|---|
| Date | 2016-06-08 11:20 +0200 |
| Subject | [PATCH v9 06/14] usb: gadget.h: Add OTG to gadget interface |
| Message-ID | <rHHOy-6Iz-43@gated-at.bofh.it> |
| In reply to | #1417111 |
The OTG core will use struct otg_gadget_ops to
start/stop the gadget controller.
The main purpose of this interface is to avoid directly
calling usb_gadget_start/stop() from the OTG core as they
wouldn't be defined in the built-in symbol table if
CONFIG_USB_GADGET is m.
Signed-off-by: Roger Quadros <rogerq@ti.com>
---
include/linux/usb/gadget.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 457651b..51e3bde 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -1100,6 +1100,22 @@ struct usb_gadget_driver {
};
+/*-------------------------------------------------------------------------*/
+
+/**
+ * struct otg_gadget_ops - Interface between OTG core and gadget
+ *
+ * Provided by the gadget core to allow the OTG core to start/stop the gadget
+ *
+ * @start: function to start the gadget
+ * @stop: function to stop the gadget
+ * @connect_control: function to connect/disconnect from the bus
+ */
+struct otg_gadget_ops {
+ int (*start)(struct usb_gadget *gadget);
+ int (*stop)(struct usb_gadget *gadget);
+ int (*connect_control)(struct usb_gadget *gadget, bool connect);
+};
/*-------------------------------------------------------------------------*/
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Peter Chen <hzpeterchen@gmail.com> |
|---|---|
| Date | 2016-06-09 07:30 +0200 |
| Message-ID | <rI0Hv-1YI-1@gated-at.bofh.it> |
| In reply to | #1417111 |
On Wed, Jun 8, 2016 at 5:03 PM, Roger Quadros <rogerq@ti.com> wrote:
> Hi,
>
> This series centralizes OTG/Dual-role functionality in the kernel.
> As of now I've got Dual-role functionality working pretty reliably on
> dra7-evm and am437x-gp-evm.
>
> DWC3 controller and TI platform related patches will be sent separately.
>
> Series is based on v4.7-rc1.
>
Roger, I will wait your dwc3 and TI patch set since one framework needs
one user at least, thanks.
Peter
> Why?:
> ----
>
> Currently there is no central location where OTG/dual-role functionality is
> implemented in the Linux USB stack and every USB controller driver is
> doing their own thing for OTG/dual-role. We can benefit from code-reuse
> and simplicity by adding the OTG/dual-role core driver.
>
> Newer OTG cores support standard host interface (e.g. xHCI) so
> host and gadget functionality are no longer closely knit like older
> cores. There needs to be a way to co-ordinate the operation of the
> host and gadget controllers in dual-role mode. i.e. to stop and start them
> from a central location. This central location should be the
> USB OTG/dual-role core.
>
> Host and gadget controllers might be sharing resources and can't
> be always running. One has to be stopped for the other to run.
> This couldn't be done till now but can be done from the OTG core.
>
> What?:
> -----
>
> The OTG/dual-role core consists of a set of APIs that allow
> registration of OTG controller device and OTG capable host and gadget
> controllers.
>
> - The OTG controller driver can provide the OTG capabilities and the
> Finite State Machine work function via 'struct usb_otg_config'
> at the time of registration i.e. usb_otg_register();
>
> struct usb_otg *usb_otg_register(struct device *dev,
> struct usb_otg_config *config);
> int usb_otg_unregister(struct device *dev);
> /**
> * struct usb_otg_config - otg controller configuration
> * @caps: otg capabilities of the controller
> * @ops: otg fsm operations
> * @otg_work: optional custom otg state machine work function
> */
> struct usb_otg_config {
> struct usb_otg_caps *otg_caps;
> struct otg_fsm_ops *fsm_ops;
> void (*otg_work)(struct work_struct *work);
> };
>
> The dual-role state machine is built-into the OTG core so nothing
> special needs to be provided if only dual-role functionality is desired.
> The low level OTG controller driver ops are povided via
> 'struct otg_fsm_ops *fsm_ops' in the 'struct usb_otg_config'.
>
> After registration, the OTG core waits for host, gadget controller
> and the gadget function driver to be registered. Once all resources are
> available it instantiates the Finite State Machine (FSM).
> The host/gadget controllers are started/stopped according to the FSM.
>
> - Host and gadget controllers that are a part of OTG/dual-role port must
> use the OTG core provided APIs to add/remove the host/gadget.
> i.e. hosts must use usb_otg_add_hcd() usb_otg_remove_hcd(),,
> gadgets must use usb_otg_add_gadget_udc() usb_del_gadget_udc().
> This ensures that the host and gadget controllers are not started till
> the state machine is ready and the right bus conditions are met.
> It also allows the host and gadget controllers to provide the OTG
> controller device to link them together. For Device tree boots
> the related OTG controller is automatically picked up via the
> 'otg-controller' property in the Host/Gadget controller nodes.
>
> int usb_otg_add_hcd(struct usb_hcd *hcd,
> unsigned int irqnum, unsigned long irqflags,
> struct device *otg_dev);
> void usb_otg_remove_hcd(struct usb_hcd *hcd);
>
> int usb_otg_add_gadget_udc(struct device *parent,
> struct usb_gadget *gadget,
> struct device *otg_dev);
> usb_del_gadget_udc() must be used for removal.
>
>
> - During the lifetime of the FSM, the OTG controller driver can provide
> inputs event changes using usb_otg_sync_inputs(). The OTG core will
> then schedule the FSM work function (or internal dual-role state machine)
> to update the FSM state. The FSM then calls the OTG controller
> operations (fsm_ops) as necessary.
> void usb_otg_sync_inputs(struct usb_otg *otg);
>
> - The following 2 functions are provided as helpers for use by the
> OTG controller driver to start/stop the host/gadget controllers.
> int usb_otg_start_host(struct usb_otg *otg, int on);
> int usb_otg_start_gadget(struct usb_otg *otg, int on);
>
> - The following function is provided for use by the USB host stack
> to sync OTG related events to the OTG state machine.
> e.g. change in host_bus->b_hnp_enable, gadget->b_hnp_enable
> int usb_otg_kick_fsm(struct device *otg_device);
>
> - The following function is provided for use by the USB gadget stack
> to notify OTG/DRD about gadget function driver being ready/not-ready
> int usb_otg_gadget_ready(struct usb_gadget *gadget, bool ready)
>
> Changelog:
> ---------
> v9:
> - In the DT bindings, clearly indicate which properties are for OTG controller
> and which ones are for host/device controllers
> - Removed host/gadget wait list from otg core. Use defer probing if host/gadget
> registers before dual-role/otg controller.
> - move gadget registering to otg core from udc_bind_to_driver()/usb_gadget_remove_driver()
> to usb_add_gadget_udc_release()/usb_del_gadget_udc(). This means that we need
> an additional mechanism to know when the gadget function driver registers.
> So we add usb_otg_gadget_ready() API to allow gadget to notify otg core about
> ready/not-ready function driver.
> - update otg->caps based on capabilities provided by the controller and the
> device tree overrides.
> - in usb_drd_work() we must keep calling the drd_statemachine() as long as
> there is a state change.
> - updated kconfig so that usbotg can be a module when both host and gadget
> are modules.
> - rebased on v4.7-rc1
>
> v8:
> - split out start/stop gadget and connect/disconnect operations.
> - make CONFIG_OTG dpend on CONFIG_USB_GADGET as well apart from CONFIG_USB
> - use create_freezable_workqueue() for OTG work as per Peter's suggestion.
> - remove usb-otg.h as we're not initializing any OTG timers.
> - don't include unnecessary headers in usb-otg.c (i.e. hrtimer.h & ktime.h)
>
> v7:
> - added dual-role support for host controllers requiring a companion
> controller. e.g. EHCI + OHCI.
> - added of_usb_get_otg() to get the OTG controller device
> from the USB controller's device node.
> - addressed review comments.
>
> v6:
> - added otg specific APIs for host/gadget registration. behaviour of
> original host/gadget API remains unchanged. Platform devices can now
> pass the otg device explicitly while registering host/gadget.
> - moved hcd specific operations from struct otg_fsm to struct hcd_ops.
> - made struct usb_otg mandatory for all otg related APIs.
> - allow otg controller to provide it's own otg_work function so that
> it can implement it's own state machine.
> - removed otg fsm and timers from usb-otg.c. Only dual-role state machine
> is implemented.
> - vbus is controlled in the dual-role state machine.
> - PM runtime is used around drd_statemachine().
> - added otg_dev to xhci platform data to allow platform code to specify
> the otg controller tied to the xhci host controller.
>
> v5: Internal version. Not sent to mailing list
>
> v4:
> - Added DT support for tying otg-controller to host and gadget
> controllers. For DT we no longer have the constraint that
> OTG controller needs to be parent of host and gadget. They can be
> tied together using the "otg-controller" property.
> - Relax the requirement for DT case that otg controller must register
> before host/gadget. We maintain a wait list of host/gadget devices
> waiting on the otg controller.
> - Use a single struct usb_otg for otg data.
> - Don't override host/gadget start/stop APIs. Let the controller
> drivers do what they want as they know best. Helper API is provided
> for controller start/stop that controller driver can use.
> - Introduce struct usb_otg_config to pass the otg capabilities,
> otg ops and otg timer timeouts during otg controller registration.
> - rebased on Greg's usb.git/usb-next
>
> v3:
> - all otg related definations now in otg.h
> - single kernel config USB_OTG to enable OTG core and FSM.
> - resolved symbol dependency issues.
> - use dev_vdbg instead of VDBG() in usb-otg-fsm.c
> - rebased on v4.2-rc1
>
> v2:
> - Use add/remove_hcd() instead of start/stop_hcd() to enable/disable
> the host controller
> - added dual-role-device (DRD) state machine which is a much simpler
> mode of operation when compared to OTG. Here we don't support fancy
> OTG features like HNP, SRP, on the fly role-swap. The mode of operation
> is determined based on ID pin (cable type) and the role doesn't change
> till the cable type changes.
>
> --
> cheers,
> -roger
>
> Roger Quadros (13):
> usb: hcd: Initialize hcd->flags to 0
> usb: otg-fsm: Prevent build warning "VDBG" redefined
> usb: hcd.h: Add OTG to HCD interface
> usb: otg-fsm: use usb_otg wherever possible
> usb: otg-fsm: move host controller operations into usb_otg->hcd_ops
> usb: gadget.h: Add OTG to gadget interface
> usb: otg: get rid of CONFIG_USB_OTG_FSM in favour of CONFIG_USB_OTG
> usb: otg: add OTG/dual-role core
> usb: of: add an API to get OTG device from USB controller node
> usb: otg: use dev_dbg() instead of VDBG()
> usb: hcd: Adapt to OTG core
> usb: gadget: udc: adapt to OTG core
> usb: host: xhci-plat: Add otg device to platform data
>
> Yoshihiro Shimoda (1):
> usb: otg: add hcd companion support
>
> Documentation/devicetree/bindings/usb/generic.txt | 6 +
> Documentation/usb/chipidea.txt | 2 +-
> drivers/usb/Kconfig | 18 +
> drivers/usb/Makefile | 1 +
> drivers/usb/chipidea/Makefile | 2 +-
> drivers/usb/chipidea/ci.h | 3 +-
> drivers/usb/chipidea/core.c | 14 +-
> drivers/usb/chipidea/debug.c | 2 +-
> drivers/usb/chipidea/otg_fsm.c | 176 ++---
> drivers/usb/chipidea/otg_fsm.h | 2 +-
> drivers/usb/chipidea/udc.c | 17 +-
> drivers/usb/common/Makefile | 5 +-
> drivers/usb/common/common.c | 27 +
> drivers/usb/common/usb-otg-fsm.c | 203 +++---
> drivers/usb/common/usb-otg.c | 846 ++++++++++++++++++++++
> drivers/usb/core/Kconfig | 22 -
> drivers/usb/core/hcd.c | 56 ++
> drivers/usb/gadget/Kconfig | 1 +
> drivers/usb/gadget/udc/udc-core.c | 202 +++++-
> drivers/usb/host/xhci-plat.c | 35 +-
> drivers/usb/phy/Kconfig | 2 +-
> drivers/usb/phy/phy-fsl-usb.c | 155 ++--
> drivers/usb/phy/phy-fsl-usb.h | 3 +-
> include/linux/usb/gadget.h | 22 +
> include/linux/usb/hcd.h | 29 +
> include/linux/usb/of.h | 9 +
> include/linux/usb/otg-fsm.h | 154 +---
> include/linux/usb/otg.h | 293 +++++++-
> include/linux/usb/xhci_pdriver.h | 3 +
> 29 files changed, 1848 insertions(+), 462 deletions(-)
> create mode 100644 drivers/usb/common/usb-otg.c
>
> --
> 2.7.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
[toc] | [prev] | [next] | [standalone]
| From | Roger Quadros <rogerq@ti.com> |
|---|---|
| Date | 2016-06-09 09:40 +0200 |
| Message-ID | <rI2Jk-3h2-19@gated-at.bofh.it> |
| In reply to | #1418089 |
Peter & Yoshihiro, On 09/06/16 08:27, Peter Chen wrote: > On Wed, Jun 8, 2016 at 5:03 PM, Roger Quadros <rogerq@ti.com> wrote: >> Hi, >> >> This series centralizes OTG/Dual-role functionality in the kernel. >> As of now I've got Dual-role functionality working pretty reliably on >> dra7-evm and am437x-gp-evm. >> >> DWC3 controller and TI platform related patches will be sent separately. >> >> Series is based on v4.7-rc1. >> > > Roger, I will wait your dwc3 and TI patch set since one framework needs > one user at least, thanks. Sure I will post the dwc3 patch. Yoshihiro, could you please post the platform side patches for your platform that enables dual-role using this framework? Thanks. -- cheers, -roger
[toc] | [prev] | [next] | [standalone]
| From | Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> |
|---|---|
| Date | 2016-06-09 12:20 +0200 |
| Message-ID | <rI5e9-4ZN-7@gated-at.bofh.it> |
| In reply to | #1418133 |
Hi Roger, > From: Roger Quadros > Sent: Thursday, June 09, 2016 4:31 PM > > Peter & Yoshihiro, > > On 09/06/16 08:27, Peter Chen wrote: > > On Wed, Jun 8, 2016 at 5:03 PM, Roger Quadros <rogerq@ti.com> wrote: > >> Hi, > >> > >> This series centralizes OTG/Dual-role functionality in the kernel. > >> As of now I've got Dual-role functionality working pretty reliably on > >> dra7-evm and am437x-gp-evm. > >> > >> DWC3 controller and TI platform related patches will be sent separately. > >> > >> Series is based on v4.7-rc1. > >> > > > > Roger, I will wait your dwc3 and TI patch set since one framework needs > > one user at least, thanks. > > Sure I will post the dwc3 patch. > > Yoshihiro, > > could you please post the platform side patches for your platform > that enables dual-role using this framework? Thanks. Sure. I will do that. Best regards, Yoshihiro Shimoda > -- > cheers, > -roger
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | linux.kernel
csiph-web