Commit ac23b6c4 authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[PATCH] USB: usb suspend support for hid-core

Basic HID driver support for USB suspend/resume.  At least one keyboard
works OK as a remote wakeup source ... unless you write the sysfs
power/state attribute using that USB keyboard, in which case the input
subsystem reports an endless stream of newlines!  :)

Someone still needs to implement some configurable timer to support the
"suspend idle mice/keyboards/..." policy for devices that can issue
wakeup events.  In conjunction with autosuspend policies in hub and
HCD (UHCI) code, that could allegedly save 2W of power by enabling the
C3 state on Centrino laptops that use USB mice.
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent 5cbab4cd
...@@ -925,6 +925,7 @@ static void hid_irq_in(struct urb *urb, struct pt_regs *regs) ...@@ -925,6 +925,7 @@ static void hid_irq_in(struct urb *urb, struct pt_regs *regs)
case -ECONNRESET: /* unlink */ case -ECONNRESET: /* unlink */
case -ENOENT: case -ENOENT:
case -ESHUTDOWN: case -ESHUTDOWN:
case -EPERM:
return; return;
case -ETIMEDOUT: /* NAK */ case -ETIMEDOUT: /* NAK */
break; break;
...@@ -1833,6 +1834,30 @@ static int hid_probe (struct usb_interface *intf, const struct usb_device_id *id ...@@ -1833,6 +1834,30 @@ static int hid_probe (struct usb_interface *intf, const struct usb_device_id *id
return 0; return 0;
} }
static int hid_suspend(struct usb_interface *intf, u32 state)
{
struct hid_device *hid = usb_get_intfdata (intf);
usb_kill_urb(hid->urbin);
intf->dev.power.power_state = state;
dev_dbg(&intf->dev, "suspend\n");
return 0;
}
static int hid_resume(struct usb_interface *intf)
{
struct hid_device *hid = usb_get_intfdata (intf);
int status;
intf->dev.power.power_state = PM_SUSPEND_ON;
if (hid->open)
status = usb_submit_urb(hid->urbin, GFP_NOIO);
else
status = 0;
dev_dbg(&intf->dev, "resume status %d\n", status);
return status;
}
static struct usb_device_id hid_usb_ids [] = { static struct usb_device_id hid_usb_ids [] = {
{ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
.bInterfaceClass = USB_INTERFACE_CLASS_HID }, .bInterfaceClass = USB_INTERFACE_CLASS_HID },
...@@ -1846,6 +1871,8 @@ static struct usb_driver hid_driver = { ...@@ -1846,6 +1871,8 @@ static struct usb_driver hid_driver = {
.name = "usbhid", .name = "usbhid",
.probe = hid_probe, .probe = hid_probe,
.disconnect = hid_disconnect, .disconnect = hid_disconnect,
.suspend = hid_suspend,
.resume = hid_resume,
.id_table = hid_usb_ids, .id_table = hid_usb_ids,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment