Received: by 2002:a25:7ec1:0:0:0:0:0 with SMTP id z184csp8388376ybc; Fri, 29 Nov 2019 09:42:46 -0800 (PST) X-Google-Smtp-Source: APXvYqwvCDwi4xLRyYGvD3v+LFPxRr8Rh0/dtA7bmjqytJZLgENQzyIjrLQoGcZKNE9M8H2D+sug X-Received: by 2002:a05:6402:1692:: with SMTP id a18mr47381229edv.297.1575049366115; Fri, 29 Nov 2019 09:42:46 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1575049366; cv=none; d=google.com; s=arc-20160816; b=f0OU57AcBwG5LFavjKnAIw9kutBqjqwF9n0Zxdeu1X25Vrtzu4TO6Ec/9SjP7ifSui ts912FwZB6DdcsEaJP+mNqkl8rB2pCSNX5orHOBt6JcTmcIkt+CS7RvEFyuQQEHxmJff acJMedmNMAgXclByMV1vNUye5yfjnVsoXTC4qDOQZyQAU+RYTl9NHLWFwKbkLrp6R8Ua oQf6Vp8MN9xciuHnAxPJdJXWIAjKU3AZ5gYO4CL5aLYiW+mwGPdW1NGccZ3IrYXJweA2 XJAlvGu1w1uQea1if5I7TUqXy/p9tAR/bBbs3ufmwSp1qCcDB3CfR9Qz1637DjYXpUvn pIZQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from; bh=wX4/013R/hSA8286Ipp//pUCV3JOJzgQ3HprzgzqYfw=; b=EjhS80bxWIh91FQzi0xJSGdDmzQTCNBC2Q4Qe2tHwxcAqdVqRs9CU5rTOmavvuYcWH jp4x2h4KTh+q/rgYVXgflTzdYiXPs/2OY7yyS1Sgq8+/GHNxq3fGsxCBXceglfpRoTY5 xY1UFlYrofILwUNyfjcWMdyZ5WQ5cOKDrC+rfEdtRU4dNrU37CDHDoKZkeRNSlWcGDMs 2/4g251Iit5kGDiFZjnIccSB+ImTXSWnqUvCHEhb94dZxPVUvgPujl9yFn3LuG9PVvu0 CqgvIMlqg9UcgTLk/GlZl+J7nch3eh/dFOP+ZWA8WD9jpnleFy857Uf6zviZixhOmsV5 h8rg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=canonical.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x10si4919684edj.318.2019.11.29.09.42.21; Fri, 29 Nov 2019 09:42:46 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=canonical.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727040AbfK2RlY (ORCPT + 99 others); Fri, 29 Nov 2019 12:41:24 -0500 Received: from youngberry.canonical.com ([91.189.89.112]:52164 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726970AbfK2RlX (ORCPT ); Fri, 29 Nov 2019 12:41:23 -0500 Received: from 61-220-137-37.hinet-ip.hinet.net ([61.220.137.37] helo=localhost) by youngberry.canonical.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1iakGe-0005X5-M5; Fri, 29 Nov 2019 17:41:21 +0000 From: Kai-Heng Feng To: gregkh@linuxfoundation.org Cc: stern@rowland.harvard.edu, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Kai-Heng Feng Subject: [PATCH v2 1/2] USB: core: Make port power cycle a seperate helper function Date: Sat, 30 Nov 2019 01:41:14 +0800 Message-Id: <20191129174115.31683-1-kai.heng.feng@canonical.com> X-Mailer: git-send-email 2.17.1 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add a new function, hub_port_power_cycle() to power cycle port's power. It'll be used by a following patch. In addition to that, check the return value of usb_hub_set_port_power(), so we don't need to wait if the set power operation fails. Furthermore, remove parameter *hdev from usb_hub_set_port_power(), since we can get *hdev from *hub directly. Signed-off-by: Kai-Heng Feng --- v2: - No change. drivers/usb/core/hub.c | 30 ++++++++++++++++++++++++------ drivers/usb/core/hub.h | 3 +-- drivers/usb/core/port.c | 4 ++-- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 1709895387b9..6b6cd76ac5e6 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -817,9 +817,9 @@ static void hub_tt_work(struct work_struct *work) * * Return: 0 if successful. A negative error code otherwise. */ -int usb_hub_set_port_power(struct usb_device *hdev, struct usb_hub *hub, - int port1, bool set) +int usb_hub_set_port_power(struct usb_hub *hub, int port1, bool set) { + struct usb_device *hdev = hub->hdev; int ret; if (set) @@ -2739,6 +2739,27 @@ static bool hub_port_warm_reset_required(struct usb_hub *hub, int port1, || link_state == USB_SS_PORT_LS_COMP_MOD; } +static void hub_port_power_cycle(struct usb_hub *hub, int port1) +{ + struct usb_port *port_dev = hub->ports[port1 - 1]; + int ret; + + ret = usb_hub_set_port_power(hub, port1, false); + if (ret) { + dev_info(&port_dev->dev, "failed to disable port power\n"); + return; + } + + msleep(2 * hub_power_on_good_delay(hub)); + ret = usb_hub_set_port_power(hub, port1, true); + if (ret) { + dev_info(&port_dev->dev, "failed to enable port power\n"); + return; + } + + msleep(hub_power_on_good_delay(hub)); +} + static int hub_port_wait_reset(struct usb_hub *hub, int port1, struct usb_device *udev, unsigned int delay, bool warm) { @@ -5216,10 +5237,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, /* When halfway through our retry count, power-cycle the port */ if (i == (SET_CONFIG_TRIES / 2) - 1) { dev_info(&port_dev->dev, "attempt power cycle\n"); - usb_hub_set_port_power(hdev, hub, port1, false); - msleep(2 * hub_power_on_good_delay(hub)); - usb_hub_set_port_power(hdev, hub, port1, true); - msleep(hub_power_on_good_delay(hub)); + hub_port_power_cycle(hub, port1); } } if (hub->hdev->parent || diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index a9e24e4b8df1..325a55637a6f 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h @@ -113,8 +113,7 @@ extern int usb_hub_create_port_device(struct usb_hub *hub, int port1); extern void usb_hub_remove_port_device(struct usb_hub *hub, int port1); -extern int usb_hub_set_port_power(struct usb_device *hdev, struct usb_hub *hub, - int port1, bool set); +extern int usb_hub_set_port_power(struct usb_hub *hub, int port1, bool set); extern struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev); extern int hub_port_debounce(struct usb_hub *hub, int port1, bool must_be_connected); diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c index bbbb35fa639f..0fc6f24c6da1 100644 --- a/drivers/usb/core/port.c +++ b/drivers/usb/core/port.c @@ -214,7 +214,7 @@ static int usb_port_runtime_resume(struct device *dev) pm_runtime_get_sync(&peer->dev); usb_autopm_get_interface(intf); - retval = usb_hub_set_port_power(hdev, hub, port1, true); + retval = usb_hub_set_port_power(hub, port1, true); msleep(hub_power_on_good_delay(hub)); if (udev && !retval) { /* @@ -267,7 +267,7 @@ static int usb_port_runtime_suspend(struct device *dev) return -EBUSY; usb_autopm_get_interface(intf); - retval = usb_hub_set_port_power(hdev, hub, port1, false); + retval = usb_hub_set_port_power(hub, port1, false); usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION); if (!port_dev->is_superspeed) usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE); -- 2.17.1