Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1371633 > unrolled thread
| Started by | Roger Quadros <rogerq@ti.com> |
|---|---|
| First post | 2016-04-05 16:10 +0200 |
| Last post | 2016-04-05 16:20 +0200 |
| Articles | 14 on this page of 34 — 4 participants |
Back to article view | Back to linux.kernel
[PATCH v6 00/12] USB OTG/dual-role framework Roger Quadros <rogerq@ti.com> - 2016-04-05 16:10 +0200
[PATCH v6 10/12] usb: doc: dt-binding: Add otg-controller property Roger Quadros <rogerq@ti.com> - 2016-04-05 16:10 +0200
[PATCH v6 09/12] usb: gadget: udc: adapt to OTG core Roger Quadros <rogerq@ti.com> - 2016-04-05 16:10 +0200
[PATCH v6 12/12] usb: host: xhci-plat: Add otg device to platform data Roger Quadros <rogerq@ti.com> - 2016-04-05 16:10 +0200
RE: [PATCH v6 12/12] usb: host: xhci-plat: Add otg device to platform data Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> - 2016-04-06 05:30 +0200
Re: [PATCH v6 12/12] usb: host: xhci-plat: Add otg device to platform data Roger Quadros <rogerq@ti.com> - 2016-04-06 08:40 +0200
[PATCH v6 06/12] usb: otg: get rid of CONFIG_USB_OTG_FSM in favour of CONFIG_USB_OTG Roger Quadros <rogerq@ti.com> - 2016-04-05 16:10 +0200
[PATCH v6 07/12] usb: otg: add OTG/dual-role core Roger Quadros <rogerq@ti.com> - 2016-04-05 16:10 +0200
RE: [PATCH v6 07/12] usb: otg: add OTG/dual-role core Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> - 2016-04-07 11:00 +0200
Re: [PATCH v6 07/12] usb: otg: add OTG/dual-role core Roger Quadros <rogerq@ti.com> - 2016-04-07 13:50 +0200
RE: [PATCH v6 07/12] usb: otg: add OTG/dual-role core Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> - 2016-04-08 13:30 +0200
Re: [PATCH v6 07/12] usb: otg: add OTG/dual-role core Roger Quadros <rogerq@ti.com> - 2016-04-11 13:00 +0200
RE: [PATCH v6 07/12] usb: otg: add OTG/dual-role core Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> - 2016-04-14 10:40 +0200
Re: [PATCH v6 07/12] usb: otg: add OTG/dual-role core Roger Quadros <rogerq@ti.com> - 2016-04-14 13:10 +0200
RE: [PATCH v6 07/12] usb: otg: add OTG/dual-role core Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> - 2016-04-14 13:20 +0200
Re: [PATCH v6 07/12] usb: otg: add OTG/dual-role core Roger Quadros <rogerq@ti.com> - 2016-04-14 13:40 +0200
RE: [PATCH v6 07/12] usb: otg: add OTG/dual-role core Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> - 2016-04-15 12:00 +0200
Re: [PATCH v6 07/12] usb: otg: add OTG/dual-role core Roger Quadros <rogerq@ti.com> - 2016-04-15 13:00 +0200
RE: [PATCH v6 07/12] usb: otg: add OTG/dual-role core Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> - 2016-04-15 12:10 +0200
Re: [PATCH v6 07/12] usb: otg: add OTG/dual-role core Peter Chen <hzpeterchen@gmail.com> - 2016-04-15 11:40 +0200
Re: [PATCH v6 07/12] usb: otg: add OTG/dual-role core Roger Quadros <rogerq@ti.com> - 2016-04-15 13:10 +0200
[PATCH v6 05/12] usb: gadget.h: Add OTG to gadget interface Roger Quadros <rogerq@ti.com> - 2016-04-05 16:10 +0200
[PATCH v6 02/12] usb: hcd.h: Add OTG to HCD interface Roger Quadros <rogerq@ti.com> - 2016-04-05 16:10 +0200
[PATCH v6 04/12] usb: otg-fsm: move host controller operations into usb_otg->hcd_ops Roger Quadros <rogerq@ti.com> - 2016-04-05 16:10 +0200
[PATCH v6 11/12] usb: core: hub: Notify OTG fsm when A device sets b_hnp_enable Roger Quadros <rogerq@ti.com> - 2016-04-05 16:10 +0200
[PATCH v6 01/12] usb: hcd: Initialize hcd->flags to 0 Roger Quadros <rogerq@ti.com> - 2016-04-05 16:10 +0200
Re: [PATCH v6 01/12] usb: hcd: Initialize hcd->flags to 0 Felipe Balbi <balbi@kernel.org> - 2016-04-06 08:20 +0200
Re: [PATCH v6 01/12] usb: hcd: Initialize hcd->flags to 0 Roger Quadros <rogerq@ti.com> - 2016-04-06 08:40 +0200
Re: [PATCH v6 01/12] usb: hcd: Initialize hcd->flags to 0 Peter Chen <hzpeterchen@gmail.com> - 2016-04-07 11:50 +0200
Re: [PATCH v6 01/12] usb: hcd: Initialize hcd->flags to 0 Roger Quadros <rogerq@ti.com> - 2016-04-07 12:50 +0200
Re: [PATCH v6 01/12] usb: hcd: Initialize hcd->flags to 0 Peter Chen <hzpeterchen@gmail.com> - 2016-04-08 03:10 +0200
Re: [PATCH v6 01/12] usb: hcd: Initialize hcd->flags to 0 Roger Quadros <rogerq@ti.com> - 2016-04-08 09:20 +0200
Re: [PATCH v6 01/12] usb: hcd: Initialize hcd->flags to 0 Peter Chen <hzpeterchen@gmail.com> - 2016-04-08 10:00 +0200
[PATCH v6 08/12] usb: hcd: Adapt to OTG core Roger Quadros <rogerq@ti.com> - 2016-04-05 16:20 +0200
Page 2 of 2 — ← Prev page 1 [2]
| From | Roger Quadros <rogerq@ti.com> |
|---|---|
| Date | 2016-04-15 13:10 +0200 |
| Subject | Re: [PATCH v6 07/12] usb: otg: add OTG/dual-role core |
| Message-ID | <ro9No-21n-11@gated-at.bofh.it> |
| In reply to | #1379647 |
On 15/04/16 12:25, Peter Chen wrote:
> On Tue, Apr 05, 2016 at 05:05:12PM +0300, Roger Quadros wrote:
>> + * usb_otg_register() - Register the OTG/dual-role device to OTG core
>> + * @dev: OTG/dual-role controller device.
>> + * @config: OTG configuration.
>> + *
>> + * Registers the OTG/dual-role controller device with the USB OTG core.
>> + *
>> + * Return: struct usb_otg * if success, ERR_PTR() if error.
>> + */
>> +struct usb_otg *usb_otg_register(struct device *dev,
>> + struct usb_otg_config *config)
>> +{
>> + struct usb_otg *otg;
>> + struct otg_wait_data *wait;
>> + int ret = 0;
>> +
>> + if (!dev || !config || !config->fsm_ops)
>> + return ERR_PTR(-EINVAL);
>> +
>> + /* already in list? */
>> + mutex_lock(&otg_list_mutex);
>> + if (usb_otg_get_data(dev)) {
>> + dev_err(dev, "otg: %s: device already in otg list\n",
>> + __func__);
>> + ret = -EINVAL;
>> + goto unlock;
>> + }
>> +
>> + /* allocate and add to list */
>> + otg = kzalloc(sizeof(*otg), GFP_KERNEL);
>> + if (!otg) {
>> + ret = -ENOMEM;
>> + goto unlock;
>> + }
>> +
>> + otg->dev = dev;
>> + otg->caps = config->otg_caps;
>> +
>> + if ((otg->caps->hnp_support || otg->caps->srp_support ||
>> + otg->caps->adp_support) && !config->otg_work)
>> + dev_info(dev, "otg: limiting to dual-role\n");
>
> What does above mean? Customized otg_work item may be dual-role,
> may be full otg.
I'm checking for !config->otg_work so we're sure of using the
default dual-role only work function.
>
>> +
>> + if (config->otg_work) /* custom otg_work ? */
>> + INIT_WORK(&otg->work, config->otg_work);
>> + else
>> + INIT_WORK(&otg->work, usb_otg_work);
>> +
>> + otg->wq = create_singlethread_workqueue("usb_otg");
>> + if (!otg->wq) {
>> + dev_err(dev, "otg: %s: can't create workqueue\n",
>> + __func__);
>> + ret = -ENOMEM;
>> + goto err_wq;
>> + }
>
> I found a bug that caused by non-freezable workqueue, change it
> as freezable please.
>
> https://marc.ttias.be/linux-stable/2016-03/msg00723.php
OK.
>
> I will review the whole set from next week.
Thanks.
--
cheers,
-roger
[toc] | [prev] | [next] | [standalone]
| From | Roger Quadros <rogerq@ti.com> |
|---|---|
| Date | 2016-04-05 16:10 +0200 |
| Subject | [PATCH v6 05/12] usb: gadget.h: Add OTG to gadget interface |
| Message-ID | <rkzQ7-4UX-53@gated-at.bofh.it> |
| In reply to | #1371633 |
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>
Reviewed-by: Peter Chen <peter.chen@freescale.com>
---
include/linux/usb/gadget.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 5d4e151..8c0ae64 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -1100,6 +1100,20 @@ 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
+ */
+struct otg_gadget_ops {
+ int (*start)(struct usb_gadget *gadget);
+ int (*stop)(struct usb_gadget *gadget);
+};
/*-------------------------------------------------------------------------*/
--
2.5.0
[toc] | [prev] | [next] | [standalone]
| From | Roger Quadros <rogerq@ti.com> |
|---|---|
| Date | 2016-04-05 16:10 +0200 |
| Subject | [PATCH v6 02/12] usb: hcd.h: Add OTG to HCD interface |
| Message-ID | <rkzQ8-4UX-65@gated-at.bofh.it> |
| In reply to | #1371633 |
The OTG core will use struct otg_hcd_ops to interface
with the HCD controller.
The main purpose of this interface is to avoid directly
calling HCD APIs from the OTG core as they
wouldn't be defined in the built-in symbol table if
CONFIG_USB is m.
Signed-off-by: Roger Quadros <rogerq@ti.com>
---
include/linux/usb/hcd.h | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index b98f831..861ccaa 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -399,6 +399,30 @@ struct hc_driver {
};
+/**
+ * struct otg_hcd_ops - Interface between OTG core and HCD
+ *
+ * Provided by the HCD core to allow the OTG core to interface with the HCD
+ *
+ * @add: function to add the HCD
+ * @remove: function to remove the HCD
+ * @usb_bus_start_enum: function to immediately start bus enumeration
+ * @usb_control_msg: function to build and send of a control urb
+ * @usb_hub_find_child: function to get pointer to the child device
+ */
+struct otg_hcd_ops {
+ int (*add)(struct usb_hcd *hcd,
+ unsigned int irqnum, unsigned long irqflags);
+ void (*remove)(struct usb_hcd *hcd);
+ int (*usb_bus_start_enum)(struct usb_bus *bus, unsigned int port_num);
+ int (*usb_control_msg)(struct usb_device *dev, unsigned int pipe,
+ __u8 request, __u8 requesttype, __u16 value,
+ __u16 index, void *data, __u16 size,
+ int timeout);
+ struct usb_device * (*usb_hub_find_child)(struct usb_device *hdev,
+ int port1);
+};
+
static inline int hcd_giveback_urb_in_bh(struct usb_hcd *hcd)
{
return hcd->driver->flags & HCD_BH;
--
2.5.0
[toc] | [prev] | [next] | [standalone]
| From | Roger Quadros <rogerq@ti.com> |
|---|---|
| Date | 2016-04-05 16:10 +0200 |
| Subject | [PATCH v6 04/12] usb: otg-fsm: move host controller operations into usb_otg->hcd_ops |
| Message-ID | <rkzQ8-4UX-69@gated-at.bofh.it> |
| In reply to | #1371633 |
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>
---
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 f4e9fb5..5fdf8ca 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)
{
/*
@@ -805,6 +811,7 @@ int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci)
ci->otg.state = OTG_STATE_UNDEFINED;
ci->otg.fsm.ops = &ci_otg_ops;
ci->otg.fsm.dev = ci->dev;
+ 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 abc462c..2cb4aed 100644
--- a/drivers/usb/common/usb-otg-fsm.c
+++ b/drivers/usb/common/usb-otg-fsm.c
@@ -135,11 +135,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");
@@ -148,7 +153,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,
@@ -177,7 +182,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,
@@ -256,7 +261,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 a18a2ee..39605d5 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)
{
@@ -821,6 +827,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.fsm.dev = &pdev->dev;
+ 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.5.0
[toc] | [prev] | [next] | [standalone]
| From | Roger Quadros <rogerq@ti.com> |
|---|---|
| Date | 2016-04-05 16:10 +0200 |
| Subject | [PATCH v6 11/12] usb: core: hub: Notify OTG fsm when A device sets b_hnp_enable |
| Message-ID | <rkzQ7-4UX-51@gated-at.bofh.it> |
| In reply to | #1371633 |
This is the a_set_b_hnp_enable flag in the OTG state machine
diagram and must be set when the A-Host has successfully set
the b_hnp_enable feature of the OTG-B-Peripheral attached to it.
When this bit changes we kick our OTG FSM to make note of the
change and act accordingly.
Signed-off-by: Roger Quadros <rogerq@ti.com>
---
drivers/usb/core/hub.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 38cc4ba..27e3b4c 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2273,6 +2273,7 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
&& udev->parent == udev->bus->root_hub) {
struct usb_otg_descriptor *desc = NULL;
struct usb_bus *bus = udev->bus;
+ struct usb_hcd *hcd = bus_to_hcd(bus);
unsigned port1 = udev->portnum;
/* descriptor may appear anywhere in config */
@@ -2302,6 +2303,9 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
dev_err(&udev->dev, "can't set HNP mode: %d\n",
err);
bus->b_hnp_enable = 0;
+ } else {
+ /* notify OTG fsm about a_set_b_hnp_enable */
+ usb_otg_kick_fsm(hcd->otg_dev);
}
} else if (desc->bLength == sizeof
(struct usb_otg_descriptor)) {
@@ -2312,10 +2316,14 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
USB_DEVICE_A_ALT_HNP_SUPPORT,
0, NULL, 0,
USB_CTRL_SET_TIMEOUT);
- if (err < 0)
+ if (err < 0) {
dev_err(&udev->dev,
"set a_alt_hnp_support failed: %d\n",
err);
+ } else {
+ /* notify OTG fsm about a_set_b_hnp_enable */
+ usb_otg_kick_fsm(hcd->otg_dev);
+ }
}
}
#endif
@@ -4355,8 +4363,13 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
*/
if (!hdev->parent) {
delay = HUB_ROOT_RESET_TIME;
- if (port1 == hdev->bus->otg_port)
+ if (port1 == hdev->bus->otg_port) {
hdev->bus->b_hnp_enable = 0;
+#ifdef CONFIG_USB_OTG
+ /* notify OTG fsm about a_set_b_hnp_enable change */
+ usb_otg_kick_fsm(hcd->otg_dev);
+#endif
+ }
}
/* Some low speed devices have problems with the quick delay, so */
--
2.5.0
[toc] | [prev] | [next] | [standalone]
| From | Roger Quadros <rogerq@ti.com> |
|---|---|
| Date | 2016-04-05 16:10 +0200 |
| Subject | [PATCH v6 01/12] usb: hcd: Initialize hcd->flags to 0 |
| Message-ID | <rkzQ8-4UX-55@gated-at.bofh.it> |
| In reply to | #1371633 |
When using the OTG/drd library we can call hcd_add/remove
consecutively without calling hcd_alloc in between so 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>
---
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 2ca2cef..6b1930d 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2706,6 +2706,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
int retval;
struct usb_device *rhdev;
+ hcd->flags = 0;
if (IS_ENABLED(CONFIG_USB_PHY) && !hcd->usb_phy) {
struct usb_phy *phy = usb_get_phy_dev(hcd->self.controller, 0);
--
2.5.0
[toc] | [prev] | [next] | [standalone]
| From | Felipe Balbi <balbi@kernel.org> |
|---|---|
| Date | 2016-04-06 08:20 +0200 |
| Subject | Re: [PATCH v6 01/12] usb: hcd: Initialize hcd->flags to 0 |
| Message-ID | <rkOYO-880-9@gated-at.bofh.it> |
| In reply to | #1371655 |
[Multipart message — attachments visible in raw view] — view raw
Hi, Roger Quadros <rogerq@ti.com> writes: > diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c > index 2ca2cef..6b1930d 100644 > --- a/drivers/usb/core/hcd.c > +++ b/drivers/usb/core/hcd.c > @@ -2706,6 +2706,7 @@ int usb_add_hcd(struct usb_hcd *hcd, > int retval; > struct usb_device *rhdev; > > + hcd->flags = 0; seems like this would make more sense in usb_del_hcd() instead. -- balbi
[toc] | [prev] | [next] | [standalone]
| From | Roger Quadros <rogerq@ti.com> |
|---|---|
| Date | 2016-04-06 08:40 +0200 |
| Subject | Re: [PATCH v6 01/12] usb: hcd: Initialize hcd->flags to 0 |
| Message-ID | <rkPia-8gZ-9@gated-at.bofh.it> |
| In reply to | #1372215 |
On 06/04/16 09:09, Felipe Balbi wrote: > > Hi, > > Roger Quadros <rogerq@ti.com> writes: >> diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c >> index 2ca2cef..6b1930d 100644 >> --- a/drivers/usb/core/hcd.c >> +++ b/drivers/usb/core/hcd.c >> @@ -2706,6 +2706,7 @@ int usb_add_hcd(struct usb_hcd *hcd, >> int retval; >> struct usb_device *rhdev; >> >> + hcd->flags = 0; > > seems like this would make more sense in usb_del_hcd() instead. > OK, I'll move it there. cheers, -roger
[toc] | [prev] | [next] | [standalone]
| From | Peter Chen <hzpeterchen@gmail.com> |
|---|---|
| Date | 2016-04-07 11:50 +0200 |
| Subject | Re: [PATCH v6 01/12] usb: hcd: Initialize hcd->flags to 0 |
| Message-ID | <rleJA-1Ne-7@gated-at.bofh.it> |
| In reply to | #1372224 |
On Wed, Apr 06, 2016 at 09:32:22AM +0300, Roger Quadros wrote: > On 06/04/16 09:09, Felipe Balbi wrote: > > > > Hi, > > > > Roger Quadros <rogerq@ti.com> writes: > >> diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c > >> index 2ca2cef..6b1930d 100644 > >> --- a/drivers/usb/core/hcd.c > >> +++ b/drivers/usb/core/hcd.c > >> @@ -2706,6 +2706,7 @@ int usb_add_hcd(struct usb_hcd *hcd, > >> int retval; > >> struct usb_device *rhdev; > >> > >> + hcd->flags = 0; > > I am not sure if this usb_add(remove)_hcd pair is safe and clean enough for start/stop host role. From my point, we may need to do like .probe/.remove host platform driver interface. In that case, we can make sure the clocks and regulators are off, and hcd will be zero-initialized next time. Assume we are at gadget mode, we may not hope the vbus regulator is still on which is for host only. So, this part may need to implement by each user. -- Best Regards, Peter Chen
[toc] | [prev] | [next] | [standalone]
| From | Roger Quadros <rogerq@ti.com> |
|---|---|
| Date | 2016-04-07 12:50 +0200 |
| Subject | Re: [PATCH v6 01/12] usb: hcd: Initialize hcd->flags to 0 |
| Message-ID | <rlfFE-2v3-7@gated-at.bofh.it> |
| In reply to | #1373210 |
On 07/04/16 12:42, Peter Chen wrote: > On Wed, Apr 06, 2016 at 09:32:22AM +0300, Roger Quadros wrote: >> On 06/04/16 09:09, Felipe Balbi wrote: >>> >>> Hi, >>> >>> Roger Quadros <rogerq@ti.com> writes: >>>> diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c >>>> index 2ca2cef..6b1930d 100644 >>>> --- a/drivers/usb/core/hcd.c >>>> +++ b/drivers/usb/core/hcd.c >>>> @@ -2706,6 +2706,7 @@ int usb_add_hcd(struct usb_hcd *hcd, >>>> int retval; >>>> struct usb_device *rhdev; >>>> >>>> + hcd->flags = 0; >>> > > I am not sure if this usb_add(remove)_hcd pair is safe and clean enough > for start/stop host role. From my point, we may need to do like > .probe/.remove host platform driver interface. In that case, we can make probe and remove are meant to be called from bus layer. I do not see a way how OTG framework can call probe/remove of HCD driver. Some HCDs may be platform devices, some PCI, so different entities are calling the HCD .probe hook. > sure the clocks and regulators are off, and hcd will be zero-initialized why can't we make that sure that is taken care of within the hcd_ops? Why should some driver keep its regulators and clocks enabled when hcd is stopped? It doesn't need to. If it is doing so now, it needs to be fixed. > next time. Assume we are at gadget mode, we may not hope the vbus regulator > is still on which is for host only. So, this part may need to implement > by each user. > Yes, correctness of this has to be taken care by each driver. cheers, -roger
[toc] | [prev] | [next] | [standalone]
| From | Peter Chen <hzpeterchen@gmail.com> |
|---|---|
| Date | 2016-04-08 03:10 +0200 |
| Subject | Re: [PATCH v6 01/12] usb: hcd: Initialize hcd->flags to 0 |
| Message-ID | <rlt5T-4eY-5@gated-at.bofh.it> |
| In reply to | #1373266 |
On Thu, Apr 07, 2016 at 01:40:21PM +0300, Roger Quadros wrote: > On 07/04/16 12:42, Peter Chen wrote: > > On Wed, Apr 06, 2016 at 09:32:22AM +0300, Roger Quadros wrote: > >> On 06/04/16 09:09, Felipe Balbi wrote: > >>> > >>> Hi, > >>> > >>> Roger Quadros <rogerq@ti.com> writes: > >>>> diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c > >>>> index 2ca2cef..6b1930d 100644 > >>>> --- a/drivers/usb/core/hcd.c > >>>> +++ b/drivers/usb/core/hcd.c > >>>> @@ -2706,6 +2706,7 @@ int usb_add_hcd(struct usb_hcd *hcd, > >>>> int retval; > >>>> struct usb_device *rhdev; > >>>> > >>>> + hcd->flags = 0; > >>> > > > > I am not sure if this usb_add(remove)_hcd pair is safe and clean enough > > for start/stop host role. From my point, we may need to do like > > .probe/.remove host platform driver interface. In that case, we can make > > probe and remove are meant to be called from bus layer. > I do not see a way how OTG framework can call probe/remove of HCD driver. > Some HCDs may be platform devices, some PCI, so different entities are calling > the HCD .probe hook. > > > sure the clocks and regulators are off, and hcd will be zero-initialized > > why can't we make that sure that is taken care of within the hcd_ops? > Why should some driver keep its regulators and clocks enabled when hcd is stopped? > It doesn't need to. If it is doing so now, it needs to be fixed. > Well, you may misunderstand me. I mean your hcd_ops->start or ->stop is hard to be a general one which only calls usb_hcd_add or usb_hcd_remove. It needs to implement like .probe or .remove at platform driver, some example code like host_start and host_stop at drivers/usb/chipidea/host.c. -- Best Regards, Peter Chen
[toc] | [prev] | [next] | [standalone]
| From | Roger Quadros <rogerq@ti.com> |
|---|---|
| Date | 2016-04-08 09:20 +0200 |
| Subject | Re: [PATCH v6 01/12] usb: hcd: Initialize hcd->flags to 0 |
| Message-ID | <rlyRY-eV-7@gated-at.bofh.it> |
| In reply to | #1373918 |
On 08/04/16 04:01, Peter Chen wrote: > On Thu, Apr 07, 2016 at 01:40:21PM +0300, Roger Quadros wrote: >> On 07/04/16 12:42, Peter Chen wrote: >>> On Wed, Apr 06, 2016 at 09:32:22AM +0300, Roger Quadros wrote: >>>> On 06/04/16 09:09, Felipe Balbi wrote: >>>>> >>>>> Hi, >>>>> >>>>> Roger Quadros <rogerq@ti.com> writes: >>>>>> diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c >>>>>> index 2ca2cef..6b1930d 100644 >>>>>> --- a/drivers/usb/core/hcd.c >>>>>> +++ b/drivers/usb/core/hcd.c >>>>>> @@ -2706,6 +2706,7 @@ int usb_add_hcd(struct usb_hcd *hcd, >>>>>> int retval; >>>>>> struct usb_device *rhdev; >>>>>> >>>>>> + hcd->flags = 0; >>>>> >>> >>> I am not sure if this usb_add(remove)_hcd pair is safe and clean enough >>> for start/stop host role. From my point, we may need to do like >>> .probe/.remove host platform driver interface. In that case, we can make >> >> probe and remove are meant to be called from bus layer. >> I do not see a way how OTG framework can call probe/remove of HCD driver. >> Some HCDs may be platform devices, some PCI, so different entities are calling >> the HCD .probe hook. >> >>> sure the clocks and regulators are off, and hcd will be zero-initialized >> >> why can't we make that sure that is taken care of within the hcd_ops? >> Why should some driver keep its regulators and clocks enabled when hcd is stopped? >> It doesn't need to. If it is doing so now, it needs to be fixed. >> > > Well, you may misunderstand me. I mean your hcd_ops->start or ->stop > is hard to be a general one which only calls usb_hcd_add or > usb_hcd_remove. It needs to implement like .probe or .remove at platform > driver, some example code like host_start and host_stop at > drivers/usb/chipidea/host.c. > The only extra thing the host_start/stop() of that driver is doing is enabling/disabling the VBUS regulator. In the OTG/dual role scope VBUS regulator handling has to be done via the OTG driver using the otg ops otg_drv_vbus() and not at HCD level. Do you agree? I don't want to complicate the OTG to HCD interface by adding new hooks there. If HCD driver wants to do something special for OTG case it can always do that within the struct hc_driver interface. But ideally OTG specific handling must be done in the OTG driver. All that the HCD driver should care about is making sure all used resources are disabled once usb_remove_hcd() is called. cheers, -roger
[toc] | [prev] | [next] | [standalone]
| From | Peter Chen <hzpeterchen@gmail.com> |
|---|---|
| Date | 2016-04-08 10:00 +0200 |
| Subject | Re: [PATCH v6 01/12] usb: hcd: Initialize hcd->flags to 0 |
| Message-ID | <rlzuG-vj-9@gated-at.bofh.it> |
| In reply to | #1374031 |
On Fri, Apr 08, 2016 at 10:16:30AM +0300, Roger Quadros wrote:
> On 08/04/16 04:01, Peter Chen wrote:
> > On Thu, Apr 07, 2016 at 01:40:21PM +0300, Roger Quadros wrote:
> >> On 07/04/16 12:42, Peter Chen wrote:
> >>> On Wed, Apr 06, 2016 at 09:32:22AM +0300, Roger Quadros wrote:
> >>>> On 06/04/16 09:09, Felipe Balbi wrote:
> >>>>>
> >>>>> Hi,
> >>>>>
> >>>>> Roger Quadros <rogerq@ti.com> writes:
> >>>>>> diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
> >>>>>> index 2ca2cef..6b1930d 100644
> >>>>>> --- a/drivers/usb/core/hcd.c
> >>>>>> +++ b/drivers/usb/core/hcd.c
> >>>>>> @@ -2706,6 +2706,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
> >>>>>> int retval;
> >>>>>> struct usb_device *rhdev;
> >>>>>>
> >>>>>> + hcd->flags = 0;
> >>>>>
> >>>
> >>> I am not sure if this usb_add(remove)_hcd pair is safe and clean enough
> >>> for start/stop host role. From my point, we may need to do like
> >>> .probe/.remove host platform driver interface. In that case, we can make
> >>
> >> probe and remove are meant to be called from bus layer.
> >> I do not see a way how OTG framework can call probe/remove of HCD driver.
> >> Some HCDs may be platform devices, some PCI, so different entities are calling
> >> the HCD .probe hook.
> >>
> >>> sure the clocks and regulators are off, and hcd will be zero-initialized
> >>
> >> why can't we make that sure that is taken care of within the hcd_ops?
> >> Why should some driver keep its regulators and clocks enabled when hcd is stopped?
> >> It doesn't need to. If it is doing so now, it needs to be fixed.
> >>
> >
> > Well, you may misunderstand me. I mean your hcd_ops->start or ->stop
> > is hard to be a general one which only calls usb_hcd_add or
> > usb_hcd_remove. It needs to implement like .probe or .remove at platform
> > driver, some example code like host_start and host_stop at
> > drivers/usb/chipidea/host.c.
> >
> The only extra thing the host_start/stop() of that driver is doing is
> enabling/disabling the VBUS regulator.
> In the OTG/dual role scope VBUS regulator handling has to be done via the
> OTG driver using the otg ops otg_drv_vbus() and not at HCD level. Do you agree?
>
I agree with you that vbus handling should be handled by otg_drv_vbus
for OTG case.
> I don't want to complicate the OTG to HCD interface by adding new hooks there.
> If HCD driver wants to do something special for OTG case it can always do that
> within the struct hc_driver interface. But ideally OTG specific handling must
> be done in the OTG driver. All that the HCD driver should care about is making sure
> all used resources are disabled once usb_remove_hcd() is called.
>
In this patch, we set hcd->flag as 0 to fix one problem, but if any
problems are still existed due to non-zero hcd structure. We have
tested a lot for insmod/rmmod procedure for host driver, it doesn't
show many problems. In a word, once the host role is stopped do we
need to remove all things belong to host, and re-initialized all things
belong to host when the host role is re-started? From my point is 'yes'.
host_stop()
{
usb_remove_hcd(hcd);
usb_put_hcd(hcd);
platform_deinit(); /* clock, gpio, etc */
}
host_start()
{
platform_init(); /* clock, gpio, etc */
usb_create_hcd();
... /* initialize hcd structure from platform information */
usb_add_hcd(hcd);
}
Maybe you have already done something, but there is no user now.
Things will be more clear after your post your dwc3 changes :)
--
Best Regards,
Peter Chen
[toc] | [prev] | [next] | [standalone]
| From | Roger Quadros <rogerq@ti.com> |
|---|---|
| Date | 2016-04-05 16:20 +0200 |
| Subject | [PATCH v6 08/12] usb: hcd: Adapt to OTG core |
| Message-ID | <rkzZL-4ZG-7@gated-at.bofh.it> |
| In reply to | #1371633 |
Introduce usb_otg_add/remove_hcd() for use by host
controllers that are part of OTG/dual-role port.
Non Device tree platforms can use the otg_dev argument
to specify the OTG controller device. If otg_dev is NULL
then the device tree node's otg-controller property is used to
get the otg_dev device.
Signed-off-by: Roger Quadros <rogerq@ti.com>
---
drivers/usb/core/hcd.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/usb/hcd.h | 4 +++
2 files changed, 75 insertions(+)
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 6b1930d..6a80193 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -46,6 +46,10 @@
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/usb/phy.h>
+#include <linux/usb/otg.h>
+
+#include <linux/of.h>
+#include <linux/of_platform.h>
#include "usb.h"
@@ -3013,6 +3017,73 @@ void usb_remove_hcd(struct usb_hcd *hcd)
}
EXPORT_SYMBOL_GPL(usb_remove_hcd);
+
+static struct otg_hcd_ops otg_hcd_intf = {
+ .add = usb_add_hcd,
+ .remove = usb_remove_hcd,
+ .usb_bus_start_enum = usb_bus_start_enum,
+ .usb_control_msg = usb_control_msg,
+ .usb_hub_find_child = usb_hub_find_child,
+};
+
+/**
+ * usb_otg_add_hcd - Register the HCD with OTG core.
+ * @hcd: the usb_hcd structure to initialize
+ * @irqnum: Interrupt line to allocate
+ * @irqflags: Interrupt type flags
+ * @otg_dev: OTG controller device manging this HCD
+ *
+ * Registers the HCD with OTG core. OTG core will call usb_add_hcd()
+ * or usb_remove_hcd() as necessary.
+ * If otg_dev is NULL then device tree node is checked for OTG
+ * controller device via the otg-controller property.
+ */
+int usb_otg_add_hcd(struct usb_hcd *hcd,
+ unsigned int irqnum, unsigned long irqflags,
+ struct device *otg_dev)
+{
+ struct device *dev = hcd->self.controller;
+
+ if (!otg_dev) {
+ struct device_node *np;
+ struct platform_device *pdev;
+
+ np = of_parse_phandle(dev->of_node, "otg-controller", 0);
+ if (!np) {
+ dev_err(dev,
+ "otg_dev is NULL and no otg-controller property in DT\n");
+ return -EINVAL;
+ }
+
+ pdev = of_find_device_by_node(np);
+ of_node_put(np);
+ if (!pdev) {
+ dev_err(dev,
+ "couldn't get otg-controller device\n");
+ return -ENODEV;
+ }
+
+ hcd->otg_dev = &pdev->dev;
+ } else {
+ hcd->otg_dev = otg_dev;
+ }
+
+ return usb_otg_register_hcd(hcd, irqnum, irqflags, &otg_hcd_intf);
+}
+EXPORT_SYMBOL_GPL(usb_otg_add_hcd);
+
+/**
+ * usb_otg_remove_hcd - Unregister the HCD with OTG core.
+ * @hcd: the usb_hcd structure to remove
+ *
+ * Unregisters the HCD from the OTG core.
+ */
+void usb_otg_remove_hcd(struct usb_hcd *hcd)
+{
+ usb_otg_unregister_hcd(hcd);
+}
+EXPORT_SYMBOL_GPL(usb_otg_remove_hcd);
+
void
usb_hcd_platform_shutdown(struct platform_device *dev)
{
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 2017cd4..adcf2e7 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -472,6 +472,10 @@ extern int usb_hcd_is_primary_hcd(struct usb_hcd *hcd);
extern int usb_add_hcd(struct usb_hcd *hcd,
unsigned int irqnum, unsigned long irqflags);
extern void usb_remove_hcd(struct usb_hcd *hcd);
+extern int usb_otg_add_hcd(struct usb_hcd *hcd,
+ unsigned int irqnum, unsigned long irqflags,
+ struct device *otg_dev);
+extern void usb_otg_remove_hcd(struct usb_hcd *hcd);
extern int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1);
struct platform_device;
--
2.5.0
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | linux.kernel
csiph-web