[PATCH v9 10/14] usb: otg: add hcd companion support
From: Yoshihiro Shimoda Since some host controller (e.g. EHCI) needs a companion host controller (e.g. OHCI), this patch adds such a configuration to use it in the OTG core. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Roger Quadros Acked-by: Peter Chen Acked-by: Rob Herring --- Documentation/devicetree/bindings/usb/generic.txt | 3 +++ drivers/usb/common/usb-otg.c | 32 --- include/linux/usb/otg.h | 7 - 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/generic.txt b/Documentation/devicetree/bindings/usb/generic.txt index f6866c1..1db1c33 100644 --- a/Documentation/devicetree/bindings/usb/generic.txt +++ b/Documentation/devicetree/bindings/usb/generic.txt @@ -27,6 +27,9 @@ Optional properties: - otg-controller: phandle to otg controller. Host or gadget controllers can contain this property to link it to a particular OTG controller. + - hcd-needs-companion: must be present if otg controller is dealing with + EHCI host controller that needs a companion OHCI host + controller. This is an attribute to a USB controller such as: diff --git a/drivers/usb/common/usb-otg.c b/drivers/usb/common/usb-otg.c index b5bdf62..98fcfa2 100644 --- a/drivers/usb/common/usb-otg.c +++ b/drivers/usb/common/usb-otg.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -348,6 +349,10 @@ struct usb_otg *usb_otg_register(struct device *dev, else INIT_WORK(&otg->work, usb_drd_work); + if (of_find_property(dev->of_node, "hcd-needs-companion", NULL) || + config->hcd_needs_companion)/* needs companion ? */ + otg->flags |= OTG_FLAG_HCD_NEEDS_COMPANION; + otg->wq = create_freezable_workqueue("usb_otg"); if (!otg->wq) { dev_err(dev, "otg: %s: can't create workqueue\n", @@ -562,15 +567,18 @@ int usb_otg_register_hcd(struct usb_hcd *hcd, unsigned int irqnum, /* HCD will be started by OTG fsm when needed */ mutex_lock(&otg->fsm.lock); if (otg->primary_hcd.hcd) { - /* probably a shared HCD ? */ - if (usb_otg_hcd_is_primary_hcd(hcd)) { + /* probably a shared HCD or a companion OHCI HCD ? */ + if (!(otg->flags & OTG_FLAG_HCD_NEEDS_COMPANION) && + usb_otg_hcd_is_primary_hcd(hcd)) { dev_err(otg_dev, "otg: primary host already registered\n"); goto err; } - if (hcd->shared_hcd == otg->primary_hcd.hcd) { + if (otg->flags & OTG_FLAG_HCD_NEEDS_COMPANION || + (hcd->shared_hcd == otg->primary_hcd.hcd)) { if (otg->shared_hcd.hcd) { - dev_err(otg_dev, "otg: shared host already registered\n"); + dev_err(otg_dev, + "otg: shared/companion host already registered\n"); goto err; } @@ -578,10 +586,12 @@ int usb_otg_register_hcd(struct usb_hcd *hcd, unsigned int irqnum, otg->shared_hcd.irqnum = irqnum; otg->shared_hcd.irqflags = irqflags; otg->shared_hcd.ops = ops; - dev_info(otg_dev, "otg: shared host %s registered\n", + dev_info(otg_dev, +"otg: shared/companion host %s registered\n", dev_name(hcd->self.controller)); } else { - dev_err(otg_dev, "otg: invalid shared host %s\n", + dev_err(otg_dev, + "otg: invalid shared/companion host %s\n", dev_name(hcd->self.controller)); goto err; } @@ -604,14 +614,17 @@ int usb_otg_register_hcd(struct usb_hcd *hcd, unsigned int irqnum, * we're ready only if we have shared HCD * or we don't need shared HCD. */ - if (otg->shared_hcd.hcd || !otg->primary_hcd.hcd->shared_hcd) { + if (otg->shared_hcd.hcd || + (!(otg->flags & OTG_FLAG_HCD_NEEDS_COMPANION) && +!otg->primary_hcd.hcd->shared_hcd)) { otg->host = hcd_to_bus(hcd); /* FIXME: set bus->otg_port if this is true OTG port with HNP */ /* start FSM */ usb_otg_start_fsm(otg); } else { - dev_dbg(otg_dev, "otg: can't start till shared host registers\n"); + dev_dbg(otg_dev, + "otg: can't start till shared/companion host registers\n"); } mutex_unlock(&otg->fsm.lock); @@ -659,7 +672,8 @@
Re: [PATCH v9 10/14] usb: otg: add hcd companion support
On Fri, May 20, 2016 at 12:32:27PM +0300, Roger Quadros wrote: > Since some host controller (e.g. EHCI) needs a companion host controller > (e.g. OHCI), this patch adds such a configuration to use it in the OTG > core. > > Signed-off-by: Yoshihiro Shimoda > Signed-off-by: Roger Quadros > Acked-by: Peter Chen > --- > v9: > - add DT property documentation under OTG controllers. > > Documentation/devicetree/bindings/usb/generic.txt | 3 +++ Acked-by: Rob Herring > drivers/usb/common/usb-otg.c | 32 > --- > include/linux/usb/otg.h | 7 - > 3 files changed, 32 insertions(+), 10 deletions(-)
[PATCH v9 10/14] usb: otg: add hcd companion support
Since some host controller (e.g. EHCI) needs a companion host controller (e.g. OHCI), this patch adds such a configuration to use it in the OTG core. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Roger Quadros Acked-by: Peter Chen --- v9: - add DT property documentation under OTG controllers. Documentation/devicetree/bindings/usb/generic.txt | 3 +++ drivers/usb/common/usb-otg.c | 32 --- include/linux/usb/otg.h | 7 - 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/generic.txt b/Documentation/devicetree/bindings/usb/generic.txt index 0887d6e..6013296 100644 --- a/Documentation/devicetree/bindings/usb/generic.txt +++ b/Documentation/devicetree/bindings/usb/generic.txt @@ -26,6 +26,9 @@ Optional properties for OTG controllers: optional for OTG device. - adp-disable: tells OTG controllers we want to disable OTG ADP, ADP is optional for OTG device. + - hcd-needs-companion: must be present if otg controller is dealing with + EHCI host controller that needs a companion OHCI host + controller. Optional properties for host/device controllers: - otg-controller: phandle to otg controller. Host or gadget controllers can diff --git a/drivers/usb/common/usb-otg.c b/drivers/usb/common/usb-otg.c index 64be6df..8a2a0d4 100644 --- a/drivers/usb/common/usb-otg.c +++ b/drivers/usb/common/usb-otg.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -584,6 +585,10 @@ struct usb_otg *usb_otg_register(struct device *dev, else INIT_WORK(&otg->work, usb_drd_work); + if (of_find_property(dev->of_node, "hcd-needs-companion", NULL) || + config->hcd_needs_companion)/* needs companion ? */ + otg->flags |= OTG_FLAG_HCD_NEEDS_COMPANION; + otg->wq = create_freezable_workqueue("usb_otg"); if (!otg->wq) { dev_err(dev, "otg: %s: can't create workqueue\n", @@ -807,15 +812,18 @@ int usb_otg_register_hcd(struct usb_hcd *hcd, unsigned int irqnum, /* HCD will be started by OTG fsm when needed */ mutex_lock(&otg->fsm.lock); if (otg->primary_hcd.hcd) { - /* probably a shared HCD ? */ - if (usb_otg_hcd_is_primary_hcd(hcd)) { + /* probably a shared HCD or a companion OHCI HCD ? */ + if (!(otg->flags & OTG_FLAG_HCD_NEEDS_COMPANION) && + usb_otg_hcd_is_primary_hcd(hcd)) { dev_err(otg_dev, "otg: primary host already registered\n"); goto err; } - if (hcd->shared_hcd == otg->primary_hcd.hcd) { + if (otg->flags & OTG_FLAG_HCD_NEEDS_COMPANION || + (hcd->shared_hcd == otg->primary_hcd.hcd)) { if (otg->shared_hcd.hcd) { - dev_err(otg_dev, "otg: shared host already registered\n"); + dev_err(otg_dev, + "otg: shared/companion host already registered\n"); goto err; } @@ -823,10 +831,12 @@ int usb_otg_register_hcd(struct usb_hcd *hcd, unsigned int irqnum, otg->shared_hcd.irqnum = irqnum; otg->shared_hcd.irqflags = irqflags; otg->shared_hcd.ops = ops; - dev_info(otg_dev, "otg: shared host %s registered\n", + dev_info(otg_dev, +"otg: shared/companion host %s registered\n", dev_name(hcd->self.controller)); } else { - dev_err(otg_dev, "otg: invalid shared host %s\n", + dev_err(otg_dev, + "otg: invalid shared/companion host %s\n", dev_name(hcd->self.controller)); goto err; } @@ -849,14 +859,17 @@ int usb_otg_register_hcd(struct usb_hcd *hcd, unsigned int irqnum, * we're ready only if we have shared HCD * or we don't need shared HCD. */ - if (otg->shared_hcd.hcd || !otg->primary_hcd.hcd->shared_hcd) { + if (otg->shared_hcd.hcd || + (!(otg->flags & OTG_FLAG_HCD_NEEDS_COMPANION) && +!otg->primary_hcd.hcd->shared_hcd)) { otg->host = hcd_to_bus(hcd); /* FIXME: set bus->otg_port if this is true OTG port with HNP */ /* start FSM */ usb_otg_start_fsm(otg); } else { - dev_dbg(otg_dev, "otg: can't start till shared host registers\n"); + dev_dbg(otg_dev, + "otg: can't start till shared/companion host