linux/drivers/usb/musb/blackfin.c
<<
>>
Prefs
   1/*
   2 * MUSB OTG controller driver for Blackfin Processors
   3 *
   4 * Copyright 2006-2008 Analog Devices Inc.
   5 *
   6 * Enter bugs at http://blackfin.uclinux.org/
   7 *
   8 * Licensed under the GPL-2 or later.
   9 */
  10
  11#include <linux/module.h>
  12#include <linux/kernel.h>
  13#include <linux/sched.h>
  14#include <linux/list.h>
  15#include <linux/gpio.h>
  16#include <linux/io.h>
  17#include <linux/err.h>
  18#include <linux/platform_device.h>
  19#include <linux/dma-mapping.h>
  20#include <linux/prefetch.h>
  21#include <linux/usb/usb_phy_generic.h>
  22
  23#include <asm/cacheflush.h>
  24
  25#include "musb_core.h"
  26#include "musbhsdma.h"
  27#include "blackfin.h"
  28
  29struct bfin_glue {
  30        struct device           *dev;
  31        struct platform_device  *musb;
  32        struct platform_device  *phy;
  33};
  34#define glue_to_musb(g)         platform_get_drvdata(g->musb)
  35
  36static u32 bfin_fifo_offset(u8 epnum)
  37{
  38        return USB_OFFSET(USB_EP0_FIFO) + (epnum * 8);
  39}
  40
  41static u8 bfin_readb(const void __iomem *addr, unsigned offset)
  42{
  43        return (u8)(bfin_read16(addr + offset));
  44}
  45
  46static u16 bfin_readw(const void __iomem *addr, unsigned offset)
  47{
  48        return bfin_read16(addr + offset);
  49}
  50
  51static u32 bfin_readl(const void __iomem *addr, unsigned offset)
  52{
  53        return (u32)(bfin_read16(addr + offset));
  54}
  55
  56static void bfin_writeb(void __iomem *addr, unsigned offset, u8 data)
  57{
  58        bfin_write16(addr + offset, (u16)data);
  59}
  60
  61static void bfin_writew(void __iomem *addr, unsigned offset, u16 data)
  62{
  63        bfin_write16(addr + offset, data);
  64}
  65
  66static void bfin_writel(void __iomem *addr, unsigned offset, u32 data)
  67{
  68        bfin_write16(addr + offset, (u16)data);
  69}
  70
  71/*
  72 * Load an endpoint's FIFO
  73 */
  74static void bfin_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src)
  75{
  76        struct musb *musb = hw_ep->musb;
  77        void __iomem *fifo = hw_ep->fifo;
  78        void __iomem *epio = hw_ep->regs;
  79        u8 epnum = hw_ep->epnum;
  80
  81        prefetch((u8 *)src);
  82
  83        musb_writew(epio, MUSB_TXCOUNT, len);
  84
  85        dev_dbg(musb->controller, "TX ep%d fifo %p count %d buf %p, epio %p\n",
  86                        hw_ep->epnum, fifo, len, src, epio);
  87
  88        dump_fifo_data(src, len);
  89
  90        if (!ANOMALY_05000380 && epnum != 0) {
  91                u16 dma_reg;
  92
  93                flush_dcache_range((unsigned long)src,
  94                        (unsigned long)(src + len));
  95
  96                /* Setup DMA address register */
  97                dma_reg = (u32)src;
  98                bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg);
  99                SSYNC();
 100
 101                dma_reg = (u32)src >> 16;
 102                bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg);
 103                SSYNC();
 104
 105                /* Setup DMA count register */
 106                bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len);
 107                bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0);
 108                SSYNC();
 109
 110                /* Enable the DMA */
 111                dma_reg = (epnum << 4) | DMA_ENA | INT_ENA | DIRECTION;
 112                bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg);
 113                SSYNC();
 114
 115                /* Wait for complete */
 116                while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum)))
 117                        cpu_relax();
 118
 119                /* acknowledge dma interrupt */
 120                bfin_write_USB_DMA_INTERRUPT(1 << epnum);
 121                SSYNC();
 122
 123                /* Reset DMA */
 124                bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0);
 125                SSYNC();
 126        } else {
 127                SSYNC();
 128
 129                if (unlikely((unsigned long)src & 0x01))
 130                        outsw_8((unsigned long)fifo, src, (len + 1) >> 1);
 131                else
 132                        outsw((unsigned long)fifo, src, (len + 1) >> 1);
 133        }
 134}
 135/*
 136 * Unload an endpoint's FIFO
 137 */
 138static void bfin_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
 139{
 140        struct musb *musb = hw_ep->musb;
 141        void __iomem *fifo = hw_ep->fifo;
 142        u8 epnum = hw_ep->epnum;
 143
 144        if (ANOMALY_05000467 && epnum != 0) {
 145                u16 dma_reg;
 146
 147                invalidate_dcache_range((unsigned long)dst,
 148                        (unsigned long)(dst + len));
 149
 150                /* Setup DMA address register */
 151                dma_reg = (u32)dst;
 152                bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg);
 153                SSYNC();
 154
 155                dma_reg = (u32)dst >> 16;
 156                bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg);
 157                SSYNC();
 158
 159                /* Setup DMA count register */
 160                bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len);
 161                bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0);
 162                SSYNC();
 163
 164                /* Enable the DMA */
 165                dma_reg = (epnum << 4) | DMA_ENA | INT_ENA;
 166                bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg);
 167                SSYNC();
 168
 169                /* Wait for complete */
 170                while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum)))
 171                        cpu_relax();
 172
 173                /* acknowledge dma interrupt */
 174                bfin_write_USB_DMA_INTERRUPT(1 << epnum);
 175                SSYNC();
 176
 177                /* Reset DMA */
 178                bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0);
 179                SSYNC();
 180        } else {
 181                SSYNC();
 182                /* Read the last byte of packet with odd size from address fifo + 4
 183                 * to trigger 1 byte access to EP0 FIFO.
 184                 */
 185                if (len == 1)
 186                        *dst = (u8)inw((unsigned long)fifo + 4);
 187                else {
 188                        if (unlikely((unsigned long)dst & 0x01))
 189                                insw_8((unsigned long)fifo, dst, len >> 1);
 190                        else
 191                                insw((unsigned long)fifo, dst, len >> 1);
 192
 193                        if (len & 0x01)
 194                                *(dst + len - 1) = (u8)inw((unsigned long)fifo + 4);
 195                }
 196        }
 197        dev_dbg(musb->controller, "%cX ep%d fifo %p count %d buf %p\n",
 198                        'R', hw_ep->epnum, fifo, len, dst);
 199
 200        dump_fifo_data(dst, len);
 201}
 202
 203static irqreturn_t blackfin_interrupt(int irq, void *__hci)
 204{
 205        unsigned long   flags;
 206        irqreturn_t     retval = IRQ_NONE;
 207        struct musb     *musb = __hci;
 208
 209        spin_lock_irqsave(&musb->lock, flags);
 210
 211        musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
 212        musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
 213        musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
 214
 215        if (musb->int_usb || musb->int_tx || musb->int_rx) {
 216                musb_writeb(musb->mregs, MUSB_INTRUSB, musb->int_usb);
 217                musb_writew(musb->mregs, MUSB_INTRTX, musb->int_tx);
 218                musb_writew(musb->mregs, MUSB_INTRRX, musb->int_rx);
 219                retval = musb_interrupt(musb);
 220        }
 221
 222        /* Start sampling ID pin, when plug is removed from MUSB */
 223        if ((musb->xceiv->otg->state == OTG_STATE_B_IDLE
 224                || musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON) ||
 225                (musb->int_usb & MUSB_INTR_DISCONNECT && is_host_active(musb))) {
 226                mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY);
 227                musb->a_wait_bcon = TIMER_DELAY;
 228        }
 229
 230        spin_unlock_irqrestore(&musb->lock, flags);
 231
 232        return retval;
 233}
 234
 235static void musb_conn_timer_handler(unsigned long _musb)
 236{
 237        struct musb *musb = (void *)_musb;
 238        unsigned long flags;
 239        u16 val;
 240        static u8 toggle;
 241
 242        spin_lock_irqsave(&musb->lock, flags);
 243        switch (musb->xceiv->otg->state) {
 244        case OTG_STATE_A_IDLE:
 245        case OTG_STATE_A_WAIT_BCON:
 246                /* Start a new session */
 247                val = musb_readw(musb->mregs, MUSB_DEVCTL);
 248                val &= ~MUSB_DEVCTL_SESSION;
 249                musb_writew(musb->mregs, MUSB_DEVCTL, val);
 250                val |= MUSB_DEVCTL_SESSION;
 251                musb_writew(musb->mregs, MUSB_DEVCTL, val);
 252                /* Check if musb is host or peripheral. */
 253                val = musb_readw(musb->mregs, MUSB_DEVCTL);
 254
 255                if (!(val & MUSB_DEVCTL_BDEVICE)) {
 256                        gpio_set_value(musb->config->gpio_vrsel, 1);
 257                        musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON;
 258                } else {
 259                        gpio_set_value(musb->config->gpio_vrsel, 0);
 260                        /* Ignore VBUSERROR and SUSPEND IRQ */
 261                        val = musb_readb(musb->mregs, MUSB_INTRUSBE);
 262                        val &= ~MUSB_INTR_VBUSERROR;
 263                        musb_writeb(musb->mregs, MUSB_INTRUSBE, val);
 264
 265                        val = MUSB_INTR_SUSPEND | MUSB_INTR_VBUSERROR;
 266                        musb_writeb(musb->mregs, MUSB_INTRUSB, val);
 267                        musb->xceiv->otg->state = OTG_STATE_B_IDLE;
 268                }
 269                mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY);
 270                break;
 271        case OTG_STATE_B_IDLE:
 272                /*
 273                 * Start a new session.  It seems that MUSB needs taking
 274                 * some time to recognize the type of the plug inserted?
 275                 */
 276                val = musb_readw(musb->mregs, MUSB_DEVCTL);
 277                val |= MUSB_DEVCTL_SESSION;
 278                musb_writew(musb->mregs, MUSB_DEVCTL, val);
 279                val = musb_readw(musb->mregs, MUSB_DEVCTL);
 280
 281                if (!(val & MUSB_DEVCTL_BDEVICE)) {
 282                        gpio_set_value(musb->config->gpio_vrsel, 1);
 283                        musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON;
 284                } else {
 285                        gpio_set_value(musb->config->gpio_vrsel, 0);
 286
 287                        /* Ignore VBUSERROR and SUSPEND IRQ */
 288                        val = musb_readb(musb->mregs, MUSB_INTRUSBE);
 289                        val &= ~MUSB_INTR_VBUSERROR;
 290                        musb_writeb(musb->mregs, MUSB_INTRUSBE, val);
 291
 292                        val = MUSB_INTR_SUSPEND | MUSB_INTR_VBUSERROR;
 293                        musb_writeb(musb->mregs, MUSB_INTRUSB, val);
 294
 295                        /* Toggle the Soft Conn bit, so that we can response to
 296                         * the inserting of either A-plug or B-plug.
 297                         */
 298                        if (toggle) {
 299                                val = musb_readb(musb->mregs, MUSB_POWER);
 300                                val &= ~MUSB_POWER_SOFTCONN;
 301                                musb_writeb(musb->mregs, MUSB_POWER, val);
 302                                toggle = 0;
 303                        } else {
 304                                val = musb_readb(musb->mregs, MUSB_POWER);
 305                                val |= MUSB_POWER_SOFTCONN;
 306                                musb_writeb(musb->mregs, MUSB_POWER, val);
 307                                toggle = 1;
 308                        }
 309                        /* The delay time is set to 1/4 second by default,
 310                         * shortening it, if accelerating A-plug detection
 311                         * is needed in OTG mode.
 312                         */
 313                        mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY / 4);
 314                }
 315                break;
 316        default:
 317                dev_dbg(musb->controller, "%s state not handled\n",
 318                        usb_otg_state_string(musb->xceiv->otg->state));
 319                break;
 320        }
 321        spin_unlock_irqrestore(&musb->lock, flags);
 322
 323        dev_dbg(musb->controller, "state is %s\n",
 324                usb_otg_state_string(musb->xceiv->otg->state));
 325}
 326
 327static void bfin_musb_enable(struct musb *musb)
 328{
 329        /* REVISIT is this really correct ? */
 330}
 331
 332static void bfin_musb_disable(struct musb *musb)
 333{
 334}
 335
 336static void bfin_musb_set_vbus(struct musb *musb, int is_on)
 337{
 338        int value = musb->config->gpio_vrsel_active;
 339        if (!is_on)
 340                value = !value;
 341        gpio_set_value(musb->config->gpio_vrsel, value);
 342
 343        dev_dbg(musb->controller, "VBUS %s, devctl %02x "
 344                /* otg %3x conf %08x prcm %08x */ "\n",
 345                usb_otg_state_string(musb->xceiv->otg->state),
 346                musb_readb(musb->mregs, MUSB_DEVCTL));
 347}
 348
 349static int bfin_musb_set_power(struct usb_phy *x, unsigned mA)
 350{
 351        return 0;
 352}
 353
 354static int bfin_musb_vbus_status(struct musb *musb)
 355{
 356        return 0;
 357}
 358
 359static int bfin_musb_set_mode(struct musb *musb, u8 musb_mode)
 360{
 361        return -EIO;
 362}
 363
 364static int bfin_musb_adjust_channel_params(struct dma_channel *channel,
 365                                u16 packet_sz, u8 *mode,
 366                                dma_addr_t *dma_addr, u32 *len)
 367{
 368        struct musb_dma_channel *musb_channel = channel->private_data;
 369
 370        /*
 371         * Anomaly 05000450 might cause data corruption when using DMA
 372         * MODE 1 transmits with short packet.  So to work around this,
 373         * we truncate all MODE 1 transfers down to a multiple of the
 374         * max packet size, and then do the last short packet transfer
 375         * (if there is any) using MODE 0.
 376         */
 377        if (ANOMALY_05000450) {
 378                if (musb_channel->transmit && *mode == 1)
 379                        *len = *len - (*len % packet_sz);
 380        }
 381
 382        return 0;
 383}
 384
 385static void bfin_musb_reg_init(struct musb *musb)
 386{
 387        if (ANOMALY_05000346) {
 388                bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value);
 389                SSYNC();
 390        }
 391
 392        if (ANOMALY_05000347) {
 393                bfin_write_USB_APHY_CNTRL(0x0);
 394                SSYNC();
 395        }
 396
 397        /* Configure PLL oscillator register */
 398        bfin_write_USB_PLLOSC_CTRL(0x3080 |
 399                        ((480/musb->config->clkin) << 1));
 400        SSYNC();
 401
 402        bfin_write_USB_SRP_CLKDIV((get_sclk()/1000) / 32 - 1);
 403        SSYNC();
 404
 405        bfin_write_USB_EP_NI0_RXMAXP(64);
 406        SSYNC();
 407
 408        bfin_write_USB_EP_NI0_TXMAXP(64);
 409        SSYNC();
 410
 411        /* Route INTRUSB/INTR_RX/INTR_TX to USB_INT0*/
 412        bfin_write_USB_GLOBINTR(0x7);
 413        SSYNC();
 414
 415        bfin_write_USB_GLOBAL_CTL(GLOBAL_ENA | EP1_TX_ENA | EP2_TX_ENA |
 416                                EP3_TX_ENA | EP4_TX_ENA | EP5_TX_ENA |
 417                                EP6_TX_ENA | EP7_TX_ENA | EP1_RX_ENA |
 418                                EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA |
 419                                EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA);
 420        SSYNC();
 421}
 422
 423static int bfin_musb_init(struct musb *musb)
 424{
 425
 426        /*
 427         * Rev 1.0 BF549 EZ-KITs require PE7 to be high for both DEVICE
 428         * and OTG HOST modes, while rev 1.1 and greater require PE7 to
 429         * be low for DEVICE mode and high for HOST mode. We set it high
 430         * here because we are in host mode
 431         */
 432
 433        if (gpio_request(musb->config->gpio_vrsel, "USB_VRSEL")) {
 434                printk(KERN_ERR "Failed ro request USB_VRSEL GPIO_%d\n",
 435                        musb->config->gpio_vrsel);
 436                return -ENODEV;
 437        }
 438        gpio_direction_output(musb->config->gpio_vrsel, 0);
 439
 440        musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
 441        if (IS_ERR_OR_NULL(musb->xceiv)) {
 442                gpio_free(musb->config->gpio_vrsel);
 443                return -EPROBE_DEFER;
 444        }
 445
 446        bfin_musb_reg_init(musb);
 447
 448        setup_timer(&musb_conn_timer, musb_conn_timer_handler,
 449                        (unsigned long) musb);
 450
 451        musb->xceiv->set_power = bfin_musb_set_power;
 452
 453        musb->isr = blackfin_interrupt;
 454        musb->double_buffer_not_ok = true;
 455
 456        return 0;
 457}
 458
 459static int bfin_musb_exit(struct musb *musb)
 460{
 461        gpio_free(musb->config->gpio_vrsel);
 462        usb_put_phy(musb->xceiv);
 463
 464        return 0;
 465}
 466
 467static const struct musb_platform_ops bfin_ops = {
 468        .quirks         = MUSB_DMA_INVENTRA,
 469        .init           = bfin_musb_init,
 470        .exit           = bfin_musb_exit,
 471
 472        .fifo_offset    = bfin_fifo_offset,
 473        .readb          = bfin_readb,
 474        .writeb         = bfin_writeb,
 475        .readw          = bfin_readw,
 476        .writew         = bfin_writew,
 477        .readl          = bfin_readl,
 478        .writel         = bfin_writel,
 479        .fifo_mode      = 2,
 480        .read_fifo      = bfin_read_fifo,
 481        .write_fifo     = bfin_write_fifo,
 482#ifdef CONFIG_USB_INVENTRA_DMA
 483        .dma_init       = musbhs_dma_controller_create,
 484        .dma_exit       = musbhs_dma_controller_destroy,
 485#endif
 486        .enable         = bfin_musb_enable,
 487        .disable        = bfin_musb_disable,
 488
 489        .set_mode       = bfin_musb_set_mode,
 490
 491        .vbus_status    = bfin_musb_vbus_status,
 492        .set_vbus       = bfin_musb_set_vbus,
 493
 494        .adjust_channel_params = bfin_musb_adjust_channel_params,
 495};
 496
 497static u64 bfin_dmamask = DMA_BIT_MASK(32);
 498
 499static int bfin_probe(struct platform_device *pdev)
 500{
 501        struct resource musb_resources[2];
 502        struct musb_hdrc_platform_data  *pdata = dev_get_platdata(&pdev->dev);
 503        struct platform_device          *musb;
 504        struct bfin_glue                *glue;
 505
 506        int                             ret = -ENOMEM;
 507
 508        glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
 509        if (!glue)
 510                goto err0;
 511
 512        musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
 513        if (!musb)
 514                goto err0;
 515
 516        musb->dev.parent                = &pdev->dev;
 517        musb->dev.dma_mask              = &bfin_dmamask;
 518        musb->dev.coherent_dma_mask     = bfin_dmamask;
 519
 520        glue->dev                       = &pdev->dev;
 521        glue->musb                      = musb;
 522
 523        pdata->platform_ops             = &bfin_ops;
 524
 525        glue->phy = usb_phy_generic_register();
 526        if (IS_ERR(glue->phy))
 527                goto err1;
 528        platform_set_drvdata(pdev, glue);
 529
 530        memset(musb_resources, 0x00, sizeof(*musb_resources) *
 531                        ARRAY_SIZE(musb_resources));
 532
 533        musb_resources[0].name = pdev->resource[0].name;
 534        musb_resources[0].start = pdev->resource[0].start;
 535        musb_resources[0].end = pdev->resource[0].end;
 536        musb_resources[0].flags = pdev->resource[0].flags;
 537
 538        musb_resources[1].name = pdev->resource[1].name;
 539        musb_resources[1].start = pdev->resource[1].start;
 540        musb_resources[1].end = pdev->resource[1].end;
 541        musb_resources[1].flags = pdev->resource[1].flags;
 542
 543        ret = platform_device_add_resources(musb, musb_resources,
 544                        ARRAY_SIZE(musb_resources));
 545        if (ret) {
 546                dev_err(&pdev->dev, "failed to add resources\n");
 547                goto err2;
 548        }
 549
 550        ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
 551        if (ret) {
 552                dev_err(&pdev->dev, "failed to add platform_data\n");
 553                goto err2;
 554        }
 555
 556        ret = platform_device_add(musb);
 557        if (ret) {
 558                dev_err(&pdev->dev, "failed to register musb device\n");
 559                goto err2;
 560        }
 561
 562        return 0;
 563
 564err2:
 565        usb_phy_generic_unregister(glue->phy);
 566
 567err1:
 568        platform_device_put(musb);
 569
 570err0:
 571        return ret;
 572}
 573
 574static int bfin_remove(struct platform_device *pdev)
 575{
 576        struct bfin_glue                *glue = platform_get_drvdata(pdev);
 577
 578        platform_device_unregister(glue->musb);
 579        usb_phy_generic_unregister(glue->phy);
 580
 581        return 0;
 582}
 583
 584static int __maybe_unused bfin_suspend(struct device *dev)
 585{
 586        struct bfin_glue        *glue = dev_get_drvdata(dev);
 587        struct musb             *musb = glue_to_musb(glue);
 588
 589        if (is_host_active(musb))
 590                /*
 591                 * During hibernate gpio_vrsel will change from high to low
 592                 * low which will generate wakeup event resume the system
 593                 * immediately.  Set it to 0 before hibernate to avoid this
 594                 * wakeup event.
 595                 */
 596                gpio_set_value(musb->config->gpio_vrsel, 0);
 597
 598        return 0;
 599}
 600
 601static int __maybe_unused bfin_resume(struct device *dev)
 602{
 603        struct bfin_glue        *glue = dev_get_drvdata(dev);
 604        struct musb             *musb = glue_to_musb(glue);
 605
 606        bfin_musb_reg_init(musb);
 607
 608        return 0;
 609}
 610
 611static SIMPLE_DEV_PM_OPS(bfin_pm_ops, bfin_suspend, bfin_resume);
 612
 613static struct platform_driver bfin_driver = {
 614        .probe          = bfin_probe,
 615        .remove         = bfin_remove,
 616        .driver         = {
 617                .name   = "musb-blackfin",
 618                .pm     = &bfin_pm_ops,
 619        },
 620};
 621
 622MODULE_DESCRIPTION("Blackfin MUSB Glue Layer");
 623MODULE_AUTHOR("Bryan Wy <cooloney@kernel.org>");
 624MODULE_LICENSE("GPL v2");
 625module_platform_driver(bfin_driver);
 626