mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-01 02:33:57 +00:00
Bluetooth: Remove unneeded commands for suspend
During suspend, there are a few scan enable and set event filter commands that don't need to be sent unless there are actual BR/EDR devices capable of waking the system. Check the HCI_PSCAN bit before writing scan enable and use a new dev flag, HCI_EVENT_FILTER_CONFIGURED to control whether to clear the event filter. Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org> Reviewed-by: Archie Pusaka <apusaka@chromium.org> Reviewed-by: Alain Michaud <alainm@chromium.org> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
parent
5cb08553f7
commit
e5b0ad69c9
@ -320,6 +320,7 @@ enum {
|
||||
HCI_BREDR_ENABLED,
|
||||
HCI_LE_SCAN_INTERRUPTED,
|
||||
HCI_WIDEBAND_SPEECH_ENABLED,
|
||||
HCI_EVENT_FILTER_CONFIGURED,
|
||||
|
||||
HCI_DUT_MODE,
|
||||
HCI_VENDOR_DIAG,
|
||||
|
@ -395,6 +395,29 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static void hci_cc_set_event_filter(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
__u8 status = *((__u8 *)skb->data);
|
||||
struct hci_cp_set_event_filter *cp;
|
||||
void *sent;
|
||||
|
||||
BT_DBG("%s status 0x%2.2x", hdev->name, status);
|
||||
|
||||
if (status)
|
||||
return;
|
||||
|
||||
sent = hci_sent_cmd_data(hdev, HCI_OP_SET_EVENT_FLT);
|
||||
if (!sent)
|
||||
return;
|
||||
|
||||
cp = (struct hci_cp_set_event_filter *)sent;
|
||||
|
||||
if (cp->flt_type == HCI_FLT_CLEAR_ALL)
|
||||
hci_dev_clear_flag(hdev, HCI_EVENT_FILTER_CONFIGURED);
|
||||
else
|
||||
hci_dev_set_flag(hdev, HCI_EVENT_FILTER_CONFIGURED);
|
||||
}
|
||||
|
||||
static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
|
||||
@ -3328,6 +3351,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb,
|
||||
hci_cc_write_scan_enable(hdev, skb);
|
||||
break;
|
||||
|
||||
case HCI_OP_SET_EVENT_FLT:
|
||||
hci_cc_set_event_filter(hdev, skb);
|
||||
break;
|
||||
|
||||
case HCI_OP_READ_CLASS_OF_DEV:
|
||||
hci_cc_read_class_of_dev(hdev, skb);
|
||||
break;
|
||||
|
@ -1131,14 +1131,14 @@ static void hci_req_clear_event_filter(struct hci_request *req)
|
||||
{
|
||||
struct hci_cp_set_event_filter f;
|
||||
|
||||
memset(&f, 0, sizeof(f));
|
||||
f.flt_type = HCI_FLT_CLEAR_ALL;
|
||||
hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &f);
|
||||
if (!hci_dev_test_flag(req->hdev, HCI_BREDR_ENABLED))
|
||||
return;
|
||||
|
||||
/* Update page scan state (since we may have modified it when setting
|
||||
* the event filter).
|
||||
*/
|
||||
__hci_req_update_scan(req);
|
||||
if (hci_dev_test_flag(req->hdev, HCI_EVENT_FILTER_CONFIGURED)) {
|
||||
memset(&f, 0, sizeof(f));
|
||||
f.flt_type = HCI_FLT_CLEAR_ALL;
|
||||
hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &f);
|
||||
}
|
||||
}
|
||||
|
||||
static void hci_req_set_event_filter(struct hci_request *req)
|
||||
@ -1147,6 +1147,10 @@ static void hci_req_set_event_filter(struct hci_request *req)
|
||||
struct hci_cp_set_event_filter f;
|
||||
struct hci_dev *hdev = req->hdev;
|
||||
u8 scan = SCAN_DISABLED;
|
||||
bool scanning = test_bit(HCI_PSCAN, &hdev->flags);
|
||||
|
||||
if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
|
||||
return;
|
||||
|
||||
/* Always clear event filter when starting */
|
||||
hci_req_clear_event_filter(req);
|
||||
@ -1167,12 +1171,13 @@ static void hci_req_set_event_filter(struct hci_request *req)
|
||||
scan = SCAN_PAGE;
|
||||
}
|
||||
|
||||
if (scan)
|
||||
if (scan && !scanning) {
|
||||
set_bit(SUSPEND_SCAN_ENABLE, hdev->suspend_tasks);
|
||||
else
|
||||
hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
|
||||
} else if (!scan && scanning) {
|
||||
set_bit(SUSPEND_SCAN_DISABLE, hdev->suspend_tasks);
|
||||
|
||||
hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
|
||||
hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
|
||||
}
|
||||
}
|
||||
|
||||
static void cancel_adv_timeout(struct hci_dev *hdev)
|
||||
@ -1315,9 +1320,14 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next)
|
||||
|
||||
hdev->advertising_paused = true;
|
||||
hdev->advertising_old_state = old_state;
|
||||
/* Disable page scan */
|
||||
page_scan = SCAN_DISABLED;
|
||||
hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &page_scan);
|
||||
|
||||
/* Disable page scan if enabled */
|
||||
if (test_bit(HCI_PSCAN, &hdev->flags)) {
|
||||
page_scan = SCAN_DISABLED;
|
||||
hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1,
|
||||
&page_scan);
|
||||
set_bit(SUSPEND_SCAN_DISABLE, hdev->suspend_tasks);
|
||||
}
|
||||
|
||||
/* Disable LE passive scan if enabled */
|
||||
if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
|
||||
@ -1328,9 +1338,6 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next)
|
||||
/* Disable advertisement filters */
|
||||
hci_req_add_set_adv_filter_enable(&req, false);
|
||||
|
||||
/* Mark task needing completion */
|
||||
set_bit(SUSPEND_SCAN_DISABLE, hdev->suspend_tasks);
|
||||
|
||||
/* Prevent disconnects from causing scanning to be re-enabled */
|
||||
hdev->scanning_paused = true;
|
||||
|
||||
@ -1364,7 +1371,10 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next)
|
||||
hdev->suspended = false;
|
||||
hdev->scanning_paused = false;
|
||||
|
||||
/* Clear any event filters and restore scan state */
|
||||
hci_req_clear_event_filter(&req);
|
||||
__hci_req_update_scan(&req);
|
||||
|
||||
/* Reset passive/background scanning to normal */
|
||||
__hci_update_background_scan(&req);
|
||||
/* Enable all of the advertisement filters */
|
||||
|
Loading…
Reference in New Issue
Block a user