linux/drivers/staging/octeon-usb/octeon-hcd.c
<<
>>
Prefs
   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>
  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/* 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{
  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                 * 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
 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;
 140                /*
 141                 * The pointer to the private list is stored in the setup_packet
 142                 * field.
 143                 */
 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 {
 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                /* 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:
 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); /* not enqueued on dequeue_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                 * 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                 */
 253                if (speed != CVMX_USB_SPEED_HIGH) {
 254                        /*
 255                         * Start at this device and work our way up the usb
 256                         * tree.
 257                         */
 258                        struct usb_device *dev = urb->dev;
 259                        while (dev->parent) {
 260                                /*
 261                                 * If our parent is high speed then he'll
 262                                 * receive the splits.
 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                                 * 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                                 */
 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                 * Allocate a structure to use for our private list of
 306                 * isochronous packets.
 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                        /* 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                        }
 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                         */
 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);
 332                        /*
 333                         * If submit failed we need to free our private packet
 334                         * list.
 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                /* 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);
 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                        /* Nothing required here */
 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                        /* Not supported on Octeon */
 493                        break;
 494                case USB_PORT_FEAT_POWER:
 495                        dev_dbg(dev, " POWER\n");
 496                        /* Not supported on Octeon */
 497                        break;
 498                case USB_PORT_FEAT_INDICATOR:
 499                        dev_dbg(dev, " INDICATOR\n");
 500                        /* Port inidicator not supported */
 501                        break;
 502                case USB_PORT_FEAT_C_CONNECTION:
 503                        dev_dbg(dev, " C_CONNECTION\n");
 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:
 510                        dev_dbg(dev, " C_RESET\n");
 511                        /*
 512                         * Clears the driver's internal Port Reset Change flag.
 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                         * Clears the driver's internal Port Enable/Disable
 522                         * Change flag.
 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                         * Clears the driver's internal Port Suspend Change
 532                         * flag, which is set when resume signaling on the host
 533                         * port is complete.
 534                         */
 535                        break;
 536                case USB_PORT_FEAT_C_OVER_CURRENT:
 537                        dev_dbg(dev, " C_OVER_CURRENT\n");
 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:
 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                /* No HUB features supported */
 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                        /* Not supported */
 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         * Set the DMA mask to 64bits so we get buffers already translated for
 687         * DMA.
 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        /* 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) {
 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         * 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
 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