1
2
3
4
5
6
7
8#include <linux/kernel.h>
9#include <linux/module.h>
10#include <linux/init.h>
11#include <linux/pci.h>
12#include <linux/interrupt.h>
13#include <linux/platform_device.h>
14#include <linux/usb.h>
15
16#include <linux/time.h>
17#include <linux/delay.h>
18
19#include <asm/octeon/cvmx.h>
20#include "cvmx-usb.h"
21#include <asm/octeon/cvmx-iob-defs.h>
22
23#include <linux/usb/hcd.h>
24
25#include <linux/err.h>
26
27struct octeon_hcd {
28 spinlock_t lock;
29 cvmx_usb_state_t usb;
30 struct tasklet_struct dequeue_tasklet;
31 struct list_head dequeue_list;
32};
33
34
35static inline struct octeon_hcd *hcd_to_octeon(struct usb_hcd *hcd)
36{
37 return (struct octeon_hcd *)(hcd->hcd_priv);
38}
39
40static inline struct usb_hcd *octeon_to_hcd(struct octeon_hcd *p)
41{
42 return container_of((void *)p, struct usb_hcd, hcd_priv);
43}
44
45static inline struct octeon_hcd *cvmx_usb_to_octeon(cvmx_usb_state_t *p)
46{
47 return container_of(p, struct octeon_hcd, usb);
48}
49
50static irqreturn_t octeon_usb_irq(struct usb_hcd *hcd)
51{
52 struct octeon_hcd *priv = hcd_to_octeon(hcd);
53 unsigned long flags;
54
55 spin_lock_irqsave(&priv->lock, flags);
56 cvmx_usb_poll(&priv->usb);
57 spin_unlock_irqrestore(&priv->lock, flags);
58 return IRQ_HANDLED;
59}
60
61static void octeon_usb_port_callback(cvmx_usb_state_t *usb,
62 cvmx_usb_callback_t reason,
63 cvmx_usb_complete_t status,
64 int pipe_handle,
65 int submit_handle,
66 int bytes_transferred,
67 void *user_data)
68{
69 struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
70
71 spin_unlock(&priv->lock);
72 usb_hcd_poll_rh_status(octeon_to_hcd(priv));
73 spin_lock(&priv->lock);
74}
75
76static int octeon_usb_start(struct usb_hcd *hcd)
77{
78 struct octeon_hcd *priv = hcd_to_octeon(hcd);
79 unsigned long flags;
80
81 hcd->state = HC_STATE_RUNNING;
82 spin_lock_irqsave(&priv->lock, flags);
83 cvmx_usb_register_callback(&priv->usb, CVMX_USB_CALLBACK_PORT_CHANGED,
84 octeon_usb_port_callback, NULL);
85 spin_unlock_irqrestore(&priv->lock, flags);
86 return 0;
87}
88
89static void octeon_usb_stop(struct usb_hcd *hcd)
90{
91 struct octeon_hcd *priv = hcd_to_octeon(hcd);
92 unsigned long flags;
93
94 spin_lock_irqsave(&priv->lock, flags);
95 cvmx_usb_register_callback(&priv->usb, CVMX_USB_CALLBACK_PORT_CHANGED,
96 NULL, NULL);
97 spin_unlock_irqrestore(&priv->lock, flags);
98 hcd->state = HC_STATE_HALT;
99}
100
101static int octeon_usb_get_frame_number(struct usb_hcd *hcd)
102{
103 struct octeon_hcd *priv = hcd_to_octeon(hcd);
104
105 return cvmx_usb_get_frame_number(&priv->usb);
106}
107
108static void octeon_usb_urb_complete_callback(cvmx_usb_state_t *usb,
109 cvmx_usb_callback_t reason,
110 cvmx_usb_complete_t status,
111 int pipe_handle,
112 int submit_handle,
113 int bytes_transferred,
114 void *user_data)
115{
116 struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
117 struct usb_hcd *hcd = octeon_to_hcd(priv);
118 struct device *dev = hcd->self.controller;
119 struct urb *urb = user_data;
120
121 urb->actual_length = bytes_transferred;
122 urb->hcpriv = NULL;
123
124 if (!list_empty(&urb->urb_list)) {
125
126
127
128
129
130
131 list_del(&urb->urb_list);
132
133 INIT_LIST_HEAD(&urb->urb_list);
134 }
135
136
137
138 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
139 int i;
140
141
142
143
144 cvmx_usb_iso_packet_t *iso_packet = (cvmx_usb_iso_packet_t *) urb->setup_packet;
145
146 urb->actual_length = 0;
147 for (i = 0; i < urb->number_of_packets; i++) {
148 if (iso_packet[i].status == CVMX_USB_COMPLETE_SUCCESS) {
149 urb->iso_frame_desc[i].status = 0;
150 urb->iso_frame_desc[i].actual_length = iso_packet[i].length;
151 urb->actual_length += urb->iso_frame_desc[i].actual_length;
152 } else {
153 dev_dbg(dev, "ISOCHRONOUS packet=%d of %d status=%d pipe=%d submit=%d size=%d\n",
154 i, urb->number_of_packets,
155 iso_packet[i].status, pipe_handle,
156 submit_handle, iso_packet[i].length);
157 urb->iso_frame_desc[i].status = -EREMOTEIO;
158 }
159 }
160
161 kfree(iso_packet);
162 urb->setup_packet = NULL;
163 }
164
165 switch (status) {
166 case CVMX_USB_COMPLETE_SUCCESS:
167 urb->status = 0;
168 break;
169 case CVMX_USB_COMPLETE_CANCEL:
170 if (urb->status == 0)
171 urb->status = -ENOENT;
172 break;
173 case CVMX_USB_COMPLETE_STALL:
174 dev_dbg(dev, "status=stall pipe=%d submit=%d size=%d\n",
175 pipe_handle, submit_handle, bytes_transferred);
176 urb->status = -EPIPE;
177 break;
178 case CVMX_USB_COMPLETE_BABBLEERR:
179 dev_dbg(dev, "status=babble pipe=%d submit=%d size=%d\n",
180 pipe_handle, submit_handle, bytes_transferred);
181 urb->status = -EPIPE;
182 break;
183 case CVMX_USB_COMPLETE_SHORT:
184 dev_dbg(dev, "status=short pipe=%d submit=%d size=%d\n",
185 pipe_handle, submit_handle, bytes_transferred);
186 urb->status = -EREMOTEIO;
187 break;
188 case CVMX_USB_COMPLETE_ERROR:
189 case CVMX_USB_COMPLETE_XACTERR:
190 case CVMX_USB_COMPLETE_DATATGLERR:
191 case CVMX_USB_COMPLETE_FRAMEERR:
192 dev_dbg(dev, "status=%d pipe=%d submit=%d size=%d\n",
193 status, pipe_handle, submit_handle, bytes_transferred);
194 urb->status = -EPROTO;
195 break;
196 }
197 spin_unlock(&priv->lock);
198 usb_hcd_giveback_urb(octeon_to_hcd(priv), urb, urb->status);
199 spin_lock(&priv->lock);
200}
201
202static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
203 struct urb *urb,
204 gfp_t mem_flags)
205{
206 struct octeon_hcd *priv = hcd_to_octeon(hcd);
207 struct device *dev = hcd->self.controller;
208 int submit_handle = -1;
209 int pipe_handle;
210 unsigned long flags;
211 cvmx_usb_iso_packet_t *iso_packet;
212 struct usb_host_endpoint *ep = urb->ep;
213
214 urb->status = 0;
215 INIT_LIST_HEAD(&urb->urb_list);
216 spin_lock_irqsave(&priv->lock, flags);
217
218 if (!ep->hcpriv) {
219 cvmx_usb_transfer_t transfer_type;
220 cvmx_usb_speed_t speed;
221 int split_device = 0;
222 int split_port = 0;
223 switch (usb_pipetype(urb->pipe)) {
224 case PIPE_ISOCHRONOUS:
225 transfer_type = CVMX_USB_TRANSFER_ISOCHRONOUS;
226 break;
227 case PIPE_INTERRUPT:
228 transfer_type = CVMX_USB_TRANSFER_INTERRUPT;
229 break;
230 case PIPE_CONTROL:
231 transfer_type = CVMX_USB_TRANSFER_CONTROL;
232 break;
233 default:
234 transfer_type = CVMX_USB_TRANSFER_BULK;
235 break;
236 }
237 switch (urb->dev->speed) {
238 case USB_SPEED_LOW:
239 speed = CVMX_USB_SPEED_LOW;
240 break;
241 case USB_SPEED_FULL:
242 speed = CVMX_USB_SPEED_FULL;
243 break;
244 default:
245 speed = CVMX_USB_SPEED_HIGH;
246 break;
247 }
248
249
250
251
252
253 if (speed != CVMX_USB_SPEED_HIGH) {
254
255
256
257
258 struct usb_device *dev = urb->dev;
259 while (dev->parent) {
260
261
262
263
264 if (dev->parent->speed == USB_SPEED_HIGH) {
265 split_device = dev->parent->devnum;
266 split_port = dev->portnum;
267 break;
268 }
269
270
271
272
273
274
275 dev = dev->parent;
276 }
277 }
278 pipe_handle = cvmx_usb_open_pipe(&priv->usb,
279 0,
280 usb_pipedevice(urb->pipe),
281 usb_pipeendpoint(urb->pipe),
282 speed,
283 le16_to_cpu(ep->desc.wMaxPacketSize) & 0x7ff,
284 transfer_type,
285 usb_pipein(urb->pipe) ? CVMX_USB_DIRECTION_IN : CVMX_USB_DIRECTION_OUT,
286 urb->interval,
287 (le16_to_cpu(ep->desc.wMaxPacketSize) >> 11) & 0x3,
288 split_device,
289 split_port);
290 if (pipe_handle < 0) {
291 spin_unlock_irqrestore(&priv->lock, flags);
292 dev_dbg(dev, "Failed to create pipe\n");
293 return -ENOMEM;
294 }
295 ep->hcpriv = (void *)(0x10000L + pipe_handle);
296 } else {
297 pipe_handle = 0xffff & (long)ep->hcpriv;
298 }
299
300 switch (usb_pipetype(urb->pipe)) {
301 case PIPE_ISOCHRONOUS:
302 dev_dbg(dev, "Submit isochronous to %d.%d\n",
303 usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
304
305
306
307
308 iso_packet = kmalloc(urb->number_of_packets * sizeof(cvmx_usb_iso_packet_t), GFP_ATOMIC);
309 if (iso_packet) {
310 int i;
311
312 for (i = 0; i < urb->number_of_packets; i++) {
313 iso_packet[i].offset = urb->iso_frame_desc[i].offset;
314 iso_packet[i].length = urb->iso_frame_desc[i].length;
315 iso_packet[i].status = CVMX_USB_COMPLETE_ERROR;
316 }
317
318
319
320
321
322 urb->setup_packet = (char *)iso_packet;
323 submit_handle = cvmx_usb_submit_isochronous(&priv->usb, pipe_handle,
324 urb->start_frame,
325 0 ,
326 urb->number_of_packets,
327 iso_packet,
328 urb->transfer_dma,
329 urb->transfer_buffer_length,
330 octeon_usb_urb_complete_callback,
331 urb);
332
333
334
335
336 if (submit_handle < 0) {
337 urb->setup_packet = NULL;
338 kfree(iso_packet);
339 }
340 }
341 break;
342 case PIPE_INTERRUPT:
343 dev_dbg(dev, "Submit interrupt to %d.%d\n",
344 usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
345 submit_handle = cvmx_usb_submit_interrupt(&priv->usb, pipe_handle,
346 urb->transfer_dma,
347 urb->transfer_buffer_length,
348 octeon_usb_urb_complete_callback,
349 urb);
350 break;
351 case PIPE_CONTROL:
352 dev_dbg(dev, "Submit control to %d.%d\n",
353 usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
354 submit_handle = cvmx_usb_submit_control(&priv->usb, pipe_handle,
355 urb->setup_dma,
356 urb->transfer_dma,
357 urb->transfer_buffer_length,
358 octeon_usb_urb_complete_callback,
359 urb);
360 break;
361 case PIPE_BULK:
362 dev_dbg(dev, "Submit bulk to %d.%d\n",
363 usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
364 submit_handle = cvmx_usb_submit_bulk(&priv->usb, pipe_handle,
365 urb->transfer_dma,
366 urb->transfer_buffer_length,
367 octeon_usb_urb_complete_callback,
368 urb);
369 break;
370 }
371 if (submit_handle < 0) {
372 spin_unlock_irqrestore(&priv->lock, flags);
373 dev_dbg(dev, "Failed to submit\n");
374 return -ENOMEM;
375 }
376 urb->hcpriv = (void *)(long)(((submit_handle & 0xffff) << 16) | pipe_handle);
377 spin_unlock_irqrestore(&priv->lock, flags);
378 return 0;
379}
380
381static void octeon_usb_urb_dequeue_work(unsigned long arg)
382{
383 unsigned long flags;
384 struct octeon_hcd *priv = (struct octeon_hcd *)arg;
385
386 spin_lock_irqsave(&priv->lock, flags);
387
388 while (!list_empty(&priv->dequeue_list)) {
389 int pipe_handle;
390 int submit_handle;
391 struct urb *urb = container_of(priv->dequeue_list.next, struct urb, urb_list);
392 list_del(&urb->urb_list);
393
394 INIT_LIST_HEAD(&urb->urb_list);
395 pipe_handle = 0xffff & (long)urb->hcpriv;
396 submit_handle = ((long)urb->hcpriv) >> 16;
397 cvmx_usb_cancel(&priv->usb, pipe_handle, submit_handle);
398 }
399
400 spin_unlock_irqrestore(&priv->lock, flags);
401}
402
403static int octeon_usb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
404{
405 struct octeon_hcd *priv = hcd_to_octeon(hcd);
406 unsigned long flags;
407
408 if (!urb->dev)
409 return -EINVAL;
410
411 spin_lock_irqsave(&priv->lock, flags);
412
413 urb->status = status;
414 list_add_tail(&urb->urb_list, &priv->dequeue_list);
415
416 spin_unlock_irqrestore(&priv->lock, flags);
417
418 tasklet_schedule(&priv->dequeue_tasklet);
419
420 return 0;
421}
422
423static void octeon_usb_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
424{
425 struct device *dev = hcd->self.controller;
426
427 if (ep->hcpriv) {
428 struct octeon_hcd *priv = hcd_to_octeon(hcd);
429 int pipe_handle = 0xffff & (long)ep->hcpriv;
430 unsigned long flags;
431 spin_lock_irqsave(&priv->lock, flags);
432 cvmx_usb_cancel_all(&priv->usb, pipe_handle);
433 if (cvmx_usb_close_pipe(&priv->usb, pipe_handle))
434 dev_dbg(dev, "Closing pipe %d failed\n", pipe_handle);
435 spin_unlock_irqrestore(&priv->lock, flags);
436 ep->hcpriv = NULL;
437 }
438}
439
440static int octeon_usb_hub_status_data(struct usb_hcd *hcd, char *buf)
441{
442 struct octeon_hcd *priv = hcd_to_octeon(hcd);
443 cvmx_usb_port_status_t port_status;
444 unsigned long flags;
445
446 spin_lock_irqsave(&priv->lock, flags);
447 port_status = cvmx_usb_get_status(&priv->usb);
448 spin_unlock_irqrestore(&priv->lock, flags);
449 buf[0] = 0;
450 buf[0] = port_status.connect_change << 1;
451
452 return (buf[0] != 0);
453}
454
455static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength)
456{
457 struct octeon_hcd *priv = hcd_to_octeon(hcd);
458 struct device *dev = hcd->self.controller;
459 cvmx_usb_port_status_t usb_port_status;
460 int port_status;
461 struct usb_hub_descriptor *desc;
462 unsigned long flags;
463
464 switch (typeReq) {
465 case ClearHubFeature:
466 dev_dbg(dev, "ClearHubFeature\n");
467 switch (wValue) {
468 case C_HUB_LOCAL_POWER:
469 case C_HUB_OVER_CURRENT:
470
471 break;
472 default:
473 return -EINVAL;
474 }
475 break;
476 case ClearPortFeature:
477 dev_dbg(dev, "ClearPortFeature\n");
478 if (wIndex != 1) {
479 dev_dbg(dev, " INVALID\n");
480 return -EINVAL;
481 }
482
483 switch (wValue) {
484 case USB_PORT_FEAT_ENABLE:
485 dev_dbg(dev, " ENABLE\n");
486 spin_lock_irqsave(&priv->lock, flags);
487 cvmx_usb_disable(&priv->usb);
488 spin_unlock_irqrestore(&priv->lock, flags);
489 break;
490 case USB_PORT_FEAT_SUSPEND:
491 dev_dbg(dev, " SUSPEND\n");
492
493 break;
494 case USB_PORT_FEAT_POWER:
495 dev_dbg(dev, " POWER\n");
496
497 break;
498 case USB_PORT_FEAT_INDICATOR:
499 dev_dbg(dev, " INDICATOR\n");
500
501 break;
502 case USB_PORT_FEAT_C_CONNECTION:
503 dev_dbg(dev, " C_CONNECTION\n");
504
505 spin_lock_irqsave(&priv->lock, flags);
506 cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
507 spin_unlock_irqrestore(&priv->lock, flags);
508 break;
509 case USB_PORT_FEAT_C_RESET:
510 dev_dbg(dev, " C_RESET\n");
511
512
513
514 spin_lock_irqsave(&priv->lock, flags);
515 cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
516 spin_unlock_irqrestore(&priv->lock, flags);
517 break;
518 case USB_PORT_FEAT_C_ENABLE:
519 dev_dbg(dev, " C_ENABLE\n");
520
521
522
523
524 spin_lock_irqsave(&priv->lock, flags);
525 cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
526 spin_unlock_irqrestore(&priv->lock, flags);
527 break;
528 case USB_PORT_FEAT_C_SUSPEND:
529 dev_dbg(dev, " C_SUSPEND\n");
530
531
532
533
534
535 break;
536 case USB_PORT_FEAT_C_OVER_CURRENT:
537 dev_dbg(dev, " C_OVER_CURRENT\n");
538
539 spin_lock_irqsave(&priv->lock, flags);
540 cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
541 spin_unlock_irqrestore(&priv->lock, flags);
542 break;
543 default:
544 dev_dbg(dev, " UNKNOWN\n");
545 return -EINVAL;
546 }
547 break;
548 case GetHubDescriptor:
549 dev_dbg(dev, "GetHubDescriptor\n");
550 desc = (struct usb_hub_descriptor *)buf;
551 desc->bDescLength = 9;
552 desc->bDescriptorType = 0x29;
553 desc->bNbrPorts = 1;
554 desc->wHubCharacteristics = 0x08;
555 desc->bPwrOn2PwrGood = 1;
556 desc->bHubContrCurrent = 0;
557 desc->u.hs.DeviceRemovable[0] = 0;
558 desc->u.hs.DeviceRemovable[1] = 0xff;
559 break;
560 case GetHubStatus:
561 dev_dbg(dev, "GetHubStatus\n");
562 *(__le32 *) buf = 0;
563 break;
564 case GetPortStatus:
565 dev_dbg(dev, "GetPortStatus\n");
566 if (wIndex != 1) {
567 dev_dbg(dev, " INVALID\n");
568 return -EINVAL;
569 }
570
571 spin_lock_irqsave(&priv->lock, flags);
572 usb_port_status = cvmx_usb_get_status(&priv->usb);
573 spin_unlock_irqrestore(&priv->lock, flags);
574 port_status = 0;
575
576 if (usb_port_status.connect_change) {
577 port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
578 dev_dbg(dev, " C_CONNECTION\n");
579 }
580
581 if (usb_port_status.port_enabled) {
582 port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
583 dev_dbg(dev, " C_ENABLE\n");
584 }
585
586 if (usb_port_status.connected) {
587 port_status |= (1 << USB_PORT_FEAT_CONNECTION);
588 dev_dbg(dev, " CONNECTION\n");
589 }
590
591 if (usb_port_status.port_enabled) {
592 port_status |= (1 << USB_PORT_FEAT_ENABLE);
593 dev_dbg(dev, " ENABLE\n");
594 }
595
596 if (usb_port_status.port_over_current) {
597 port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);
598 dev_dbg(dev, " OVER_CURRENT\n");
599 }
600
601 if (usb_port_status.port_powered) {
602 port_status |= (1 << USB_PORT_FEAT_POWER);
603 dev_dbg(dev, " POWER\n");
604 }
605
606 if (usb_port_status.port_speed == CVMX_USB_SPEED_HIGH) {
607 port_status |= USB_PORT_STAT_HIGH_SPEED;
608 dev_dbg(dev, " HIGHSPEED\n");
609 } else if (usb_port_status.port_speed == CVMX_USB_SPEED_LOW) {
610 port_status |= (1 << USB_PORT_FEAT_LOWSPEED);
611 dev_dbg(dev, " LOWSPEED\n");
612 }
613
614 *((__le32 *) buf) = cpu_to_le32(port_status);
615 break;
616 case SetHubFeature:
617 dev_dbg(dev, "SetHubFeature\n");
618
619 break;
620 case SetPortFeature:
621 dev_dbg(dev, "SetPortFeature\n");
622 if (wIndex != 1) {
623 dev_dbg(dev, " INVALID\n");
624 return -EINVAL;
625 }
626
627 switch (wValue) {
628 case USB_PORT_FEAT_SUSPEND:
629 dev_dbg(dev, " SUSPEND\n");
630 return -EINVAL;
631 case USB_PORT_FEAT_POWER:
632 dev_dbg(dev, " POWER\n");
633 return -EINVAL;
634 case USB_PORT_FEAT_RESET:
635 dev_dbg(dev, " RESET\n");
636 spin_lock_irqsave(&priv->lock, flags);
637 cvmx_usb_disable(&priv->usb);
638 if (cvmx_usb_enable(&priv->usb))
639 dev_dbg(dev, "Failed to enable the port\n");
640 spin_unlock_irqrestore(&priv->lock, flags);
641 return 0;
642 case USB_PORT_FEAT_INDICATOR:
643 dev_dbg(dev, " INDICATOR\n");
644
645 break;
646 default:
647 dev_dbg(dev, " UNKNOWN\n");
648 return -EINVAL;
649 }
650 break;
651 default:
652 dev_dbg(dev, "Unknown root hub request\n");
653 return -EINVAL;
654 }
655 return 0;
656}
657
658
659static const struct hc_driver octeon_hc_driver = {
660 .description = "Octeon USB",
661 .product_desc = "Octeon Host Controller",
662 .hcd_priv_size = sizeof(struct octeon_hcd),
663 .irq = octeon_usb_irq,
664 .flags = HCD_MEMORY | HCD_USB2,
665 .start = octeon_usb_start,
666 .stop = octeon_usb_stop,
667 .urb_enqueue = octeon_usb_urb_enqueue,
668 .urb_dequeue = octeon_usb_urb_dequeue,
669 .endpoint_disable = octeon_usb_endpoint_disable,
670 .get_frame_number = octeon_usb_get_frame_number,
671 .hub_status_data = octeon_usb_hub_status_data,
672 .hub_control = octeon_usb_hub_control,
673};
674
675
676static int octeon_usb_driver_probe(struct device *dev)
677{
678 int status;
679 int usb_num = to_platform_device(dev)->id;
680 int irq = platform_get_irq(to_platform_device(dev), 0);
681 struct octeon_hcd *priv;
682 struct usb_hcd *hcd;
683 unsigned long flags;
684
685
686
687
688
689 dev->coherent_dma_mask = ~0;
690 dev->dma_mask = &dev->coherent_dma_mask;
691
692 hcd = usb_create_hcd(&octeon_hc_driver, dev, dev_name(dev));
693 if (!hcd) {
694 dev_dbg(dev, "Failed to allocate memory for HCD\n");
695 return -1;
696 }
697 hcd->uses_new_polling = 1;
698 priv = (struct octeon_hcd *)hcd->hcd_priv;
699
700 spin_lock_init(&priv->lock);
701
702 tasklet_init(&priv->dequeue_tasklet, octeon_usb_urb_dequeue_work, (unsigned long)priv);
703 INIT_LIST_HEAD(&priv->dequeue_list);
704
705 status = cvmx_usb_initialize(&priv->usb, usb_num, CVMX_USB_INITIALIZE_FLAGS_CLOCK_AUTO);
706 if (status) {
707 dev_dbg(dev, "USB initialization failed with %d\n", status);
708 kfree(hcd);
709 return -1;
710 }
711
712
713 mdelay(10);
714
715 spin_lock_irqsave(&priv->lock, flags);
716 cvmx_usb_poll(&priv->usb);
717 spin_unlock_irqrestore(&priv->lock, flags);
718
719 status = usb_add_hcd(hcd, irq, IRQF_SHARED);
720 if (status) {
721 dev_dbg(dev, "USB add HCD failed with %d\n", status);
722 kfree(hcd);
723 return -1;
724 }
725
726 dev_dbg(dev, "Registered HCD for port %d on irq %d\n", usb_num, irq);
727
728 return 0;
729}
730
731static int octeon_usb_driver_remove(struct device *dev)
732{
733 int status;
734 struct usb_hcd *hcd = dev_get_drvdata(dev);
735 struct octeon_hcd *priv = hcd_to_octeon(hcd);
736 unsigned long flags;
737
738 usb_remove_hcd(hcd);
739 tasklet_kill(&priv->dequeue_tasklet);
740 spin_lock_irqsave(&priv->lock, flags);
741 status = cvmx_usb_shutdown(&priv->usb);
742 spin_unlock_irqrestore(&priv->lock, flags);
743 if (status)
744 dev_dbg(dev, "USB shutdown failed with %d\n", status);
745
746 kfree(hcd);
747
748 return 0;
749}
750
751static struct device_driver octeon_usb_driver = {
752 .name = "OcteonUSB",
753 .bus = &platform_bus_type,
754 .probe = octeon_usb_driver_probe,
755 .remove = octeon_usb_driver_remove,
756};
757
758
759#define MAX_USB_PORTS 10
760static struct platform_device *pdev_glob[MAX_USB_PORTS];
761static int octeon_usb_registered;
762static int __init octeon_usb_module_init(void)
763{
764 int num_devices = cvmx_usb_get_num_ports();
765 int device;
766
767 if (usb_disabled() || num_devices == 0)
768 return -ENODEV;
769
770 if (driver_register(&octeon_usb_driver))
771 return -ENOMEM;
772
773 octeon_usb_registered = 1;
774
775
776
777
778
779
780
781
782
783
784
785
786 if (OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN56XX)) {
787 union cvmx_iob_n2c_l2c_pri_cnt pri_cnt;
788
789 pri_cnt.u64 = 0;
790 pri_cnt.s.cnt_enb = 1;
791 pri_cnt.s.cnt_val = 400;
792 cvmx_write_csr(CVMX_IOB_N2C_L2C_PRI_CNT, pri_cnt.u64);
793 }
794
795 for (device = 0; device < num_devices; device++) {
796 struct resource irq_resource;
797 struct platform_device *pdev;
798 memset(&irq_resource, 0, sizeof(irq_resource));
799 irq_resource.start = (device == 0) ? OCTEON_IRQ_USB0 : OCTEON_IRQ_USB1;
800 irq_resource.end = irq_resource.start;
801 irq_resource.flags = IORESOURCE_IRQ;
802 pdev = platform_device_register_simple((char *)octeon_usb_driver. name, device, &irq_resource, 1);
803 if (IS_ERR(pdev)) {
804 driver_unregister(&octeon_usb_driver);
805 octeon_usb_registered = 0;
806 return PTR_ERR(pdev);
807 }
808 if (device < MAX_USB_PORTS)
809 pdev_glob[device] = pdev;
810
811 }
812 return 0;
813}
814
815static void __exit octeon_usb_module_cleanup(void)
816{
817 int i;
818
819 for (i = 0; i < MAX_USB_PORTS; i++)
820 if (pdev_glob[i]) {
821 platform_device_unregister(pdev_glob[i]);
822 pdev_glob[i] = NULL;
823 }
824 if (octeon_usb_registered)
825 driver_unregister(&octeon_usb_driver);
826}
827
828MODULE_LICENSE("GPL");
829MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>");
830MODULE_DESCRIPTION("Cavium Networks Octeon USB Host driver.");
831module_init(octeon_usb_module_init);
832module_exit(octeon_usb_module_cleanup);
833