staging: octeon-usb: cvmx_usb_complete_t -> enum cvmx_usb_complete
[deliverable/linux.git] / drivers / staging / octeon-usb / octeon-hcd.c
CommitLineData
b164935b
AK
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2008 Cavium Networks
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>
b164935b
AK
14#include <linux/usb.h>
15
2a81d2b0
AK
16#include <linux/time.h>
17#include <linux/delay.h>
b164935b
AK
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
55fa328a
DN
25#include <linux/err.h>
26
b164935b 27struct octeon_hcd {
771378bb
AK
28 spinlock_t lock;
29 cvmx_usb_state_t usb;
30 struct tasklet_struct dequeue_tasklet;
31 struct list_head dequeue_list;
b164935b
AK
32};
33
34/* convert between an HCD pointer and the corresponding struct octeon_hcd */
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{
771378bb
AK
52 struct octeon_hcd *priv = hcd_to_octeon(hcd);
53 unsigned long flags;
71e06db3 54
771378bb
AK
55 spin_lock_irqsave(&priv->lock, flags);
56 cvmx_usb_poll(&priv->usb);
57 spin_unlock_irqrestore(&priv->lock, flags);
58 return IRQ_HANDLED;
b164935b
AK
59}
60
61static void octeon_usb_port_callback(cvmx_usb_state_t *usb,
771378bb 62 cvmx_usb_callback_t reason,
1c1bdf27 63 enum cvmx_usb_complete status,
771378bb
AK
64 int pipe_handle,
65 int submit_handle,
66 int bytes_transferred,
67 void *user_data)
b164935b 68{
771378bb 69 struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
71e06db3 70
771378bb
AK
71 spin_unlock(&priv->lock);
72 usb_hcd_poll_rh_status(octeon_to_hcd(priv));
73 spin_lock(&priv->lock);
b164935b
AK
74}
75
76static int octeon_usb_start(struct usb_hcd *hcd)
77{
771378bb
AK
78 struct octeon_hcd *priv = hcd_to_octeon(hcd);
79 unsigned long flags;
71e06db3 80
771378bb
AK
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;
b164935b
AK
87}
88
89static void octeon_usb_stop(struct usb_hcd *hcd)
90{
771378bb
AK
91 struct octeon_hcd *priv = hcd_to_octeon(hcd);
92 unsigned long flags;
71e06db3 93
771378bb
AK
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;
b164935b
AK
99}
100
101static int octeon_usb_get_frame_number(struct usb_hcd *hcd)
102{
771378bb 103 struct octeon_hcd *priv = hcd_to_octeon(hcd);
71e06db3 104
771378bb 105 return cvmx_usb_get_frame_number(&priv->usb);
b164935b
AK
106}
107
108static void octeon_usb_urb_complete_callback(cvmx_usb_state_t *usb,
771378bb 109 cvmx_usb_callback_t reason,
1c1bdf27 110 enum cvmx_usb_complete status,
771378bb
AK
111 int pipe_handle,
112 int submit_handle,
113 int bytes_transferred,
114 void *user_data)
b164935b 115{
771378bb 116 struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
71e06db3
AK
117 struct usb_hcd *hcd = octeon_to_hcd(priv);
118 struct device *dev = hcd->self.controller;
771378bb 119 struct urb *urb = user_data;
71e06db3 120
771378bb
AK
121 urb->actual_length = bytes_transferred;
122 urb->hcpriv = NULL;
b164935b
AK
123
124 if (!list_empty(&urb->urb_list)) {
125 /*
126 * It is on the dequeue_list, but we are going to call
127 * usb_hcd_giveback_urb(), so we must clear it from
128 * the list. We got to it before the
129 * octeon_usb_urb_dequeue_work() tasklet did.
130 */
131 list_del(&urb->urb_list);
132 /* No longer on the dequeue_list. */
133 INIT_LIST_HEAD(&urb->urb_list);
134 }
135
771378bb
AK
136 /* For Isochronous transactions we need to update the URB packet status
137 list from data in our private copy */
138 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
139 int i;
87e7e57a
AK
140 /*
141 * The pointer to the private list is stored in the setup_packet
142 * field.
143 */
771378bb
AK
144 cvmx_usb_iso_packet_t *iso_packet = (cvmx_usb_iso_packet_t *) urb->setup_packet;
145 /* Recalculate the transfer size by adding up each packet */
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 {
71e06db3
AK
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);
771378bb
AK
157 urb->iso_frame_desc[i].status = -EREMOTEIO;
158 }
159 }
160 /* Free the private list now that we don't need it anymore */
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:
71e06db3
AK
174 dev_dbg(dev, "status=stall pipe=%d submit=%d size=%d\n",
175 pipe_handle, submit_handle, bytes_transferred);
771378bb
AK
176 urb->status = -EPIPE;
177 break;
178 case CVMX_USB_COMPLETE_BABBLEERR:
71e06db3
AK
179 dev_dbg(dev, "status=babble pipe=%d submit=%d size=%d\n",
180 pipe_handle, submit_handle, bytes_transferred);
771378bb
AK
181 urb->status = -EPIPE;
182 break;
183 case CVMX_USB_COMPLETE_SHORT:
71e06db3
AK
184 dev_dbg(dev, "status=short pipe=%d submit=%d size=%d\n",
185 pipe_handle, submit_handle, bytes_transferred);
771378bb
AK
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:
71e06db3
AK
192 dev_dbg(dev, "status=%d pipe=%d submit=%d size=%d\n",
193 status, pipe_handle, submit_handle, bytes_transferred);
771378bb
AK
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);
b164935b
AK
200}
201
202static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
771378bb
AK
203 struct urb *urb,
204 gfp_t mem_flags)
b164935b 205{
771378bb 206 struct octeon_hcd *priv = hcd_to_octeon(hcd);
71e06db3 207 struct device *dev = hcd->self.controller;
771378bb
AK
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
771378bb
AK
214 urb->status = 0;
215 INIT_LIST_HEAD(&urb->urb_list); /* not enqueued on dequeue_list */
216 spin_lock_irqsave(&priv->lock, flags);
217
218 if (!ep->hcpriv) {
394d4e08 219 enum cvmx_usb_transfer transfer_type;
4918072e 220 enum cvmx_usb_speed speed;
771378bb
AK
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 }
87e7e57a
AK
248 /*
249 * For slow devices on high speed ports we need to find the hub
250 * that does the speed translation so we know where to send the
251 * split transactions.
252 */
771378bb 253 if (speed != CVMX_USB_SPEED_HIGH) {
87e7e57a
AK
254 /*
255 * Start at this device and work our way up the usb
256 * tree.
257 */
771378bb
AK
258 struct usb_device *dev = urb->dev;
259 while (dev->parent) {
87e7e57a
AK
260 /*
261 * If our parent is high speed then he'll
262 * receive the splits.
263 */
771378bb
AK
264 if (dev->parent->speed == USB_SPEED_HIGH) {
265 split_device = dev->parent->devnum;
266 split_port = dev->portnum;
267 break;
268 }
87e7e57a
AK
269 /*
270 * Move up the tree one level. If we make it all
271 * the way up the tree, then the port must not
272 * be in high speed mode and we don't need a
273 * split.
274 */
771378bb
AK
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);
71e06db3 292 dev_dbg(dev, "Failed to create pipe\n");
771378bb
AK
293 return -ENOMEM;
294 }
295 ep->hcpriv = (void *)(0x10000L + pipe_handle);
c7609eac 296 } else {
771378bb 297 pipe_handle = 0xffff & (long)ep->hcpriv;
c7609eac 298 }
771378bb
AK
299
300 switch (usb_pipetype(urb->pipe)) {
301 case PIPE_ISOCHRONOUS:
71e06db3
AK
302 dev_dbg(dev, "Submit isochronous to %d.%d\n",
303 usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
87e7e57a
AK
304 /*
305 * Allocate a structure to use for our private list of
306 * isochronous packets.
307 */
771378bb
AK
308 iso_packet = kmalloc(urb->number_of_packets * sizeof(cvmx_usb_iso_packet_t), GFP_ATOMIC);
309 if (iso_packet) {
310 int i;
311 /* Fill the list with the data from the URB */
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 }
87e7e57a
AK
317 /*
318 * Store a pointer to the list in the URB setup_packet
319 * field. We know this currently isn't being used and
320 * this saves us a bunch of logic.
321 */
771378bb
AK
322 urb->setup_packet = (char *)iso_packet;
323 submit_handle = cvmx_usb_submit_isochronous(&priv->usb, pipe_handle,
324 urb->start_frame,
325 0 /* flags */ ,
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);
87e7e57a
AK
332 /*
333 * If submit failed we need to free our private packet
334 * list.
335 */
771378bb
AK
336 if (submit_handle < 0) {
337 urb->setup_packet = NULL;
338 kfree(iso_packet);
339 }
340 }
341 break;
342 case PIPE_INTERRUPT:
71e06db3
AK
343 dev_dbg(dev, "Submit interrupt to %d.%d\n",
344 usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
771378bb
AK
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:
71e06db3
AK
352 dev_dbg(dev, "Submit control to %d.%d\n",
353 usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
771378bb
AK
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:
71e06db3
AK
362 dev_dbg(dev, "Submit bulk to %d.%d\n",
363 usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
771378bb
AK
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);
71e06db3 373 dev_dbg(dev, "Failed to submit\n");
771378bb
AK
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;
b164935b
AK
379}
380
381static void octeon_usb_urb_dequeue_work(unsigned long arg)
382{
771378bb
AK
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 /* not enqueued on dequeue_list */
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);
b164935b
AK
401}
402
403static int octeon_usb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
404{
771378bb
AK
405 struct octeon_hcd *priv = hcd_to_octeon(hcd);
406 unsigned long flags;
b164935b 407
771378bb
AK
408 if (!urb->dev)
409 return -EINVAL;
b164935b 410
771378bb 411 spin_lock_irqsave(&priv->lock, flags);
b164935b 412
771378bb
AK
413 urb->status = status;
414 list_add_tail(&urb->urb_list, &priv->dequeue_list);
b164935b 415
771378bb 416 spin_unlock_irqrestore(&priv->lock, flags);
b164935b 417
771378bb 418 tasklet_schedule(&priv->dequeue_tasklet);
b164935b 419
771378bb 420 return 0;
b164935b
AK
421}
422
423static void octeon_usb_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
424{
71e06db3
AK
425 struct device *dev = hcd->self.controller;
426
771378bb
AK
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))
71e06db3 434 dev_dbg(dev, "Closing pipe %d failed\n", pipe_handle);
771378bb
AK
435 spin_unlock_irqrestore(&priv->lock, flags);
436 ep->hcpriv = NULL;
437 }
b164935b
AK
438}
439
440static int octeon_usb_hub_status_data(struct usb_hcd *hcd, char *buf)
441{
771378bb
AK
442 struct octeon_hcd *priv = hcd_to_octeon(hcd);
443 cvmx_usb_port_status_t port_status;
444 unsigned long flags;
b164935b 445
771378bb
AK
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;
b164935b 451
771378bb 452 return (buf[0] != 0);
b164935b
AK
453}
454
455static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength)
456{
771378bb 457 struct octeon_hcd *priv = hcd_to_octeon(hcd);
71e06db3 458 struct device *dev = hcd->self.controller;
771378bb
AK
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:
71e06db3 466 dev_dbg(dev, "ClearHubFeature\n");
771378bb
AK
467 switch (wValue) {
468 case C_HUB_LOCAL_POWER:
469 case C_HUB_OVER_CURRENT:
470 /* Nothing required here */
471 break;
472 default:
473 return -EINVAL;
474 }
475 break;
476 case ClearPortFeature:
71e06db3 477 dev_dbg(dev, "ClearPortFeature\n");
771378bb 478 if (wIndex != 1) {
71e06db3 479 dev_dbg(dev, " INVALID\n");
771378bb
AK
480 return -EINVAL;
481 }
482
483 switch (wValue) {
484 case USB_PORT_FEAT_ENABLE:
71e06db3 485 dev_dbg(dev, " ENABLE\n");
771378bb
AK
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:
71e06db3 491 dev_dbg(dev, " SUSPEND\n");
771378bb
AK
492 /* Not supported on Octeon */
493 break;
494 case USB_PORT_FEAT_POWER:
71e06db3 495 dev_dbg(dev, " POWER\n");
771378bb
AK
496 /* Not supported on Octeon */
497 break;
498 case USB_PORT_FEAT_INDICATOR:
71e06db3 499 dev_dbg(dev, " INDICATOR\n");
771378bb
AK
500 /* Port inidicator not supported */
501 break;
502 case USB_PORT_FEAT_C_CONNECTION:
71e06db3 503 dev_dbg(dev, " C_CONNECTION\n");
771378bb
AK
504 /* Clears drivers internal connect status change flag */
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:
71e06db3 510 dev_dbg(dev, " C_RESET\n");
87e7e57a
AK
511 /*
512 * Clears the driver's internal Port Reset Change flag.
513 */
771378bb
AK
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:
71e06db3 519 dev_dbg(dev, " C_ENABLE\n");
87e7e57a
AK
520 /*
521 * Clears the driver's internal Port Enable/Disable
522 * Change flag.
523 */
771378bb
AK
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:
71e06db3 529 dev_dbg(dev, " C_SUSPEND\n");
87e7e57a
AK
530 /*
531 * Clears the driver's internal Port Suspend Change
532 * flag, which is set when resume signaling on the host
533 * port is complete.
534 */
771378bb
AK
535 break;
536 case USB_PORT_FEAT_C_OVER_CURRENT:
71e06db3 537 dev_dbg(dev, " C_OVER_CURRENT\n");
771378bb
AK
538 /* Clears the driver's overcurrent Change flag */
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:
71e06db3 544 dev_dbg(dev, " UNKNOWN\n");
771378bb
AK
545 return -EINVAL;
546 }
771378bb
AK
547 break;
548 case GetHubDescriptor:
71e06db3 549 dev_dbg(dev, "GetHubDescriptor\n");
771378bb
AK
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:
71e06db3 561 dev_dbg(dev, "GetHubStatus\n");
771378bb
AK
562 *(__le32 *) buf = 0;
563 break;
564 case GetPortStatus:
71e06db3 565 dev_dbg(dev, "GetPortStatus\n");
771378bb 566 if (wIndex != 1) {
71e06db3 567 dev_dbg(dev, " INVALID\n");
771378bb
AK
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);
71e06db3 578 dev_dbg(dev, " C_CONNECTION\n");
771378bb
AK
579 }
580
581 if (usb_port_status.port_enabled) {
582 port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
71e06db3 583 dev_dbg(dev, " C_ENABLE\n");
771378bb
AK
584 }
585
586 if (usb_port_status.connected) {
587 port_status |= (1 << USB_PORT_FEAT_CONNECTION);
71e06db3 588 dev_dbg(dev, " CONNECTION\n");
771378bb
AK
589 }
590
591 if (usb_port_status.port_enabled) {
592 port_status |= (1 << USB_PORT_FEAT_ENABLE);
71e06db3 593 dev_dbg(dev, " ENABLE\n");
771378bb
AK
594 }
595
596 if (usb_port_status.port_over_current) {
597 port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);
71e06db3 598 dev_dbg(dev, " OVER_CURRENT\n");
771378bb
AK
599 }
600
601 if (usb_port_status.port_powered) {
602 port_status |= (1 << USB_PORT_FEAT_POWER);
71e06db3 603 dev_dbg(dev, " POWER\n");
771378bb
AK
604 }
605
606 if (usb_port_status.port_speed == CVMX_USB_SPEED_HIGH) {
607 port_status |= USB_PORT_STAT_HIGH_SPEED;
71e06db3 608 dev_dbg(dev, " HIGHSPEED\n");
771378bb
AK
609 } else if (usb_port_status.port_speed == CVMX_USB_SPEED_LOW) {
610 port_status |= (1 << USB_PORT_FEAT_LOWSPEED);
71e06db3 611 dev_dbg(dev, " LOWSPEED\n");
771378bb
AK
612 }
613
614 *((__le32 *) buf) = cpu_to_le32(port_status);
771378bb
AK
615 break;
616 case SetHubFeature:
71e06db3 617 dev_dbg(dev, "SetHubFeature\n");
771378bb
AK
618 /* No HUB features supported */
619 break;
620 case SetPortFeature:
71e06db3 621 dev_dbg(dev, "SetPortFeature\n");
771378bb 622 if (wIndex != 1) {
71e06db3 623 dev_dbg(dev, " INVALID\n");
771378bb
AK
624 return -EINVAL;
625 }
626
627 switch (wValue) {
628 case USB_PORT_FEAT_SUSPEND:
71e06db3 629 dev_dbg(dev, " SUSPEND\n");
771378bb
AK
630 return -EINVAL;
631 case USB_PORT_FEAT_POWER:
71e06db3 632 dev_dbg(dev, " POWER\n");
771378bb
AK
633 return -EINVAL;
634 case USB_PORT_FEAT_RESET:
71e06db3 635 dev_dbg(dev, " RESET\n");
771378bb
AK
636 spin_lock_irqsave(&priv->lock, flags);
637 cvmx_usb_disable(&priv->usb);
638 if (cvmx_usb_enable(&priv->usb))
71e06db3 639 dev_dbg(dev, "Failed to enable the port\n");
771378bb
AK
640 spin_unlock_irqrestore(&priv->lock, flags);
641 return 0;
642 case USB_PORT_FEAT_INDICATOR:
71e06db3 643 dev_dbg(dev, " INDICATOR\n");
771378bb
AK
644 /* Not supported */
645 break;
646 default:
71e06db3 647 dev_dbg(dev, " UNKNOWN\n");
771378bb
AK
648 return -EINVAL;
649 }
650 break;
651 default:
71e06db3 652 dev_dbg(dev, "Unknown root hub request\n");
771378bb
AK
653 return -EINVAL;
654 }
655 return 0;
b164935b
AK
656}
657
658
659static const struct hc_driver octeon_hc_driver = {
771378bb
AK
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,
b164935b
AK
673};
674
675
676static int octeon_usb_driver_probe(struct device *dev)
677{
771378bb
AK
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
87e7e57a
AK
685 /*
686 * Set the DMA mask to 64bits so we get buffers already translated for
687 * DMA.
688 */
771378bb
AK
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) {
71e06db3 694 dev_dbg(dev, "Failed to allocate memory for HCD\n");
771378bb
AK
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
771378bb
AK
705 status = cvmx_usb_initialize(&priv->usb, usb_num, CVMX_USB_INITIALIZE_FLAGS_CLOCK_AUTO);
706 if (status) {
71e06db3 707 dev_dbg(dev, "USB initialization failed with %d\n", status);
771378bb
AK
708 kfree(hcd);
709 return -1;
710 }
711
712 /* This delay is needed for CN3010, but I don't know why... */
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) {
71e06db3 721 dev_dbg(dev, "USB add HCD failed with %d\n", status);
771378bb
AK
722 kfree(hcd);
723 return -1;
724 }
725
d935217d 726 dev_dbg(dev, "Registered HCD for port %d on irq %d\n", usb_num, irq);
771378bb
AK
727
728 return 0;
b164935b
AK
729}
730
731static int octeon_usb_driver_remove(struct device *dev)
732{
771378bb
AK
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;
b164935b 737
771378bb
AK
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)
71e06db3 744 dev_dbg(dev, "USB shutdown failed with %d\n", status);
b164935b 745
771378bb 746 kfree(hcd);
b164935b 747
771378bb 748 return 0;
b164935b
AK
749}
750
751static struct device_driver octeon_usb_driver = {
771378bb
AK
752 .name = "OcteonUSB",
753 .bus = &platform_bus_type,
754 .probe = octeon_usb_driver_probe,
755 .remove = octeon_usb_driver_remove,
b164935b
AK
756};
757
758
759#define MAX_USB_PORTS 10
f5ed3a38 760static struct platform_device *pdev_glob[MAX_USB_PORTS];
b164935b
AK
761static int octeon_usb_registered;
762static int __init octeon_usb_module_init(void)
763{
771378bb
AK
764 int num_devices = cvmx_usb_get_num_ports();
765 int device;
b164935b 766
771378bb
AK
767 if (usb_disabled() || num_devices == 0)
768 return -ENODEV;
b164935b 769
71e06db3 770 if (driver_register(&octeon_usb_driver))
771378bb 771 return -ENOMEM;
71e06db3 772
771378bb 773 octeon_usb_registered = 1;
b164935b
AK
774
775 /*
776 * Only cn52XX and cn56XX have DWC_OTG USB hardware and the
777 * IOB priority registers. Under heavy network load USB
778 * hardware can be starved by the IOB causing a crash. Give
779 * it a priority boost if it has been waiting more than 400
780 * cycles to avoid this situation.
781 *
782 * Testing indicates that a cnt_val of 8192 is not sufficient,
783 * but no failures are seen with 4096. We choose a value of
784 * 400 to give a safety factor of 10.
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
771378bb
AK
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)) {
771378bb
AK
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;
b164935b
AK
813}
814
815static void __exit octeon_usb_module_cleanup(void)
816{
771378bb 817 int i;
71e06db3 818
771378bb
AK
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 }
b164935b
AK
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);
This page took 0.091047 seconds and 5 git commands to generate.