aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/btusb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bluetooth/btusb.c')
-rw-r--r--drivers/bluetooth/btusb.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 9ca95208fc24..0cd4a55dd5c4 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -198,6 +198,7 @@ struct btusb_data {
198 struct usb_endpoint_descriptor *isoc_rx_ep; 198 struct usb_endpoint_descriptor *isoc_rx_ep;
199 199
200 int isoc_altsetting; 200 int isoc_altsetting;
201 int suspend_count;
201}; 202};
202 203
203static void btusb_intr_complete(struct urb *urb) 204static void btusb_intr_complete(struct urb *urb)
@@ -948,10 +949,71 @@ static void btusb_disconnect(struct usb_interface *intf)
948 hci_free_dev(hdev); 949 hci_free_dev(hdev);
949} 950}
950 951
952static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
953{
954 struct btusb_data *data = usb_get_intfdata(intf);
955
956 BT_DBG("intf %p", intf);
957
958 if (data->suspend_count++)
959 return 0;
960
961 cancel_work_sync(&data->work);
962
963 usb_kill_anchored_urbs(&data->tx_anchor);
964
965 usb_kill_anchored_urbs(&data->isoc_anchor);
966 usb_kill_anchored_urbs(&data->bulk_anchor);
967 usb_kill_anchored_urbs(&data->intr_anchor);
968
969 return 0;
970}
971
972static int btusb_resume(struct usb_interface *intf)
973{
974 struct btusb_data *data = usb_get_intfdata(intf);
975 struct hci_dev *hdev = data->hdev;
976 int err;
977
978 BT_DBG("intf %p", intf);
979
980 if (--data->suspend_count)
981 return 0;
982
983 if (!test_bit(HCI_RUNNING, &hdev->flags))
984 return 0;
985
986 if (test_bit(BTUSB_INTR_RUNNING, &data->flags)) {
987 err = btusb_submit_intr_urb(hdev, GFP_NOIO);
988 if (err < 0) {
989 clear_bit(BTUSB_INTR_RUNNING, &data->flags);
990 return err;
991 }
992 }
993
994 if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
995 if (btusb_submit_bulk_urb(hdev, GFP_NOIO) < 0)
996 clear_bit(BTUSB_BULK_RUNNING, &data->flags);
997 else
998 btusb_submit_bulk_urb(hdev, GFP_NOIO);
999 }
1000
1001 if (test_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
1002 if (btusb_submit_isoc_urb(hdev, GFP_NOIO) < 0)
1003 clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
1004 else
1005 btusb_submit_isoc_urb(hdev, GFP_NOIO);
1006 }
1007
1008 return 0;
1009}
1010
951static struct usb_driver btusb_driver = { 1011static struct usb_driver btusb_driver = {
952 .name = "btusb", 1012 .name = "btusb",
953 .probe = btusb_probe, 1013 .probe = btusb_probe,
954 .disconnect = btusb_disconnect, 1014 .disconnect = btusb_disconnect,
1015 .suspend = btusb_suspend,
1016 .resume = btusb_resume,
955 .id_table = btusb_table, 1017 .id_table = btusb_table,
956}; 1018};
957 1019