aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2021-09-28 14:36:51 -0700
committerMarcel Holtmann <marcel@holtmann.org>2021-09-29 15:50:14 +0200
commite1b77d68feea20e59dd9a797e3bc520282cd4b25 (patch)
tree98134504daf21c18ef3b288aebee647008bf04ec /net/bluetooth
parentBluetooth: btrsi: remove superfluous header files from btrsi.c (diff)
downloadlinux-dev-e1b77d68feea20e59dd9a797e3bc520282cd4b25.tar.xz
linux-dev-e1b77d68feea20e59dd9a797e3bc520282cd4b25.zip
Bluetooth: Make use of hci_{suspend,resume}_dev on suspend notifier
This moves code from hci_suspend_notifier to hci_{suspend,resume}_dev since some driver may handle pm directly using HCI_QUIRK_NO_SUSPEND_NOTIFIER they would instead call hci_{suspend,resume}_dev directly and we want that to have the same behavior regardless of where pm is being handled. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_core.c116
1 files changed, 67 insertions, 49 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index aeec5a3031a6..ea063ce4d7af 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3626,55 +3626,12 @@ static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action,
struct hci_dev *hdev =
container_of(nb, struct hci_dev, suspend_notifier);
int ret = 0;
- u8 state = BT_RUNNING;
-
- /* If powering down, wait for completion. */
- if (mgmt_powering_down(hdev)) {
- set_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks);
- ret = hci_suspend_wait_event(hdev);
- if (ret)
- goto done;
- }
- /* Suspend notifier should only act on events when powered. */
- if (!hdev_is_powered(hdev) ||
- hci_dev_test_flag(hdev, HCI_UNREGISTER))
- goto done;
-
- if (action == PM_SUSPEND_PREPARE) {
- /* Suspend consists of two actions:
- * - First, disconnect everything and make the controller not
- * connectable (disabling scanning)
- * - Second, program event filter/accept list and enable scan
- */
- ret = hci_change_suspend_state(hdev, BT_SUSPEND_DISCONNECT);
- if (!ret)
- state = BT_SUSPEND_DISCONNECT;
-
- /* Only configure accept list if disconnect succeeded and wake
- * isn't being prevented.
- */
- if (!ret && !(hdev->prevent_wake && hdev->prevent_wake(hdev))) {
- ret = hci_change_suspend_state(hdev,
- BT_SUSPEND_CONFIGURE_WAKE);
- if (!ret)
- state = BT_SUSPEND_CONFIGURE_WAKE;
- }
+ if (action == PM_SUSPEND_PREPARE)
+ ret = hci_suspend_dev(hdev);
+ else if (action == PM_POST_SUSPEND)
+ ret = hci_resume_dev(hdev);
- hci_clear_wake_reason(hdev);
- mgmt_suspending(hdev, state);
-
- } else if (action == PM_POST_SUSPEND) {
- ret = hci_change_suspend_state(hdev, BT_RUNNING);
-
- mgmt_resuming(hdev, hdev->wake_reason, &hdev->wake_addr,
- hdev->wake_addr_type);
- }
-
-done:
- /* We always allow suspend even if suspend preparation failed and
- * attempt to recover in resume.
- */
if (ret)
bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d",
action, ret);
@@ -4017,16 +3974,77 @@ EXPORT_SYMBOL(hci_release_dev);
/* Suspend HCI device */
int hci_suspend_dev(struct hci_dev *hdev)
{
+ int ret;
+ u8 state = BT_RUNNING;
+
+ bt_dev_dbg(hdev, "");
+
+ /* Suspend should only act on when powered. */
+ if (!hdev_is_powered(hdev) ||
+ hci_dev_test_flag(hdev, HCI_UNREGISTER))
+ return 0;
+
+ /* If powering down, wait for completion. */
+ if (mgmt_powering_down(hdev)) {
+ set_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks);
+ ret = hci_suspend_wait_event(hdev);
+ if (ret)
+ goto done;
+ }
+
+ /* Suspend consists of two actions:
+ * - First, disconnect everything and make the controller not
+ * connectable (disabling scanning)
+ * - Second, program event filter/accept list and enable scan
+ */
+ ret = hci_change_suspend_state(hdev, BT_SUSPEND_DISCONNECT);
+ if (!ret)
+ state = BT_SUSPEND_DISCONNECT;
+
+ /* Only configure accept list if disconnect succeeded and wake
+ * isn't being prevented.
+ */
+ if (!ret && !(hdev->prevent_wake && hdev->prevent_wake(hdev))) {
+ ret = hci_change_suspend_state(hdev, BT_SUSPEND_CONFIGURE_WAKE);
+ if (!ret)
+ state = BT_SUSPEND_CONFIGURE_WAKE;
+ }
+
+ hci_clear_wake_reason(hdev);
+ mgmt_suspending(hdev, state);
+
+done:
+ /* We always allow suspend even if suspend preparation failed and
+ * attempt to recover in resume.
+ */
hci_sock_dev_event(hdev, HCI_DEV_SUSPEND);
- return 0;
+ return ret;
}
EXPORT_SYMBOL(hci_suspend_dev);
/* Resume HCI device */
int hci_resume_dev(struct hci_dev *hdev)
{
+ int ret;
+
+ bt_dev_dbg(hdev, "");
+
+ /* Resume should only act on when powered. */
+ if (!hdev_is_powered(hdev) ||
+ hci_dev_test_flag(hdev, HCI_UNREGISTER))
+ return 0;
+
+ /* If powering down don't attempt to resume */
+ if (mgmt_powering_down(hdev))
+ return 0;
+
+ ret = hci_change_suspend_state(hdev, BT_RUNNING);
+
+ mgmt_resuming(hdev, hdev->wake_reason, &hdev->wake_addr,
+ hdev->wake_addr_type);
+
hci_sock_dev_event(hdev, HCI_DEV_RESUME);
- return 0;
+ return ret;
}
EXPORT_SYMBOL(hci_resume_dev);