Commit 621de593 authored by Jiri Kosina's avatar Jiri Kosina

Merge branch 'autosuspend' into for-next

Conflicts:

	drivers/hid/hid-core.c
parents afa5eb7c 6d779768
...@@ -1819,6 +1819,22 @@ void hid_unregister_driver(struct hid_driver *hdrv) ...@@ -1819,6 +1819,22 @@ void hid_unregister_driver(struct hid_driver *hdrv)
} }
EXPORT_SYMBOL_GPL(hid_unregister_driver); EXPORT_SYMBOL_GPL(hid_unregister_driver);
int hid_check_keys_pressed(struct hid_device *hid)
{
struct hid_input *hidinput;
int i;
list_for_each_entry(hidinput, &hid->inputs, list) {
for (i = 0; i < BITS_TO_LONGS(KEY_MAX); i++)
if (hidinput->input->key[i])
return 1;
}
return 0;
}
EXPORT_SYMBOL_GPL(hid_check_keys_pressed);
static int __init hid_init(void) static int __init hid_init(void)
{ {
int ret; int ret;
......
...@@ -181,9 +181,17 @@ static int hidraw_open(struct inode *inode, struct file *file) ...@@ -181,9 +181,17 @@ static int hidraw_open(struct inode *inode, struct file *file)
dev = hidraw_table[minor]; dev = hidraw_table[minor];
if (!dev->open++) { if (!dev->open++) {
if (dev->hid->ll_driver->power) {
err = dev->hid->ll_driver->power(dev->hid, PM_HINT_FULLON);
if (err < 0)
goto out_unlock;
}
err = dev->hid->ll_driver->open(dev->hid); err = dev->hid->ll_driver->open(dev->hid);
if (err < 0) if (err < 0) {
if (dev->hid->ll_driver->power)
dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL);
dev->open--; dev->open--;
}
} }
out_unlock: out_unlock:
...@@ -209,10 +217,13 @@ static int hidraw_release(struct inode * inode, struct file * file) ...@@ -209,10 +217,13 @@ static int hidraw_release(struct inode * inode, struct file * file)
list_del(&list->node); list_del(&list->node);
dev = hidraw_table[minor]; dev = hidraw_table[minor];
if (!--dev->open) { if (!--dev->open) {
if (list->hidraw->exist) if (list->hidraw->exist) {
if (dev->hid->ll_driver->power)
dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL);
dev->hid->ll_driver->close(dev->hid); dev->hid->ll_driver->close(dev->hid);
else } else {
kfree(list->hidraw); kfree(list->hidraw);
}
} }
kfree(list); kfree(list);
......
This diff is collapsed.
...@@ -246,10 +246,12 @@ static int hiddev_release(struct inode * inode, struct file * file) ...@@ -246,10 +246,12 @@ static int hiddev_release(struct inode * inode, struct file * file)
spin_unlock_irqrestore(&list->hiddev->list_lock, flags); spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
if (!--list->hiddev->open) { if (!--list->hiddev->open) {
if (list->hiddev->exist) if (list->hiddev->exist) {
usbhid_close(list->hiddev->hid); usbhid_close(list->hiddev->hid);
else usbhid_put_power(list->hiddev->hid);
} else {
kfree(list->hiddev); kfree(list->hiddev);
}
} }
kfree(list); kfree(list);
...@@ -300,6 +302,17 @@ static int hiddev_open(struct inode *inode, struct file *file) ...@@ -300,6 +302,17 @@ static int hiddev_open(struct inode *inode, struct file *file)
list_add_tail(&list->node, &hiddev_table[i]->list); list_add_tail(&list->node, &hiddev_table[i]->list);
spin_unlock_irq(&list->hiddev->list_lock); spin_unlock_irq(&list->hiddev->list_lock);
if (!list->hiddev->open++)
if (list->hiddev->exist) {
struct hid_device *hid = hiddev_table[i]->hid;
res = usbhid_get_power(hid);
if (res < 0) {
res = -EIO;
goto bail;
}
usbhid_open(hid);
}
return 0; return 0;
bail: bail:
file->private_data = NULL; file->private_data = NULL;
......
...@@ -38,7 +38,10 @@ int usbhid_wait_io(struct hid_device* hid); ...@@ -38,7 +38,10 @@ int usbhid_wait_io(struct hid_device* hid);
void usbhid_close(struct hid_device *hid); void usbhid_close(struct hid_device *hid);
int usbhid_open(struct hid_device *hid); int usbhid_open(struct hid_device *hid);
void usbhid_init_reports(struct hid_device *hid); void usbhid_init_reports(struct hid_device *hid);
void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir); void usbhid_submit_report
(struct hid_device *hid, struct hid_report *report, unsigned char dir);
int usbhid_get_power(struct hid_device *hid);
void usbhid_put_power(struct hid_device *hid);
/* iofl flags */ /* iofl flags */
#define HID_CTRL_RUNNING 1 #define HID_CTRL_RUNNING 1
...@@ -49,6 +52,9 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns ...@@ -49,6 +52,9 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
#define HID_CLEAR_HALT 6 #define HID_CLEAR_HALT 6
#define HID_DISCONNECTED 7 #define HID_DISCONNECTED 7
#define HID_STARTED 8 #define HID_STARTED 8
#define HID_REPORTED_IDLE 9
#define HID_KEYS_PRESSED 10
#define HID_LED_ON 11
/* /*
* USB-specific HID struct, to be pointed to * USB-specific HID struct, to be pointed to
...@@ -66,7 +72,6 @@ struct usbhid_device { ...@@ -66,7 +72,6 @@ struct usbhid_device {
struct urb *urbin; /* Input URB */ struct urb *urbin; /* Input URB */
char *inbuf; /* Input buffer */ char *inbuf; /* Input buffer */
dma_addr_t inbuf_dma; /* Input buffer dma */ dma_addr_t inbuf_dma; /* Input buffer dma */
spinlock_t inlock; /* Input fifo spinlock */
struct urb *urbctrl; /* Control URB */ struct urb *urbctrl; /* Control URB */
struct usb_ctrlrequest *cr; /* Control request struct */ struct usb_ctrlrequest *cr; /* Control request struct */
...@@ -75,21 +80,22 @@ struct usbhid_device { ...@@ -75,21 +80,22 @@ struct usbhid_device {
unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */ unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */
char *ctrlbuf; /* Control buffer */ char *ctrlbuf; /* Control buffer */
dma_addr_t ctrlbuf_dma; /* Control buffer dma */ dma_addr_t ctrlbuf_dma; /* Control buffer dma */
spinlock_t ctrllock; /* Control fifo spinlock */
struct urb *urbout; /* Output URB */ struct urb *urbout; /* Output URB */
struct hid_output_fifo out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */ struct hid_output_fifo out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */
unsigned char outhead, outtail; /* Output pipe fifo head & tail */ unsigned char outhead, outtail; /* Output pipe fifo head & tail */
char *outbuf; /* Output buffer */ char *outbuf; /* Output buffer */
dma_addr_t outbuf_dma; /* Output buffer dma */ dma_addr_t outbuf_dma; /* Output buffer dma */
spinlock_t outlock; /* Output fifo spinlock */
spinlock_t lock; /* fifo spinlock */
unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
struct timer_list io_retry; /* Retry timer */ struct timer_list io_retry; /* Retry timer */
unsigned long stop_retry; /* Time to give up, in jiffies */ unsigned long stop_retry; /* Time to give up, in jiffies */
unsigned int retry_delay; /* Delay length in ms */ unsigned int retry_delay; /* Delay length in ms */
struct work_struct reset_work; /* Task context for resets */ struct work_struct reset_work; /* Task context for resets */
struct work_struct restart_work; /* waking up for output to be done in a task */
wait_queue_head_t wait; /* For sleeping */ wait_queue_head_t wait; /* For sleeping */
int ledcount; /* counting the number of active leds */
}; };
#define hid_to_usb_dev(hid_dev) \ #define hid_to_usb_dev(hid_dev) \
......
...@@ -604,12 +604,17 @@ struct hid_ll_driver { ...@@ -604,12 +604,17 @@ struct hid_ll_driver {
int (*open)(struct hid_device *hdev); int (*open)(struct hid_device *hdev);
void (*close)(struct hid_device *hdev); void (*close)(struct hid_device *hdev);
int (*power)(struct hid_device *hdev, int level);
int (*hidinput_input_event) (struct input_dev *idev, unsigned int type, int (*hidinput_input_event) (struct input_dev *idev, unsigned int type,
unsigned int code, int value); unsigned int code, int value);
int (*parse)(struct hid_device *hdev); int (*parse)(struct hid_device *hdev);
}; };
#define PM_HINT_FULLON 1<<5
#define PM_HINT_NORMAL 1<<1
/* Applications from HID Usage Tables 4/8/99 Version 1.1 */ /* Applications from HID Usage Tables 4/8/99 Version 1.1 */
/* We ignore a few input applications that are not widely used */ /* We ignore a few input applications that are not widely used */
#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001) || (a == 0x000d0002)) #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001) || (a == 0x000d0002))
...@@ -642,6 +647,7 @@ int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int ...@@ -642,6 +647,7 @@ int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int
void hid_output_report(struct hid_report *report, __u8 *data); void hid_output_report(struct hid_report *report, __u8 *data);
struct hid_device *hid_allocate_device(void); struct hid_device *hid_allocate_device(void);
int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
int hid_check_keys_pressed(struct hid_device *hid);
int hid_connect(struct hid_device *hid, unsigned int connect_mask); int hid_connect(struct hid_device *hid, unsigned int connect_mask);
/** /**
......
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