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>
This commit is contained in:
parent
ab195c58b8
commit
6a740aa4f4
|
@ -1290,6 +1290,11 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
|
||||||
{
|
{
|
||||||
set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
|
set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
|
||||||
spin_unlock_irq(&usbhid->lock);
|
spin_unlock_irq(&usbhid->lock);
|
||||||
|
if (hid->driver && hid->driver->suspend) {
|
||||||
|
status = hid->driver->suspend(hid, message);
|
||||||
|
if (status < 0)
|
||||||
|
return status;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
usbhid_mark_busy(usbhid);
|
usbhid_mark_busy(usbhid);
|
||||||
spin_unlock_irq(&usbhid->lock);
|
spin_unlock_irq(&usbhid->lock);
|
||||||
|
@ -1297,6 +1302,11 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
if (hid->driver && hid->driver->suspend) {
|
||||||
|
status = hid->driver->suspend(hid, message);
|
||||||
|
if (status < 0)
|
||||||
|
return status;
|
||||||
|
}
|
||||||
spin_lock_irq(&usbhid->lock);
|
spin_lock_irq(&usbhid->lock);
|
||||||
set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
|
set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
|
||||||
spin_unlock_irq(&usbhid->lock);
|
spin_unlock_irq(&usbhid->lock);
|
||||||
|
@ -1351,6 +1361,11 @@ static int hid_resume(struct usb_interface *intf)
|
||||||
hid_io_error(hid);
|
hid_io_error(hid);
|
||||||
usbhid_restart_queues(usbhid);
|
usbhid_restart_queues(usbhid);
|
||||||
|
|
||||||
|
if (status >= 0 && hid->driver && hid->driver->resume) {
|
||||||
|
int ret = hid->driver->resume(hid);
|
||||||
|
if (ret < 0)
|
||||||
|
status = ret;
|
||||||
|
}
|
||||||
dev_dbg(&intf->dev, "resume status %d\n", status);
|
dev_dbg(&intf->dev, "resume status %d\n", status);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1359,9 +1374,16 @@ static int hid_reset_resume(struct usb_interface *intf)
|
||||||
{
|
{
|
||||||
struct hid_device *hid = usb_get_intfdata(intf);
|
struct hid_device *hid = usb_get_intfdata(intf);
|
||||||
struct usbhid_device *usbhid = hid->driver_data;
|
struct usbhid_device *usbhid = hid->driver_data;
|
||||||
|
int status;
|
||||||
|
|
||||||
clear_bit(HID_REPORTED_IDLE, &usbhid->iofl);
|
clear_bit(HID_REPORTED_IDLE, &usbhid->iofl);
|
||||||
return hid_post_reset(intf);
|
status = hid_post_reset(intf);
|
||||||
|
if (status >= 0 && hid->driver && hid->driver->reset_resume) {
|
||||||
|
int ret = hid->driver->reset_resume(hid);
|
||||||
|
if (ret < 0)
|
||||||
|
status = ret;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_PM */
|
#endif /* CONFIG_PM */
|
||||||
|
|
|
@ -589,6 +589,9 @@ struct hid_usage_id {
|
||||||
* @report_fixup: called before report descriptor parsing (NULL means nop)
|
* @report_fixup: called before report descriptor parsing (NULL means nop)
|
||||||
* @input_mapping: invoked on input registering before mapping an usage
|
* @input_mapping: invoked on input registering before mapping an usage
|
||||||
* @input_mapped: invoked on input registering after mapping an usage
|
* @input_mapped: invoked on input registering after mapping an usage
|
||||||
|
* @suspend: invoked on suspend (NULL means nop)
|
||||||
|
* @resume: invoked on resume if device was not reset (NULL means nop)
|
||||||
|
* @reset_resume: invoked on resume if device was reset (NULL means nop)
|
||||||
*
|
*
|
||||||
* raw_event and event should return 0 on no action performed, 1 when no
|
* raw_event and event should return 0 on no action performed, 1 when no
|
||||||
* further processing should be done and negative on error
|
* further processing should be done and negative on error
|
||||||
|
@ -629,6 +632,11 @@ struct hid_driver {
|
||||||
int (*input_mapped)(struct hid_device *hdev,
|
int (*input_mapped)(struct hid_device *hdev,
|
||||||
struct hid_input *hidinput, struct hid_field *field,
|
struct hid_input *hidinput, struct hid_field *field,
|
||||||
struct hid_usage *usage, unsigned long **bit, int *max);
|
struct hid_usage *usage, unsigned long **bit, int *max);
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
int (*suspend)(struct hid_device *hdev, pm_message_t message);
|
||||||
|
int (*resume)(struct hid_device *hdev);
|
||||||
|
int (*reset_resume)(struct hid_device *hdev);
|
||||||
|
#endif
|
||||||
/* private: */
|
/* private: */
|
||||||
struct device_driver driver;
|
struct device_driver driver;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue