From patchwork Wed Apr 18 19:39:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Blumenstingl X-Patchwork-Id: 10348837 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 AA90E60244 for ; Wed, 18 Apr 2018 19:40:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9BA0228831 for ; Wed, 18 Apr 2018 19:40:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 902DE28834; Wed, 18 Apr 2018 19:40:24 +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=-7.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, MAILING_LIST_MULTI, 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 0A36728837 for ; Wed, 18 Apr 2018 19:40:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752702AbeDRTkU (ORCPT ); Wed, 18 Apr 2018 15:40:20 -0400 Received: from mail-wr0-f195.google.com ([209.85.128.195]:42055 "EHLO mail-wr0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752658AbeDRTkP (ORCPT ); Wed, 18 Apr 2018 15:40:15 -0400 Received: by mail-wr0-f195.google.com with SMTP id s18-v6so7844337wrg.9 for ; Wed, 18 Apr 2018 12:40:15 -0700 (PDT) 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=3QvXc9hL2wigfvAzWk3hEK8RU/iA+AJNtDnoC0FSxEM=; b=PerFmq3u3Q2LhPJEyn1DSV3P6gv8vpszEuoQwb+6oHQMPjgeCAOMmXSds9uN/AdOMS bSd3sRuo+D7Mv9+P4V78B6KdRxESV204mu1kbXP6dE5o0LeU9y9LWd8KqsplqyK6ZN3p x0dOikyUsGDIaMaX5cFTHZD+7M3uYvCowfXA8vEKnaAdENcrymx+M6v0o4uN8rrAksJV /jEQqnsj7GQBDMS8pr27YtTxOaf938spR2kYyusGxmA4noJGUYGUlSwbJqqmbF/yfhKs 7BbZB2zWpf0KZ+Tr9BwYWSC52i8+Dd8tmHUgbkd9S77kztFY4KI7YZYUv9xsM81zIbHj iQWQ== 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=3QvXc9hL2wigfvAzWk3hEK8RU/iA+AJNtDnoC0FSxEM=; b=VUeDYvftoclNXY55bZyPPoDZhFR1O7+eWfaSR/qUtF2ZZFeynwUH+s7cni8r2+I504 Ik+PJ/HwFlH2UO5xoOSjaUluG1fGdhD2LWs8xWPZH9BOyikxtSutV3c1S3aApcaMAqxi KCjRAhH66uw54f7u2dfOd+L8nW3CpXXR0RIsaph4hxXrvaBgqmAkgw58BCjoi1ZetdQ0 MJW7PSqfb6t9Yfn999/rEiFaqdL023UH1Pzsc6BfA2LS0GlyylBZn2JkmcbDLoDIEMGd Yx7qxCSuFmeG4+43AO3H63L8HEIHe7N3G6t0a67eSejUdTTE1hfLqFyYKACYuxt8SMm2 G4eQ== X-Gm-Message-State: ALQs6tAFyfPhyRvF+2E8FordlmvZ51amoX12N6OlrteV3Q29ZLLoGIm6 1W0bwfxPUjDl+nuN3yQ5y3sXy63Z X-Google-Smtp-Source: AIpwx49r/1JRd482w9pom23gFk1ILTAeZO/suF5HHTgY22E6FpHNclP7MXrOMhOgJADEi/Oc2Sm2JQ== X-Received: by 2002:adf:9853:: with SMTP id v77-v6mr2553447wrb.225.1524080414089; Wed, 18 Apr 2018 12:40:14 -0700 (PDT) Received: from blackbox.darklights.net (p200300DCD743A504F9143C002217B8ED.dip0.t-ipconnect.de. [2003:dc:d743:a504:f914:3c00:2217:b8ed]) by smtp.googlemail.com with ESMTPSA id 60-v6sm1871990wrj.62.2018.04.18.12.40.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 18 Apr 2018 12:40:13 -0700 (PDT) From: Martin Blumenstingl To: linux-usb@vger.kernel.org, gregkh@linuxfoundation.org Cc: matthias.bgg@gmail.com, stern@rowland.harvard.edu, rogerq@ti.com, linux-mediatek@lists.infradead.org, linux-amlogic@lists.infradead.org, j-keerthy@ti.com, d-gerlach@ti.com, kishon@ti.com, chunfeng.yun@mediatek.com, linux-rpi-kernel@lists.infradead.org, eric@anholt.net, yamada.masahiro@socionext.com, Martin Blumenstingl Subject: [PATCH usb v6 3/6] usb: core: use phy_exit during suspend if wake up is not supported Date: Wed, 18 Apr 2018 21:39:48 +0200 Message-Id: <20180418193951.17922-4-martin.blumenstingl@googlemail.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180418193951.17922-1-martin.blumenstingl@googlemail.com> References: <20180418193951.17922-1-martin.blumenstingl@googlemail.com> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP If the USB controller can wake up the system (which is the case for example with the Mediatek USB3 IP) then we must not call phy_exit during suspend to ensure that the USB controller doesn't have to re-enumerate the devices during resume. However, if the USB controller cannot wake up the system (which is the case for example on various TI platforms using a dwc3 controller) then we must call phy_exit during suspend. Otherwise the PHY driver keeps the clocks enabled, which prevents the system from reaching the lowest power levels in the suspend state. Solve this by introducing two new functions in the PHY wrapper which are dedicated to the suspend and resume handling. If the controller can wake up the system the new usb_phy_roothub_suspend function will simply call usb_phy_roothub_power_off. However, if wake up is not supported by the controller it will also call usb_phy_roothub_exit. The also new usb_phy_roothub_resume function takes care of calling usb_phy_roothub_init (if the controller can't wake up the system) in addition to usb_phy_roothub_power_on. Fixes: 07dbff0ddbd86c ("usb: core: add a wrapper for the USB PHYs on the HCD") Fixes: 178a0bce05cbc1 ("usb: core: hcd: integrate the PHY wrapper into the HCD core") Reported-by: Roger Quadros Suggested-by: Roger Quadros Suggested-by: Chunfeng Yun Signed-off-by: Martin Blumenstingl Tested-by: Chunfeng Yun Reviewed-by: Roger Quadros Tested-by: Keerthy --- drivers/usb/core/hcd.c | 8 +++++--- drivers/usb/core/phy.c | 35 +++++++++++++++++++++++++++++++++++ drivers/usb/core/phy.h | 5 +++++ 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 15b0418e3b6a..78bae4ecd68b 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2262,7 +2262,8 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg) hcd->state = HC_STATE_SUSPENDED; if (!PMSG_IS_AUTO(msg)) - usb_phy_roothub_power_off(hcd->phy_roothub); + usb_phy_roothub_suspend(hcd->self.sysdev, + hcd->phy_roothub); /* Did we race with a root-hub wakeup event? */ if (rhdev->do_remote_wakeup) { @@ -2302,7 +2303,8 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) } if (!PMSG_IS_AUTO(msg)) { - status = usb_phy_roothub_power_on(hcd->phy_roothub); + status = usb_phy_roothub_resume(hcd->self.sysdev, + hcd->phy_roothub); if (status) return status; } @@ -2344,7 +2346,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); + usb_phy_roothub_suspend(hcd->self.sysdev, hcd->phy_roothub); dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", "resume", status); if (status != -ESHUTDOWN) diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index 44f008cda7a8..a39d9bb26a4f 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -157,3 +157,38 @@ void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub) phy_power_off(roothub_entry->phy); } EXPORT_SYMBOL_GPL(usb_phy_roothub_power_off); + +int usb_phy_roothub_suspend(struct device *controller_dev, + struct usb_phy_roothub *phy_roothub) +{ + usb_phy_roothub_power_off(phy_roothub); + + /* keep the PHYs initialized so the device can wake up the system */ + if (device_may_wakeup(controller_dev)) + return 0; + + return usb_phy_roothub_exit(phy_roothub); +} +EXPORT_SYMBOL_GPL(usb_phy_roothub_suspend); + +int usb_phy_roothub_resume(struct device *controller_dev, + struct usb_phy_roothub *phy_roothub) +{ + int err; + + /* if the device can't wake up the system _exit was called */ + if (!device_may_wakeup(controller_dev)) { + err = usb_phy_roothub_init(phy_roothub); + if (err) + return err; + } + + err = usb_phy_roothub_power_on(phy_roothub); + + /* undo _init if _power_on failed */ + if (err && !device_may_wakeup(controller_dev)) + usb_phy_roothub_exit(phy_roothub); + + return err; +} +EXPORT_SYMBOL_GPL(usb_phy_roothub_resume); diff --git a/drivers/usb/core/phy.h b/drivers/usb/core/phy.h index eb31253201ad..605555901d44 100644 --- a/drivers/usb/core/phy.h +++ b/drivers/usb/core/phy.h @@ -7,3 +7,8 @@ int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub); int usb_phy_roothub_power_on(struct usb_phy_roothub *phy_roothub); void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub); + +int usb_phy_roothub_suspend(struct device *controller_dev, + struct usb_phy_roothub *phy_roothub); +int usb_phy_roothub_resume(struct device *controller_dev, + struct usb_phy_roothub *phy_roothub);