aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/usbhid/hid-core.c71
1 files changed, 44 insertions, 27 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 4309c03038f6..dedd8e4e5c6d 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -993,9 +993,10 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
993 993
994static void usbhid_restart_queues(struct usbhid_device *usbhid) 994static void usbhid_restart_queues(struct usbhid_device *usbhid)
995{ 995{
996 if (usbhid->urbout) 996 if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl))
997 usbhid_restart_out_queue(usbhid); 997 usbhid_restart_out_queue(usbhid);
998 usbhid_restart_ctrl_queue(usbhid); 998 if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
999 usbhid_restart_ctrl_queue(usbhid);
999} 1000}
1000 1001
1001static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) 1002static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
@@ -1462,11 +1463,38 @@ void usbhid_put_power(struct hid_device *hid)
1462 1463
1463 1464
1464#ifdef CONFIG_PM 1465#ifdef CONFIG_PM
1466static int hid_resume_common(struct hid_device *hid, bool driver_suspended)
1467{
1468 struct usbhid_device *usbhid = hid->driver_data;
1469 int status;
1470
1471 spin_lock_irq(&usbhid->lock);
1472 clear_bit(HID_SUSPENDED, &usbhid->iofl);
1473 usbhid_mark_busy(usbhid);
1474
1475 if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) ||
1476 test_bit(HID_RESET_PENDING, &usbhid->iofl))
1477 schedule_work(&usbhid->reset_work);
1478 usbhid->retry_delay = 0;
1479
1480 usbhid_restart_queues(usbhid);
1481 spin_unlock_irq(&usbhid->lock);
1482
1483 status = hid_start_in(hid);
1484 if (status < 0)
1485 hid_io_error(hid);
1486
1487 if (driver_suspended && hid->driver && hid->driver->resume)
1488 status = hid->driver->resume(hid);
1489 return status;
1490}
1491
1465static int hid_suspend(struct usb_interface *intf, pm_message_t message) 1492static int hid_suspend(struct usb_interface *intf, pm_message_t message)
1466{ 1493{
1467 struct hid_device *hid = usb_get_intfdata(intf); 1494 struct hid_device *hid = usb_get_intfdata(intf);
1468 struct usbhid_device *usbhid = hid->driver_data; 1495 struct usbhid_device *usbhid = hid->driver_data;
1469 int status; 1496 int status;
1497 bool driver_suspended = false;
1470 1498
1471 if (PMSG_IS_AUTO(message)) { 1499 if (PMSG_IS_AUTO(message)) {
1472 spin_lock_irq(&usbhid->lock); /* Sync with error handler */ 1500 spin_lock_irq(&usbhid->lock); /* Sync with error handler */
@@ -1482,8 +1510,9 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
1482 if (hid->driver && hid->driver->suspend) { 1510 if (hid->driver && hid->driver->suspend) {
1483 status = hid->driver->suspend(hid, message); 1511 status = hid->driver->suspend(hid, message);
1484 if (status < 0) 1512 if (status < 0)
1485 return status; 1513 goto failed;
1486 } 1514 }
1515 driver_suspended = true;
1487 } else { 1516 } else {
1488 usbhid_mark_busy(usbhid); 1517 usbhid_mark_busy(usbhid);
1489 spin_unlock_irq(&usbhid->lock); 1518 spin_unlock_irq(&usbhid->lock);
@@ -1496,11 +1525,14 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
1496 if (status < 0) 1525 if (status < 0)
1497 return status; 1526 return status;
1498 } 1527 }
1528 driver_suspended = true;
1499 spin_lock_irq(&usbhid->lock); 1529 spin_lock_irq(&usbhid->lock);
1500 set_bit(HID_SUSPENDED, &usbhid->iofl); 1530 set_bit(HID_SUSPENDED, &usbhid->iofl);
1501 spin_unlock_irq(&usbhid->lock); 1531 spin_unlock_irq(&usbhid->lock);
1502 if (usbhid_wait_io(hid) < 0) 1532 if (usbhid_wait_io(hid) < 0) {
1503 return -EIO; 1533 status = -EIO;
1534 goto failed;
1535 }
1504 } 1536 }
1505 1537
1506 hid_cancel_delayed_stuff(usbhid); 1538 hid_cancel_delayed_stuff(usbhid);
@@ -1508,14 +1540,15 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
1508 1540
1509 if (PMSG_IS_AUTO(message) && test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) { 1541 if (PMSG_IS_AUTO(message) && test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) {
1510 /* lost race against keypresses */ 1542 /* lost race against keypresses */
1511 status = hid_start_in(hid); 1543 status = -EBUSY;
1512 if (status < 0) 1544 goto failed;
1513 hid_io_error(hid);
1514 usbhid_mark_busy(usbhid);
1515 return -EBUSY;
1516 } 1545 }
1517 dev_dbg(&intf->dev, "suspend\n"); 1546 dev_dbg(&intf->dev, "suspend\n");
1518 return 0; 1547 return 0;
1548
1549 failed:
1550 hid_resume_common(hid, driver_suspended);
1551 return status;
1519} 1552}
1520 1553
1521static int hid_resume(struct usb_interface *intf) 1554static int hid_resume(struct usb_interface *intf)
@@ -1527,23 +1560,7 @@ static int hid_resume(struct usb_interface *intf)
1527 if (!test_bit(HID_STARTED, &usbhid->iofl)) 1560 if (!test_bit(HID_STARTED, &usbhid->iofl))
1528 return 0; 1561 return 0;
1529 1562
1530 clear_bit(HID_SUSPENDED, &usbhid->iofl); 1563 status = hid_resume_common(hid, true);
1531 usbhid_mark_busy(usbhid);
1532
1533 if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) ||
1534 test_bit(HID_RESET_PENDING, &usbhid->iofl))
1535 schedule_work(&usbhid->reset_work);
1536 usbhid->retry_delay = 0;
1537 status = hid_start_in(hid);
1538 if (status < 0)
1539 hid_io_error(hid);
1540 usbhid_restart_queues(usbhid);
1541
1542 if (status >= 0 && hid->driver && hid->driver->resume) {
1543 int ret = hid->driver->resume(hid);
1544 if (ret < 0)
1545 status = ret;
1546 }
1547 dev_dbg(&intf->dev, "resume status %d\n", status); 1564 dev_dbg(&intf->dev, "resume status %d\n", status);
1548 return 0; 1565 return 0;
1549} 1566}