From patchwork Fri May 20 09:32:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roger Quadros X-Patchwork-Id: 9129023 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 1F73C60467 for ; Fri, 20 May 2016 09:33:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 11CFF1FFC9 for ; Fri, 20 May 2016 09:33:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 06AF02793B; Fri, 20 May 2016 09:33:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F34A81FFC9 for ; Fri, 20 May 2016 09:33:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933211AbcETJcx (ORCPT ); Fri, 20 May 2016 05:32:53 -0400 Received: from arroyo.ext.ti.com ([198.47.19.12]:38698 "EHLO arroyo.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932110AbcETJcv (ORCPT ); Fri, 20 May 2016 05:32:51 -0400 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by arroyo.ext.ti.com (8.13.7/8.13.7) with ESMTP id u4K9WXpU031391; Fri, 20 May 2016 04:32:33 -0500 Received: from DFLE73.ent.ti.com (dfle73.ent.ti.com [128.247.5.110]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id u4K9WXLR025970; Fri, 20 May 2016 04:32:33 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DFLE73.ent.ti.com (128.247.5.110) with Microsoft SMTP Server id 14.3.294.0; Fri, 20 May 2016 04:32:33 -0500 Received: from [192.168.2.6] (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id u4K9WRUs022097; Fri, 20 May 2016 04:32:28 -0500 Subject: [PATCH v9 10/14] usb: otg: add hcd companion support To: , References: <1463133808-10630-1-git-send-email-rogerq@ti.com> <1463133808-10630-11-git-send-email-rogerq@ti.com> CC: , , , , , , , , , , , , , , , , From: Roger Quadros Message-ID: <573ED9AB.6010508@ti.com> Date: Fri, 20 May 2016 12:32:27 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.7.2 MIME-Version: 1.0 In-Reply-To: <1463133808-10630-11-git-send-email-rogerq@ti.com> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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 registers\n"); } mutex_unlock(&otg->fsm.lock); @@ -907,7 +920,8 @@ int usb_otg_unregister_hcd(struct usb_hcd *hcd) dev_name(hcd_dev)); } else if (hcd == otg->shared_hcd.hcd) { otg->shared_hcd.hcd = NULL; - dev_info(otg_dev, "otg: shared host %s unregistered\n", + dev_info(otg_dev, + "otg: shared/companion host %s unregistered\n", dev_name(hcd_dev)); } else { dev_err(otg_dev, "otg: host %s wasn't registered with otg\n", diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index b094352..6f4ca77 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -57,7 +57,8 @@ struct otg_hcd { * @list: list of otg controllers * @work: otg state machine work * @wq: otg state machine work queue - * @flags: to track if host/gadget is running + * @flags: to track if host/gadget is running, or to indicate if hcd needs + * companion */ struct usb_otg { u8 default_a; @@ -84,6 +85,7 @@ struct usb_otg { u32 flags; #define OTG_FLAG_GADGET_RUNNING (1 << 0) #define OTG_FLAG_HOST_RUNNING (1 << 1) +#define OTG_FLAG_HCD_NEEDS_COMPANION (1 << 2) /* use otg->fsm.lock for serializing access */ /*------------- deprecated interface -----------------------------*/ @@ -125,11 +127,14 @@ struct usb_otg_caps { * @caps: otg capabilities of the controller * @ops: otg fsm operations * @otg_work: optional custom otg state machine work function + * @hcd_needs_companion: Indicates if host controller needs a companion + * controller */ struct usb_otg_config { struct usb_otg_caps *otg_caps; struct otg_fsm_ops *fsm_ops; void (*otg_work)(struct work_struct *work); + bool hcd_needs_companion; }; extern const char *usb_otg_state_string(enum usb_otg_state state);