From patchwork Wed Nov 18 23:43:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Abhishek Pandit-Subedi X-Patchwork-Id: 328533 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=-18.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 4FA49C64E7B for ; Wed, 18 Nov 2020 23:44:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0B1E0246D4 for ; Wed, 18 Nov 2020 23:44:29 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="nk0Ghbdp" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727311AbgKRXoH (ORCPT ); Wed, 18 Nov 2020 18:44:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40512 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727294AbgKRXoG (ORCPT ); Wed, 18 Nov 2020 18:44:06 -0500 Received: from mail-pg1-x543.google.com (mail-pg1-x543.google.com [IPv6:2607:f8b0:4864:20::543]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 251FEC0617A7 for ; Wed, 18 Nov 2020 15:44:06 -0800 (PST) Received: by mail-pg1-x543.google.com with SMTP id 81so2508980pgf.0 for ; Wed, 18 Nov 2020 15:44:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=YNVmomPsfoKndzhCgIIwvVulBDHSaUyYS9Lmo0Fh/4g=; b=nk0GhbdpNORnDl6nwa8uen7IN7R0ti5psYLfmNxsQms1GpbKULyrzSWIg0BePVl1Wo mCRcnyHsVEGxEhYU/M1dPxjBr+SvW5i0aY9SYkTMMS+uLIAzlpC1QNHxWOwitZ8sdJst URUi+ZmlnyPas/Jr3Sz6DnLgu4c+lfg8X2Bn8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=YNVmomPsfoKndzhCgIIwvVulBDHSaUyYS9Lmo0Fh/4g=; b=G2t7hGhVHQeO7FCAdYHbItjna9TpaJIYQLUdKMFxAdytHXN2zB/mSjghaYE9ZdNqWX wXHHJ/s16eWkr/M+qFjCt0DmaBBYhW5gI4BXAPriaJ+B6SUeu7+tgSAPC44MWolpGneg ndgV63c46h939VlzN7HqtKYaDwvM9byDOmXTg5JbnmvURMF+V9lqGZNoGcK4doz1nkoW 6b2QR9Tl4FF890cVK5W1ySFejU3IV2Tqpp6DL+s5Z5zp7hc53gEfmeTM+eTNfiMh4axC rGQ1zOm3Syvt/A/EIyWUj9Ez99v93qPKTvTvL4Pn3UrA05ClyvNXaljDVa4mvoucYTil ulZQ== X-Gm-Message-State: AOAM532M15OMT6aGgT2LSt+IJ8RCiqa5cLrXD+/9Gg6HKLwca18m2TdZ gl62A4t80pzVIe1YB1UlKSVKuw== X-Google-Smtp-Source: ABdhPJxfameOzBmMxAymwmfLvw5AeR08O20U7SIQojuZCeR4uL/urVzwO2QbUVUlo7uaDeS08eiGUQ== X-Received: by 2002:aa7:8c16:0:b029:196:33d2:721f with SMTP id c22-20020aa78c160000b029019633d2721fmr6414397pfd.70.1605743045713; Wed, 18 Nov 2020 15:44:05 -0800 (PST) Received: from apsdesk.mtv.corp.google.com ([2620:15c:202:1:7220:84ff:fe09:2b94]) by smtp.gmail.com with ESMTPSA id f6sm21437435pgi.70.2020.11.18.15.44.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Nov 2020 15:44:05 -0800 (PST) From: Abhishek Pandit-Subedi To: marcel@holtmann.org, linux-bluetooth@vger.kernel.org Cc: chromeos-bluetooth-upstreaming@chromium.org, mcchou@chromium.org, danielwinkler@chromium.org, Abhishek Pandit-Subedi , Daniel Winkler , "David S. Miller" , Johan Hedberg , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Jakub Kicinski Subject: [PATCH 1/3] Bluetooth: Rename and move clean_up_hci_state Date: Wed, 18 Nov 2020 15:43:50 -0800 Message-Id: <20201118154349.1.I088e8a8c015ee9cc5fb5fc52c02ff4caf9a79031@changeid> X-Mailer: git-send-email 2.29.2.299.gdc1121823c-goog In-Reply-To: <20201118234352.2138694-1-abhishekpandit@chromium.org> References: <20201118234352.2138694-1-abhishekpandit@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Rename clean_up_hci_state and move to the core header so that we can power down the controller from within the kernel rather than just via mgmt commands. Signed-off-by: Abhishek Pandit-Subedi Reviewed-by: Daniel Winkler Reviewed-by: Miao-chen Chou --- include/net/bluetooth/hci_core.h | 2 ++ net/bluetooth/hci_core.c | 45 +++++++++++++++++++++++++++++++ net/bluetooth/mgmt.c | 46 +------------------------------- 3 files changed, 48 insertions(+), 45 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 9873e1c8cd163b..ff32d5a856f17f 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1072,6 +1072,8 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active); void hci_le_conn_failed(struct hci_conn *conn, u8 status); +int hci_clean_up_state(struct hci_dev *hdev); + /* * hci_conn_get() and hci_conn_put() are used to control the life-time of an * "hci_conn" object. They do not guarantee that the hci_conn object is running, diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 502552d6e9aff3..8e90850d6d769e 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2290,6 +2290,51 @@ static void hci_power_on(struct work_struct *work) } } +static void clean_up_hci_complete(struct hci_dev *hdev, u8 status, u16 opcode) +{ + BT_DBG("%s status 0x%02x", hdev->name, status); + + if (hci_conn_count(hdev) == 0) { + cancel_delayed_work(&hdev->power_off); + queue_work(hdev->req_workqueue, &hdev->power_off.work); + } +} + +/* This function requires the caller holds hdev->lock */ +int hci_clean_up_state(struct hci_dev *hdev) +{ + struct hci_request req; + struct hci_conn *conn; + bool discov_stopped; + int err; + u8 scan = 0x00; + + hci_req_init(&req, hdev); + + if (test_bit(HCI_ISCAN, &hdev->flags) || + test_bit(HCI_PSCAN, &hdev->flags)) { + hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); + } + + hci_req_clear_adv_instance(hdev, NULL, NULL, 0x00, false); + + if (hci_dev_test_flag(hdev, HCI_LE_ADV)) + __hci_req_disable_advertising(&req); + + discov_stopped = hci_req_stop_discovery(&req); + + list_for_each_entry(conn, &hdev->conn_hash.list, list) { + /* 0x15 == Terminated due to Power Off */ + __hci_abort_conn(&req, conn, 0x15); + } + + err = hci_req_run(&req, clean_up_hci_complete); + if (!err && discov_stopped) + hci_discovery_set_state(hdev, DISCOVERY_STOPPING); + + return err; +} + static void hci_power_off(struct work_struct *work) { struct hci_dev *hdev = container_of(work, struct hci_dev, diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 12d7b368b428e8..ea136a6b730f9a 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1122,16 +1122,6 @@ static int send_settings_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev) sizeof(settings)); } -static void clean_up_hci_complete(struct hci_dev *hdev, u8 status, u16 opcode) -{ - bt_dev_dbg(hdev, "status 0x%02x", status); - - if (hci_conn_count(hdev) == 0) { - cancel_delayed_work(&hdev->power_off); - queue_work(hdev->req_workqueue, &hdev->power_off.work); - } -} - void mgmt_advertising_added(struct sock *sk, struct hci_dev *hdev, u8 instance) { struct mgmt_ev_advertising_added ev; @@ -1159,40 +1149,6 @@ static void cancel_adv_timeout(struct hci_dev *hdev) } } -static int clean_up_hci_state(struct hci_dev *hdev) -{ - struct hci_request req; - struct hci_conn *conn; - bool discov_stopped; - int err; - - hci_req_init(&req, hdev); - - if (test_bit(HCI_ISCAN, &hdev->flags) || - test_bit(HCI_PSCAN, &hdev->flags)) { - u8 scan = 0x00; - hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); - } - - hci_req_clear_adv_instance(hdev, NULL, NULL, 0x00, false); - - if (hci_dev_test_flag(hdev, HCI_LE_ADV)) - __hci_req_disable_advertising(&req); - - discov_stopped = hci_req_stop_discovery(&req); - - list_for_each_entry(conn, &hdev->conn_hash.list, list) { - /* 0x15 == Terminated due to Power Off */ - __hci_abort_conn(&req, conn, 0x15); - } - - err = hci_req_run(&req, clean_up_hci_complete); - if (!err && discov_stopped) - hci_discovery_set_state(hdev, DISCOVERY_STOPPING); - - return err; -} - static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { @@ -1230,7 +1186,7 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data, err = 0; } else { /* Disconnect connections, stop scans, etc */ - err = clean_up_hci_state(hdev); + err = hci_clean_up_state(hdev); if (!err) queue_delayed_work(hdev->req_workqueue, &hdev->power_off, HCI_POWER_OFF_TIMEOUT); From patchwork Wed Nov 18 23:43:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Abhishek Pandit-Subedi X-Patchwork-Id: 327489 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=-18.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 93224C64E7A for ; Wed, 18 Nov 2020 23:44:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4DF98246CB for ; Wed, 18 Nov 2020 23:44:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="Lhy85aur" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727356AbgKRXoI (ORCPT ); Wed, 18 Nov 2020 18:44:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40516 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726081AbgKRXoH (ORCPT ); Wed, 18 Nov 2020 18:44:07 -0500 Received: from mail-pl1-x641.google.com (mail-pl1-x641.google.com [IPv6:2607:f8b0:4864:20::641]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 861AEC0613D4 for ; Wed, 18 Nov 2020 15:44:07 -0800 (PST) Received: by mail-pl1-x641.google.com with SMTP id x15so1918807pll.2 for ; Wed, 18 Nov 2020 15:44:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cfKp0r4v8KnHJMFIsfD8HVI4xTIgCH6NiDoEg1v+fx4=; b=Lhy85aur6ZtATaH4lMCvfHShYvSTGUd2rdwP41a6bLZ7s+KRY59Trub1cY+9uEsD2/ xecK2ZvoziQ/+MfCVOFcA4+9YUMUBWZLEN7jLNepCP6799YapzJIo5yI0j4igCuMeGZb /v0KkHpxKepHoUoRVN+RYY2Srq4SA/vqsFguM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cfKp0r4v8KnHJMFIsfD8HVI4xTIgCH6NiDoEg1v+fx4=; b=UUEVwbbRoMbvrGW8o9oUVcab/nWLL2uqx/QalFzU6aiwsxVO7olC1m1xhzbvYcsx6r JM9CaNw9ZrABngXdzFmcBRocOBAf2B2KtVS+2i2YWngZbsahgcbjNAung8bS3xSUQmeP 9VNL8JnKb8iabVnwykRtVtD+wd2LYdEmrdQNbapemz25kXFUKrvIZpT4yRYI9jvxerDm +5LULxDEXm47Vub0rCkfTxhZcBqEqwh4N1tjhpnfp3uGVYcGTE4sLYpfbkJkNnSYi/9a OJ/H4aBix9cNvv984Ctmu/kmSCY+obIazEIJaL2IgwcAib8YAKymCSA90akFrRbqVYCz 9Zaw== X-Gm-Message-State: AOAM531ceZZG9D7PxO4HgFt17P6Yx28RElADyXqJREUB6eBIoUktDEVM XnjUSOOnkiwCViViLEBk3rQbDg== X-Google-Smtp-Source: ABdhPJwwaHEZy70mLOkmnmMTTboXZBQPl6Emv6az9gRrpwahfvoJjzfc3++alZHHSbv+M50V5DcIpg== X-Received: by 2002:a17:902:a5c5:b029:d9:d27d:a1ce with SMTP id t5-20020a170902a5c5b02900d9d27da1cemr2701575plq.78.1605743047090; Wed, 18 Nov 2020 15:44:07 -0800 (PST) Received: from apsdesk.mtv.corp.google.com ([2620:15c:202:1:7220:84ff:fe09:2b94]) by smtp.gmail.com with ESMTPSA id f6sm21437435pgi.70.2020.11.18.15.44.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Nov 2020 15:44:06 -0800 (PST) From: Abhishek Pandit-Subedi To: marcel@holtmann.org, linux-bluetooth@vger.kernel.org Cc: chromeos-bluetooth-upstreaming@chromium.org, mcchou@chromium.org, danielwinkler@chromium.org, Abhishek Pandit-Subedi , "David S. Miller" , Johan Hedberg , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Jakub Kicinski Subject: [PATCH 2/3] Bluetooth: Add quirk to power down on suspend Date: Wed, 18 Nov 2020 15:43:51 -0800 Message-Id: <20201118154349.2.Ia5f019f5309cc9f2be9070484a001dc7ddaca354@changeid> X-Mailer: git-send-email 2.29.2.299.gdc1121823c-goog In-Reply-To: <20201118234352.2138694-1-abhishekpandit@chromium.org> References: <20201118234352.2138694-1-abhishekpandit@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Some older controllers fail to enter a quiescent state reliably when supporting remote wake. For those cases, add a quirk that will power down the controller when suspending and power it back up when resuming. Signed-off-by: Abhishek Pandit-Subedi Reviewed-by: Miao-chen Chou --- include/net/bluetooth/hci.h | 7 +++++ include/net/bluetooth/hci_core.h | 4 +++ net/bluetooth/hci_core.c | 48 ++++++++++++++++++++++++++++++-- net/bluetooth/hci_request.c | 26 ++++++++++++++++- 4 files changed, 82 insertions(+), 3 deletions(-) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index c8e67042a3b14c..88d5c9554e4840 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -238,6 +238,13 @@ enum { * during the hdev->setup vendor callback. */ HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, + + /* When this quirk is set, the adapter will be powered down during + * system suspend and powerd up on resume. This should be used on + * controllers that don't behave well during suspend, either causing + * spurious wakeups or not entering a suspend state reliably. + */ + HCI_QUIRK_POWER_DOWN_SYSTEM_SUSPEND, }; /* HCI device flags */ diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index ff32d5a856f17f..e7dc6e3efbf246 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -90,6 +90,7 @@ struct discovery_state { }; #define SUSPEND_NOTIFIER_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ +#define SUSPEND_POWER_DOWN_TIMEOUT msecs_to_jiffies(1000) enum suspend_tasks { SUSPEND_PAUSE_DISCOVERY, @@ -112,6 +113,9 @@ enum suspended_state { BT_RUNNING = 0, BT_SUSPEND_DISCONNECT, BT_SUSPEND_CONFIGURE_WAKE, + BT_SUSPEND_DO_POWER_DOWN, + BT_SUSPEND_DO_POWER_UP, + BT_SUSPEND_POWERED_DOWN, /* Powered down prior to suspend */ }; struct hci_conn_hash { diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 8e90850d6d769e..d73e097d3ce16b 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -3562,6 +3562,7 @@ static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action, container_of(nb, struct hci_dev, suspend_notifier); int ret = 0; u8 state = BT_RUNNING; + bool powered; /* If powering down, wait for completion. */ if (mgmt_powering_down(hdev)) { @@ -3571,8 +3572,51 @@ static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action, goto done; } - /* Suspend notifier should only act on events when powered. */ - if (!hdev_is_powered(hdev)) + powered = hdev_is_powered(hdev); + + /* Update the suspend state when entering suspend if the system is + * currently powered off or if it is powered on but was previously + * powered off. + */ + if (action == PM_SUSPEND_PREPARE) { + /* Must hold dev lock when modifying suspend state. */ + hci_dev_lock(hdev); + if (powered && hdev->suspend_state == BT_SUSPEND_POWERED_DOWN) + hdev->suspend_state = BT_RUNNING; + else if (!powered && + hdev->suspend_state != BT_SUSPEND_POWERED_DOWN) + hdev->suspend_state = BT_SUSPEND_POWERED_DOWN; + + hci_dev_unlock(hdev); + } + + /* When the power down quirk is set, we power down the adapter when + * suspending and power it up when resuming. If the adapter was already + * powered down before suspend, we don't do anything here. + */ + if (test_bit(HCI_QUIRK_POWER_DOWN_SYSTEM_SUSPEND, &hdev->quirks) && + hdev->suspend_state != BT_SUSPEND_POWERED_DOWN) { + if (action == PM_SUSPEND_PREPARE && powered) { + state = BT_SUSPEND_DO_POWER_DOWN; + ret = hci_change_suspend_state(hdev, state); + + /* Emit that we're powering down for suspend */ + hci_clear_wake_reason(hdev); + mgmt_suspending(hdev, state); + goto done; + } else if (action == PM_POST_SUSPEND && !powered) { + /* Emit that we're resuming before powering up. */ + mgmt_resuming(hdev, hdev->wake_reason, &hdev->wake_addr, + hdev->wake_addr_type); + + state = BT_SUSPEND_DO_POWER_UP; + ret = hci_change_suspend_state(hdev, state); + goto done; + } + } + + /* Skip to end if we weren't powered. */ + if (!powered) goto done; if (action == PM_SUSPEND_PREPARE) { diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index 048d4db9d4ea53..804bd0652edd1c 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -1194,6 +1194,7 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next) struct hci_request req; u8 page_scan; int disconnect_counter; + int err; if (next == hdev->suspend_state) { bt_dev_dbg(hdev, "Same state before and after: %d", next); @@ -1273,7 +1274,7 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next) /* Pause scan changes again. */ hdev->scanning_paused = true; hci_req_run(&req, suspend_req_complete); - } else { + } else if (next == BT_RUNNING) { hdev->suspended = false; hdev->scanning_paused = false; @@ -1306,6 +1307,29 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next) } hci_req_run(&req, suspend_req_complete); + } else if (next == BT_SUSPEND_DO_POWER_DOWN) { + hdev->suspended = true; + hdev->scanning_paused = true; + + err = hci_clean_up_state(hdev); + + if (!err) + queue_delayed_work(hdev->req_workqueue, + &hdev->power_off, + SUSPEND_POWER_DOWN_TIMEOUT); + + if (err == -ENODATA) { + cancel_delayed_work(&hdev->power_off); + queue_work(hdev->req_workqueue, &hdev->power_off.work); + err = 0; + } + + set_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks); + } else if (next == BT_SUSPEND_DO_POWER_UP) { + hdev->suspended = false; + hdev->scanning_paused = false; + + queue_work(hdev->req_workqueue, &hdev->power_on); } hdev->suspend_state = next; From patchwork Wed Nov 18 23:43:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Abhishek Pandit-Subedi X-Patchwork-Id: 328534 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=-18.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 6CB62C64E75 for ; Wed, 18 Nov 2020 23:44:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 12627246EE for ; Wed, 18 Nov 2020 23:44:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="WYix7Y11" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727377AbgKRXoK (ORCPT ); Wed, 18 Nov 2020 18:44:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40526 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727363AbgKRXoI (ORCPT ); Wed, 18 Nov 2020 18:44:08 -0500 Received: from mail-pl1-x642.google.com (mail-pl1-x642.google.com [IPv6:2607:f8b0:4864:20::642]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B670AC0613D4 for ; Wed, 18 Nov 2020 15:44:08 -0800 (PST) Received: by mail-pl1-x642.google.com with SMTP id j5so1905414plk.7 for ; Wed, 18 Nov 2020 15:44:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=iTB3bo1UF4JJAzKkMT7p3MoDedREDQBRrj3yyH4Dl9Y=; b=WYix7Y11RrVt/dV88uG6yY7owq0gesu0k3Uq1qb9Jo40C/n097r0FsHMlWEZqBrVSI ML5yXL/+0ZlmVhUqg0d7l3feJCosQNnAHwuZZOHbxACwxin1AUgod0sJcLMh4ULrPD/3 nos0h6RJi90luya6+9dAc3gfYPJU/Lau8xW2g= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=iTB3bo1UF4JJAzKkMT7p3MoDedREDQBRrj3yyH4Dl9Y=; b=cA1+36jO8bI9U9hUOFU0Bq9no5hWysfjitr3/vbup2fCxufeS9jgskFFVf21R4KEJs W/CwgbHGtv9OgozOfrevo9YoQxQgMMmOjyDJ5TK7rhlptQ64Hp1yXcU6lx9IWvEZfm7Y AwKME3GCBUQspeNAwvcYqt0HJzs1zWyLLWR9UIXxXCFIzVjfbpfZyEs45mq1AT5B4x2v 1pHCfFTMn1JS8gQjKCX4GrX1LwZsyXjw/GYOH7P1a3dn3rkP81Uywue6mRG1ztcVJ615 KHuJvEgt/CijqTCkk99cwaM7u8xeeFHgIHlbSYL3//grOLYlm/qFtqYt1XDoyvC4TPxy rPyw== X-Gm-Message-State: AOAM533/940kO3Rc/NPhtKdBRlGOScb6UN6nXQWtPUM8JJsYtYaghsJi pZeYU/ncZyqE/rgS9Linnwbu5Q== X-Google-Smtp-Source: ABdhPJx0o4QdC0y6N2nNJxQWQ+otJDXcwXowHU259cVnDIjOI+IOlgmejl3o0Homa+Q4GM9jUyawvQ== X-Received: by 2002:a17:902:9042:b029:d6:fe3f:6688 with SMTP id w2-20020a1709029042b02900d6fe3f6688mr6388780plz.75.1605743048346; Wed, 18 Nov 2020 15:44:08 -0800 (PST) Received: from apsdesk.mtv.corp.google.com ([2620:15c:202:1:7220:84ff:fe09:2b94]) by smtp.gmail.com with ESMTPSA id f6sm21437435pgi.70.2020.11.18.15.44.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Nov 2020 15:44:07 -0800 (PST) From: Abhishek Pandit-Subedi To: marcel@holtmann.org, linux-bluetooth@vger.kernel.org Cc: chromeos-bluetooth-upstreaming@chromium.org, mcchou@chromium.org, danielwinkler@chromium.org, Abhishek Pandit-Subedi , Johan Hedberg , linux-kernel@vger.kernel.org Subject: [PATCH 3/3] Bluetooth: btmrvl_sdio: Power down when suspending Date: Wed, 18 Nov 2020 15:43:52 -0800 Message-Id: <20201118154349.3.If6a8ea0def7ff7a1f6a8ba349b9c840201b1d1f0@changeid> X-Mailer: git-send-email 2.29.2.299.gdc1121823c-goog In-Reply-To: <20201118234352.2138694-1-abhishekpandit@chromium.org> References: <20201118234352.2138694-1-abhishekpandit@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org After seeing a large number of suspend failures due to -EBUSY, the most common cause for failure seems to be the log snippet below: [ 4764.773873] Bluetooth: hci_cmd_timeout() hci0 command 0x0c14 tx timeout [ 4767.777897] Bluetooth: btmrvl_enable_hs() Host sleep enable command failed [ 4767.777920] Bluetooth: btmrvl_sdio_suspend() HS not actived, suspend failed! [ 4767.777946] dpm_run_callback(): pm_generic_suspend+0x0/0x48 returns -16 [ 4767.777963] call mmc2:0001:2+ returned -16 after 4882288 usecs Since the sleep command is timing out, this points to the firmware as the most likely source of the problem and we don't have a way to address the fix there (this is an old controller). So, to mitigate this issue, we can simply power down the Bluetooth controller when entering suspend and power it back up when exiting suspend. We control setting this quirk via a module parameter, power_down_suspend (which defaults to false). Signed-off-by: Abhishek Pandit-Subedi --- drivers/bluetooth/btmrvl_sdio.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 33d58b30c5acfc..e2e4917b4fe589 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -35,6 +35,12 @@ #define VERSION "1.0" +/* Add module param to control whether the controller is powered down during + * suspend. Default is False. + */ +static bool power_down_suspend; +module_param(power_down_suspend, bool, 0644); + static struct memory_type_mapping mem_type_mapping_tbl[] = { {"ITCM", NULL, 0, 0xF0}, {"DTCM", NULL, 0, 0xF1}, @@ -1587,6 +1593,10 @@ static int btmrvl_sdio_probe(struct sdio_func *func, goto disable_host_int; } + if (power_down_suspend) + set_bit(HCI_QUIRK_POWER_DOWN_SYSTEM_SUSPEND, + &priv->btmrvl_dev.hcidev->quirks); + return 0; disable_host_int: