aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/storage/onetouch.c27
-rw-r--r--drivers/usb/storage/usb.c4
-rw-r--r--drivers/usb/storage/usb.h9
3 files changed, 39 insertions, 1 deletions
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
index 89401a59f952..55ee2d36d585 100644
--- a/drivers/usb/storage/onetouch.c
+++ b/drivers/usb/storage/onetouch.c
@@ -52,6 +52,7 @@ struct usb_onetouch {
52 struct urb *irq; /* urb for interrupt in report */ 52 struct urb *irq; /* urb for interrupt in report */
53 unsigned char *data; /* input data */ 53 unsigned char *data; /* input data */
54 dma_addr_t data_dma; 54 dma_addr_t data_dma;
55 unsigned int is_open:1;
55}; 56};
56 57
57static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs) 58static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs)
@@ -89,6 +90,7 @@ static int usb_onetouch_open(struct input_dev *dev)
89{ 90{
90 struct usb_onetouch *onetouch = dev->private; 91 struct usb_onetouch *onetouch = dev->private;
91 92
93 onetouch->is_open = 1;
92 onetouch->irq->dev = onetouch->udev; 94 onetouch->irq->dev = onetouch->udev;
93 if (usb_submit_urb(onetouch->irq, GFP_KERNEL)) { 95 if (usb_submit_urb(onetouch->irq, GFP_KERNEL)) {
94 err("usb_submit_urb failed"); 96 err("usb_submit_urb failed");
@@ -103,8 +105,30 @@ static void usb_onetouch_close(struct input_dev *dev)
103 struct usb_onetouch *onetouch = dev->private; 105 struct usb_onetouch *onetouch = dev->private;
104 106
105 usb_kill_urb(onetouch->irq); 107 usb_kill_urb(onetouch->irq);
108 onetouch->is_open = 0;
106} 109}
107 110
111#ifdef CONFIG_PM
112static void usb_onetouch_pm_hook(struct us_data *us, int action)
113{
114 struct usb_onetouch *onetouch = (struct usb_onetouch *) us->extra;
115
116 if (onetouch->is_open) {
117 switch (action) {
118 case US_SUSPEND:
119 usb_kill_urb(onetouch->irq);
120 break;
121 case US_RESUME:
122 if (usb_submit_urb(onetouch->irq, GFP_KERNEL) != 0)
123 err("usb_submit_urb failed");
124 break;
125 default:
126 break;
127 }
128 }
129}
130#endif /* CONFIG_PM */
131
108int onetouch_connect_input(struct us_data *ss) 132int onetouch_connect_input(struct us_data *ss)
109{ 133{
110 struct usb_device *udev = ss->pusb_dev; 134 struct usb_device *udev = ss->pusb_dev;
@@ -185,6 +209,9 @@ int onetouch_connect_input(struct us_data *ss)
185 209
186 ss->extra_destructor = onetouch_release_input; 210 ss->extra_destructor = onetouch_release_input;
187 ss->extra = onetouch; 211 ss->extra = onetouch;
212#ifdef CONFIG_PM
213 ss->suspend_resume_hook = usb_onetouch_pm_hook;
214#endif
188 215
189 input_register_device(onetouch->dev); 216 input_register_device(onetouch->dev);
190 217
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 356f471ba83b..ca02ae97be86 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -188,6 +188,8 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message)
188 down(&us->dev_semaphore); 188 down(&us->dev_semaphore);
189 189
190 US_DEBUGP("%s\n", __FUNCTION__); 190 US_DEBUGP("%s\n", __FUNCTION__);
191 if (us->suspend_resume_hook)
192 (us->suspend_resume_hook)(us, US_SUSPEND);
191 iface->dev.power.power_state.event = message.event; 193 iface->dev.power.power_state.event = message.event;
192 194
193 /* When runtime PM is working, we'll set a flag to indicate 195 /* When runtime PM is working, we'll set a flag to indicate
@@ -204,6 +206,8 @@ static int storage_resume(struct usb_interface *iface)
204 down(&us->dev_semaphore); 206 down(&us->dev_semaphore);
205 207
206 US_DEBUGP("%s\n", __FUNCTION__); 208 US_DEBUGP("%s\n", __FUNCTION__);
209 if (us->suspend_resume_hook)
210 (us->suspend_resume_hook)(us, US_RESUME);
207 iface->dev.power.power_state.event = PM_EVENT_ON; 211 iface->dev.power.power_state.event = PM_EVENT_ON;
208 212
209 up(&us->dev_semaphore); 213 up(&us->dev_semaphore);
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 0cd1eebc4497..7259fd1f6b0d 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -93,7 +93,11 @@ struct us_unusual_dev {
93typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*); 93typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*);
94typedef int (*trans_reset)(struct us_data*); 94typedef int (*trans_reset)(struct us_data*);
95typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*); 95typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*);
96typedef void (*extra_data_destructor)(void *); /* extra data destructor */ 96typedef void (*extra_data_destructor)(void *); /* extra data destructor */
97typedef void (*pm_hook)(struct us_data *, int); /* power management hook */
98
99#define US_SUSPEND 0
100#define US_RESUME 1
97 101
98/* we allocate one of these for every device that we remember */ 102/* we allocate one of these for every device that we remember */
99struct us_data { 103struct us_data {
@@ -149,6 +153,9 @@ struct us_data {
149 /* subdriver information */ 153 /* subdriver information */
150 void *extra; /* Any extra data */ 154 void *extra; /* Any extra data */
151 extra_data_destructor extra_destructor;/* extra data destructor */ 155 extra_data_destructor extra_destructor;/* extra data destructor */
156#ifdef CONFIG_PM
157 pm_hook suspend_resume_hook;
158#endif
152}; 159};
153 160
154/* Convert between us_data and the corresponding Scsi_Host */ 161/* Convert between us_data and the corresponding Scsi_Host */