From patchwork Thu Jan 24 23:28:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajat Jain X-Patchwork-Id: 1030718 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="txV6W1Zt"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43lyyJ4YTlz9s7h for ; Fri, 25 Jan 2019 10:28:24 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728340AbfAXX2V (ORCPT ); Thu, 24 Jan 2019 18:28:21 -0500 Received: from mail-pf1-f201.google.com ([209.85.210.201]:48052 "EHLO mail-pf1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728248AbfAXX2V (ORCPT ); Thu, 24 Jan 2019 18:28:21 -0500 Received: by mail-pf1-f201.google.com with SMTP id m3so5943641pfj.14 for ; Thu, 24 Jan 2019 15:28:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=D/n+iLRONY/z6dZgG+EgYqvlkP4ooj+2tYEzHi4XON8=; b=txV6W1ZtraQlt92o41uu1lgVNKxl2QudDXVTpqZUX1sEpcpYGASapdFDOP9Tp4EuUs TV73GzGOZrUzx+fP3gd7iRe77Fl+NiW8iyDU2+BbJck6Re40dDYsLxuFY7n6aFV2ET/w HGVo/O7C9mit0ZagtYTYyvS6NpNAlh4kcCeFkk374tEf07QTFlexStj1z+970VSBkNm2 9jZRImP/0EDw1w4NDB6B6Q+J6u97QmVoKRGQCk8I9naVbseIVOeQ9gQ7bTRbxuNzQWfz oTXatJWHh0KY0qpJVFM03TF8A0+nnB5wZe1tpQCdiF7I6lw5UMfpo79IPVrhsr75O7cH xqzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=D/n+iLRONY/z6dZgG+EgYqvlkP4ooj+2tYEzHi4XON8=; b=teswpnBvdoWRebFhZ9xsOc5VyOLNAL/FNiWzO9J+F5ErfVnw3Xpv62tnsKKcwNQjxn rp9eIY8DD4DuGPVVQKPSjFXDp28cNUdUZ0g+RIkpikKsS5FiKWZ/Dhp6ZU1JBjxKm00U k+CMxdKjSTTWkeoJGaGEbHLG2G0xHrQOCKoE0hGjPUiAiKcc1k+iaERI95/VeTSqH0SJ ZoFpxb7HH5T6m4pOVzR+dSoiyJ16MHxUFasrk3wb+EnSMPSTpYGGylDyRf7P8J3kL+tp fxiASlE/BnRgjGdwosCFGxn3M825eh2Qmo7AenM7DVL2rOBdn7mxvgWhiad09IgMrlZt Ralw== X-Gm-Message-State: AJcUukdZS478x0TiRGghoKJowa889uFAWAUGBRZw28/VtDvTZQ9VKV1s eBgKzAZM0LzX2Vbgwhi0JzGmHlHgYBHN X-Google-Smtp-Source: ALg8bN6HHHD2nMkSDU1L8mSuEWBGcMe9KW51EMyzOioDKV6Cqj7V505GT7KeSuUfz7QfElfy2qXxsIQGLGmL X-Received: by 2002:a63:790f:: with SMTP id u15mr3805073pgc.125.1548372499784; Thu, 24 Jan 2019 15:28:19 -0800 (PST) Date: Thu, 24 Jan 2019 15:28:11 -0800 In-Reply-To: <20181117010748.24347-1-rajatja@google.com> Message-Id: <20190124232814.252661-1-rajatja@google.com> Mime-Version: 1.0 References: <20181117010748.24347-1-rajatja@google.com> X-Mailer: git-send-email 2.20.1.321.g9e740568ce-goog Subject: [PATCH v6 1/4] usb: split code locating ACPI companion into port and device From: Rajat Jain To: Marcel Holtmann , Johan Hedberg , Greg Kroah-Hartman , "David S. Miller" , Dmitry Torokhov , Rajat Jain , Alex Hung , linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, netdev@vger.kernel.org Cc: rajatxjain@gmail.com, dtor@google.com, raghuram.hegde@intel.com, chethan.tumkur.narayan@intel.com, sukumar.ghorai@intel.com Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Dmitry Torokhov In preparation for handling embedded USB devices let's split usb_acpi_find_companion() into usb_acpi_find_companion_for_device() and usb_acpi_find_companion_for_port(). Signed-off-by: Dmitry Torokhov Signed-off-by: Rajat Jain Acked-by: Greg Kroah-Hartman Tested-by: Sukumar Ghorai --- v6: same as v4 v5: same as v4 v4: Add Acked-by and Tested-by in signatures. v3: same as v1 v2: same as v1 drivers/usb/core/usb-acpi.c | 133 +++++++++++++++++++----------------- 1 file changed, 72 insertions(+), 61 deletions(-) diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c index e221861b3187..8ff73c83e8e8 100644 --- a/drivers/usb/core/usb-acpi.c +++ b/drivers/usb/core/usb-acpi.c @@ -139,12 +139,79 @@ static struct acpi_device *usb_acpi_find_port(struct acpi_device *parent, return acpi_find_child_device(parent, raw, false); } -static struct acpi_device *usb_acpi_find_companion(struct device *dev) +static struct acpi_device * +usb_acpi_get_companion_for_port(struct usb_port *port_dev) { struct usb_device *udev; struct acpi_device *adev; acpi_handle *parent_handle; + int port1; + + /* Get the struct usb_device point of port's hub */ + udev = to_usb_device(port_dev->dev.parent->parent); + + /* + * The root hub ports' parent is the root hub. The non-root-hub + * ports' parent is the parent hub port which the hub is + * connected to. + */ + if (!udev->parent) { + adev = ACPI_COMPANION(&udev->dev); + port1 = usb_hcd_find_raw_port_number(bus_to_hcd(udev->bus), + port_dev->portnum); + } else { + parent_handle = usb_get_hub_port_acpi_handle(udev->parent, + udev->portnum); + if (!parent_handle) + return NULL; + + acpi_bus_get_device(parent_handle, &adev); + port1 = port_dev->portnum; + } + + return usb_acpi_find_port(adev, port1); +} + +static struct acpi_device * +usb_acpi_find_companion_for_port(struct usb_port *port_dev) +{ + struct acpi_device *adev; + struct acpi_pld_info *pld; + acpi_handle *handle; + acpi_status status; + + adev = usb_acpi_get_companion_for_port(port_dev); + if (!adev) + return NULL; + + handle = adev->handle; + status = acpi_get_physical_device_location(handle, &pld); + if (!ACPI_FAILURE(status) && pld) { + port_dev->location = USB_ACPI_LOCATION_VALID + | pld->group_token << 8 | pld->group_position; + port_dev->connect_type = usb_acpi_get_connect_type(handle, pld); + ACPI_FREE(pld); + } + return adev; +} + +static struct acpi_device * +usb_acpi_find_companion_for_device(struct usb_device *udev) +{ + struct acpi_device *adev; + + if (!udev->parent) + return NULL; + + /* root hub is only child (_ADR=0) under its parent, the HC */ + adev = ACPI_COMPANION(udev->dev.parent); + return acpi_find_child_device(adev, 0, false); +} + + +static struct acpi_device *usb_acpi_find_companion(struct device *dev) +{ /* * In the ACPI DSDT table, only usb root hub and usb ports are * acpi device nodes. The hierarchy like following. @@ -158,66 +225,10 @@ static struct acpi_device *usb_acpi_find_companion(struct device *dev) * So all binding process is divided into two parts. binding * root hub and usb ports. */ - if (is_usb_device(dev)) { - udev = to_usb_device(dev); - if (udev->parent) - return NULL; - - /* root hub is only child (_ADR=0) under its parent, the HC */ - adev = ACPI_COMPANION(dev->parent); - return acpi_find_child_device(adev, 0, false); - } else if (is_usb_port(dev)) { - struct usb_port *port_dev = to_usb_port(dev); - int port1 = port_dev->portnum; - struct acpi_pld_info *pld; - acpi_handle *handle; - acpi_status status; - - /* Get the struct usb_device point of port's hub */ - udev = to_usb_device(dev->parent->parent); - - /* - * The root hub ports' parent is the root hub. The non-root-hub - * ports' parent is the parent hub port which the hub is - * connected to. - */ - if (!udev->parent) { - struct usb_hcd *hcd = bus_to_hcd(udev->bus); - int raw; - - raw = usb_hcd_find_raw_port_number(hcd, port1); - - adev = usb_acpi_find_port(ACPI_COMPANION(&udev->dev), - raw); - - if (!adev) - return NULL; - } else { - parent_handle = - usb_get_hub_port_acpi_handle(udev->parent, - udev->portnum); - if (!parent_handle) - return NULL; - - acpi_bus_get_device(parent_handle, &adev); - - adev = usb_acpi_find_port(adev, port1); - - if (!adev) - return NULL; - } - handle = adev->handle; - status = acpi_get_physical_device_location(handle, &pld); - if (ACPI_FAILURE(status) || !pld) - return adev; - - port_dev->location = USB_ACPI_LOCATION_VALID - | pld->group_token << 8 | pld->group_position; - port_dev->connect_type = usb_acpi_get_connect_type(handle, pld); - ACPI_FREE(pld); - - return adev; - } + if (is_usb_device(dev)) + return usb_acpi_find_companion_for_device(to_usb_device(dev)); + else if (is_usb_port(dev)) + return usb_acpi_find_companion_for_port(to_usb_port(dev)); return NULL; } From patchwork Thu Jan 24 23:28:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajat Jain X-Patchwork-Id: 1030719 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="tK9R/vSj"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43lyyN4WRgz9s3q for ; Fri, 25 Jan 2019 10:28:28 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728416AbfAXX21 (ORCPT ); Thu, 24 Jan 2019 18:28:27 -0500 Received: from mail-qt1-f201.google.com ([209.85.160.201]:53068 "EHLO mail-qt1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727649AbfAXX2Y (ORCPT ); Thu, 24 Jan 2019 18:28:24 -0500 Received: by mail-qt1-f201.google.com with SMTP id w15so8642160qtk.19 for ; Thu, 24 Jan 2019 15:28:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=0rkfpEA/d3iZMk/qx88pe5jvJaVmohCl4yWkGMLx7kE=; b=tK9R/vSj8YxKuzvaK8praKtVcY67uuEOHkDjPDM0fP7nuv4drY6JZngQhE8iasiBeC zIpaoZTC9esmzzBvpNiCMPcZ4Rf2A/7q405XWpJfJRszbCECoS/agsNDvoyf3x4fOPAz 3kKDxyy4pQq12bZgMIKS0SP52BCAZRsfp2t2WtPJnrezBHY9H1R3LvY68zCGxqnG8bmB LAAYbcVGXXczraUpPAGsS1iyDTCIxWBNVy6GJrIMsWaaXKgUIE0tm0zx8YfCX3qP5LZ4 im4/kTUlkgZ+km1y9+815XnaU1Yqbvh2p5ZSNwX4FSzL03crvZQw47oXxw3h8EpyhvtR z5Ww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=0rkfpEA/d3iZMk/qx88pe5jvJaVmohCl4yWkGMLx7kE=; b=gm3/bFVfZC9A4S9F0ChUfW0xK1/qMq+lUoz0gvfccVe8TMKUtbk7M3dIxT8Gshqr5Z ivdZX9BbLi3ajKK8YeAMeJxVl4UsFUGekVPBbXuDeYQR/Gi4pq4ZDUawQTVXK9vDv6A0 HY4llDoX2/x7MW5PB7sXIxp1T/faQ/B/n5AE55ekq8SKS0CS10z7dtllq64YTCD7Uhyb kqzIcIuwGTAMxX+XeDPRmgtM/zid4lMH0cfEgpUADvI2i8vNLymFU8jn/lSzVYAMxla4 2I/+PTMXng4yLk+D66cvGaMT2lKsrmhtI6zaQHh5il3O7+9T/0wLnvan82Qr0R/bV8UT 3QLg== X-Gm-Message-State: AJcUukfyLRwkqQgbnCle8lWX2e4+KcuoVMzylQgzHQLW0KtMbaijC1Qo dyIEokky+w0YD6RDz406sB68lGMfjVvt X-Google-Smtp-Source: ALg8bN7qAomA+F0Kw6k2N4w6M/em8ydj1Qn0nznCSbB6/13jILrms8yrDuJDf/TECVFoynJsNw+nRjoUe1bG X-Received: by 2002:a0c:9ad6:: with SMTP id k22mr5833836qvf.7.1548372503254; Thu, 24 Jan 2019 15:28:23 -0800 (PST) Date: Thu, 24 Jan 2019 15:28:12 -0800 In-Reply-To: <20190124232814.252661-1-rajatja@google.com> Message-Id: <20190124232814.252661-2-rajatja@google.com> Mime-Version: 1.0 References: <20181117010748.24347-1-rajatja@google.com> <20190124232814.252661-1-rajatja@google.com> X-Mailer: git-send-email 2.20.1.321.g9e740568ce-goog Subject: [PATCH v6 2/4] usb: assign ACPI companions for embedded USB devices From: Rajat Jain To: Marcel Holtmann , Johan Hedberg , Greg Kroah-Hartman , "David S. Miller" , Dmitry Torokhov , Rajat Jain , Alex Hung , linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, netdev@vger.kernel.org Cc: rajatxjain@gmail.com, dtor@google.com, raghuram.hegde@intel.com, chethan.tumkur.narayan@intel.com, sukumar.ghorai@intel.com Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Dmitry Torokhov USB devices permanently connected to USB ports may be described in ACPI tables and share ACPI devices with ports they are connected to. See [1] for details. This will allow us to describe sideband resources for devices, such as, for example, hard reset line for BT USB controllers. [1] https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/other-acpi-namespace-objects#acpi-namespace-hierarchy-and-adr-for-embedded-usb-devices Signed-off-by: Dmitry Torokhov Signed-off-by: Rajat Jain (changed how we get the usb_port) Acked-by: Greg Kroah-Hartman Tested-by: Sukumar Ghorai --- v6: same as v4 v5: same as v4 v4: Add Acked-by and Tested-by in signatures. v3: same as v1 v2: same as v1 drivers/usb/core/usb-acpi.c | 44 +++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c index 8ff73c83e8e8..9043d7242d67 100644 --- a/drivers/usb/core/usb-acpi.c +++ b/drivers/usb/core/usb-acpi.c @@ -200,30 +200,56 @@ static struct acpi_device * usb_acpi_find_companion_for_device(struct usb_device *udev) { struct acpi_device *adev; + struct usb_port *port_dev; + struct usb_hub *hub; + + if (!udev->parent) { + /* root hub is only child (_ADR=0) under its parent, the HC */ + adev = ACPI_COMPANION(udev->dev.parent); + return acpi_find_child_device(adev, 0, false); + } - if (!udev->parent) + hub = usb_hub_to_struct_hub(udev->parent); + if (!hub) return NULL; - /* root hub is only child (_ADR=0) under its parent, the HC */ - adev = ACPI_COMPANION(udev->dev.parent); - return acpi_find_child_device(adev, 0, false); + /* + * This is an embedded USB device connected to a port and such + * devices share port's ACPI companion. + */ + port_dev = hub->ports[udev->portnum - 1]; + return usb_acpi_get_companion_for_port(port_dev); } - static struct acpi_device *usb_acpi_find_companion(struct device *dev) { /* - * In the ACPI DSDT table, only usb root hub and usb ports are - * acpi device nodes. The hierarchy like following. + * The USB hierarchy like following: + * * Device (EHC1) * Device (HUBN) * Device (PR01) * Device (PR11) * Device (PR12) + * Device (FN12) + * Device (FN13) * Device (PR13) * ... - * So all binding process is divided into two parts. binding - * root hub and usb ports. + * where HUBN is root hub, and PRNN are USB ports and devices + * connected to them, and FNNN are individualk functions for + * connected composite USB devices. PRNN and FNNN may contain + * _CRS and other methods describing sideband resources for + * the connected device. + * + * On the kernel side both root hub and embedded USB devices are + * represented as instances of usb_device structure, and ports + * are represented as usb_port structures, so the whole process + * is split into 2 parts: finding companions for devices and + * finding companions for ports. + * + * Note that we do not handle individual functions of composite + * devices yet, for that we would need to assign companions to + * devices corresponding to USB interfaces. */ if (is_usb_device(dev)) return usb_acpi_find_companion_for_device(to_usb_device(dev)); From patchwork Thu Jan 24 23:28:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajat Jain X-Patchwork-Id: 1030721 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="shmD9xAr"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43lyym6NYdz9s7h for ; Fri, 25 Jan 2019 10:28:48 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728505AbfAXX2n (ORCPT ); Thu, 24 Jan 2019 18:28:43 -0500 Received: from mail-io1-f73.google.com ([209.85.166.73]:57102 "EHLO mail-io1-f73.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728365AbfAXX21 (ORCPT ); Thu, 24 Jan 2019 18:28:27 -0500 Received: by mail-io1-f73.google.com with SMTP id x2so5989901ioa.23 for ; Thu, 24 Jan 2019 15:28:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=dEGzE6ZUNinj7i2O6gc8hdUlWcvJ+gY38NNifJVHTbc=; b=shmD9xArlr1UCRljf6+W6ekzQnCm+lB7FPZ0c4aeyUDCITlowJhhtTz6eCuBoU58BW /LhQ1Yx9V3rSxr5pXrSn4KWRMrPhc8IO79HCmP/hCJT+Ao6X7wrWiB01S18Ni8dWOKPO +oIqSGruvfSXvFCNTu1nEh3nzVzSgarN2U0lzo2tktLxvAQ+h/T6i9KUcoXXzV68/vgx uhT2aPvFiV16Zh6lCEvKmmtozPbIHnizRqOxMGhgY9kmmH/Fv+uFcYFbWI68NvbB0c/2 a1e9RfY2Y1bkGho3o+38osjpE/N+zsL9y1t1tEODqKSeyeJWxnYPOLPu0O6H7RUTbANF YbMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=dEGzE6ZUNinj7i2O6gc8hdUlWcvJ+gY38NNifJVHTbc=; b=tmwgx/qxfmMvU/5CKEaLRfqAyDuO/n2j3WEu/OWLC5Tm82tOUzBlErBWThVV7MMate Y+MWEoz3TV+rT7Yzs3Mw4ghV+ZGnS7wKUsHd2JJXsgJAewaZlgMdRhPm3Y730HtLiuIo zpXHyAOQEhNCo0yRYO2yFolsCkzL6icrhWW5FIexwVUY34Zh9SA4Gs8wcSXF+WM0NGsa WUCgmSahiOmP78qtWXl93MGqzuOGDEGReRaULQDvp6SB1cj4eW2Y0no5l67Hy8Y01sq1 xgo8oNDaU5Ox1L9iaX4ne96BMXEDrHwQYnptUg/h66aGYgKWGvXDiJxApX74v9zEcPYq hh0A== X-Gm-Message-State: AJcUukfnYlWMGMywv//2dUODvPhcXicShDhoSkm0iYogLOfNr5G6f9bK AEYd6Qe74Pkdb7Zv+Aej8jD0nWuHLE1Y X-Google-Smtp-Source: ALg8bN4Vg+vr7QJTQjTPcJOIJiQD7mXoxMohOlAKGdTRRmlINUqo0xIi5q58L/XCJgEWuuQfv9SgCFdBTQvc X-Received: by 2002:a24:2951:: with SMTP id p78mr3654125itp.28.1548372506346; Thu, 24 Jan 2019 15:28:26 -0800 (PST) Date: Thu, 24 Jan 2019 15:28:13 -0800 In-Reply-To: <20190124232814.252661-1-rajatja@google.com> Message-Id: <20190124232814.252661-3-rajatja@google.com> Mime-Version: 1.0 References: <20181117010748.24347-1-rajatja@google.com> <20190124232814.252661-1-rajatja@google.com> X-Mailer: git-send-email 2.20.1.321.g9e740568ce-goog Subject: [PATCH v6 3/4] Bluetooth: Allow driver specific cmd timeout handling From: Rajat Jain To: Marcel Holtmann , Johan Hedberg , Greg Kroah-Hartman , "David S. Miller" , Dmitry Torokhov , Rajat Jain , Alex Hung , linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, netdev@vger.kernel.org Cc: rajatxjain@gmail.com, dtor@google.com, raghuram.hegde@intel.com, chethan.tumkur.narayan@intel.com, sukumar.ghorai@intel.com Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add a hook to allow the BT driver to do device or command specific handling in case of timeouts. This is to be used by Intel driver to reset the device after certain number of timeouts. Signed-off-by: Rajat Jain --- v6: Dropped the "sent command" parameter from cmd_timeout() v5: Drop the quirk, and rename the hook function to cmd_timeout() v4: same as v1 v3: same as v1 v2: same as v1 include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_core.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index e5ea633ea368..094e61e07030 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -437,6 +437,7 @@ struct hci_dev { int (*post_init)(struct hci_dev *hdev); int (*set_diag)(struct hci_dev *hdev, bool enable); int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr); + void (*cmd_timeout)(struct hci_dev *hdev); }; #define HCI_PHY_HANDLE(handle) (handle & 0xff) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 7352fe85674b..75793265ba9e 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2578,6 +2578,9 @@ static void hci_cmd_timeout(struct work_struct *work) bt_dev_err(hdev, "command tx timeout"); } + if (hdev->cmd_timeout) + hdev->cmd_timeout(hdev); + atomic_set(&hdev->cmd_cnt, 1); queue_work(hdev->workqueue, &hdev->cmd_work); } From patchwork Thu Jan 24 23:28:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajat Jain X-Patchwork-Id: 1030720 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="cLMIDUAe"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43lyyX6pnRz9s7h for ; Fri, 25 Jan 2019 10:28:36 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728477AbfAXX2c (ORCPT ); Thu, 24 Jan 2019 18:28:32 -0500 Received: from mail-oi1-f202.google.com ([209.85.167.202]:43940 "EHLO mail-oi1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728454AbfAXX2b (ORCPT ); Thu, 24 Jan 2019 18:28:31 -0500 Received: by mail-oi1-f202.google.com with SMTP id p131so3595860oig.10 for ; Thu, 24 Jan 2019 15:28:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=AyptAvfvM/wcW1EoZU8xDvJM9SOpx5lXxyZ/dg3vpOA=; b=cLMIDUAeUxUTQwen6ta2KO0L/aNMWhOUpqV7A2dhQbyNN/FXERU+DtaH0fgAA7Z4qr 0zRuEQ8ZxgoEynTK+H0Dxa+tFt72i/BHUSxK+v4NXiyxMADPATUZNY5FIOZ1BKEoEaQL svKhFsx80KRknGu5UaqDkEiyjzKTjtNMkKusH7kUnTUvBkSel+FXl6p8B6H2ChZ7athf lpEjUfO40sMX7/YYBCIOZOMs0Fa4j1Kinnr/cdvE8XGV5jbEgVO2j70ViSESv2qlTkgL jkgZgbWlOGVqsQRubOrsDZmG3aIISY4ULCxaptq4ehEesvP3BBuf3hU79NNUI/OacB5O OetA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=AyptAvfvM/wcW1EoZU8xDvJM9SOpx5lXxyZ/dg3vpOA=; b=a76nQssOAc8aXPOhi4t7ulGsrtAw0NxNMd9YGoT4pwXhLuyix/32V1cyMwzGveceVQ jETfbUkwxduyEpCh6ZZCqJFgX+sbThBiU0A+N7AAv6aIMWAq5ZO2oMhMFqGeLzEzY+3l n3OIx+JBmS1xavvHs3HJRARe3H02cMyS4ieBh2dIJ5ZW8TG32GyqSakxz4FhfNaaC98P Xgb7rJo0so8NnWjAVCpQ4MmbejEojMtfxowQ4xL7LfbU5zDYq69BO6xf3bI0EpCT49Yr VRJJF5v5pjQG5C4yvJ3UUMe9bwCiEMwOU41Awhn1djlQxFL1htDbPcgeYTz3nEYuR3vb yCJQ== X-Gm-Message-State: AJcUukdvbngSVI3VbRWx43NRZArCr8xHY7kaO98unmX70f39JSbkc8/i FTdEZkX5W0coZUp+6AaxOjdaZ9nlBnUH X-Google-Smtp-Source: ALg8bN4+/rvFAxXRPJdKuvtD6VUqqn8fJ80Cs1wKwE6x5hBQph3eFbxKCcmF5BttejzUtvidEsyyfgKx5DIJ X-Received: by 2002:a9d:7f15:: with SMTP id j21mr6121444otq.71.1548372509988; Thu, 24 Jan 2019 15:28:29 -0800 (PST) Date: Thu, 24 Jan 2019 15:28:14 -0800 In-Reply-To: <20190124232814.252661-1-rajatja@google.com> Message-Id: <20190124232814.252661-4-rajatja@google.com> Mime-Version: 1.0 References: <20181117010748.24347-1-rajatja@google.com> <20190124232814.252661-1-rajatja@google.com> X-Mailer: git-send-email 2.20.1.321.g9e740568ce-goog Subject: [PATCH v6 4/4] Bluetooth: btusb: Use the cmd_timeout method to reset the Intel BT chip From: Rajat Jain To: Marcel Holtmann , Johan Hedberg , Greg Kroah-Hartman , "David S. Miller" , Dmitry Torokhov , Rajat Jain , Alex Hung , linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, netdev@vger.kernel.org Cc: rajatxjain@gmail.com, dtor@google.com, raghuram.hegde@intel.com, chethan.tumkur.narayan@intel.com, sukumar.ghorai@intel.com Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org If the platform provides it, use the reset gpio to reset the Intel BT chip, as part of cmd_timeout handling. This has been found helpful on Intel bluetooth controllers where the firmware gets stuck and the only way out is a hard reset pin provided by the platform. Signed-off-by: Rajat Jain --- v6: Move the cmd_timeout() hook assignment with other hooks, move the reset_gpio check in the timeout function. v5: Rename the hook to cmd_timeout, and wait for 5 timeouts before resetting the device. v4: Use data->flags instead of clearing the quirk in btusb_hw_reset() v3: Better error handling for gpiod_get_optional() v2: Handle the EPROBE_DEFER case. drivers/bluetooth/btusb.c | 54 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 4761499db9ee..5de0c2e59b97 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -439,6 +440,7 @@ static const struct dmi_system_id btusb_needs_reset_resume_table[] = { #define BTUSB_BOOTING 9 #define BTUSB_DIAG_RUNNING 10 #define BTUSB_OOB_WAKE_ENABLED 11 +#define BTUSB_HW_RESET_ACTIVE 12 struct btusb_data { struct hci_dev *hdev; @@ -476,6 +478,8 @@ struct btusb_data { struct usb_endpoint_descriptor *diag_tx_ep; struct usb_endpoint_descriptor *diag_rx_ep; + struct gpio_desc *reset_gpio; + __u8 cmdreq_type; __u8 cmdreq; @@ -489,8 +493,41 @@ struct btusb_data { int (*setup_on_usb)(struct hci_dev *hdev); int oob_wake_irq; /* irq for out-of-band wake-on-bt */ + unsigned cmd_timeout_cnt; }; + +static void btusb_intel_cmd_timeout(struct hci_dev *hdev) +{ + struct btusb_data *data = hci_get_drvdata(hdev); + struct gpio_desc *reset_gpio = data->reset_gpio; + + if (++data->cmd_timeout_cnt < 5) + return; + + if (!reset_gpio) { + bt_dev_err(hdev, "No way to reset. Ignoring and continuing"); + return; + } + + /* + * Toggle the hard reset line if the platform provides one. The reset + * is going to yank the device off the USB and then replug. So doing + * once is enough. The cleanup is handled correctly on the way out + * (standard USB disconnect), and the new device is detected cleanly + * and bound to the driver again like it should be. + */ + if (test_and_set_bit(BTUSB_HW_RESET_ACTIVE, &data->flags)) { + bt_dev_err(hdev, "last reset failed? Not resetting again"); + return; + } + + bt_dev_err(hdev, "Initiating HW reset via gpio"); + gpiod_set_value(reset_gpio, 1); + mdelay(100); + gpiod_set_value(reset_gpio, 0); +} + static inline void btusb_free_frags(struct btusb_data *data) { unsigned long flags; @@ -2915,6 +2952,7 @@ static int btusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_endpoint_descriptor *ep_desc; + struct gpio_desc *reset_gpio; struct btusb_data *data; struct hci_dev *hdev; unsigned ifnum_base; @@ -3028,6 +3066,15 @@ static int btusb_probe(struct usb_interface *intf, SET_HCIDEV_DEV(hdev, &intf->dev); + reset_gpio = gpiod_get_optional(&data->udev->dev, "reset", + GPIOD_OUT_LOW); + if (IS_ERR(reset_gpio)) { + err = PTR_ERR(reset_gpio); + goto out_free_dev; + } else if (reset_gpio) { + data->reset_gpio = reset_gpio; + } + hdev->open = btusb_open; hdev->close = btusb_close; hdev->flush = btusb_flush; @@ -3082,6 +3129,7 @@ static int btusb_probe(struct usb_interface *intf, hdev->shutdown = btusb_shutdown_intel; hdev->set_diag = btintel_set_diag_mfg; hdev->set_bdaddr = btintel_set_bdaddr; + hdev->cmd_timeout = btusb_intel_cmd_timeout; set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks); @@ -3094,6 +3142,7 @@ static int btusb_probe(struct usb_interface *intf, hdev->hw_error = btintel_hw_error; hdev->set_diag = btintel_set_diag; hdev->set_bdaddr = btintel_set_bdaddr; + hdev->cmd_timeout = btusb_intel_cmd_timeout; set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks); @@ -3226,6 +3275,8 @@ static int btusb_probe(struct usb_interface *intf, return 0; out_free_dev: + if (data->reset_gpio) + gpiod_put(data->reset_gpio); hci_free_dev(hdev); return err; } @@ -3269,6 +3320,9 @@ static void btusb_disconnect(struct usb_interface *intf) if (data->oob_wake_irq) device_init_wakeup(&data->udev->dev, false); + if (data->reset_gpio) + gpiod_put(data->reset_gpio); + hci_free_dev(hdev); }