From patchwork Wed Jan 23 20:57:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajat Jain X-Patchwork-Id: 1030165 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="tlzkQDI8"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43lHfl4CVMz9sCX for ; Thu, 24 Jan 2019 07:57:35 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726772AbfAWU5e (ORCPT ); Wed, 23 Jan 2019 15:57:34 -0500 Received: from mail-vs1-f73.google.com ([209.85.217.73]:48617 "EHLO mail-vs1-f73.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726343AbfAWU5d (ORCPT ); Wed, 23 Jan 2019 15:57:33 -0500 Received: by mail-vs1-f73.google.com with SMTP id w22so1285474vsj.15 for ; Wed, 23 Jan 2019 12:57:31 -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=66N0nnVy7ZeFP1SFsZPBRguoq/ldZpv35aMOmW31chg=; b=tlzkQDI8+8AB5azQXeDGuNm6veoYP9zWn2BhPDZnxYjaWrlBFQppyVEWx1QkYS85k6 IygNYRfuhGdYy5aap5OlpxJz1UmT23SidjQlRDlcbBItKcr7ZkJv0KvCT++pz2uWMVIo 5o167QWlZ/oU16oOVSmeZei+aCu9U5eG7kvCm6YZ+N8Oq6Xp5kdi/lJIVp9DKeRxpt9A L7o51ufTgWdq0H5XX7ss6pAR3uK+T6pV+Xj9mKPYNjDWln5LMwSO5p1lUe0yw+ylv0kt 7seMiDbNukqzGDuEcMVnj+fp62QF4b+VOUhFNyuUNBSY6/AhB2Jv3zTXBEb4SaljkwMY TSwg== 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=66N0nnVy7ZeFP1SFsZPBRguoq/ldZpv35aMOmW31chg=; b=s+L/Yyo9DrdF33SuYqme7/NGuuRWKkzj5wiWtEj5W60w0grlqzkkatnZdPZRkfH6OF 3QgrU8XBwv+1SGNl3daF+lej5w/ljf7deAs3XT+FaT3rsWVRq98d+2SW4+TFwbv8IeEH K5JtFeJUIF7K4LoPJLHsX4pj/rqDKltlBhRimaoO0xtvHSNz7g0KsFWYB3oBvSyp+2Il iTy3ygbG0jY2KPoW3H1PcBvcrZu+ua+Mu+HZXbtSc8d3CJpujEBF2YewnX3KiAVgLX8u rAPiB1Xw4yamhD0OYrU6lpuihe49D4dzdscuyMeH1BhazuNALDroh4MyIjTbtsUynBQJ OVpg== X-Gm-Message-State: AJcUukcrmZ5wccociTNXhDcCvduNDmcGJmE6p6+cgzA+giIkZf8IsJu4 qLR+IA/0AjZf3kcmDqprtzSzRYopLjM/ X-Google-Smtp-Source: ALg8bN5xc2h05A/VYfCqaHxF8KwkVT3SaJ7TWLCck9Rjba8cSJhAzC4zTTtPfx0XsOwng+tJDM+puWr9vRhT X-Received: by 2002:a1f:91d4:: with SMTP id t203mr2948783vkd.2.1548277051177; Wed, 23 Jan 2019 12:57:31 -0800 (PST) Date: Wed, 23 Jan 2019 12:57:22 -0800 In-Reply-To: <20181117010748.24347-1-rajatja@google.com> Message-Id: <20190123205725.239661-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 v5 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 --- 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 Wed Jan 23 20:57:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajat Jain X-Patchwork-Id: 1030166 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="VTpMHj4R"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43lHfq1GMKz9sCX for ; Thu, 24 Jan 2019 07:57:39 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726853AbfAWU5i (ORCPT ); Wed, 23 Jan 2019 15:57:38 -0500 Received: from mail-pl1-f201.google.com ([209.85.214.201]:37769 "EHLO mail-pl1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726785AbfAWU5f (ORCPT ); Wed, 23 Jan 2019 15:57:35 -0500 Received: by mail-pl1-f201.google.com with SMTP id v11so2360521ply.4 for ; Wed, 23 Jan 2019 12:57:35 -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=Ek5tAZVik4G9S7yKc/57HwUfLe97vNLtRwX9GtGPda0=; b=VTpMHj4RkCyPjddfwWYChBEF6JtKg4Q1eRQkTwA27oOOlHIvp+SAeTjMjde6gpC7I2 ZNxlywaGpPSFn8NYZb1a0CAo3YqnkjNfYVa5m2ZwTgP5BdmvpmIv5/q1a2uDXvmzJGDc 1LzueglMwUK2Ei9iMx72XtQK6vBb4ssvinjqgWh+Dhe9if/OSOMGA6igayEMFHBU7XmY 2Tcxo6skC0lS/1KhpnuG/zy/x51+wt0K9AMgKj0b32kkRufy5MuWGqn0qizkt8kaUuL8 KGWzXjdSzqr7GrwOBHIO5oSX/BZdEbOBs9DnKfYJnIRcxsu5SxisWt1hEqk17R3P3wBy kHhw== 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=Ek5tAZVik4G9S7yKc/57HwUfLe97vNLtRwX9GtGPda0=; b=lRlCSttdbzwExLC3Dq+XArqFfP3JYAlhQljaRCDxu6vJ6+MpW5dR5j5ZfjyWgHNThT 4BeY0rjqIuD5LLWI9MiNbF5Of3as5aEXdaek0Cl2HDmKdyq9/ij/RdedD/kLfnLzJlnD TeEMUprSe3MNC/DJnq8lu/0OvN/UfxRMu/SJ2onqCFKILcLMzKKBGJa5oxThzAdtMtaL x1t3b11g69VmU8wCquDwXJhJtzdueWrjvthCJ64jioo5jiL71WCcCPYCmrMLwWguq7Q9 2zzTmG/BbTuX+VcGoj9gs1n73+J+7263R7e+VSzyIuev9kLAJAMOg/tIauikrfesxok9 UQjQ== X-Gm-Message-State: AJcUukdl62Se2rGgSrm0+6hH9UZarjdNN8y/YNQRRGM/yiE6/DHh+x37 DSmUrZ8c6/IMTNqLLqeYSIWxZX+Ra5XN X-Google-Smtp-Source: ALg8bN5heWrQHKZ5AW/1jiRDx0O+rkQFFKfIx2BOCX8lXbDR+ILchcN0iFY5FLMuLrU8ZI/tw8mUxfakaB+N X-Received: by 2002:a17:902:5e3:: with SMTP id f90mr1271204plf.51.1548277054611; Wed, 23 Jan 2019 12:57:34 -0800 (PST) Date: Wed, 23 Jan 2019 12:57:23 -0800 In-Reply-To: <20190123205725.239661-1-rajatja@google.com> Message-Id: <20190123205725.239661-2-rajatja@google.com> Mime-Version: 1.0 References: <20181117010748.24347-1-rajatja@google.com> <20190123205725.239661-1-rajatja@google.com> X-Mailer: git-send-email 2.20.1.321.g9e740568ce-goog Subject: [PATCH v5 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 --- 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 Wed Jan 23 20:57:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajat Jain X-Patchwork-Id: 1030167 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="UGrv71G9"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43lHg072G6z9s55 for ; Thu, 24 Jan 2019 07:57:48 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726946AbfAWU5m (ORCPT ); Wed, 23 Jan 2019 15:57:42 -0500 Received: from mail-pl1-f202.google.com ([209.85.214.202]:52192 "EHLO mail-pl1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726867AbfAWU5i (ORCPT ); Wed, 23 Jan 2019 15:57:38 -0500 Received: by mail-pl1-f202.google.com with SMTP id 12so2325946plb.18 for ; Wed, 23 Jan 2019 12:57:38 -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=b1uUbZsyhmSj82CJe/fFgzrboSy+IQsjI8LagdR/gaM=; b=UGrv71G90YQNeN5Vvdea+LRmvJ2MZnJhJOpfkZTfdIcOtavVJazMi0+Gw37w+Un9on M0vSFHl6xhJNXXr3vnSwaK5OLjVSgv1ZK2nDZI0BAx1iSOUkRdCfIw+3KFlsjbwP1E/I sozdRo4HJal7EgSWnckzLV66uoAn77pqWacV187BtF+XwrsqB425EGQLkQxCOqtX6MBd 3pTOmueac2f/7tHoeBKrk/ul7gAFKyxjPnJZVoutBanZdqfSUGXlZU0sZEzBntoutC0V 7VrKJNyf/tyN46FjHD9V/WMcuaB27K/24MTB7pkWSGu3TdwnqHVVv5CBr+EktXlbcdo5 FIiw== 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=b1uUbZsyhmSj82CJe/fFgzrboSy+IQsjI8LagdR/gaM=; b=dqsGhsliHDlvIzfYAO1pRpedkzEN5XtSFQ3FQDXnFGBtgjXmxlzVD9rhQ2FunYkzQc 2Bvkl59b0u2ckjCU5XnRV/cR4G4BGIiIqF6ILwGj9ADIsrYyBtsfqdHPH9ylD+MgrvfF IEcjsdFpuVQDA3BLOCg2UI+aPYzYVfsECJoST8ywas2sh/naQE+gvAOdTAT8Vb2MIWji Zi0lOny1XgrNY+PeU0yDqrjrLL9P/VHXy5efeTRNqvwn4BFdgs+XRyyoQ67vmAllYW23 BaMg5XNgwzIkKg2DgiLJr8+UpcD3KUnTde96I319fpl4SvSDKk4dcdy403u65R9lA832 21SA== X-Gm-Message-State: AJcUukdr6ATK7KwnPCcP0nMQ8byuPRHUB9Q++1gmgaP5Hf2qzsYKiHr+ 3yuKdEkUlQHPGFNE37yeOanp0BoXS3uU X-Google-Smtp-Source: ALg8bN4fb62tI1JN8/1GdsgJIFzKkowPGf7t+rbHtvK6Su1eMYtqXFjaphAT7mQ+h4NP+ysf0TcZAq4/KFU7 X-Received: by 2002:a62:1195:: with SMTP id 21mr1544185pfr.61.1548277057637; Wed, 23 Jan 2019 12:57:37 -0800 (PST) Date: Wed, 23 Jan 2019 12:57:24 -0800 In-Reply-To: <20190123205725.239661-1-rajatja@google.com> Message-Id: <20190123205725.239661-3-rajatja@google.com> Mime-Version: 1.0 References: <20181117010748.24347-1-rajatja@google.com> <20190123205725.239661-1-rajatja@google.com> X-Mailer: git-send-email 2.20.1.321.g9e740568ce-goog Subject: [PATCH v5 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 --- 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 | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index e5ea633ea368..624d5f2b1f36 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, struct hci_command_hdr *cmd); }; #define HCI_PHY_HANDLE(handle) (handle & 0xff) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 7352fe85674b..c6917f57581a 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2568,16 +2568,22 @@ static void hci_cmd_timeout(struct work_struct *work) { struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_timer.work); + struct hci_command_hdr *sent = NULL; if (hdev->sent_cmd) { - struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; - u16 opcode = __le16_to_cpu(sent->opcode); + u16 opcode; + + sent = (void *) hdev->sent_cmd->data; + opcode = __le16_to_cpu(sent->opcode); bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode); } else { bt_dev_err(hdev, "command tx timeout"); } + if (hdev->cmd_timeout) + hdev->cmd_timeout(hdev, sent); + atomic_set(&hdev->cmd_cnt, 1); queue_work(hdev->workqueue, &hdev->cmd_work); } From patchwork Wed Jan 23 20:57:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajat Jain X-Patchwork-Id: 1030168 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="KPqiIjRi"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43lHg16q7Zz9sD4 for ; Thu, 24 Jan 2019 07:57:49 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726976AbfAWU5t (ORCPT ); Wed, 23 Jan 2019 15:57:49 -0500 Received: from mail-vs1-f73.google.com ([209.85.217.73]:57322 "EHLO mail-vs1-f73.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726910AbfAWU5m (ORCPT ); Wed, 23 Jan 2019 15:57:42 -0500 Received: by mail-vs1-f73.google.com with SMTP id e81so1245436vsd.23 for ; Wed, 23 Jan 2019 12:57:41 -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=NfnIiqmrqgT5KkxLxxzewrtxoVbG/bYu9guRRR7bbjU=; b=KPqiIjRi2oveYkiaVkE64/05N0OfazIQ7G3qWcDpZyGc7qHQNDpUOzJdgxevZaOG6c wZaB0wdsfLo3/Xy4qtBeilfG+pDYBhoUWdjqy32DL/2mh8f05FDv9eYxEg420IUXzM+F fh3Yzclze2YCvGliykQW9j/dvAf/ZAiK2jQ5gDKgS5ph8ZJsnBJjEZRxPpa4MYjYTnsK 1/auDG+3oydmqLRYLEBXZi9cgjRq5thcQhqBS0jcA3s/7O3zG/4im1ydLvA5ugLcYecx EqIy6uKzY7MHNkxNTNKfsxYxzzcpmYn4zRB5ufMdX2xuKE4NSWZrkrzNST+Z4j6TFR9R 8j5g== 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=NfnIiqmrqgT5KkxLxxzewrtxoVbG/bYu9guRRR7bbjU=; b=euIn1dlF1ytYRGAWsTeKKQ4gK7oIGB4uqDLYNuX1457DKerAY5r0CqIT+f7BCfNRgJ jNwfWFr1RI+fnQ52ZTiGVGa6t4Dt/h1Q6ECjiAim6NPhL6czvGVgLhtNN3WhEA0sNwNq Cj0HmPS7M6G22vHuIO1qzSrgRmxIUXzj/G4O4uIIHF0iA9PLsODdKolZRcoB3TA1dnrH CJLzDECbZWRvE5u+J5n7WydeVGwHSpCrcWv4QPLyZSrHl9Lwf0VvjR1TMkYEtyLovuNU Z9/uHJhoGDn9CAJqD2us1cbXNdSmNJuJXaow/8mojGutSfdBCw7kygySlXFEk2k1w0Q3 UPTg== X-Gm-Message-State: AJcUukc3BsWqbkbfP+V/IgNg8UVayXq7xdzuzBwF1I2lcja1Dh/O/kFf JVGG/Lncy6NFVCzYEVl3u5V0EM4VX3H/ X-Google-Smtp-Source: ALg8bN5IexxK6W7en1oWzrXdWLGC7CJ6WXC2viDjFkUWF63bba/OpTd1sz3zh4ygKP3CaArBgwcOP99dN9f8 X-Received: by 2002:a67:e218:: with SMTP id g24mr3057516vsa.2.1548277061160; Wed, 23 Jan 2019 12:57:41 -0800 (PST) Date: Wed, 23 Jan 2019 12:57:25 -0800 In-Reply-To: <20190123205725.239661-1-rajatja@google.com> Message-Id: <20190123205725.239661-4-rajatja@google.com> Mime-Version: 1.0 References: <20181117010748.24347-1-rajatja@google.com> <20190123205725.239661-1-rajatja@google.com> X-Mailer: git-send-email 2.20.1.321.g9e740568ce-goog Subject: [PATCH v5 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 --- 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..8949ea30a1bc 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,39 @@ struct btusb_data { int (*setup_on_usb)(struct hci_dev *hdev); int oob_wake_irq; /* irq for out-of-band wake-on-bt */ + unsigned num_cmd_timeout; }; + +static void btusb_intel_cmd_timeout(struct hci_dev *hdev, + struct hci_command_hdr *cmd) +{ + struct btusb_data *data = hci_get_drvdata(hdev); + struct gpio_desc *reset_gpio = data->reset_gpio; + + bt_dev_err(hdev, "btusb num_cmd_timeout = %u", ++data->num_cmd_timeout); + + if (data->num_cmd_timeout < 5) + 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 +2950,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 +3064,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; @@ -3085,6 +3130,8 @@ static int btusb_probe(struct usb_interface *intf, 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); + if (data->reset_gpio) + hdev->cmd_timeout = btusb_intel_cmd_timeout; } if (id->driver_info & BTUSB_INTEL_NEW) { @@ -3097,6 +3144,8 @@ static int btusb_probe(struct usb_interface *intf, 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); + if (data->reset_gpio) + hdev->cmd_timeout = btusb_intel_cmd_timeout; } if (id->driver_info & BTUSB_MARVELL) @@ -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); }