Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2220761/?format=api
{ "id": 2220761, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2220761/?format=api", "web_url": "http://patchwork.ozlabs.org/project/ubuntu-kernel/patch/20260408002809.232479-2-acelan.kao@canonical.com/", "project": { "id": 15, "url": "http://patchwork.ozlabs.org/api/1.1/projects/15/?format=api", "name": "Ubuntu Kernel", "link_name": "ubuntu-kernel", "list_id": "kernel-team.lists.ubuntu.com", "list_email": "kernel-team@lists.ubuntu.com", "web_url": null, "scm_url": null, "webscm_url": null }, "msgid": "<20260408002809.232479-2-acelan.kao@canonical.com>", "date": "2026-04-08T00:28:09", "name": "[SRU,R,1/1] UBUNTU: SAUCE: USB: hub: call ACPI _PRR reset during port power-cycle on enumeration failure", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "3e1878675a9fbafaf2e001b10a4d36e2a61d8893", "submitter": { "id": 2976, "url": "http://patchwork.ozlabs.org/api/1.1/people/2976/?format=api", "name": "AceLan Kao", "email": "acelan.kao@canonical.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/ubuntu-kernel/patch/20260408002809.232479-2-acelan.kao@canonical.com/mbox/", "series": [ { "id": 499052, "url": "http://patchwork.ozlabs.org/api/1.1/series/499052/?format=api", "web_url": "http://patchwork.ozlabs.org/project/ubuntu-kernel/list/?series=499052", "date": "2026-04-08T00:28:08", "name": "Bluetooth device (MT7925) not detected on USB bus with linux-oem-6.17", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/499052/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2220761/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2220761/checks/", "tags": {}, "headers": { "Return-Path": "<kernel-team-bounces@lists.ubuntu.com>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=Wf6HbTDs;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com\n (client-ip=185.125.189.65; helo=lists.ubuntu.com;\n envelope-from=kernel-team-bounces@lists.ubuntu.com;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fr3nn5MFCz1yD3\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 08 Apr 2026 10:28:29 +1000 (AEST)", "from localhost ([127.0.0.1] helo=lists.ubuntu.com)\n\tby lists.ubuntu.com with esmtp (Exim 4.86_2)\n\t(envelope-from <kernel-team-bounces@lists.ubuntu.com>)\n\tid 1wAGmL-0005DX-Ho; Wed, 08 Apr 2026 00:28:21 +0000", "from mail-qt1-f182.google.com ([209.85.160.182])\n by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.86_2) (envelope-from <acelan@gmail.com>) id 1wAGmJ-0005Bc-Dz\n for kernel-team@lists.ubuntu.com; Wed, 08 Apr 2026 00:28:19 +0000", "by mail-qt1-f182.google.com with SMTP id\n d75a77b69052e-50b392f1846so80069981cf.3\n for <kernel-team@lists.ubuntu.com>; Tue, 07 Apr 2026 17:28:19 -0700 (PDT)", "from localhost (211-75-139-220.hinet-ip.hinet.net. [211.75.139.220])\n by smtp.gmail.com with ESMTPSA id\n d75a77b69052e-50d4d4a034asm146174741cf.6.2026.04.07.17.28.16\n for <kernel-team@lists.ubuntu.com>\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 07 Apr 2026 17:28:17 -0700 (PDT)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20251104; t=1775608098; x=1776212898; darn=lists.ubuntu.com;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:to:from:sender:from:to:cc:subject:date\n :message-id:reply-to;\n bh=PT2KBmcxbAO9tAsRh+Dr+f70qMBI4lswoPkcdrTVMjs=;\n b=Wf6HbTDsFShlXBLJcTAAgLUnwT5YIO96pQs9RIwQwd8261qEwQAOCrleWf3AhDP+J4\n ck0OhwYRKE5CVKijac3emZOc0cslFcm7JSbkWz37acWgd/Eb4My5oPljE/PZJQY9emRK\n gjQIbc+e7ouAiKLlE6gFsp5oKHFCXYQW0YxEtyqPHU4x8q8kmKIa0npWwptFkHEXCfzb\n JCXVEaHp/6XE4qlzoFoFhy5TuNjmDfabLixiGkZqktU//tcQIdPB6m22+dEoDX8iHgQh\n pzFgx0flzuTRwy57S4K6jUBVP9E32nXNiadQj8BXzuD0wxLyYCkOe8bDVvxG27HGKvOQ\n VKOQ==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1775608098; x=1776212898;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:to:from:sender:x-gm-gg:x-gm-message-state\n :from:to:cc:subject:date:message-id:reply-to;\n bh=PT2KBmcxbAO9tAsRh+Dr+f70qMBI4lswoPkcdrTVMjs=;\n b=b2CXXAdUrgz1m5d+kDCX2UrEg7JbCaLC4i2NBfvXhjT54RqVGzcbbs61HOqyc7MDdl\n wn0aWZ/i1ABhUtYDctXEvRfZGD7Ww53/oYJ+rRnxh71PeOWjmotBUNlg56R3AO+wsxDv\n PCJ4AZH5Pclor5xIHUZQwAPL8GeY1G1jUlrLiCj2nBmFr5WbHtSMIKOC7MqmKLRrYQkP\n AoDJeN5luWJCInZIoF7YP+Y43vSDqubLdMTwE5Rao6DgIU7VCA+8wwMb5XT4WPkKJLLG\n CFaRINAlmqDgJ7kWNEk9XVCDLq98kWOP0Zuv8CLvU/tt+fSn2wcICNOxnWB01Wg4OrP3\n auJg==", "X-Gm-Message-State": "AOJu0YzWHYNN8+rikZsIACIUKUbZYps6oHtelmYlaL9u1ZGOR6h2AQ0k\n dW4zd6J1LuEbHmXGkcqXDU/Ae06g52ytprERfkL8i/1FCg5GlSaQnSdHjWRrwVCW", "X-Gm-Gg": "AeBDies18cZq5HVgGIpPmvuqRaiV+9fPSBI33OooTJzoARNsJ13147KE1YFP8BZKGqq\n 4rOCyG913jNoiSotSEA7aqEVbCyl2ujTdOX6+DtCQAXCcUhx+84H6BZ1+lz/OdcbkNhDrkzxa51\n Cf8MDtsYMA4eBVK/7gYFuSYH/tGewS9i1SOiDueA52jHSTYCeo5TMR2TFmSGMEXiwvFShBGYyJ2\n CEaRUjs4Tsnk00O/O1LaFCAzRXmRJrEcoZyU/dJLXziqZlD3bTSlH5bWvvAj8DBSe52PIs3wbIG\n nx4VpNCsNB5LL0aFIaPL5+A9jjqhn3hF3K4sCWFfKGl+vrFjiAkdAbut54vbySknI1laeO0pdDh\n T6gZwGY2HRG8B+XxDlCBK30APEg6L6ccF9teQGFJSdKz+R8waDNeV3Ijo4JPTd+xUg17xqKhPdL\n dzMNPCCGpDmVzVCTK7/dMk01duk+iOV/eGJ3ZjT+3FM1f8MPDNfmA6", "X-Received": "by 2002:ac8:57cc:0:b0:50b:4167:7889 with SMTP id\n d75a77b69052e-50d629c5299mr288303721cf.30.1775608097467;\n Tue, 07 Apr 2026 17:28:17 -0700 (PDT)", "From": "AceLan Kao <acelan.kao@canonical.com>", "To": "kernel-team@lists.ubuntu.com", "Subject": "[SRU][R][PATCH 1/1] UBUNTU: SAUCE: USB: hub: call ACPI _PRR reset\n during port power-cycle on enumeration failure", "Date": "Wed, 8 Apr 2026 08:28:09 +0800", "Message-ID": "<20260408002809.232479-2-acelan.kao@canonical.com>", "X-Mailer": "git-send-email 2.53.0", "In-Reply-To": "<20260408002809.232479-1-acelan.kao@canonical.com>", "References": "<20260408002809.232479-1-acelan.kao@canonical.com>", "MIME-Version": "1.0", "Received-SPF": "pass client-ip=209.85.160.182; envelope-from=acelan@gmail.com;\n helo=mail-qt1-f182.google.com", "X-BeenThere": "kernel-team@lists.ubuntu.com", "X-Mailman-Version": "2.1.20", "Precedence": "list", "List-Id": "Kernel team discussions <kernel-team.lists.ubuntu.com>", "List-Unsubscribe": "<https://lists.ubuntu.com/mailman/options/kernel-team>,\n <mailto:kernel-team-request@lists.ubuntu.com?subject=unsubscribe>", "List-Archive": "<https://lists.ubuntu.com/archives/kernel-team>", "List-Post": "<mailto:kernel-team@lists.ubuntu.com>", "List-Help": "<mailto:kernel-team-request@lists.ubuntu.com?subject=help>", "List-Subscribe": "<https://lists.ubuntu.com/mailman/listinfo/kernel-team>,\n <mailto:kernel-team-request@lists.ubuntu.com?subject=subscribe>", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "base64", "Errors-To": "kernel-team-bounces@lists.ubuntu.com", "Sender": "\"kernel-team\" <kernel-team-bounces@lists.ubuntu.com>" }, "content": "From: \"Chia-Lin Kao (AceLan)\" <acelan.kao@canonical.com>\n\nBugLink: https://bugs.launchpad.net/bugs/2145164\n\nSome USB-connected devices (e.g. MT7925 Bluetooth on Dell laptops) expose\ntheir hardware reset line via an ACPI Power Resource for Reset (_PRR)\nrather than relying solely on VBUS cycling for recovery. When the reset\nGPIO gets stuck low the device stops responding on USB; a VBUS power-cycle\nalone cannot recover it because the chip remains in reset regardless of\nVBUS state.\n\nAdd usb_acpi_port_prr_reset() in usb-acpi.c that, given a hub device and\none-based port number, looks up the port's ACPI companion handle, evaluates\n_PRR to obtain the power-resource reference, and then calls _RST on that\nreference to toggle the reset line. The function is a no-op if the port\nhas no ACPI handle or no _PRR method, so it is safe to call unconditionally\nfor every port.\n\nWire it into hub_port_connect() during the mid-retry VBUS power-cycle\n(at (PORT_INIT_TRIES-1)/2 iterations), calling usb_acpi_port_prr_reset()\n*after* VBUS goes off and *before* VBUS comes back on. The ordering is\ncritical: on the tested hardware the ACPI _RST method (MBTR._RST) drives\nBT_RST low for 200 ms then high again. If _RST is called after VBUS is\nalready restored the GPIO pulse races with device enumeration starting on\nthe live bus; the device begins asserting USB signals while still held in\nreset and enumeration fails. Performing the reset while the port is\nde-powered ensures the GPIO pulse completes fully before the device is\ngiven power and time to initialise.\n\nAfter VBUS is restored, add an msleep(100) conditional on _PRR._RST having\nsucceeded. USB 2.0 spec §7.1.7.3 (Fig. 7-29) mandates a minimum of 100 ms\nbetween VBUS power-on and the first reset signalling for power settling.\nhub_power_on_good_delay() returns bPwrOn2PwrGood * 2 with no minimum floor;\non the tested xHCI root hub bPwrOn2PwrGood = 10, yielding only 20 ms —\nwell below the spec minimum. When _PRR._RST has been exercised the device\nmust also complete its full power-on sequence (GPIO de-assertion, internal\noscillator start, firmware load) before USB enumeration begins. The\n100 ms sleep enforces the spec minimum and gives the device adequate\nsettling time.\n\nTested on a Dell laptop with MT7925 Bluetooth (idVendor=0489,\nidProduct=e139) whose BT_RST GPIO was stuck low. With this fix the\ndevice recovers autonomously at boot without requiring a G3\n(mechanical power-off) cycle. The relevant dmesg sequence:\n\n [ 1.448491] usb 3-10: new high-speed USB device number 4 using xhci_hcd\n [ 6.813942] usb 3-10: device descriptor read/64, error -110\n [ 22.685978] usb 3-10: device descriptor read/64, error -110\n [ 22.901715] usb 3-10: new high-speed USB device number 5 using xhci_hcd\n [ 28.317963] usb 3-10: device descriptor read/64, error -110\n [ 44.189949] usb 3-10: device descriptor read/64, error -110\n [ 44.294065] usb usb3-port10: attempt power cycle\n [ 44.872709] usb 3-10: new high-speed USB device number 6 using xhci_hcd\n [ 44.888293] usb 3-10: New USB device found, idVendor=0489, idProduct=e139, bcdDevice= 1.00\n [ 44.888318] usb 3-10: Manufacturer: MediaTek Inc.\n\nSigned-off-by: Chia-Lin Kao (AceLan) <acelan.kao@canonical.com>\n(cherry picked from commit https://lore.kernel.org/lkml/20260326011708.1128840-1-acelan.kao@canonical.com/T/#u)\nSigned-off-by: Chia-Lin Kao (AceLan) <acelan.kao@canonical.com>\n---\n drivers/usb/core/hub.c | 14 ++++++++\n drivers/usb/core/usb-acpi.c | 68 +++++++++++++++++++++++++++++++++++++\n drivers/usb/core/usb.h | 3 ++\n 3 files changed, 85 insertions(+)", "diff": "diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c\nindex 24960ba9caa91..1740e96f73cc6 100644\n--- a/drivers/usb/core/hub.c\n+++ b/drivers/usb/core/hub.c\n@@ -5603,11 +5603,25 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,\n \n \t\t/* When halfway through our retry count, power-cycle the port */\n \t\tif (i == (PORT_INIT_TRIES - 1) / 2) {\n+\t\t\tint prr_reset;\n+\n \t\t\tdev_info(&port_dev->dev, \"attempt power cycle\\n\");\n \t\t\tusb_hub_set_port_power(hdev, hub, port1, false);\n \t\t\tmsleep(2 * hub_power_on_good_delay(hub));\n+\t\t\tprr_reset = usb_acpi_port_prr_reset(hdev, port1);\n \t\t\tusb_hub_set_port_power(hdev, hub, port1, true);\n \t\t\tmsleep(hub_power_on_good_delay(hub));\n+\t\t\t/*\n+\t\t\t * USB 2.0 spec §7.1.7.3 requires at least 100 ms\n+\t\t\t * between VBUS power-on and the first reset for power\n+\t\t\t * settling. hub_power_on_good_delay() on an xHCI root\n+\t\t\t * hub returns bPwrOn2PwrGood * 2 with no minimum floor,\n+\t\t\t * which can be as little as 20 ms. When _PRR _RST was\n+\t\t\t * also exercised the device must complete its power-on\n+\t\t\t * sequence before enumeration; enforce the spec minimum.\n+\t\t\t */\n+\t\t\tif (prr_reset == 0)\n+\t\t\t\tmsleep(100);\n \t\t}\n \t}\n \tif (hub->hdev->parent ||\ndiff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c\nindex 489dbdc96f94a..ee62e3fd8e3a1 100644\n--- a/drivers/usb/core/usb-acpi.c\n+++ b/drivers/usb/core/usb-acpi.c\n@@ -142,6 +142,74 @@ int usb_acpi_set_power_state(struct usb_device *hdev, int index, bool enable)\n }\n EXPORT_SYMBOL_GPL(usb_acpi_set_power_state);\n \n+/**\n+ * usb_acpi_port_prr_reset - issue an ACPI _PRR reset on a hub port\n+ * @hdev: USB device belonging to the usb hub\n+ * @port1: port number (one-based)\n+ *\n+ * Some devices expose their hardware reset line via an ACPI Power Resource for\n+ * Reset (_PRR). When such a device fails to enumerate (e.g. because the reset\n+ * GPIO is stuck low), the USB power-cycle alone is not enough; the firmware\n+ * reset path must also be exercised.\n+ *\n+ * This function evaluates _PRR on the port's ACPI companion to obtain the\n+ * power-resource reference and then calls _RST on that resource to toggle the\n+ * reset line. It is intended to be called alongside the mid-retry VBUS\n+ * power-cycle already performed by hub_port_connect().\n+ *\n+ * Returns 0 on success, -ENODEV if the port has no ACPI handle or no _PRR\n+ * method, or a negative error code on failure.\n+ */\n+int usb_acpi_port_prr_reset(struct usb_device *hdev, int port1)\n+{\n+\tacpi_handle port_handle;\n+\tstruct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };\n+\tunion acpi_object *pkg, *ref;\n+\tacpi_status status;\n+\tint ret = 0;\n+\n+\tport_handle = usb_get_hub_port_acpi_handle(hdev, port1);\n+\tif (!port_handle)\n+\t\treturn -ENODEV;\n+\n+\tif (!acpi_has_method(port_handle, \"_PRR\"))\n+\t\treturn -ENODEV;\n+\n+\tstatus = acpi_evaluate_object(port_handle, \"_PRR\", NULL, &buffer);\n+\tif (ACPI_FAILURE(status)) {\n+\t\tdev_dbg(&hdev->dev, \"port%d: _PRR evaluation failed: %s\\n\",\n+\t\t\tport1, acpi_format_exception(status));\n+\t\treturn -ENODEV;\n+\t}\n+\n+\tpkg = buffer.pointer;\n+\tif (!pkg || pkg->type != ACPI_TYPE_PACKAGE || pkg->package.count < 1) {\n+\t\tdev_dbg(&hdev->dev, \"port%d: _PRR returned unexpected object\\n\",\n+\t\t\tport1);\n+\t\tret = -EINVAL;\n+\t\tgoto out;\n+\t}\n+\n+\tref = &pkg->package.elements[0];\n+\tif (ref->type != ACPI_TYPE_LOCAL_REFERENCE || !ref->reference.handle) {\n+\t\tdev_dbg(&hdev->dev, \"port%d: _PRR element is not a reference\\n\",\n+\t\t\tport1);\n+\t\tret = -EINVAL;\n+\t\tgoto out;\n+\t}\n+\n+\tstatus = acpi_evaluate_object(ref->reference.handle, \"_RST\", NULL, NULL);\n+\tif (ACPI_FAILURE(status)) {\n+\t\tdev_dbg(&hdev->dev, \"port%d: _RST evaluation failed: %s\\n\",\n+\t\t\tport1, acpi_format_exception(status));\n+\t\tret = -EIO;\n+\t}\n+\n+out:\n+\tkfree(buffer.pointer);\n+\treturn ret;\n+}\n+\n /**\n * usb_acpi_add_usb4_devlink - add device link to USB4 Host Interface for tunneled USB3 devices\n *\ndiff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h\nindex a9b37aeb515be..4d3dc3bd881b2 100644\n--- a/drivers/usb/core/usb.h\n+++ b/drivers/usb/core/usb.h\n@@ -211,7 +211,10 @@ extern int usb_acpi_register(void);\n extern void usb_acpi_unregister(void);\n extern acpi_handle usb_get_hub_port_acpi_handle(struct usb_device *hdev,\n \tint port1);\n+extern int usb_acpi_port_prr_reset(struct usb_device *hdev, int port1);\n #else\n static inline int usb_acpi_register(void) { return 0; };\n static inline void usb_acpi_unregister(void) { };\n+static inline int usb_acpi_port_prr_reset(struct usb_device *hdev,\n+\t\t\t\t\t int port1) { return -ENODEV; }\n #endif\n", "prefixes": [ "SRU", "R", "1/1" ] }