From patchwork Sat Apr 10 00:46:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thinh Nguyen X-Patchwork-Id: 12195251 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D5A25C433ED for ; Sat, 10 Apr 2021 00:46:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A644261165 for ; Sat, 10 Apr 2021 00:46:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235307AbhDJArB (ORCPT ); Fri, 9 Apr 2021 20:47:01 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:39296 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235215AbhDJArB (ORCPT ); Fri, 9 Apr 2021 20:47:01 -0400 Received: from mailhost.synopsys.com (sv2-mailhost2.synopsys.com [10.205.2.134]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id BFA8D401F1; Sat, 10 Apr 2021 00:46:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1618015607; bh=IxpWvVBMbFls3MbK5nrnbd/pFI+0uaSHETWPRteanf0=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=e36RTBhCWytveYUx4FT68A5AzVh63t+0t/ICox0TgxHJ8xxgfSLxipKgXGC3N5Lw+ e/RfOOJv1Fu6x2uXWXzzWmCA8UTleXC3QLyTHc6h4MPD8fRE9TYbcGbEIb1Yhg240H mkm8uBwFUOOwC5TEHNDix2WYkUGr9xJjSFmXjXk4En0c8rX8NdVIFJD3huyDLdKxf9 7hToN2jPXq3DUodB4wzDG1CiookRtvdCtlA+S0I7EZl0saCQfvaVPwCvPeja10NB3/ 4njfUuMG0yeeqTSdMDG91PWD7H2Xfk4npjU3fdh7U8SWsb3AYgElQ+/UUcHBOdBDm5 IiwTNTIIBe+1g== Received: from lab-vbox (unknown [10.205.130.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 1B2B4A0096; Sat, 10 Apr 2021 00:46:45 +0000 (UTC) Received: by lab-vbox (sSMTP sendmail emulation); Fri, 09 Apr 2021 17:46:45 -0700 Date: Fri, 09 Apr 2021 17:46:45 -0700 Message-Id: In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Thinh Nguyen Subject: [PATCH v2 1/7] usb: xhci: Move quirks definitions to common usb header To: Felipe Balbi , Greg Kroah-Hartman , Thinh.Nguyen@synopsys.com, linux-usb@vger.kernel.org, Mathias Nyman Cc: John Youn Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org DWC3 (and possibly others such as CDNS3) will need to access these xHCI quirks' definitions to initialize their hosts. Currently, to set these quirks, we'd need to create new DT properties matching the quirks. This may not be necessary as the driver can check the controller IP and version at runtime to determine which quirks are needed. Let's move these quirks' definitions to a common header under include/linux/usb so DWC3 can properly access them. Signed-off-by: Thinh Nguyen --- Changes in v2: - Only keep the xHCI quirks' definitions and remove xhci-plat priv structure drivers/usb/host/xhci.h | 53 +--------------------------- include/linux/usb/xhci-quirks.h | 62 +++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 52 deletions(-) create mode 100644 include/linux/usb/xhci-quirks.h diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 2595a8f057c4..9a4e2808668b 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -17,6 +17,7 @@ #include #include #include +#include /* Code sharing between pci-quirks and xhci hcd */ #include "xhci-ext-caps.h" @@ -1840,58 +1841,6 @@ struct xhci_hcd { #define XHCI_STATE_HALTED (1 << 1) #define XHCI_STATE_REMOVING (1 << 2) unsigned long long quirks; -#define XHCI_LINK_TRB_QUIRK BIT_ULL(0) -#define XHCI_RESET_EP_QUIRK BIT_ULL(1) -#define XHCI_NEC_HOST BIT_ULL(2) -#define XHCI_AMD_PLL_FIX BIT_ULL(3) -#define XHCI_SPURIOUS_SUCCESS BIT_ULL(4) -/* - * Certain Intel host controllers have a limit to the number of endpoint - * contexts they can handle. Ideally, they would signal that they can't handle - * anymore endpoint contexts by returning a Resource Error for the Configure - * Endpoint command, but they don't. Instead they expect software to keep track - * of the number of active endpoints for them, across configure endpoint - * commands, reset device commands, disable slot commands, and address device - * commands. - */ -#define XHCI_EP_LIMIT_QUIRK BIT_ULL(5) -#define XHCI_BROKEN_MSI BIT_ULL(6) -#define XHCI_RESET_ON_RESUME BIT_ULL(7) -#define XHCI_SW_BW_CHECKING BIT_ULL(8) -#define XHCI_AMD_0x96_HOST BIT_ULL(9) -#define XHCI_TRUST_TX_LENGTH BIT_ULL(10) -#define XHCI_LPM_SUPPORT BIT_ULL(11) -#define XHCI_INTEL_HOST BIT_ULL(12) -#define XHCI_SPURIOUS_REBOOT BIT_ULL(13) -#define XHCI_COMP_MODE_QUIRK BIT_ULL(14) -#define XHCI_AVOID_BEI BIT_ULL(15) -#define XHCI_PLAT BIT_ULL(16) -#define XHCI_SLOW_SUSPEND BIT_ULL(17) -#define XHCI_SPURIOUS_WAKEUP BIT_ULL(18) -/* For controllers with a broken beyond repair streams implementation */ -#define XHCI_BROKEN_STREAMS BIT_ULL(19) -#define XHCI_PME_STUCK_QUIRK BIT_ULL(20) -#define XHCI_MTK_HOST BIT_ULL(21) -#define XHCI_SSIC_PORT_UNUSED BIT_ULL(22) -#define XHCI_NO_64BIT_SUPPORT BIT_ULL(23) -#define XHCI_MISSING_CAS BIT_ULL(24) -/* For controller with a broken Port Disable implementation */ -#define XHCI_BROKEN_PORT_PED BIT_ULL(25) -#define XHCI_LIMIT_ENDPOINT_INTERVAL_7 BIT_ULL(26) -#define XHCI_U2_DISABLE_WAKE BIT_ULL(27) -#define XHCI_ASMEDIA_MODIFY_FLOWCONTROL BIT_ULL(28) -#define XHCI_HW_LPM_DISABLE BIT_ULL(29) -#define XHCI_SUSPEND_DELAY BIT_ULL(30) -#define XHCI_INTEL_USB_ROLE_SW BIT_ULL(31) -#define XHCI_ZERO_64B_REGS BIT_ULL(32) -#define XHCI_DEFAULT_PM_RUNTIME_ALLOW BIT_ULL(33) -#define XHCI_RESET_PLL_ON_DISCONNECT BIT_ULL(34) -#define XHCI_SNPS_BROKEN_SUSPEND BIT_ULL(35) -#define XHCI_RENESAS_FW_QUIRK BIT_ULL(36) -#define XHCI_SKIP_PHY_INIT BIT_ULL(37) -#define XHCI_DISABLE_SPARSE BIT_ULL(38) -#define XHCI_SG_TRB_CACHE_SIZE_QUIRK BIT_ULL(39) -#define XHCI_NO_SOFT_RETRY BIT_ULL(40) unsigned int num_active_eps; unsigned int limit_active_eps; diff --git a/include/linux/usb/xhci-quirks.h b/include/linux/usb/xhci-quirks.h new file mode 100644 index 000000000000..4001b10b418a --- /dev/null +++ b/include/linux/usb/xhci-quirks.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * This file holds the definitions of quirks found in xHCI USB hosts. + */ + +#ifndef __LINUX_USB_XHCI_QUIRKS_H +#define __LINUX_USB_XHCI_QUIRKS_H + +#define XHCI_LINK_TRB_QUIRK BIT_ULL(0) +#define XHCI_RESET_EP_QUIRK BIT_ULL(1) +#define XHCI_NEC_HOST BIT_ULL(2) +#define XHCI_AMD_PLL_FIX BIT_ULL(3) +#define XHCI_SPURIOUS_SUCCESS BIT_ULL(4) +/* + * Certain Intel host controllers have a limit to the number of endpoint + * contexts they can handle. Ideally, they would signal that they can't handle + * anymore endpoint contexts by returning a Resource Error for the Configure + * Endpoint command, but they don't. Instead they expect software to keep track + * of the number of active endpoints for them, across configure endpoint + * commands, reset device commands, disable slot commands, and address device + * commands. + */ +#define XHCI_EP_LIMIT_QUIRK BIT_ULL(5) +#define XHCI_BROKEN_MSI BIT_ULL(6) +#define XHCI_RESET_ON_RESUME BIT_ULL(7) +#define XHCI_SW_BW_CHECKING BIT_ULL(8) +#define XHCI_AMD_0x96_HOST BIT_ULL(9) +#define XHCI_TRUST_TX_LENGTH BIT_ULL(10) +#define XHCI_LPM_SUPPORT BIT_ULL(11) +#define XHCI_INTEL_HOST BIT_ULL(12) +#define XHCI_SPURIOUS_REBOOT BIT_ULL(13) +#define XHCI_COMP_MODE_QUIRK BIT_ULL(14) +#define XHCI_AVOID_BEI BIT_ULL(15) +#define XHCI_PLAT BIT_ULL(16) +#define XHCI_SLOW_SUSPEND BIT_ULL(17) +#define XHCI_SPURIOUS_WAKEUP BIT_ULL(18) +/* For controllers with a broken beyond repair streams implementation */ +#define XHCI_BROKEN_STREAMS BIT_ULL(19) +#define XHCI_PME_STUCK_QUIRK BIT_ULL(20) +#define XHCI_MTK_HOST BIT_ULL(21) +#define XHCI_SSIC_PORT_UNUSED BIT_ULL(22) +#define XHCI_NO_64BIT_SUPPORT BIT_ULL(23) +#define XHCI_MISSING_CAS BIT_ULL(24) +/* For controller with a broken Port Disable implementation */ +#define XHCI_BROKEN_PORT_PED BIT_ULL(25) +#define XHCI_LIMIT_ENDPOINT_INTERVAL_7 BIT_ULL(26) +#define XHCI_U2_DISABLE_WAKE BIT_ULL(27) +#define XHCI_ASMEDIA_MODIFY_FLOWCONTROL BIT_ULL(28) +#define XHCI_HW_LPM_DISABLE BIT_ULL(29) +#define XHCI_SUSPEND_DELAY BIT_ULL(30) +#define XHCI_INTEL_USB_ROLE_SW BIT_ULL(31) +#define XHCI_ZERO_64B_REGS BIT_ULL(32) +#define XHCI_DEFAULT_PM_RUNTIME_ALLOW BIT_ULL(33) +#define XHCI_RESET_PLL_ON_DISCONNECT BIT_ULL(34) +#define XHCI_SNPS_BROKEN_SUSPEND BIT_ULL(35) +#define XHCI_RENESAS_FW_QUIRK BIT_ULL(36) +#define XHCI_SKIP_PHY_INIT BIT_ULL(37) +#define XHCI_DISABLE_SPARSE BIT_ULL(38) +#define XHCI_SG_TRB_CACHE_SIZE_QUIRK BIT_ULL(39) +#define XHCI_NO_SOFT_RETRY BIT_ULL(40) + +#endif /* __LINUX_USB_XHCI_QUIRKS_H */ From patchwork Sat Apr 10 00:46:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thinh Nguyen X-Patchwork-Id: 12195253 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DCC98C433ED for ; Sat, 10 Apr 2021 00:46:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ACD6C610A6 for ; Sat, 10 Apr 2021 00:46:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235311AbhDJArK (ORCPT ); Fri, 9 Apr 2021 20:47:10 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:39308 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235215AbhDJArJ (ORCPT ); Fri, 9 Apr 2021 20:47:09 -0400 Received: from mailhost.synopsys.com (sv1-mailhost1.synopsys.com [10.205.2.131]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id D2138401F1; Sat, 10 Apr 2021 00:46:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1618015616; bh=RdQLhzKTixlRLwaPIZsQGBw3e8nw+wSYiVqpTUvN2zQ=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=Qvc22IvYK6rbewN4NHgnsh3e2HHybIJSWkXjMgKIfAKc8+ph9riWt/4WpmtZO5UKM enyWpFQ6xPikMcXB/Jxlih4guiaJdNY/ijOQfl11KWX4BOSXBRa9E5o+6d3hWkIM8/ cYWh56ofvTY6ppNu1wNS4Ke8Vmc1lXzcijt7MUJ1pEyN9OUeNc6pZ8vUf6QoqKIPD6 DYkvLFgRiu7eg1625Oj7Zzk53839A4h4uc6ePnnt0TmCgoiRWmIjWXApK6LQfui8or tZxGsVhJpmKE9chrvHefEJ3c78CCb/TxxX0TRYAkhOX5bhiSPESfT4a/5wvl6SJSsv 6U2UgHtyMD4tw== Received: from lab-vbox (unknown [10.205.130.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id A0056A006A; Sat, 10 Apr 2021 00:46:53 +0000 (UTC) Received: by lab-vbox (sSMTP sendmail emulation); Fri, 09 Apr 2021 17:46:53 -0700 Date: Fri, 09 Apr 2021 17:46:53 -0700 Message-Id: <29484f4633a2b0e19b37fe407aebe415e9214390.1618014279.git.Thinh.Nguyen@synopsys.com> In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Thinh Nguyen Subject: [PATCH v2 2/7] usb: xhci: Move xhci-plat header to common usb header To: Felipe Balbi , Greg Kroah-Hartman , Thinh.Nguyen@synopsys.com, linux-usb@vger.kernel.org, Pawel Laszczak , Aswath Govindraju , Mathias Nyman , Roger Quadros , Peter Chen Cc: John Youn Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org DWC3 and CDNS3 need to access the private platform structure to pass quirks to the xhci-plat glue layer. Move xhci-plat.h to a common header location under include/linux/usb so DWC3 and CDNS3 can properly access them. Signed-off-by: Thinh Nguyen --- Changes in v2: - New patch for this series drivers/usb/cdns3/host.c | 2 +- drivers/usb/host/xhci-plat.c | 2 +- drivers/usb/host/xhci-rcar.c | 2 +- .../usb/host => include/linux/usb}/xhci-plat.h | 18 +++++++++--------- 4 files changed, 12 insertions(+), 12 deletions(-) rename {drivers/usb/host => include/linux/usb}/xhci-plat.h (54%) diff --git a/drivers/usb/cdns3/host.c b/drivers/usb/cdns3/host.c index 84dadfa726aa..02634d9762a4 100644 --- a/drivers/usb/cdns3/host.c +++ b/drivers/usb/cdns3/host.c @@ -14,8 +14,8 @@ #include "drd.h" #include "host-export.h" #include +#include #include "../host/xhci.h" -#include "../host/xhci-plat.h" #define XECP_PORT_CAP_REG 0x8000 #define XECP_AUX_CTRL_REG1 0x8120 diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index c1edcc9b13ce..3003fde3b430 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -19,9 +19,9 @@ #include #include #include +#include #include "xhci.h" -#include "xhci-plat.h" #include "xhci-mvebu.h" #include "xhci-rcar.h" diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c index 1bc4fe7b8c75..8d779df7b1e1 100644 --- a/drivers/usb/host/xhci-rcar.c +++ b/drivers/usb/host/xhci-rcar.c @@ -12,9 +12,9 @@ #include #include #include +#include #include "xhci.h" -#include "xhci-plat.h" #include "xhci-rcar.h" /* diff --git a/drivers/usb/host/xhci-plat.h b/include/linux/usb/xhci-plat.h similarity index 54% rename from drivers/usb/host/xhci-plat.h rename to include/linux/usb/xhci-plat.h index 561d0b7bce09..a58f1d44306d 100644 --- a/drivers/usb/host/xhci-plat.h +++ b/include/linux/usb/xhci-plat.h @@ -5,21 +5,21 @@ * Copyright (C) 2015 Renesas Electronics Corporation */ -#ifndef _XHCI_PLAT_H -#define _XHCI_PLAT_H +#ifndef __LINUX_USB_XHCI_PLAT_H +#define __LINUX_USB_XHCI_PLAT_H -#include "xhci.h" /* for hcd_to_xhci() */ +struct usb_hcd; struct xhci_plat_priv { const char *firmware_name; unsigned long long quirks; - int (*plat_setup)(struct usb_hcd *); - void (*plat_start)(struct usb_hcd *); - int (*init_quirk)(struct usb_hcd *); - int (*suspend_quirk)(struct usb_hcd *); - int (*resume_quirk)(struct usb_hcd *); + int (*plat_setup)(struct usb_hcd *hcd); + void (*plat_start)(struct usb_hcd *hcd); + int (*init_quirk)(struct usb_hcd *hcd); + int (*suspend_quirk)(struct usb_hcd *hcd); + int (*resume_quirk)(struct usb_hcd *hcd); }; #define hcd_to_xhci_priv(h) ((struct xhci_plat_priv *)hcd_to_xhci(h)->priv) #define xhci_to_priv(x) ((struct xhci_plat_priv *)(x)->priv) -#endif /* _XHCI_PLAT_H */ +#endif /* __LINUX_USB_XHCI_PLAT_H */ From patchwork Sat Apr 10 00:47:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thinh Nguyen X-Patchwork-Id: 12195255 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4C49FC433ED for ; Sat, 10 Apr 2021 00:47:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1952E6113A for ; Sat, 10 Apr 2021 00:47:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235313AbhDJArR (ORCPT ); Fri, 9 Apr 2021 20:47:17 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.87.133]:46934 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235312AbhDJArQ (ORCPT ); Fri, 9 Apr 2021 20:47:16 -0400 Received: from mailhost.synopsys.com (sv2-mailhost1.synopsys.com [10.205.2.133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id BF5D0C00CB; Sat, 10 Apr 2021 00:47:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1618015622; bh=kCQj7VfovKDSTD3qr4qVt/ENZ7Kcmdsxrciiw0PT99Y=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=jG7GbIjDlX3yo+4HUI7dKIR4nZgUfOZzoutwlAm+vRjNkZXGnqzPO15EvnqyQ7Awx cB82WKEcnLs/sbXY3PTInhKPRqhXfBU8XsjMILZsJjEfuq2f1VHLICQyIv+0nAShqS OPy41+NR2o8CPm03ddrjyjsYaJR+QVJJv659sTwYatw2GogMOSWWJ/zSYVbxELPQvF Wocpai4uXF2Oqltns2BlBG5KI1HzhsTSWgTHknf7eZHsj0CuQYDsVijuJPFPllk3Uk iVAVHESG2NQSVgaZNS7EGvC80poIrV4yewMzLpqtMQgld2Q9YUIMz342U1Cj+nDvvp mlgM/i7WNdV/Q== Received: from lab-vbox (unknown [10.205.130.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 3D0E9A007C; Sat, 10 Apr 2021 00:47:00 +0000 (UTC) Received: by lab-vbox (sSMTP sendmail emulation); Fri, 09 Apr 2021 17:47:00 -0700 Date: Fri, 09 Apr 2021 17:47:00 -0700 Message-Id: <07196754c6de290bb46cc235ce6e96c5df304150.1618014279.git.Thinh.Nguyen@synopsys.com> In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Thinh Nguyen Subject: [PATCH v2 3/7] usb: xhci: Check for blocked disconnection To: Felipe Balbi , Greg Kroah-Hartman , Thinh.Nguyen@synopsys.com, linux-usb@vger.kernel.org, Mathias Nyman Cc: John Youn Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org If there is a device with active enhanced super-speed (eSS) isoc IN endpoint(s) behind one or more eSS hubs, DWC_usb31 (v1.90a and prior) host controller will not detect the device disconnection until no more isoc URB is submitted. If there's a device disconnection, internally the wait for tHostTransactionTimeout (USB 3.2 spec 8.13) blocks the other endpoints from being scheduled. So, it blocks the interrupt endpoint of the eSS hub indicating the port change status. This can be an issue for applications that continuously submitting isoc URBs to the xHCI. To work around this, stop processing new URBs after 3 consecutive isoc transaction errors. If new isoc transfers are queued after the device is disconnected, the host will respond with USB transaction error. After 3 consecutive USB transaction errors, the driver can wait a period of time (at least 2 * largest periodic interval of the topology) without ringing isoc endpoint doorbell to detect the port change status. If there is no disconnection detected, ring the endpoint doorbell to resume isoc transfers. This workaround tracks the max eSS periodic interval every time there's an endpoint added or dropped, which happens when there's bandwidth check. So, scan the topology and update the xhci->max_ess_interval whenever there's a bandwidth check. Introduced a new flag VDEV_DISCONN_CHECK_PENDING to prevent ringing the doorbell while waiting for a disconnection status. After 2 * max_ess_interval time and no disconnection detected, a delayed work will ring the doorbell to resume the active isoc transfers. Signed-off-by: Thinh Nguyen --- Changes in v2: - None drivers/usb/host/xhci-mem.c | 3 ++ drivers/usb/host/xhci-ring.c | 76 +++++++++++++++++++++++++++++++++ drivers/usb/host/xhci.c | 49 +++++++++++++++++++++ drivers/usb/host/xhci.h | 10 +++++ include/linux/usb/xhci-quirks.h | 1 + 5 files changed, 139 insertions(+) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index f66815fe8482..1053b43008e4 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -995,6 +995,8 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, xhci_dbg(xhci, "Slot %d input ctx = 0x%llx (dma)\n", slot_id, (unsigned long long)dev->in_ctx->dma); + INIT_DELAYED_WORK(&dev->resume_isoc, xhci_resume_isoc); + /* Initialize the cancellation list and watchdog timers for each ep */ for (i = 0; i < 31; i++) { dev->eps[i].ep_index = i; @@ -1010,6 +1012,7 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, goto fail; dev->udev = udev; + dev->xhci = xhci; /* Point to output device context in dcbaa. */ xhci->dcbaa->dev_context_ptrs[slot_id] = cpu_to_le64(dev->out_ctx->dma); diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 05c38dd3ee36..a434a4b3609f 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -419,6 +419,14 @@ void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index]; unsigned int ep_state = ep->ep_state; + /* + * Don't ring the doorbell for isoc IN endpoint while checking for + * device disconnection. + */ + if (ep->ring && ep->ring->type == TYPE_ISOC && !(ep_index % 2) && + (xhci->devs[slot_id]->flags & VDEV_DISCONN_CHECK_PENDING)) + return; + /* Don't ring the doorbell for this endpoint if there are pending * cancellations because we don't want to interrupt processing. * We don't want to restart any stream rings if there's a set dequeue @@ -2330,6 +2338,8 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, struct xhci_ring *ep_ring, struct xhci_td *td, union xhci_trb *ep_trb, struct xhci_transfer_event *event) { + struct usb_device *udev; + struct xhci_virt_device *vdev; struct urb_priv *urb_priv; int idx; struct usb_iso_packet_descriptor *frame; @@ -2347,10 +2357,13 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, ep_trb_len = TRB_LEN(le32_to_cpu(ep_trb->generic.field[2])); short_framestatus = td->urb->transfer_flags & URB_SHORT_NOT_OK ? -EREMOTEIO : 0; + udev = td->urb->dev; + vdev = xhci->devs[udev->slot_id]; /* handle completion code */ switch (trb_comp_code) { case COMP_SUCCESS: + ep->ring->err_count = 0; if (remaining) { frame->status = short_framestatus; if (xhci->quirks & XHCI_TRUST_TX_LENGTH) @@ -2375,6 +2388,23 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, frame->status = -EPROTO; break; case COMP_USB_TRANSACTION_ERROR: + if ((xhci->quirks & XHCI_ISOC_BLOCKED_DISCONNECT) && + usb_urb_dir_in(td->urb) && + udev->parent && udev->parent->parent && + udev->speed >= USB_SPEED_SUPER) { + if (!(vdev->flags & VDEV_DISCONN_CHECK_PENDING) && + ep->ring->err_count++ >= 3) { + unsigned long timeout; + + /* Wait for at least max interval x 2 x 125us */ + timeout = (1 << xhci->max_ess_interval) * 250; + vdev->flags |= VDEV_DISCONN_CHECK_PENDING; + queue_delayed_work(system_wq, + &vdev->resume_isoc, + usecs_to_jiffies(timeout)); + } + } + frame->status = -EPROTO; if (ep_trb != td->last_trb) return 0; @@ -4171,6 +4201,9 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags, for (i = 0; i < num_tds; i++) num_trbs += count_isoc_trbs_needed(urb, i); + if ((xdev->flags & VDEV_DISCONN_CHECK_PENDING) && usb_urb_dir_in(urb)) + return -EINVAL; + /* Check the ring to guarantee there is enough room for the whole urb. * Do not insert any td of the urb to the ring if the check failed. */ @@ -4359,3 +4392,46 @@ int xhci_queue_reset_ep(struct xhci_hcd *xhci, struct xhci_command *cmd, return queue_command(xhci, cmd, 0, 0, 0, trb_slot_id | trb_ep_index | type, false); } + +void xhci_resume_isoc(struct work_struct *work) +{ + struct xhci_hcd *xhci; + struct xhci_virt_device *vdev; + unsigned int slot_id; + unsigned long flags; + + vdev = container_of(to_delayed_work(work), + struct xhci_virt_device, resume_isoc); + xhci = vdev->xhci; + + spin_lock_irqsave(&xhci->lock, flags); + + /* Check if the device is dropped before this work takes place */ + if (!vdev->udev) + goto out; + + slot_id = vdev->udev->slot_id; + + vdev->flags &= ~VDEV_DISCONN_CHECK_PENDING; + + /* Resume isoc transfers if the device is still connected */ + if (xhci->devs[slot_id]) { + int i; + + /* Ring doorbell for IN isoc endpoints only */ + for (i = 2; i < 31; i += 2) { + struct xhci_virt_ep *ep = &vdev->eps[i]; + + if (!ep) + break; + + if (ep->ring && ep->ring->type == TYPE_ISOC) { + ep->ring->err_count = 0; + ring_doorbell_for_active_rings(xhci, slot_id, i); + } + } + } + +out: + spin_unlock_irqrestore(&xhci->lock, flags); +} diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index ca9385d22f68..e1136a6b9372 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -2973,6 +2973,44 @@ static void xhci_check_bw_drop_ep_streams(struct xhci_hcd *xhci, } } +static void xhci_update_ess_max_interval(struct xhci_hcd *xhci) +{ + unsigned int max_ess_interval = 0; + int j; + + for (j = 1; j < HCS_MAX_SLOTS(xhci->hcs_params1); j++) { + struct xhci_virt_device *virt_dev; + int i; + + virt_dev = xhci->devs[j]; + if (!virt_dev) + continue; + + /* Only update for eSS devices */ + if (virt_dev->udev && + virt_dev->udev->speed < USB_SPEED_SUPER) + continue; + + for (i = 0; i < 31; i++) { + struct xhci_ep_ctx *ep_ctx; + unsigned int ep_type; + unsigned int interval; + + ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->out_ctx, i); + ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2)); + + if (xhci_is_async_ep(ep_type)) + continue; + + interval = CTX_TO_EP_INTERVAL(le32_to_cpu(ep_ctx->ep_info)); + if (interval > max_ess_interval) + max_ess_interval = interval; + } + } + + xhci->max_ess_interval = max_ess_interval; +} + /* Called after one or more calls to xhci_add_endpoint() or * xhci_drop_endpoint(). If this call fails, the USB core is expected * to call xhci_reset_bandwidth(). @@ -3047,6 +3085,17 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) /* Callee should call reset_bandwidth() */ goto command_cleanup; + if (xhci->quirks & XHCI_ISOC_BLOCKED_DISCONNECT) { + xhci_update_ess_max_interval(xhci); + + /* Cancel disconnection check on change of context */ + if (delayed_work_pending(&virt_dev->resume_isoc) && + ctrl_ctx->drop_flags) { + cancel_delayed_work(&virt_dev->resume_isoc); + virt_dev->flags &= ~VDEV_DISCONN_CHECK_PENDING; + } + } + /* Free any rings that were dropped, but not changed. */ for (i = 1; i < 31; i++) { if ((le32_to_cpu(ctrl_ctx->drop_flags) & (1 << (i + 1))) && diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 9a4e2808668b..27d2c1176dd1 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1000,6 +1000,7 @@ struct xhci_interval_bw_table { struct xhci_virt_device { int slot_id; + struct xhci_hcd *xhci; struct usb_device *udev; /* * Commands to the hardware are passed an "input context" that @@ -1025,11 +1026,15 @@ struct xhci_virt_device { */ unsigned long flags; #define VDEV_PORT_ERROR BIT(0) /* Port error, link inactive */ +#define VDEV_DISCONN_CHECK_PENDING BIT(1) /* Disconnection check */ /* The current max exit latency for the enabled USB3 link states. */ u16 current_mel; /* Used for the debugfs interfaces. */ void *debugfs_private; + + /* For undetected disconnection quirk */ + struct delayed_work resume_isoc; }; /* @@ -1864,6 +1869,9 @@ struct xhci_hcd { /* Compliance Mode Timer Triggered every 2 seconds */ #define COMP_MODE_RCVRY_MSECS 2000 + /* Track max eSS interval for XHCI_ISOC_BLOCKED_DISCONNECT */ + unsigned int max_ess_interval; + struct dentry *debugfs_root; struct dentry *debugfs_slots; struct list_head regset_list; @@ -1948,6 +1956,8 @@ char *xhci_get_slot_state(struct xhci_hcd *xhci, void xhci_dbg_trace(struct xhci_hcd *xhci, void (*trace)(struct va_format *), const char *fmt, ...); +void xhci_resume_isoc(struct work_struct *work); + /* xHCI memory management */ void xhci_mem_cleanup(struct xhci_hcd *xhci); int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags); diff --git a/include/linux/usb/xhci-quirks.h b/include/linux/usb/xhci-quirks.h index 4001b10b418a..65bb62d3d31d 100644 --- a/include/linux/usb/xhci-quirks.h +++ b/include/linux/usb/xhci-quirks.h @@ -58,5 +58,6 @@ #define XHCI_DISABLE_SPARSE BIT_ULL(38) #define XHCI_SG_TRB_CACHE_SIZE_QUIRK BIT_ULL(39) #define XHCI_NO_SOFT_RETRY BIT_ULL(40) +#define XHCI_ISOC_BLOCKED_DISCONNECT BIT_ULL(41) #endif /* __LINUX_USB_XHCI_QUIRKS_H */ From patchwork Sat Apr 10 00:47:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thinh Nguyen X-Patchwork-Id: 12195257 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 99E47C433B4 for ; Sat, 10 Apr 2021 00:47:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6D66B6113A for ; Sat, 10 Apr 2021 00:47:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235319AbhDJArX (ORCPT ); Fri, 9 Apr 2021 20:47:23 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:39328 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235312AbhDJArW (ORCPT ); Fri, 9 Apr 2021 20:47:22 -0400 Received: from mailhost.synopsys.com (sv2-mailhost2.synopsys.com [10.205.2.134]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 02EA3401F1; Sat, 10 Apr 2021 00:47:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1618015629; bh=boOwoNo4+Zfzi026H2CCOo49+BR7HecMuFsdKCIS/WI=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=b1gr4tGTZjvX6QsbhcAjZUZ6hGowogUl593zw5fSk5Y1JLmd3eDfyN9RJGKsMwv6D CEPbMu1zAjW3klBER8GGoaioRI83R/Fi+0aKxDLXLQ7n2QrFE5OH7JIgtpcgq0VLhX A7GXdyvh8cr4HT2WK3JxYn5i4letqMLBreG/BuR451NExkginAOCHIkT7PcfiMPRwn k1IZdkZgVFhySbpg7k8luCHd8Lm3NSH4VSW086Y3Kau+DTNjEpoXbNWXC4abtpY7+i bWHV6pfVARPRlsJYv/cSu/f3EUhG9w3DxZmRTjE+HKqqkHIcViPyL3UQpkEPJ/9kp5 oD3SvxsX2ZL9Q== Received: from lab-vbox (unknown [10.205.130.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id CD5C9A0096; Sat, 10 Apr 2021 00:47:07 +0000 (UTC) Received: by lab-vbox (sSMTP sendmail emulation); Fri, 09 Apr 2021 17:47:07 -0700 Date: Fri, 09 Apr 2021 17:47:07 -0700 Message-Id: In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Thinh Nguyen Subject: [PATCH v2 4/7] usb: xhci: Workaround undercalculated BW for fullspeed BI To: Felipe Balbi , Greg Kroah-Hartman , Thinh.Nguyen@synopsys.com, linux-usb@vger.kernel.org, Mathias Nyman Cc: John Youn Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org DWC_usb31 host version 1.90a and prior undercalculates the bandwidth available for interrupt endpoints. The controller will return bandwidth error on config endpoint commands if there are already 6 or more fullspeed interrupt endpoints with bInterval of 4 (or 4ms) associated with a single fullspeed bus instance (BI). To workaround this, configure and use the endpoint at a shorter interrupt interval. Lower the ep_ctx interval from 5 to 4 (or 2ms) for interrupt endpoints of the fullspeed BI. Note: we have not observed functional impact to the fullspeed devices by lowering the interrupt service interval (at least for a few devices that we tested). To simplify the workaround, let's just check and apply the workaround if the endpoint is a fullspeed interrupt endpoint with interval of 4ms and if the top parent device is also operating in fullspeed (i.e. associated with fullspeed BI). Signed-off-by: Thinh Nguyen --- Changes in v2: - None Note: Checkpatch will give a warning below for getting top_dev: WARNING: suspect code indent for conditional statements Since this logic is done everywhere else in the driver, I'm keeping it consistent here. drivers/usb/host/xhci-mem.c | 23 +++++++++++++++++++++++ include/linux/usb/xhci-quirks.h | 1 + 2 files changed, 24 insertions(+) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 1053b43008e4..e01d0ddb012a 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1463,6 +1463,29 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, } } + /* + * Check for undercalculated bandwidth quirk for interrupt endpoints + * associated with fullspeed BI. + */ + if ((xhci->quirks & XHCI_LIMIT_FS_BI_INTR_EP) && + usb_endpoint_xfer_int(&ep->desc) && + udev->speed == USB_SPEED_FULL && + interval == 5) { + struct usb_device *top_dev; + + for (top_dev = udev; + top_dev->parent && top_dev->parent->parent; + top_dev = top_dev->parent) + /* Found device below root hub */; + + /* + * If the top device is operating at fullspeed, then the + * controller is using fullspeed BI for this device. + */ + if (top_dev->speed == USB_SPEED_FULL) + interval = 4; + } + mult = xhci_get_endpoint_mult(udev, ep); max_packet = usb_endpoint_maxp(&ep->desc); max_burst = xhci_get_endpoint_max_burst(udev, ep); diff --git a/include/linux/usb/xhci-quirks.h b/include/linux/usb/xhci-quirks.h index 65bb62d3d31d..5bedf5a25f7a 100644 --- a/include/linux/usb/xhci-quirks.h +++ b/include/linux/usb/xhci-quirks.h @@ -59,5 +59,6 @@ #define XHCI_SG_TRB_CACHE_SIZE_QUIRK BIT_ULL(39) #define XHCI_NO_SOFT_RETRY BIT_ULL(40) #define XHCI_ISOC_BLOCKED_DISCONNECT BIT_ULL(41) +#define XHCI_LIMIT_FS_BI_INTR_EP BIT_ULL(42) #endif /* __LINUX_USB_XHCI_QUIRKS_H */ From patchwork Sat Apr 10 00:47:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thinh Nguyen X-Patchwork-Id: 12195259 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E8C25C433B4 for ; Sat, 10 Apr 2021 00:47:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9F50E6113A for ; Sat, 10 Apr 2021 00:47:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235320AbhDJAr3 (ORCPT ); Fri, 9 Apr 2021 20:47:29 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.87.133]:46954 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235312AbhDJAr3 (ORCPT ); Fri, 9 Apr 2021 20:47:29 -0400 Received: from mailhost.synopsys.com (sv1-mailhost2.synopsys.com [10.205.2.132]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 6FCB7C00CB; Sat, 10 Apr 2021 00:47:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1618015635; bh=tq4xc0d56NxO2c7Uf5zSd9LFdpKIsj/l+9sUWMT8oQo=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=FakvpRznVPk/1C6MxflGzCCtByGhsQLuQZqFTuR5b31zUARDt1nZjF+1S3HXi1A5i QGOKKXVCeTHg/i/Gy31VFdGVxCix3ZeJ4g7lNlX+KV9VaYu6XeFEBHl4h/GRcfS/dS 7yYgUKkpF37oFQVmGu4LYPv2ddvXLiR4MLoa+UmWxpCB8jDuCu2Qx2ZRIOS35xMC42 9V3E/RPxb1AZEzQkhHhWjbQPQAH9d40uC3ii56Os3MGrLT4S3w1oHS5nC2Ol+GSb9b TYiSUJ2qGvVPAhiEBw1jXtb+do2aG0SkhMk3qfh5Il+Y9mqsDrdMCfsr97IM15j9RF kEnA5RNJG06wQ== Received: from lab-vbox (unknown [10.205.130.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 2BBF6A007C; Sat, 10 Apr 2021 00:47:14 +0000 (UTC) Received: by lab-vbox (sSMTP sendmail emulation); Fri, 09 Apr 2021 17:47:14 -0700 Date: Fri, 09 Apr 2021 17:47:14 -0700 Message-Id: <11cd7b9c481ca0be1a3a33a8c94443fd49a59b22.1618014279.git.Thinh.Nguyen@synopsys.com> In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Thinh Nguyen Subject: [PATCH v2 5/7] usb: xhci: Rename Compliance mode timer quirk To: Felipe Balbi , Greg Kroah-Hartman , Thinh.Nguyen@synopsys.com, linux-usb@vger.kernel.org, Mathias Nyman Cc: John Youn Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org In preparation for a workaround that needs to poll for the port status, rename the timer for XHCI_COMP_MODE_QUIRK to be more generic as it can be used for the new workaround. No funtional change here. Signed-off-by: Thinh Nguyen --- Changes in v2: - None drivers/usb/host/xhci-hub.c | 2 +- drivers/usb/host/xhci.c | 41 +++++++++++++++++-------------------- drivers/usb/host/xhci.h | 8 ++++---- 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index e9b18fc17617..8bfafbd680ab 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -893,7 +893,7 @@ static void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status, if ((xhci->port_status_u0 != all_ports_seen_u0) && port_in_u0) { xhci->port_status_u0 |= 1 << wIndex; if (xhci->port_status_u0 == all_ports_seen_u0) { - del_timer_sync(&xhci->comp_mode_recovery_timer); + del_timer_sync(&xhci->port_check_timer); xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, "All USB3 ports have entered U0 already!"); xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index e1136a6b9372..e1b3d1063f6b 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -475,7 +475,7 @@ static inline void xhci_msix_sync_irqs(struct xhci_hcd *xhci) #endif -static void compliance_mode_recovery(struct timer_list *t) +static void port_check(struct timer_list *t) { struct xhci_hcd *xhci; struct usb_hcd *hcd; @@ -483,7 +483,7 @@ static void compliance_mode_recovery(struct timer_list *t) u32 temp; int i; - xhci = from_timer(xhci, t, comp_mode_recovery_timer); + xhci = from_timer(xhci, t, port_check_timer); rhub = &xhci->usb3_rhub; for (i = 0; i < rhub->num_ports; i++) { @@ -508,8 +508,8 @@ static void compliance_mode_recovery(struct timer_list *t) } if (xhci->port_status_u0 != ((1 << rhub->num_ports) - 1)) - mod_timer(&xhci->comp_mode_recovery_timer, - jiffies + msecs_to_jiffies(COMP_MODE_RCVRY_MSECS)); + mod_timer(&xhci->port_check_timer, + jiffies + msecs_to_jiffies(PORT_CHECK_MSECS)); } /* @@ -522,15 +522,14 @@ static void compliance_mode_recovery(struct timer_list *t) * status event is generated when entering compliance mode (per xhci spec), * this quirk is needed on systems that have the failing hardware installed. */ -static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci) +static void port_check_timer_init(struct xhci_hcd *xhci) { xhci->port_status_u0 = 0; - timer_setup(&xhci->comp_mode_recovery_timer, compliance_mode_recovery, - 0); - xhci->comp_mode_recovery_timer.expires = jiffies + - msecs_to_jiffies(COMP_MODE_RCVRY_MSECS); + timer_setup(&xhci->port_check_timer, port_check, 0); + xhci->port_check_timer.expires = jiffies + + msecs_to_jiffies(PORT_CHECK_MSECS); - add_timer(&xhci->comp_mode_recovery_timer); + add_timer(&xhci->port_check_timer); xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, "Compliance mode recovery timer initialized"); } @@ -596,7 +595,7 @@ static int xhci_init(struct usb_hcd *hcd) /* Initializing Compliance Mode Recovery Data If Needed */ if (xhci_compliance_mode_recovery_timer_quirk_check()) { xhci->quirks |= XHCI_COMP_MODE_QUIRK; - compliance_mode_recovery_timer_init(xhci); + port_check_timer_init(xhci); } return retval; @@ -739,10 +738,9 @@ static void xhci_stop(struct usb_hcd *hcd) /* Deleting Compliance Mode Recovery Timer */ if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && (!(xhci_all_ports_seen_u0(xhci)))) { - del_timer_sync(&xhci->comp_mode_recovery_timer); + del_timer_sync(&xhci->port_check_timer); xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, - "%s: compliance mode recovery timer deleted", - __func__); + "%s: port check timer deleted", __func__); } if (xhci->quirks & XHCI_AMD_PLL_FIX) @@ -1057,15 +1055,14 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) spin_unlock_irq(&xhci->lock); /* - * Deleting Compliance Mode Recovery Timer because the xHCI Host + * Deleting Port Check Timer because the xHCI Host * is about to be suspended. */ if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && (!(xhci_all_ports_seen_u0(xhci)))) { - del_timer_sync(&xhci->comp_mode_recovery_timer); + del_timer_sync(&xhci->port_check_timer); xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, - "%s: compliance mode recovery timer deleted", - __func__); + "%s: port check timer deleted", __func__); } /* step 5: remove core well power */ @@ -1150,9 +1147,9 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !(xhci_all_ports_seen_u0(xhci))) { - del_timer_sync(&xhci->comp_mode_recovery_timer); + del_timer_sync(&xhci->port_check_timer); xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, - "Compliance Mode Recovery Timer deleted!"); + "Port Check Timer deleted!"); } /* Let the USB core know _both_ roothubs lost power. */ @@ -1245,13 +1242,13 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) } } /* - * If system is subject to the Quirk, Compliance Mode Timer needs to + * If system is subject to the Quirk, Port Check Timer needs to * be re-initialized Always after a system resume. Ports are subject * to suffer the Compliance Mode issue again. It doesn't matter if * ports have entered previously to U0 before system's suspension. */ if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !comp_timer_running) - compliance_mode_recovery_timer_init(xhci); + port_check_timer_init(xhci); if (xhci->quirks & XHCI_ASMEDIA_MODIFY_FLOWCONTROL) usb_asmedia_modifyflowcontrol(to_pci_dev(hcd->self.controller)); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 27d2c1176dd1..b52b7dcb5bb9 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1862,12 +1862,12 @@ struct xhci_hcd { /* cached extended protocol port capabilities */ struct xhci_port_cap *port_caps; unsigned int num_port_caps; - /* Compliance Mode Recovery Data */ - struct timer_list comp_mode_recovery_timer; + /* For quirks that require to poll for port status */ + struct timer_list port_check_timer; u32 port_status_u0; u16 test_mode; -/* Compliance Mode Timer Triggered every 2 seconds */ -#define COMP_MODE_RCVRY_MSECS 2000 +/* Port polling frequency */ +#define PORT_CHECK_MSECS 2000 /* Track max eSS interval for XHCI_ISOC_BLOCKED_DISCONNECT */ unsigned int max_ess_interval; From patchwork Sat Apr 10 00:47:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thinh Nguyen X-Patchwork-Id: 12195261 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EF2F9C433B4 for ; Sat, 10 Apr 2021 00:47:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B2DBD6115A for ; Sat, 10 Apr 2021 00:47:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235323AbhDJArf (ORCPT ); Fri, 9 Apr 2021 20:47:35 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:39340 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235312AbhDJArf (ORCPT ); Fri, 9 Apr 2021 20:47:35 -0400 Received: from mailhost.synopsys.com (sv1-mailhost2.synopsys.com [10.205.2.132]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id C813940344; Sat, 10 Apr 2021 00:47:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1618015641; bh=Ity4RAQpCC9LKIRutd5Q6SyJNY07n8Go4Fm1XgNf0jo=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=iJpYeiBjg6WXOFW6p131CN0KXAqJSC7Z+PpDwqjz5R8XxVzX9wZ2tOVDITz01SPkG qMTYal+m05+AktQPM4FbjQLtlOongW/Bwbawgr42IEuSnrN+kavApaBvSf+zSOmpKG oSQvHVjdxUWYc9C/MCHw6bzAmQW7/7AE/p0FAWy72wdSb810kf33NMnCBMqFp1rNJj HXwYH46S6aERVx6mumVoAqxAL7KNeZEIqiSdzvKdBB2OqBMoRlRP5tvQUcKjCJGQ90 WNjTbpi8xhQ2Uuri99xl8dJwmF2+xdOTdGPHd5AOYI356nuTjgcWY7xoJ7XDct9LBe v29pntzG9KFvg== Received: from lab-vbox (unknown [10.205.130.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 7F81AA007C; Sat, 10 Apr 2021 00:47:20 +0000 (UTC) Received: by lab-vbox (sSMTP sendmail emulation); Fri, 09 Apr 2021 17:47:20 -0700 Date: Fri, 09 Apr 2021 17:47:20 -0700 Message-Id: In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Thinh Nguyen Subject: [PATCH v2 6/7] usb: xhci: Workaround lost disconnect port status To: Felipe Balbi , Greg Kroah-Hartman , Thinh.Nguyen@synopsys.com, linux-usb@vger.kernel.org, Mathias Nyman Cc: John Youn Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org If an eSS device with active periodic transfers is disconnected from the DWC_usb31 (v1.90a and prior) host controller at root port, the host controller may not detect a disconnection. By active transfers, it means that the endpoint is not in flow control, and there are active Transfer Descriptors available for the host to initiate transfers to the endpoint. This issue can occur if the endpoint periodic interval is in 2ms, 4ms, or 8ms. In addition, the host controller will not be able to detect a new device connection while the disconnection is not processed. The controller will set the link state of the affected port to eSS_INACTIVE. To workaround this, have the xHCI driver polls for the eSS root port status every 2 seconds. If eSS_INACTIVE state is detected, initiate a fake connection change to stop all the active endpoints and start polling for new connection change. Since XHCI_COMP_MODE_QUIRK is basically doing the same thing except for polling for a different link state, we will use the same timer and polling rate for this new workaround. Introduce a new quirk XHCI_LOST_DISCONNECT_QUIRK to poll for eSS_INACTIVE port link state and fake a connection change. Signed-off-by: Thinh Nguyen --- Changes in v2: - None drivers/usb/host/xhci-hub.c | 10 +++++++- drivers/usb/host/xhci.c | 44 ++++++++++++++++++++++++--------- include/linux/usb/xhci-quirks.h | 1 + 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 8bfafbd680ab..32fbf95f021b 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -868,6 +868,11 @@ static void xhci_hub_report_usb3_link_state(struct xhci_hcd *xhci, if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && (pls == USB_SS_PORT_LS_COMP_MOD)) pls |= USB_PORT_STAT_CONNECTION; + + /* Fake a connection change */ + if ((xhci->quirks & XHCI_LOST_DISCONNECT_QUIRK) && + pls == XDEV_INACTIVE) + pls |= USB_PORT_STAT_CONNECTION; } /* update status field */ @@ -887,7 +892,8 @@ static void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status, u32 all_ports_seen_u0 = ((1 << xhci->usb3_rhub.num_ports) - 1); bool port_in_u0 = ((status & PORT_PLS_MASK) == XDEV_U0); - if (!(xhci->quirks & XHCI_COMP_MODE_QUIRK)) + if (!(xhci->quirks & XHCI_COMP_MODE_QUIRK) || + (xhci->quirks & XHCI_LOST_DISCONNECT_QUIRK)) return; if ((xhci->port_status_u0 != all_ports_seen_u0) && port_in_u0) { @@ -1654,6 +1660,8 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) trace_xhci_hub_status_data(i, temp); if ((temp & mask) != 0 || + ((xhci->quirks & XHCI_LOST_DISCONNECT_QUIRK) && + (temp & PORT_PLS_MASK) == XDEV_INACTIVE) || (bus_state->port_c_suspend & 1 << i) || (bus_state->resume_done[i] && time_after_eq( jiffies, bus_state->resume_done[i]))) { diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index e1b3d1063f6b..62275ee88849 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -485,10 +485,14 @@ static void port_check(struct timer_list *t) xhci = from_timer(xhci, t, port_check_timer); rhub = &xhci->usb3_rhub; + hcd = xhci->shared_hcd; for (i = 0; i < rhub->num_ports; i++) { + bool poll_rhub = false; + temp = readl(rhub->ports[i]->addr); - if ((temp & PORT_PLS_MASK) == USB_SS_PORT_LS_COMP_MOD) { + if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && + ((temp & PORT_PLS_MASK) == USB_SS_PORT_LS_COMP_MOD)) { /* * Compliance Mode Detected. Letting USB Core * handle the Warm Reset @@ -498,8 +502,15 @@ static void port_check(struct timer_list *t) i + 1); xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, "Attempting compliance mode recovery"); - hcd = xhci->shared_hcd; + poll_rhub = true; + } + + if ((xhci->quirks & XHCI_LOST_DISCONNECT_QUIRK) && + ((temp & PORT_PLS_MASK) == XDEV_INACTIVE)) + poll_rhub = true; + + if (poll_rhub) { if (hcd->state == HC_STATE_SUSPENDED) usb_hcd_resume_root_hub(hcd); @@ -507,7 +518,9 @@ static void port_check(struct timer_list *t) } } - if (xhci->port_status_u0 != ((1 << rhub->num_ports) - 1)) + if ((xhci->quirks & XHCI_LOST_DISCONNECT_QUIRK) || + ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && + xhci->port_status_u0 != ((1 << rhub->num_ports) - 1))) mod_timer(&xhci->port_check_timer, jiffies + msecs_to_jiffies(PORT_CHECK_MSECS)); } @@ -593,10 +606,12 @@ static int xhci_init(struct usb_hcd *hcd) xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Finished xhci_init"); /* Initializing Compliance Mode Recovery Data If Needed */ - if (xhci_compliance_mode_recovery_timer_quirk_check()) { + if (xhci_compliance_mode_recovery_timer_quirk_check()) xhci->quirks |= XHCI_COMP_MODE_QUIRK; + + if (xhci->quirks & XHCI_LOST_DISCONNECT_QUIRK || + xhci->quirks & XHCI_COMP_MODE_QUIRK) port_check_timer_init(xhci); - } return retval; } @@ -736,8 +751,9 @@ static void xhci_stop(struct usb_hcd *hcd) xhci_cleanup_msix(xhci); /* Deleting Compliance Mode Recovery Timer */ - if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && - (!(xhci_all_ports_seen_u0(xhci)))) { + if ((xhci->quirks & XHCI_LOST_DISCONNECT_QUIRK) || + ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && + !(xhci_all_ports_seen_u0(xhci)))) { del_timer_sync(&xhci->port_check_timer); xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, "%s: port check timer deleted", __func__); @@ -1058,8 +1074,9 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) * Deleting Port Check Timer because the xHCI Host * is about to be suspended. */ - if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && - (!(xhci_all_ports_seen_u0(xhci)))) { + if ((xhci->quirks & XHCI_LOST_DISCONNECT_QUIRK) || + ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && + !(xhci_all_ports_seen_u0(xhci)))) { del_timer_sync(&xhci->port_check_timer); xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, "%s: port check timer deleted", __func__); @@ -1145,8 +1162,9 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) /* If restore operation fails, re-initialize the HC during resume */ if ((temp & STS_SRE) || hibernated) { - if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && - !(xhci_all_ports_seen_u0(xhci))) { + if ((xhci->quirks & XHCI_LOST_DISCONNECT_QUIRK) || + ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && + !(xhci_all_ports_seen_u0(xhci)))) { del_timer_sync(&xhci->port_check_timer); xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, "Port Check Timer deleted!"); @@ -1247,7 +1265,9 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) * to suffer the Compliance Mode issue again. It doesn't matter if * ports have entered previously to U0 before system's suspension. */ - if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !comp_timer_running) + if (!comp_timer_running && + ((xhci->quirks & XHCI_LOST_DISCONNECT_QUIRK) || + (xhci->quirks & XHCI_COMP_MODE_QUIRK))) port_check_timer_init(xhci); if (xhci->quirks & XHCI_ASMEDIA_MODIFY_FLOWCONTROL) diff --git a/include/linux/usb/xhci-quirks.h b/include/linux/usb/xhci-quirks.h index 5bedf5a25f7a..df92e78b8083 100644 --- a/include/linux/usb/xhci-quirks.h +++ b/include/linux/usb/xhci-quirks.h @@ -60,5 +60,6 @@ #define XHCI_NO_SOFT_RETRY BIT_ULL(40) #define XHCI_ISOC_BLOCKED_DISCONNECT BIT_ULL(41) #define XHCI_LIMIT_FS_BI_INTR_EP BIT_ULL(42) +#define XHCI_LOST_DISCONNECT_QUIRK BIT_ULL(43) #endif /* __LINUX_USB_XHCI_QUIRKS_H */ From patchwork Sat Apr 10 00:47:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thinh Nguyen X-Patchwork-Id: 12195263 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3AEB0C433ED for ; Sat, 10 Apr 2021 00:47:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 044086113A for ; Sat, 10 Apr 2021 00:47:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235324AbhDJAro (ORCPT ); Fri, 9 Apr 2021 20:47:44 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:39350 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235302AbhDJArl (ORCPT ); Fri, 9 Apr 2021 20:47:41 -0400 Received: from mailhost.synopsys.com (sv2-mailhost2.synopsys.com [10.205.2.134]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 23F7E401F1; Sat, 10 Apr 2021 00:47:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1618015648; bh=D4xc62yjlF5gA22+eduGTT9Gb/N0nG6e5KR72LP9XwI=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=lZ5go6vACw7JDUhg3dJg3SEtIfnWtR1sWA9mDrQks+fB42FIg5DeGE8Bt7uSldb7P 0i9eIcOyo2/FQ8HGhSV5Ji9WVgkj5mkni0nI76KVucKt+V5WZS8c0izOal9i3B5DTN ANFq/w680/CmW+wQtyyQOhP/aJb5d7oPVllbdAQHC1hWpvYy0Zw2n01yz/Dj4084QL Wbdc2hLz+I/FXXlK0p5c1fWFaBKaUByVyFFpJZtjGRVwk6KMBae5gIb9uPd/+XQbRd rYinfmiQAT/vpP+AwITtNmOmZS6qXpPCSmdoaRw0ux+xE5+jXPgyGsEMESWLDc6SQ9 8ZsYaU3SJvwJQ== Received: from lab-vbox (unknown [10.205.130.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id F36ABA0096; Sat, 10 Apr 2021 00:47:26 +0000 (UTC) Received: by lab-vbox (sSMTP sendmail emulation); Fri, 09 Apr 2021 17:47:26 -0700 Date: Fri, 09 Apr 2021 17:47:26 -0700 Message-Id: <0fb179b977cd187f003ae18adf01bccf09d74092.1618014279.git.Thinh.Nguyen@synopsys.com> In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Thinh Nguyen Subject: [PATCH v2 7/7] usb: dwc3: host: Set quirks base on version To: Felipe Balbi , Greg Kroah-Hartman , Thinh.Nguyen@synopsys.com, linux-usb@vger.kernel.org Cc: John Youn Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org We can check for host quirks at runtime base on the controller IP and version check. Set the following quirks for the DWC_usb31 IP host mode before creating a platform device for the xHCI driver: * XHCI_ISOC_BLOCKED_DISCONNECT * XHCI_LIMIT_FS_BI_INTR_EP * XHCI_LOST_DISCONNECT_QUIRK Signed-off-by: Thinh Nguyen --- Changes in v2: - None drivers/usb/dwc3/host.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c index f29a264635aa..8abb9be32cbb 100644 --- a/drivers/usb/dwc3/host.c +++ b/drivers/usb/dwc3/host.c @@ -9,6 +9,8 @@ #include #include +#include +#include #include "core.h" @@ -42,6 +44,17 @@ static int dwc3_host_get_irq(struct dwc3 *dwc) return irq; } +static void dwc3_host_init_quirks(struct dwc3 *dwc, struct xhci_plat_priv *priv) +{ + memset(priv, 0, sizeof(*priv)); + + if (DWC3_VER_IS_WITHIN(DWC31, ANY, 190A)) { + priv->quirks |= XHCI_ISOC_BLOCKED_DISCONNECT; + priv->quirks |= XHCI_LIMIT_FS_BI_INTR_EP; + priv->quirks |= XHCI_LOST_DISCONNECT_QUIRK; + } +} + int dwc3_host_init(struct dwc3 *dwc) { struct property_entry props[4]; @@ -49,6 +62,7 @@ int dwc3_host_init(struct dwc3 *dwc) int ret, irq; struct resource *res; struct platform_device *dwc3_pdev = to_platform_device(dwc->dev); + struct xhci_plat_priv dwc3_priv; int prop_idx = 0; irq = dwc3_host_get_irq(dwc); @@ -87,6 +101,14 @@ int dwc3_host_init(struct dwc3 *dwc) goto err; } + dwc3_host_init_quirks(dwc, &dwc3_priv); + + ret = platform_device_add_data(xhci, &dwc3_priv, sizeof(dwc3_priv)); + if (ret) { + dev_err(dwc->dev, "couldn't add platform data to xHCI device\n"); + goto err; + } + memset(props, 0, sizeof(struct property_entry) * ARRAY_SIZE(props)); if (dwc->usb3_lpm_capable)