Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / nfc / nfcmrvl / usb.c
1 /**
2  * Marvell NFC-over-USB driver: USB interface related functions
3  *
4  * Copyright (C) 2014, Marvell International Ltd.
5  *
6  * This software file (the "File") is distributed by Marvell International
7  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8  * (the "License").  You may use, redistribute and/or modify this File in
9  * accordance with the terms and conditions of the License, a copy of which
10  * is available on the worldwide web at
11  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
12  *
13  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
14  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
15  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
16  * this warranty disclaimer.
17  **/
18
19 #include <linux/module.h>
20 #include <linux/usb.h>
21 #include <linux/nfc.h>
22 #include <net/nfc/nci.h>
23 #include <net/nfc/nci_core.h>
24 #include "nfcmrvl.h"
25
26 #define VERSION "1.0"
27
28 static struct usb_device_id nfcmrvl_table[] = {
29         { USB_DEVICE_INTERFACE_CLASS(0x1286, 0x2046, 0xff) },
30         { }     /* Terminating entry */
31 };
32
33 MODULE_DEVICE_TABLE(usb, nfcmrvl_table);
34
35 #define NFCMRVL_USB_BULK_RUNNING        1
36 #define NFCMRVL_USB_SUSPENDING          2
37
38 struct nfcmrvl_usb_drv_data {
39         struct usb_device *udev;
40         struct usb_interface *intf;
41         unsigned long flags;
42         struct work_struct waker;
43         struct usb_anchor tx_anchor;
44         struct usb_anchor bulk_anchor;
45         struct usb_anchor deferred;
46         int tx_in_flight;
47         /* protects tx_in_flight */
48         spinlock_t txlock;
49         struct usb_endpoint_descriptor *bulk_tx_ep;
50         struct usb_endpoint_descriptor *bulk_rx_ep;
51         int suspend_count;
52         struct nfcmrvl_private *priv;
53 };
54
55 static int nfcmrvl_inc_tx(struct nfcmrvl_usb_drv_data *drv_data)
56 {
57         unsigned long flags;
58         int rv;
59
60         spin_lock_irqsave(&drv_data->txlock, flags);
61         rv = test_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags);
62         if (!rv)
63                 drv_data->tx_in_flight++;
64         spin_unlock_irqrestore(&drv_data->txlock, flags);
65
66         return rv;
67 }
68
69 static void nfcmrvl_bulk_complete(struct urb *urb)
70 {
71         struct nfcmrvl_usb_drv_data *drv_data = urb->context;
72         int err;
73
74         dev_dbg(&drv_data->udev->dev, "urb %p status %d count %d",
75                 urb, urb->status, urb->actual_length);
76
77         if (!test_bit(NFCMRVL_NCI_RUNNING, &drv_data->flags))
78                 return;
79
80         if (!urb->status) {
81                 if (nfcmrvl_nci_recv_frame(drv_data->priv, urb->transfer_buffer,
82                                            urb->actual_length) < 0)
83                         nfc_err(&drv_data->udev->dev, "corrupted Rx packet\n");
84         }
85
86         if (!test_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags))
87                 return;
88
89         usb_anchor_urb(urb, &drv_data->bulk_anchor);
90         usb_mark_last_busy(drv_data->udev);
91
92         err = usb_submit_urb(urb, GFP_ATOMIC);
93         if (err) {
94                 /* -EPERM: urb is being killed;
95                  * -ENODEV: device got disconnected
96                  */
97                 if (err != -EPERM && err != -ENODEV)
98                         nfc_err(&drv_data->udev->dev,
99                                 "urb %p failed to resubmit (%d)\n", urb, -err);
100                 usb_unanchor_urb(urb);
101         }
102 }
103
104 static int
105 nfcmrvl_submit_bulk_urb(struct nfcmrvl_usb_drv_data *drv_data, gfp_t mem_flags)
106 {
107         struct urb *urb;
108         unsigned char *buf;
109         unsigned int pipe;
110         int err, size = NFCMRVL_NCI_MAX_EVENT_SIZE;
111
112         if (!drv_data->bulk_rx_ep)
113                 return -ENODEV;
114
115         urb = usb_alloc_urb(0, mem_flags);
116         if (!urb)
117                 return -ENOMEM;
118
119         buf = kmalloc(size, mem_flags);
120         if (!buf) {
121                 usb_free_urb(urb);
122                 return -ENOMEM;
123         }
124
125         pipe = usb_rcvbulkpipe(drv_data->udev,
126                                drv_data->bulk_rx_ep->bEndpointAddress);
127
128         usb_fill_bulk_urb(urb, drv_data->udev, pipe, buf, size,
129                           nfcmrvl_bulk_complete, drv_data);
130
131         urb->transfer_flags |= URB_FREE_BUFFER;
132
133         usb_mark_last_busy(drv_data->udev);
134         usb_anchor_urb(urb, &drv_data->bulk_anchor);
135
136         err = usb_submit_urb(urb, mem_flags);
137         if (err) {
138                 if (err != -EPERM && err != -ENODEV)
139                         nfc_err(&drv_data->udev->dev,
140                                 "urb %p submission failed (%d)\n", urb, -err);
141                 usb_unanchor_urb(urb);
142         }
143
144         usb_free_urb(urb);
145
146         return err;
147 }
148
149 static void nfcmrvl_tx_complete(struct urb *urb)
150 {
151         struct sk_buff *skb = urb->context;
152         struct nci_dev *ndev = (struct nci_dev *)skb->dev;
153         struct nfcmrvl_private *priv = nci_get_drvdata(ndev);
154         struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data;
155
156         nfc_info(priv->dev, "urb %p status %d count %d\n",
157                  urb, urb->status, urb->actual_length);
158
159         spin_lock(&drv_data->txlock);
160         drv_data->tx_in_flight--;
161         spin_unlock(&drv_data->txlock);
162
163         kfree(urb->setup_packet);
164         kfree_skb(skb);
165 }
166
167 static int nfcmrvl_usb_nci_open(struct nfcmrvl_private *priv)
168 {
169         struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data;
170         int err;
171
172         err = usb_autopm_get_interface(drv_data->intf);
173         if (err)
174                 return err;
175
176         drv_data->intf->needs_remote_wakeup = 1;
177
178         err = nfcmrvl_submit_bulk_urb(drv_data, GFP_KERNEL);
179         if (err)
180                 goto failed;
181
182         set_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags);
183         nfcmrvl_submit_bulk_urb(drv_data, GFP_KERNEL);
184
185         usb_autopm_put_interface(drv_data->intf);
186         return 0;
187
188 failed:
189         usb_autopm_put_interface(drv_data->intf);
190         return err;
191 }
192
193 static void nfcmrvl_usb_stop_traffic(struct nfcmrvl_usb_drv_data *drv_data)
194 {
195         usb_kill_anchored_urbs(&drv_data->bulk_anchor);
196 }
197
198 static int nfcmrvl_usb_nci_close(struct nfcmrvl_private *priv)
199 {
200         struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data;
201         int err;
202
203         cancel_work_sync(&drv_data->waker);
204
205         clear_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags);
206
207         nfcmrvl_usb_stop_traffic(drv_data);
208         usb_kill_anchored_urbs(&drv_data->tx_anchor);
209         err = usb_autopm_get_interface(drv_data->intf);
210         if (err)
211                 goto failed;
212
213         drv_data->intf->needs_remote_wakeup = 0;
214         usb_autopm_put_interface(drv_data->intf);
215
216 failed:
217         usb_scuttle_anchored_urbs(&drv_data->deferred);
218         return 0;
219 }
220
221 static int nfcmrvl_usb_nci_send(struct nfcmrvl_private *priv,
222                                 struct sk_buff *skb)
223 {
224         struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data;
225         struct urb *urb;
226         unsigned int pipe;
227         int err;
228
229         if (!drv_data->bulk_tx_ep)
230                 return -ENODEV;
231
232         urb = usb_alloc_urb(0, GFP_ATOMIC);
233         if (!urb)
234                 return -ENOMEM;
235
236         pipe = usb_sndbulkpipe(drv_data->udev,
237                                 drv_data->bulk_tx_ep->bEndpointAddress);
238
239         usb_fill_bulk_urb(urb, drv_data->udev, pipe, skb->data, skb->len,
240                           nfcmrvl_tx_complete, skb);
241
242         err = nfcmrvl_inc_tx(drv_data);
243         if (err) {
244                 usb_anchor_urb(urb, &drv_data->deferred);
245                 schedule_work(&drv_data->waker);
246                 err = 0;
247                 goto done;
248         }
249
250         usb_anchor_urb(urb, &drv_data->tx_anchor);
251
252         err = usb_submit_urb(urb, GFP_ATOMIC);
253         if (err) {
254                 if (err != -EPERM && err != -ENODEV)
255                         nfc_err(&drv_data->udev->dev,
256                                 "urb %p submission failed (%d)\n", urb, -err);
257                 kfree(urb->setup_packet);
258                 usb_unanchor_urb(urb);
259         } else {
260                 usb_mark_last_busy(drv_data->udev);
261         }
262
263 done:
264         usb_free_urb(urb);
265         return err;
266 }
267
268 static struct nfcmrvl_if_ops usb_ops = {
269         .nci_open = nfcmrvl_usb_nci_open,
270         .nci_close = nfcmrvl_usb_nci_close,
271         .nci_send = nfcmrvl_usb_nci_send,
272 };
273
274 static void nfcmrvl_waker(struct work_struct *work)
275 {
276         struct nfcmrvl_usb_drv_data *drv_data =
277                         container_of(work, struct nfcmrvl_usb_drv_data, waker);
278         int err;
279
280         err = usb_autopm_get_interface(drv_data->intf);
281         if (err)
282                 return;
283
284         usb_autopm_put_interface(drv_data->intf);
285 }
286
287 static int nfcmrvl_probe(struct usb_interface *intf,
288                          const struct usb_device_id *id)
289 {
290         struct usb_endpoint_descriptor *ep_desc;
291         struct nfcmrvl_usb_drv_data *drv_data;
292         struct nfcmrvl_private *priv;
293         int i;
294         struct usb_device *udev = interface_to_usbdev(intf);
295
296         nfc_info(&udev->dev, "intf %p id %p\n", intf, id);
297
298         drv_data = devm_kzalloc(&intf->dev, sizeof(*drv_data), GFP_KERNEL);
299         if (!drv_data)
300                 return -ENOMEM;
301
302         for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
303                 ep_desc = &intf->cur_altsetting->endpoint[i].desc;
304
305                 if (!drv_data->bulk_tx_ep &&
306                     usb_endpoint_is_bulk_out(ep_desc)) {
307                         drv_data->bulk_tx_ep = ep_desc;
308                         continue;
309                 }
310
311                 if (!drv_data->bulk_rx_ep &&
312                     usb_endpoint_is_bulk_in(ep_desc)) {
313                         drv_data->bulk_rx_ep = ep_desc;
314                         continue;
315                 }
316         }
317
318         if (!drv_data->bulk_tx_ep || !drv_data->bulk_rx_ep)
319                 return -ENODEV;
320
321         drv_data->udev = udev;
322         drv_data->intf = intf;
323
324         INIT_WORK(&drv_data->waker, nfcmrvl_waker);
325         spin_lock_init(&drv_data->txlock);
326
327         init_usb_anchor(&drv_data->tx_anchor);
328         init_usb_anchor(&drv_data->bulk_anchor);
329         init_usb_anchor(&drv_data->deferred);
330
331         priv = nfcmrvl_nci_register_dev(drv_data, &usb_ops,
332                                         &drv_data->udev->dev);
333         if (IS_ERR(priv))
334                 return PTR_ERR(priv);
335
336         drv_data->priv = priv;
337         priv->dev = &drv_data->udev->dev;
338
339         usb_set_intfdata(intf, drv_data);
340
341         return 0;
342 }
343
344 static void nfcmrvl_disconnect(struct usb_interface *intf)
345 {
346         struct nfcmrvl_usb_drv_data *drv_data = usb_get_intfdata(intf);
347
348         if (!drv_data)
349                 return;
350
351         nfc_info(&drv_data->udev->dev, "intf %p\n", intf);
352
353         nfcmrvl_nci_unregister_dev(drv_data->priv);
354
355         usb_set_intfdata(drv_data->intf, NULL);
356 }
357
358 #ifdef CONFIG_PM
359 static int nfcmrvl_suspend(struct usb_interface *intf, pm_message_t message)
360 {
361         struct nfcmrvl_usb_drv_data *drv_data = usb_get_intfdata(intf);
362
363         nfc_info(&drv_data->udev->dev, "intf %p\n", intf);
364
365         if (drv_data->suspend_count++)
366                 return 0;
367
368         spin_lock_irq(&drv_data->txlock);
369         if (!(PMSG_IS_AUTO(message) && drv_data->tx_in_flight)) {
370                 set_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags);
371                 spin_unlock_irq(&drv_data->txlock);
372         } else {
373                 spin_unlock_irq(&drv_data->txlock);
374                 drv_data->suspend_count--;
375                 return -EBUSY;
376         }
377
378         nfcmrvl_usb_stop_traffic(drv_data);
379         usb_kill_anchored_urbs(&drv_data->tx_anchor);
380
381         return 0;
382 }
383
384 static void nfcmrvl_play_deferred(struct nfcmrvl_usb_drv_data *drv_data)
385 {
386         struct urb *urb;
387         int err;
388
389         while ((urb = usb_get_from_anchor(&drv_data->deferred))) {
390                 err = usb_submit_urb(urb, GFP_ATOMIC);
391                 if (err)
392                         break;
393
394                 drv_data->tx_in_flight++;
395         }
396         usb_scuttle_anchored_urbs(&drv_data->deferred);
397 }
398
399 static int nfcmrvl_resume(struct usb_interface *intf)
400 {
401         struct nfcmrvl_usb_drv_data *drv_data = usb_get_intfdata(intf);
402         int err = 0;
403
404         nfc_info(&drv_data->udev->dev, "intf %p\n", intf);
405
406         if (--drv_data->suspend_count)
407                 return 0;
408
409         if (!test_bit(NFCMRVL_NCI_RUNNING, &drv_data->flags))
410                 goto done;
411
412         if (test_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags)) {
413                 err = nfcmrvl_submit_bulk_urb(drv_data, GFP_NOIO);
414                 if (err) {
415                         clear_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags);
416                         goto failed;
417                 }
418
419                 nfcmrvl_submit_bulk_urb(drv_data, GFP_NOIO);
420         }
421
422         spin_lock_irq(&drv_data->txlock);
423         nfcmrvl_play_deferred(drv_data);
424         clear_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags);
425         spin_unlock_irq(&drv_data->txlock);
426
427         return 0;
428
429 failed:
430         usb_scuttle_anchored_urbs(&drv_data->deferred);
431 done:
432         spin_lock_irq(&drv_data->txlock);
433         clear_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags);
434         spin_unlock_irq(&drv_data->txlock);
435
436         return err;
437 }
438 #endif
439
440 static struct usb_driver nfcmrvl_usb_driver = {
441         .name           = "nfcmrvl",
442         .probe          = nfcmrvl_probe,
443         .disconnect     = nfcmrvl_disconnect,
444 #ifdef CONFIG_PM
445         .suspend        = nfcmrvl_suspend,
446         .resume         = nfcmrvl_resume,
447         .reset_resume   = nfcmrvl_resume,
448 #endif
449         .id_table       = nfcmrvl_table,
450         .supports_autosuspend = 1,
451         .disable_hub_initiated_lpm = 1,
452         .soft_unbind = 1,
453 };
454 module_usb_driver(nfcmrvl_usb_driver);
455
456 MODULE_AUTHOR("Marvell International Ltd.");
457 MODULE_DESCRIPTION("Marvell NFC-over-USB driver ver " VERSION);
458 MODULE_VERSION(VERSION);
459 MODULE_LICENSE("GPL v2");