diff options
Diffstat (limited to 'drivers/usb/misc/ftdi-elan.c')
-rw-r--r-- | drivers/usb/misc/ftdi-elan.c | 106 |
1 files changed, 31 insertions, 75 deletions
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index 9b591b8b9369..18b1925032a8 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c | |||
@@ -156,9 +156,9 @@ struct usb_ftdi { | |||
156 | struct usb_device *udev; | 156 | struct usb_device *udev; |
157 | struct usb_interface *interface; | 157 | struct usb_interface *interface; |
158 | struct usb_class_driver *class; | 158 | struct usb_class_driver *class; |
159 | struct work_struct status_work; | 159 | struct delayed_work status_work; |
160 | struct work_struct command_work; | 160 | struct delayed_work command_work; |
161 | struct work_struct respond_work; | 161 | struct delayed_work respond_work; |
162 | struct u132_platform_data platform_data; | 162 | struct u132_platform_data platform_data; |
163 | struct resource resources[0]; | 163 | struct resource resources[0]; |
164 | struct platform_device platform_dev; | 164 | struct platform_device platform_dev; |
@@ -210,23 +210,14 @@ static void ftdi_elan_init_kref(struct usb_ftdi *ftdi) | |||
210 | 210 | ||
211 | static void ftdi_status_requeue_work(struct usb_ftdi *ftdi, unsigned int delta) | 211 | static void ftdi_status_requeue_work(struct usb_ftdi *ftdi, unsigned int delta) |
212 | { | 212 | { |
213 | if (delta > 0) { | 213 | if (!queue_delayed_work(status_queue, &ftdi->status_work, delta)) |
214 | if (queue_delayed_work(status_queue, &ftdi->status_work, delta)) | 214 | kref_put(&ftdi->kref, ftdi_elan_delete); |
215 | return; | ||
216 | } else if (queue_work(status_queue, &ftdi->status_work)) | ||
217 | return; | ||
218 | kref_put(&ftdi->kref, ftdi_elan_delete); | ||
219 | return; | ||
220 | } | 215 | } |
221 | 216 | ||
222 | static void ftdi_status_queue_work(struct usb_ftdi *ftdi, unsigned int delta) | 217 | static void ftdi_status_queue_work(struct usb_ftdi *ftdi, unsigned int delta) |
223 | { | 218 | { |
224 | if (delta > 0) { | 219 | if (queue_delayed_work(status_queue, &ftdi->status_work, delta)) |
225 | if (queue_delayed_work(status_queue, &ftdi->status_work, delta)) | 220 | kref_get(&ftdi->kref); |
226 | kref_get(&ftdi->kref); | ||
227 | } else if (queue_work(status_queue, &ftdi->status_work)) | ||
228 | kref_get(&ftdi->kref); | ||
229 | return; | ||
230 | } | 221 | } |
231 | 222 | ||
232 | static void ftdi_status_cancel_work(struct usb_ftdi *ftdi) | 223 | static void ftdi_status_cancel_work(struct usb_ftdi *ftdi) |
@@ -237,25 +228,14 @@ static void ftdi_status_cancel_work(struct usb_ftdi *ftdi) | |||
237 | 228 | ||
238 | static void ftdi_command_requeue_work(struct usb_ftdi *ftdi, unsigned int delta) | 229 | static void ftdi_command_requeue_work(struct usb_ftdi *ftdi, unsigned int delta) |
239 | { | 230 | { |
240 | if (delta > 0) { | 231 | if (!queue_delayed_work(command_queue, &ftdi->command_work, delta)) |
241 | if (queue_delayed_work(command_queue, &ftdi->command_work, | 232 | kref_put(&ftdi->kref, ftdi_elan_delete); |
242 | delta)) | ||
243 | return; | ||
244 | } else if (queue_work(command_queue, &ftdi->command_work)) | ||
245 | return; | ||
246 | kref_put(&ftdi->kref, ftdi_elan_delete); | ||
247 | return; | ||
248 | } | 233 | } |
249 | 234 | ||
250 | static void ftdi_command_queue_work(struct usb_ftdi *ftdi, unsigned int delta) | 235 | static void ftdi_command_queue_work(struct usb_ftdi *ftdi, unsigned int delta) |
251 | { | 236 | { |
252 | if (delta > 0) { | 237 | if (queue_delayed_work(command_queue, &ftdi->command_work, delta)) |
253 | if (queue_delayed_work(command_queue, &ftdi->command_work, | 238 | kref_get(&ftdi->kref); |
254 | delta)) | ||
255 | kref_get(&ftdi->kref); | ||
256 | } else if (queue_work(command_queue, &ftdi->command_work)) | ||
257 | kref_get(&ftdi->kref); | ||
258 | return; | ||
259 | } | 239 | } |
260 | 240 | ||
261 | static void ftdi_command_cancel_work(struct usb_ftdi *ftdi) | 241 | static void ftdi_command_cancel_work(struct usb_ftdi *ftdi) |
@@ -267,25 +247,14 @@ static void ftdi_command_cancel_work(struct usb_ftdi *ftdi) | |||
267 | static void ftdi_response_requeue_work(struct usb_ftdi *ftdi, | 247 | static void ftdi_response_requeue_work(struct usb_ftdi *ftdi, |
268 | unsigned int delta) | 248 | unsigned int delta) |
269 | { | 249 | { |
270 | if (delta > 0) { | 250 | if (!queue_delayed_work(respond_queue, &ftdi->respond_work, delta)) |
271 | if (queue_delayed_work(respond_queue, &ftdi->respond_work, | 251 | kref_put(&ftdi->kref, ftdi_elan_delete); |
272 | delta)) | ||
273 | return; | ||
274 | } else if (queue_work(respond_queue, &ftdi->respond_work)) | ||
275 | return; | ||
276 | kref_put(&ftdi->kref, ftdi_elan_delete); | ||
277 | return; | ||
278 | } | 252 | } |
279 | 253 | ||
280 | static void ftdi_respond_queue_work(struct usb_ftdi *ftdi, unsigned int delta) | 254 | static void ftdi_respond_queue_work(struct usb_ftdi *ftdi, unsigned int delta) |
281 | { | 255 | { |
282 | if (delta > 0) { | 256 | if (queue_delayed_work(respond_queue, &ftdi->respond_work, delta)) |
283 | if (queue_delayed_work(respond_queue, &ftdi->respond_work, | 257 | kref_get(&ftdi->kref); |
284 | delta)) | ||
285 | kref_get(&ftdi->kref); | ||
286 | } else if (queue_work(respond_queue, &ftdi->respond_work)) | ||
287 | kref_get(&ftdi->kref); | ||
288 | return; | ||
289 | } | 258 | } |
290 | 259 | ||
291 | static void ftdi_response_cancel_work(struct usb_ftdi *ftdi) | 260 | static void ftdi_response_cancel_work(struct usb_ftdi *ftdi) |
@@ -303,7 +272,7 @@ void ftdi_elan_gone_away(struct platform_device *pdev) | |||
303 | 272 | ||
304 | 273 | ||
305 | EXPORT_SYMBOL_GPL(ftdi_elan_gone_away); | 274 | EXPORT_SYMBOL_GPL(ftdi_elan_gone_away); |
306 | void ftdi_release_platform_dev(struct device *dev) | 275 | static void ftdi_release_platform_dev(struct device *dev) |
307 | { | 276 | { |
308 | dev->parent = NULL; | 277 | dev->parent = NULL; |
309 | } | 278 | } |
@@ -475,9 +444,11 @@ static void ftdi_elan_kick_command_queue(struct usb_ftdi *ftdi) | |||
475 | return; | 444 | return; |
476 | } | 445 | } |
477 | 446 | ||
478 | static void ftdi_elan_command_work(void *data) | 447 | static void ftdi_elan_command_work(struct work_struct *work) |
479 | { | 448 | { |
480 | struct usb_ftdi *ftdi = data; | 449 | struct usb_ftdi *ftdi = |
450 | container_of(work, struct usb_ftdi, command_work.work); | ||
451 | |||
481 | if (ftdi->disconnected > 0) { | 452 | if (ftdi->disconnected > 0) { |
482 | ftdi_elan_put_kref(ftdi); | 453 | ftdi_elan_put_kref(ftdi); |
483 | return; | 454 | return; |
@@ -500,9 +471,10 @@ static void ftdi_elan_kick_respond_queue(struct usb_ftdi *ftdi) | |||
500 | return; | 471 | return; |
501 | } | 472 | } |
502 | 473 | ||
503 | static void ftdi_elan_respond_work(void *data) | 474 | static void ftdi_elan_respond_work(struct work_struct *work) |
504 | { | 475 | { |
505 | struct usb_ftdi *ftdi = data; | 476 | struct usb_ftdi *ftdi = |
477 | container_of(work, struct usb_ftdi, respond_work.work); | ||
506 | if (ftdi->disconnected > 0) { | 478 | if (ftdi->disconnected > 0) { |
507 | ftdi_elan_put_kref(ftdi); | 479 | ftdi_elan_put_kref(ftdi); |
508 | return; | 480 | return; |
@@ -534,9 +506,10 @@ static void ftdi_elan_respond_work(void *data) | |||
534 | * after the FTDI has been synchronized | 506 | * after the FTDI has been synchronized |
535 | * | 507 | * |
536 | */ | 508 | */ |
537 | static void ftdi_elan_status_work(void *data) | 509 | static void ftdi_elan_status_work(struct work_struct *work) |
538 | { | 510 | { |
539 | struct usb_ftdi *ftdi = data; | 511 | struct usb_ftdi *ftdi = |
512 | container_of(work, struct usb_ftdi, status_work.work); | ||
540 | int work_delay_in_msec = 0; | 513 | int work_delay_in_msec = 0; |
541 | if (ftdi->disconnected > 0) { | 514 | if (ftdi->disconnected > 0) { |
542 | ftdi_elan_put_kref(ftdi); | 515 | ftdi_elan_put_kref(ftdi); |
@@ -1426,14 +1399,6 @@ static int ftdi_elan_read_reg(struct usb_ftdi *ftdi, u32 *data) | |||
1426 | } | 1399 | } |
1427 | } | 1400 | } |
1428 | 1401 | ||
1429 | int usb_ftdi_elan_read_reg(struct platform_device *pdev, u32 *data) | ||
1430 | { | ||
1431 | struct usb_ftdi *ftdi = platform_device_to_usb_ftdi(pdev); | ||
1432 | return ftdi_elan_read_reg(ftdi, data); | ||
1433 | } | ||
1434 | |||
1435 | |||
1436 | EXPORT_SYMBOL_GPL(usb_ftdi_elan_read_reg); | ||
1437 | static int ftdi_elan_read_config(struct usb_ftdi *ftdi, int config_offset, | 1402 | static int ftdi_elan_read_config(struct usb_ftdi *ftdi, int config_offset, |
1438 | u8 width, u32 *data) | 1403 | u8 width, u32 *data) |
1439 | { | 1404 | { |
@@ -2633,10 +2598,7 @@ static int ftdi_elan_probe(struct usb_interface *interface, | |||
2633 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { | 2598 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { |
2634 | endpoint = &iface_desc->endpoint[i].desc; | 2599 | endpoint = &iface_desc->endpoint[i].desc; |
2635 | if (!ftdi->bulk_in_endpointAddr && | 2600 | if (!ftdi->bulk_in_endpointAddr && |
2636 | ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 2601 | usb_endpoint_is_bulk_in(endpoint)) { |
2637 | == USB_DIR_IN) && ((endpoint->bmAttributes & | ||
2638 | USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) | ||
2639 | { | ||
2640 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); | 2602 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); |
2641 | ftdi->bulk_in_size = buffer_size; | 2603 | ftdi->bulk_in_size = buffer_size; |
2642 | ftdi->bulk_in_endpointAddr = endpoint->bEndpointAddress; | 2604 | ftdi->bulk_in_endpointAddr = endpoint->bEndpointAddress; |
@@ -2649,10 +2611,7 @@ static int ftdi_elan_probe(struct usb_interface *interface, | |||
2649 | } | 2611 | } |
2650 | } | 2612 | } |
2651 | if (!ftdi->bulk_out_endpointAddr && | 2613 | if (!ftdi->bulk_out_endpointAddr && |
2652 | ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 2614 | usb_endpoint_is_bulk_out(endpoint)) { |
2653 | == USB_DIR_OUT) && ((endpoint->bmAttributes & | ||
2654 | USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) | ||
2655 | { | ||
2656 | ftdi->bulk_out_endpointAddr = | 2615 | ftdi->bulk_out_endpointAddr = |
2657 | endpoint->bEndpointAddress; | 2616 | endpoint->bEndpointAddress; |
2658 | } | 2617 | } |
@@ -2691,12 +2650,9 @@ static int ftdi_elan_probe(struct usb_interface *interface, | |||
2691 | ftdi->class = NULL; | 2650 | ftdi->class = NULL; |
2692 | dev_info(&ftdi->udev->dev, "USB FDTI=%p ELAN interface %d now a" | 2651 | dev_info(&ftdi->udev->dev, "USB FDTI=%p ELAN interface %d now a" |
2693 | "ctivated\n", ftdi, iface_desc->desc.bInterfaceNumber); | 2652 | "ctivated\n", ftdi, iface_desc->desc.bInterfaceNumber); |
2694 | INIT_WORK(&ftdi->status_work, ftdi_elan_status_work, | 2653 | INIT_DELAYED_WORK(&ftdi->status_work, ftdi_elan_status_work); |
2695 | (void *)ftdi); | 2654 | INIT_DELAYED_WORK(&ftdi->command_work, ftdi_elan_command_work); |
2696 | INIT_WORK(&ftdi->command_work, ftdi_elan_command_work, | 2655 | INIT_DELAYED_WORK(&ftdi->respond_work, ftdi_elan_respond_work); |
2697 | (void *)ftdi); | ||
2698 | INIT_WORK(&ftdi->respond_work, ftdi_elan_respond_work, | ||
2699 | (void *)ftdi); | ||
2700 | ftdi_status_queue_work(ftdi, msecs_to_jiffies(3 *1000)); | 2656 | ftdi_status_queue_work(ftdi, msecs_to_jiffies(3 *1000)); |
2701 | return 0; | 2657 | return 0; |
2702 | } else { | 2658 | } else { |