diff options
-rw-r--r-- | drivers/usb/storage/onetouch.c | 27 | ||||
-rw-r--r-- | drivers/usb/storage/usb.c | 4 | ||||
-rw-r--r-- | drivers/usb/storage/usb.h | 9 |
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 | ||
57 | static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs) | 58 | static 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 | ||
112 | static 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 | |||
108 | int onetouch_connect_input(struct us_data *ss) | 132 | int 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 { | |||
93 | typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*); | 93 | typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*); |
94 | typedef int (*trans_reset)(struct us_data*); | 94 | typedef int (*trans_reset)(struct us_data*); |
95 | typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*); | 95 | typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*); |
96 | typedef void (*extra_data_destructor)(void *); /* extra data destructor */ | 96 | typedef void (*extra_data_destructor)(void *); /* extra data destructor */ |
97 | typedef 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 */ |
99 | struct us_data { | 103 | struct 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 */ |