From patchwork Sat Mar 3 21:43:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Blumenstingl X-Patchwork-Id: 10256211 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 2CE706037E for ; Sat, 3 Mar 2018 21:44:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 20D5E287A1 for ; Sat, 3 Mar 2018 21:44:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 156C2287A6; Sat, 3 Mar 2018 21:44:01 +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.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham 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 E48AF287A1 for ; Sat, 3 Mar 2018 21:43:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932157AbeCCVnl (ORCPT ); Sat, 3 Mar 2018 16:43:41 -0500 Received: from mail-wm0-f68.google.com ([74.125.82.68]:50237 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932097AbeCCVnh (ORCPT ); Sat, 3 Mar 2018 16:43:37 -0500 Received: by mail-wm0-f68.google.com with SMTP id w128so9247680wmw.0; Sat, 03 Mar 2018 13:43:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=6lepbucrQVsgwhbtAjGZeShEqR9trcFZNjsqCiEcxNU=; b=BKDsQ7iBHK4Bn/jG2ARQ6SQoAubQ92tj5/t6ccBsR5W/PHeG3xr7tuvkejwFsv7TZB BYDWqUUZ0moqxpywFXjxsqBLZk5A+COK8K4hzu96z/czhyR9dlT/fYGHeiIsAudJKP5m TsjGPG90HQqHS8I/HESsvtbYMoeefTXSjAbERf5Y2/N5lk/IkVBbx8O9m4eN55DxQKSg PJ0ct7jskeCRrhEauR9G94hUi0S5b8+vMeFivP09PBpRwbvNN08O9h/zYLN7JKehSJLy 3TTue1pVF2pno16JLBAkyCQsAmWEOXsxLuu/GjL2LHTpWB/5PPSa1RkJx7f1fkwvYCzq 7aQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=6lepbucrQVsgwhbtAjGZeShEqR9trcFZNjsqCiEcxNU=; b=qFt9wJWIE0qk3X4wVQHpHBHodJPG5l8oqhmyO8F98sLT+wy6owMKBm7HRnZfVsupG9 ZcEC2oNkOxp2E5Kaj0ldQ2oWW9sr/QC65xnXNqQooZYfjYls8J3Z3R6mOEeB+8qZGw+2 D5RmI+kNkJUSLM/kAFZfAzIIV43zCoMQ7oetV7XHC77HD+WxzyUyTlqZvDzU+QEQ+08v kgOLMhEgVqFyS5WKKH6lgMTOi3H9W+6fQq5yDU3zC2yWbBOo6XwGFVpztezHwhuXauiD vPCCbCTQhj0E4tl5R+tDiwRZcGy14nqQFr29fN8Td4LlPxSAnxIJeUVL2IjDouS9SK3P 4KHA== X-Gm-Message-State: AElRT7HcXaRsF7RI+v2E3yKDQtXx77ITne0wuIi5eQcRv/Dx9E9xpGG9 aWRn9caLXIOOUcYzg4v7pAH3N8cD X-Google-Smtp-Source: AG47ELukQINGp2U44CBhEfpXr8nbvoaVVXWFkaN8QNWA3YV+69yKNfZnqS05FdZ81Lj05JdfWZ5X6w== X-Received: by 10.28.183.195 with SMTP id h186mr4619204wmf.66.1520113415044; Sat, 03 Mar 2018 13:43:35 -0800 (PST) Received: from blackbox.darklights.net (p5DD9B279.dip0.t-ipconnect.de. [93.217.178.121]) by smtp.googlemail.com with ESMTPSA id 55sm11073171wrz.6.2018.03.03.13.43.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 03 Mar 2018 13:43:34 -0800 (PST) From: Martin Blumenstingl To: linux-usb@vger.kernel.org, mathias.nyman@intel.com, arnd@arndb.de, gregkh@linuxfoundation.org, felipe.balbi@linux.intel.com Cc: linux-omap@vger.kernel.org, linux-tegra@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, jonathanh@nvidia.com, thierry.reding@gmail.com, stern@rowland.harvard.edu, linux@prisktech.co.nz, Peter.Chen@nxp.com, matthias.bgg@gmail.com, mark.rutland@arm.com, robh+dt@kernel.org, narmstrong@baylibre.com, linux-amlogic@lists.infradead.org, yixun.lan@amlogic.com, Martin Blumenstingl Subject: [usb-next PATCH v11 4/8] usb: core: hcd: integrate the PHY wrapper into the HCD core Date: Sat, 3 Mar 2018 22:43:05 +0100 Message-Id: <20180303214309.25643-5-martin.blumenstingl@googlemail.com> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180303214309.25643-1-martin.blumenstingl@googlemail.com> References: <20180303214309.25643-1-martin.blumenstingl@googlemail.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 This integrates the PHY wrapper into the core hcd infrastructure. Multiple PHYs which are part of the HCD's device tree node are now managed (= powered on/off when needed), by the new usb_phy_roothub code. Suspend and resume is also supported, however not for runtime/auto-suspend (which is triggered for example when no devices are connected to the USB bus). This is needed on some SoCs (for example Amlogic Meson GXL) because if the PHYs are disabled during auto-suspend then devices which are plugged in afterwards are not seen by the host. One example where this is required is the Amlogic GXL and GXM SoCs: They are using a dwc3 USB controller with up to three ports enabled on the internal roothub. Each port has it's own PHY which must be enabled (if one of the PHYs is left disabled then none of the USB ports works at all). The new logic works on the Amlogic GXL and GXM SoCs because the dwc3 driver internally creates a xhci-hcd which then registers a HCD which then triggers our new PHY wrapper. USB controller drivers can opt out of this by setting "skip_phy_initialization" in struct usb_hcd to true. This is identical to how it works for a single USB PHY, so the "multiple PHY" handling is disabled for drivers that opted out of the management logic of a single PHY. Signed-off-by: Martin Blumenstingl Acked-by: Alan Stern Acked-by: Chunfeng Yun Tested-by: Yixun Lan --- drivers/usb/core/hcd.c | 31 +++++++++++++++++++++++++++++++ include/linux/usb/hcd.h | 1 + 2 files changed, 32 insertions(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index f2307470a31e..32797c25ac3b 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -37,6 +37,7 @@ #include #include "usb.h" +#include "phy.h" /*-------------------------------------------------------------------------*/ @@ -2260,6 +2261,9 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg) usb_set_device_state(rhdev, USB_STATE_SUSPENDED); hcd->state = HC_STATE_SUSPENDED; + if (!PMSG_IS_AUTO(msg)) + usb_phy_roothub_power_off(hcd->phy_roothub); + /* Did we race with a root-hub wakeup event? */ if (rhdev->do_remote_wakeup) { char buffer[6]; @@ -2296,6 +2300,13 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) dev_dbg(&rhdev->dev, "skipped %s of dead bus\n", "resume"); return 0; } + + if (!PMSG_IS_AUTO(msg)) { + status = usb_phy_roothub_power_on(hcd->phy_roothub); + if (status) + return status; + } + if (!hcd->driver->bus_resume) return -ENOENT; if (HCD_RH_RUNNING(hcd)) @@ -2333,6 +2344,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) } } else { hcd->state = old_state; + usb_phy_roothub_power_off(hcd->phy_roothub); dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", "resume", status); if (status != -ESHUTDOWN) @@ -2769,6 +2781,18 @@ int usb_add_hcd(struct usb_hcd *hcd, } } + if (!hcd->skip_phy_initialization) { + hcd->phy_roothub = usb_phy_roothub_init(hcd->self.sysdev); + if (IS_ERR(hcd->phy_roothub)) { + retval = PTR_ERR(hcd->phy_roothub); + goto err_phy_roothub_init; + } + + retval = usb_phy_roothub_power_on(hcd->phy_roothub); + if (retval) + goto err_usb_phy_roothub_power_on; + } + dev_info(hcd->self.controller, "%s\n", hcd->product_desc); /* Keep old behaviour if authorized_default is not in [0, 1]. */ @@ -2933,6 +2957,10 @@ int usb_add_hcd(struct usb_hcd *hcd, err_register_bus: hcd_buffer_destroy(hcd); err_create_buf: + usb_phy_roothub_power_off(hcd->phy_roothub); +err_usb_phy_roothub_power_on: + usb_phy_roothub_exit(hcd->phy_roothub); +err_phy_roothub_init: if (IS_ENABLED(CONFIG_GENERIC_PHY) && hcd->remove_phy && hcd->phy) { phy_power_off(hcd->phy); phy_exit(hcd->phy); @@ -3017,6 +3045,9 @@ void usb_remove_hcd(struct usb_hcd *hcd) usb_deregister_bus(&hcd->self); hcd_buffer_destroy(hcd); + usb_phy_roothub_power_off(hcd->phy_roothub); + usb_phy_roothub_exit(hcd->phy_roothub); + if (IS_ENABLED(CONFIG_GENERIC_PHY) && hcd->remove_phy && hcd->phy) { phy_power_off(hcd->phy); phy_exit(hcd->phy); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 693502c84c04..a042675e03ba 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -104,6 +104,7 @@ struct usb_hcd { */ struct usb_phy *usb_phy; struct phy *phy; + struct usb_phy_roothub *phy_roothub; /* Flags that need to be manipulated atomically because they can * change while the host controller is running. Always use