Bluetooth: Make use of hci_{suspend,resume}_dev on suspend notifier
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Tue, 28 Sep 2021 21:36:51 +0000 (14:36 -0700)
committerMarcel Holtmann <marcel@holtmann.org>
Wed, 29 Sep 2021 13:50:14 +0000 (15:50 +0200)
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>
net/bluetooth/hci_core.c

index aeec5a3031a667c7e90ae947a1ea90b1023e9033..ea063ce4d7af7d0ad8a9e2d198ced092816120f1 100644 (file)
@@ -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);