aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruno Prémont <bonbons@linux-vserver.org>2010-04-25 15:40:03 -0400
committerJiri Kosina <jkosina@suse.cz>2010-04-27 09:22:00 -0400
commit6a740aa4f47b9f29bad5292cf51f008f3edad9b1 (patch)
tree179e1388bfb21bf17a93c045c29141d8bdc192b4
parentab195c58b864802c15e494f06ae109413e12d50b (diff)
HID: add suspend/resume hooks for hid drivers
Add suspend/resume hooks for HID drivers so these can do some additional state adjustment when device gets suspended/resumed. Signed-off-by: Bruno Prémont <bonbons@linux-vserver.org> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/usbhid/hid-core.c24
-rw-r--r--include/linux/hid.h8
2 files changed, 31 insertions, 1 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 56d06cd8075b..14a67fba590e 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -1290,6 +1290,11 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
1290 { 1290 {
1291 set_bit(HID_REPORTED_IDLE, &usbhid->iofl); 1291 set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
1292 spin_unlock_irq(&usbhid->lock); 1292 spin_unlock_irq(&usbhid->lock);
1293 if (hid->driver && hid->driver->suspend) {
1294 status = hid->driver->suspend(hid, message);
1295 if (status < 0)
1296 return status;
1297 }
1293 } else { 1298 } else {
1294 usbhid_mark_busy(usbhid); 1299 usbhid_mark_busy(usbhid);
1295 spin_unlock_irq(&usbhid->lock); 1300 spin_unlock_irq(&usbhid->lock);
@@ -1297,6 +1302,11 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
1297 } 1302 }
1298 1303
1299 } else { 1304 } else {
1305 if (hid->driver && hid->driver->suspend) {
1306 status = hid->driver->suspend(hid, message);
1307 if (status < 0)
1308 return status;
1309 }
1300 spin_lock_irq(&usbhid->lock); 1310 spin_lock_irq(&usbhid->lock);
1301 set_bit(HID_REPORTED_IDLE, &usbhid->iofl); 1311 set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
1302 spin_unlock_irq(&usbhid->lock); 1312 spin_unlock_irq(&usbhid->lock);
@@ -1351,6 +1361,11 @@ static int hid_resume(struct usb_interface *intf)
1351 hid_io_error(hid); 1361 hid_io_error(hid);
1352 usbhid_restart_queues(usbhid); 1362 usbhid_restart_queues(usbhid);
1353 1363
1364 if (status >= 0 && hid->driver && hid->driver->resume) {
1365 int ret = hid->driver->resume(hid);
1366 if (ret < 0)
1367 status = ret;
1368 }
1354 dev_dbg(&intf->dev, "resume status %d\n", status); 1369 dev_dbg(&intf->dev, "resume status %d\n", status);
1355 return 0; 1370 return 0;
1356} 1371}
@@ -1359,9 +1374,16 @@ static int hid_reset_resume(struct usb_interface *intf)
1359{ 1374{
1360 struct hid_device *hid = usb_get_intfdata(intf); 1375 struct hid_device *hid = usb_get_intfdata(intf);
1361 struct usbhid_device *usbhid = hid->driver_data; 1376 struct usbhid_device *usbhid = hid->driver_data;
1377 int status;
1362 1378
1363 clear_bit(HID_REPORTED_IDLE, &usbhid->iofl); 1379 clear_bit(HID_REPORTED_IDLE, &usbhid->iofl);
1364 return hid_post_reset(intf); 1380 status = hid_post_reset(intf);
1381 if (status >= 0 && hid->driver && hid->driver->reset_resume) {
1382 int ret = hid->driver->reset_resume(hid);
1383 if (ret < 0)
1384 status = ret;
1385 }
1386 return status;
1365} 1387}
1366 1388
1367#endif /* CONFIG_PM */ 1389#endif /* CONFIG_PM */
diff --git a/include/linux/hid.h b/include/linux/hid.h
index b1344ec4b7fc..069e587ae8e6 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -589,6 +589,9 @@ struct hid_usage_id {
589 * @report_fixup: called before report descriptor parsing (NULL means nop) 589 * @report_fixup: called before report descriptor parsing (NULL means nop)
590 * @input_mapping: invoked on input registering before mapping an usage 590 * @input_mapping: invoked on input registering before mapping an usage
591 * @input_mapped: invoked on input registering after mapping an usage 591 * @input_mapped: invoked on input registering after mapping an usage
592 * @suspend: invoked on suspend (NULL means nop)
593 * @resume: invoked on resume if device was not reset (NULL means nop)
594 * @reset_resume: invoked on resume if device was reset (NULL means nop)
592 * 595 *
593 * raw_event and event should return 0 on no action performed, 1 when no 596 * raw_event and event should return 0 on no action performed, 1 when no
594 * further processing should be done and negative on error 597 * further processing should be done and negative on error
@@ -629,6 +632,11 @@ struct hid_driver {
629 int (*input_mapped)(struct hid_device *hdev, 632 int (*input_mapped)(struct hid_device *hdev,
630 struct hid_input *hidinput, struct hid_field *field, 633 struct hid_input *hidinput, struct hid_field *field,
631 struct hid_usage *usage, unsigned long **bit, int *max); 634 struct hid_usage *usage, unsigned long **bit, int *max);
635#ifdef CONFIG_PM
636 int (*suspend)(struct hid_device *hdev, pm_message_t message);
637 int (*resume)(struct hid_device *hdev);
638 int (*reset_resume)(struct hid_device *hdev);
639#endif
632/* private: */ 640/* private: */
633 struct device_driver driver; 641 struct device_driver driver;
634}; 642};