linux/drivers/usb/musb/da8xx.c
<<
>>
Prefs
   1/*
   2 * Texas Instruments DA8xx/OMAP-L1x "glue layer"
   3 *
   4 * Copyright (c) 2008-2009 MontaVista Software, Inc. <source@mvista.com>
   5 *
   6 * Based on the DaVinci "glue layer" code.
   7 * Copyright (C) 2005-2006 by Texas Instruments
   8 *
   9 * This file is part of the Inventra Controller Driver for Linux.
  10 *
  11 * The Inventra Controller Driver for Linux is free software; you
  12 * can redistribute it and/or modify it under the terms of the GNU
  13 * General Public License version 2 as published by the Free Software
  14 * Foundation.
  15 *
  16 * The Inventra Controller Driver for Linux is distributed in
  17 * the hope that it will be useful, but WITHOUT ANY WARRANTY;
  18 * without even the implied warranty of MERCHANTABILITY or
  19 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
  20 * License for more details.
  21 *
  22 * You should have received a copy of the GNU General Public License
  23 * along with The Inventra Controller Driver for Linux ; if not,
  24 * write to the Free Software Foundation, Inc., 59 Temple Place,
  25 * Suite 330, Boston, MA  02111-1307  USA
  26 *
  27 */
  28
  29#include <linux/init.h>
  30#include <linux/module.h>
  31#include <linux/clk.h>
  32#include <linux/err.h>
  33#include <linux/io.h>
  34#include <linux/platform_device.h>
  35#include <linux/dma-mapping.h>
  36#include <linux/usb/nop-usb-xceiv.h>
  37
  38#include <mach/da8xx.h>
  39#include <linux/platform_data/usb-davinci.h>
  40
  41#include "musb_core.h"
  42
  43/*
  44 * DA8XX specific definitions
  45 */
  46
  47/* USB 2.0 OTG module registers */
  48#define DA8XX_USB_REVISION_REG  0x00
  49#define DA8XX_USB_CTRL_REG      0x04
  50#define DA8XX_USB_STAT_REG      0x08
  51#define DA8XX_USB_EMULATION_REG 0x0c
  52#define DA8XX_USB_MODE_REG      0x10    /* Transparent, CDC, [Generic] RNDIS */
  53#define DA8XX_USB_AUTOREQ_REG   0x14
  54#define DA8XX_USB_SRP_FIX_TIME_REG 0x18
  55#define DA8XX_USB_TEARDOWN_REG  0x1c
  56#define DA8XX_USB_INTR_SRC_REG  0x20
  57#define DA8XX_USB_INTR_SRC_SET_REG 0x24
  58#define DA8XX_USB_INTR_SRC_CLEAR_REG 0x28
  59#define DA8XX_USB_INTR_MASK_REG 0x2c
  60#define DA8XX_USB_INTR_MASK_SET_REG 0x30
  61#define DA8XX_USB_INTR_MASK_CLEAR_REG 0x34
  62#define DA8XX_USB_INTR_SRC_MASKED_REG 0x38
  63#define DA8XX_USB_END_OF_INTR_REG 0x3c
  64#define DA8XX_USB_GENERIC_RNDIS_EP_SIZE_REG(n) (0x50 + (((n) - 1) << 2))
  65
  66/* Control register bits */
  67#define DA8XX_SOFT_RESET_MASK   1
  68
  69#define DA8XX_USB_TX_EP_MASK    0x1f            /* EP0 + 4 Tx EPs */
  70#define DA8XX_USB_RX_EP_MASK    0x1e            /* 4 Rx EPs */
  71
  72/* USB interrupt register bits */
  73#define DA8XX_INTR_USB_SHIFT    16
  74#define DA8XX_INTR_USB_MASK     (0x1ff << DA8XX_INTR_USB_SHIFT) /* 8 Mentor */
  75                                        /* interrupts and DRVVBUS interrupt */
  76#define DA8XX_INTR_DRVVBUS      0x100
  77#define DA8XX_INTR_RX_SHIFT     8
  78#define DA8XX_INTR_RX_MASK      (DA8XX_USB_RX_EP_MASK << DA8XX_INTR_RX_SHIFT)
  79#define DA8XX_INTR_TX_SHIFT     0
  80#define DA8XX_INTR_TX_MASK      (DA8XX_USB_TX_EP_MASK << DA8XX_INTR_TX_SHIFT)
  81
  82#define DA8XX_MENTOR_CORE_OFFSET 0x400
  83
  84#define CFGCHIP2        IO_ADDRESS(DA8XX_SYSCFG0_BASE + DA8XX_CFGCHIP2_REG)
  85
  86struct da8xx_glue {
  87        struct device           *dev;
  88        struct platform_device  *musb;
  89        struct clk              *clk;
  90};
  91
  92/*
  93 * REVISIT (PM): we should be able to keep the PHY in low power mode most
  94 * of the time (24 MHz oscillator and PLL off, etc.) by setting POWER.D0
  95 * and, when in host mode, autosuspending idle root ports... PHY_PLLON
  96 * (overriding SUSPENDM?) then likely needs to stay off.
  97 */
  98
  99static inline void phy_on(void)
 100{
 101        u32 cfgchip2 = __raw_readl(CFGCHIP2);
 102
 103        /*
 104         * Start the on-chip PHY and its PLL.
 105         */
 106        cfgchip2 &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN);
 107        cfgchip2 |= CFGCHIP2_PHY_PLLON;
 108        __raw_writel(cfgchip2, CFGCHIP2);
 109
 110        pr_info("Waiting for USB PHY clock good...\n");
 111        while (!(__raw_readl(CFGCHIP2) & CFGCHIP2_PHYCLKGD))
 112                cpu_relax();
 113}
 114
 115static inline void phy_off(void)
 116{
 117        u32 cfgchip2 = __raw_readl(CFGCHIP2);
 118
 119        /*
 120         * Ensure that USB 1.1 reference clock is not being sourced from
 121         * USB 2.0 PHY.  Otherwise do not power down the PHY.
 122         */
 123        if (!(cfgchip2 & CFGCHIP2_USB1PHYCLKMUX) &&
 124             (cfgchip2 & CFGCHIP2_USB1SUSPENDM)) {
 125                pr_warning("USB 1.1 clocked from USB 2.0 PHY -- "
 126                           "can't power it down\n");
 127                return;
 128        }
 129
 130        /*
 131         * Power down the on-chip PHY.
 132         */
 133        cfgchip2 |= CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN;
 134        __raw_writel(cfgchip2, CFGCHIP2);
 135}
 136
 137/*
 138 * Because we don't set CTRL.UINT, it's "important" to:
 139 *      - not read/write INTRUSB/INTRUSBE (except during
 140 *        initial setup, as a workaround);
 141 *      - use INTSET/INTCLR instead.
 142 */
 143
 144/**
 145 * da8xx_musb_enable - enable interrupts
 146 */
 147static void da8xx_musb_enable(struct musb *musb)
 148{
 149        void __iomem *reg_base = musb->ctrl_base;
 150        u32 mask;
 151
 152        /* Workaround: setup IRQs through both register sets. */
 153        mask = ((musb->epmask & DA8XX_USB_TX_EP_MASK) << DA8XX_INTR_TX_SHIFT) |
 154               ((musb->epmask & DA8XX_USB_RX_EP_MASK) << DA8XX_INTR_RX_SHIFT) |
 155               DA8XX_INTR_USB_MASK;
 156        musb_writel(reg_base, DA8XX_USB_INTR_MASK_SET_REG, mask);
 157
 158        /* Force the DRVVBUS IRQ so we can start polling for ID change. */
 159        musb_writel(reg_base, DA8XX_USB_INTR_SRC_SET_REG,
 160                        DA8XX_INTR_DRVVBUS << DA8XX_INTR_USB_SHIFT);
 161}
 162
 163/**
 164 * da8xx_musb_disable - disable HDRC and flush interrupts
 165 */
 166static void da8xx_musb_disable(struct musb *musb)
 167{
 168        void __iomem *reg_base = musb->ctrl_base;
 169
 170        musb_writel(reg_base, DA8XX_USB_INTR_MASK_CLEAR_REG,
 171                    DA8XX_INTR_USB_MASK |
 172                    DA8XX_INTR_TX_MASK | DA8XX_INTR_RX_MASK);
 173        musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
 174        musb_writel(reg_base, DA8XX_USB_END_OF_INTR_REG, 0);
 175}
 176
 177#define portstate(stmt)         stmt
 178
 179static void da8xx_musb_set_vbus(struct musb *musb, int is_on)
 180{
 181        WARN_ON(is_on && is_peripheral_active(musb));
 182}
 183
 184#define POLL_SECONDS    2
 185
 186static struct timer_list otg_workaround;
 187
 188static void otg_timer(unsigned long _musb)
 189{
 190        struct musb             *musb = (void *)_musb;
 191        void __iomem            *mregs = musb->mregs;
 192        u8                      devctl;
 193        unsigned long           flags;
 194
 195        /*
 196         * We poll because DaVinci's won't expose several OTG-critical
 197         * status change events (from the transceiver) otherwise.
 198         */
 199        devctl = musb_readb(mregs, MUSB_DEVCTL);
 200        dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl,
 201                otg_state_string(musb->xceiv->state));
 202
 203        spin_lock_irqsave(&musb->lock, flags);
 204        switch (musb->xceiv->state) {
 205        case OTG_STATE_A_WAIT_BCON:
 206                devctl &= ~MUSB_DEVCTL_SESSION;
 207                musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
 208
 209                devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
 210                if (devctl & MUSB_DEVCTL_BDEVICE) {
 211                        musb->xceiv->state = OTG_STATE_B_IDLE;
 212                        MUSB_DEV_MODE(musb);
 213                } else {
 214                        musb->xceiv->state = OTG_STATE_A_IDLE;
 215                        MUSB_HST_MODE(musb);
 216                }
 217                break;
 218        case OTG_STATE_A_WAIT_VFALL:
 219                /*
 220                 * Wait till VBUS falls below SessionEnd (~0.2 V); the 1.3
 221                 * RTL seems to mis-handle session "start" otherwise (or in
 222                 * our case "recover"), in routine "VBUS was valid by the time
 223                 * VBUSERR got reported during enumeration" cases.
 224                 */
 225                if (devctl & MUSB_DEVCTL_VBUS) {
 226                        mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
 227                        break;
 228                }
 229                musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
 230                musb_writel(musb->ctrl_base, DA8XX_USB_INTR_SRC_SET_REG,
 231                            MUSB_INTR_VBUSERROR << DA8XX_INTR_USB_SHIFT);
 232                break;
 233        case OTG_STATE_B_IDLE:
 234                /*
 235                 * There's no ID-changed IRQ, so we have no good way to tell
 236                 * when to switch to the A-Default state machine (by setting
 237                 * the DEVCTL.Session bit).
 238                 *
 239                 * Workaround:  whenever we're in B_IDLE, try setting the
 240                 * session flag every few seconds.  If it works, ID was
 241                 * grounded and we're now in the A-Default state machine.
 242                 *
 243                 * NOTE: setting the session flag is _supposed_ to trigger
 244                 * SRP but clearly it doesn't.
 245                 */
 246                musb_writeb(mregs, MUSB_DEVCTL, devctl | MUSB_DEVCTL_SESSION);
 247                devctl = musb_readb(mregs, MUSB_DEVCTL);
 248                if (devctl & MUSB_DEVCTL_BDEVICE)
 249                        mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
 250                else
 251                        musb->xceiv->state = OTG_STATE_A_IDLE;
 252                break;
 253        default:
 254                break;
 255        }
 256        spin_unlock_irqrestore(&musb->lock, flags);
 257}
 258
 259static void da8xx_musb_try_idle(struct musb *musb, unsigned long timeout)
 260{
 261        static unsigned long last_timer;
 262
 263        if (timeout == 0)
 264                timeout = jiffies + msecs_to_jiffies(3);
 265
 266        /* Never idle if active, or when VBUS timeout is not set as host */
 267        if (musb->is_active || (musb->a_wait_bcon == 0 &&
 268                                musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
 269                dev_dbg(musb->controller, "%s active, deleting timer\n",
 270                        otg_state_string(musb->xceiv->state));
 271                del_timer(&otg_workaround);
 272                last_timer = jiffies;
 273                return;
 274        }
 275
 276        if (time_after(last_timer, timeout) && timer_pending(&otg_workaround)) {
 277                dev_dbg(musb->controller, "Longer idle timer already pending, ignoring...\n");
 278                return;
 279        }
 280        last_timer = timeout;
 281
 282        dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n",
 283                otg_state_string(musb->xceiv->state),
 284                jiffies_to_msecs(timeout - jiffies));
 285        mod_timer(&otg_workaround, timeout);
 286}
 287
 288static irqreturn_t da8xx_musb_interrupt(int irq, void *hci)
 289{
 290        struct musb             *musb = hci;
 291        void __iomem            *reg_base = musb->ctrl_base;
 292        struct usb_otg          *otg = musb->xceiv->otg;
 293        unsigned long           flags;
 294        irqreturn_t             ret = IRQ_NONE;
 295        u32                     status;
 296
 297        spin_lock_irqsave(&musb->lock, flags);
 298
 299        /*
 300         * NOTE: DA8XX shadows the Mentor IRQs.  Don't manage them through
 301         * the Mentor registers (except for setup), use the TI ones and EOI.
 302         */
 303
 304        /* Acknowledge and handle non-CPPI interrupts */
 305        status = musb_readl(reg_base, DA8XX_USB_INTR_SRC_MASKED_REG);
 306        if (!status)
 307                goto eoi;
 308
 309        musb_writel(reg_base, DA8XX_USB_INTR_SRC_CLEAR_REG, status);
 310        dev_dbg(musb->controller, "USB IRQ %08x\n", status);
 311
 312        musb->int_rx = (status & DA8XX_INTR_RX_MASK) >> DA8XX_INTR_RX_SHIFT;
 313        musb->int_tx = (status & DA8XX_INTR_TX_MASK) >> DA8XX_INTR_TX_SHIFT;
 314        musb->int_usb = (status & DA8XX_INTR_USB_MASK) >> DA8XX_INTR_USB_SHIFT;
 315
 316        /*
 317         * DRVVBUS IRQs are the only proxy we have (a very poor one!) for
 318         * DA8xx's missing ID change IRQ.  We need an ID change IRQ to
 319         * switch appropriately between halves of the OTG state machine.
 320         * Managing DEVCTL.Session per Mentor docs requires that we know its
 321         * value but DEVCTL.BDevice is invalid without DEVCTL.Session set.
 322         * Also, DRVVBUS pulses for SRP (but not at 5 V)...
 323         */
 324        if (status & (DA8XX_INTR_DRVVBUS << DA8XX_INTR_USB_SHIFT)) {
 325                int drvvbus = musb_readl(reg_base, DA8XX_USB_STAT_REG);
 326                void __iomem *mregs = musb->mregs;
 327                u8 devctl = musb_readb(mregs, MUSB_DEVCTL);
 328                int err;
 329
 330                err = musb->int_usb & MUSB_INTR_VBUSERROR;
 331                if (err) {
 332                        /*
 333                         * The Mentor core doesn't debounce VBUS as needed
 334                         * to cope with device connect current spikes. This
 335                         * means it's not uncommon for bus-powered devices
 336                         * to get VBUS errors during enumeration.
 337                         *
 338                         * This is a workaround, but newer RTL from Mentor
 339                         * seems to allow a better one: "re"-starting sessions
 340                         * without waiting for VBUS to stop registering in
 341                         * devctl.
 342                         */
 343                        musb->int_usb &= ~MUSB_INTR_VBUSERROR;
 344                        musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
 345                        mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
 346                        WARNING("VBUS error workaround (delay coming)\n");
 347                } else if (drvvbus) {
 348                        MUSB_HST_MODE(musb);
 349                        otg->default_a = 1;
 350                        musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
 351                        portstate(musb->port1_status |= USB_PORT_STAT_POWER);
 352                        del_timer(&otg_workaround);
 353                } else {
 354                        musb->is_active = 0;
 355                        MUSB_DEV_MODE(musb);
 356                        otg->default_a = 0;
 357                        musb->xceiv->state = OTG_STATE_B_IDLE;
 358                        portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
 359                }
 360
 361                dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n",
 362                                drvvbus ? "on" : "off",
 363                                otg_state_string(musb->xceiv->state),
 364                                err ? " ERROR" : "",
 365                                devctl);
 366                ret = IRQ_HANDLED;
 367        }
 368
 369        if (musb->int_tx || musb->int_rx || musb->int_usb)
 370                ret |= musb_interrupt(musb);
 371
 372 eoi:
 373        /* EOI needs to be written for the IRQ to be re-asserted. */
 374        if (ret == IRQ_HANDLED || status)
 375                musb_writel(reg_base, DA8XX_USB_END_OF_INTR_REG, 0);
 376
 377        /* Poll for ID change */
 378        if (musb->xceiv->state == OTG_STATE_B_IDLE)
 379                mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
 380
 381        spin_unlock_irqrestore(&musb->lock, flags);
 382
 383        return ret;
 384}
 385
 386static int da8xx_musb_set_mode(struct musb *musb, u8 musb_mode)
 387{
 388        u32 cfgchip2 = __raw_readl(CFGCHIP2);
 389
 390        cfgchip2 &= ~CFGCHIP2_OTGMODE;
 391        switch (musb_mode) {
 392        case MUSB_HOST:         /* Force VBUS valid, ID = 0 */
 393                cfgchip2 |= CFGCHIP2_FORCE_HOST;
 394                break;
 395        case MUSB_PERIPHERAL:   /* Force VBUS valid, ID = 1 */
 396                cfgchip2 |= CFGCHIP2_FORCE_DEVICE;
 397                break;
 398        case MUSB_OTG:          /* Don't override the VBUS/ID comparators */
 399                cfgchip2 |= CFGCHIP2_NO_OVERRIDE;
 400                break;
 401        default:
 402                dev_dbg(musb->controller, "Trying to set unsupported mode %u\n", musb_mode);
 403        }
 404
 405        __raw_writel(cfgchip2, CFGCHIP2);
 406        return 0;
 407}
 408
 409static int da8xx_musb_init(struct musb *musb)
 410{
 411        void __iomem *reg_base = musb->ctrl_base;
 412        u32 rev;
 413        int ret = -ENODEV;
 414
 415        musb->mregs += DA8XX_MENTOR_CORE_OFFSET;
 416
 417        /* Returns zero if e.g. not clocked */
 418        rev = musb_readl(reg_base, DA8XX_USB_REVISION_REG);
 419        if (!rev)
 420                goto fail;
 421
 422        usb_nop_xceiv_register();
 423        musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
 424        if (IS_ERR_OR_NULL(musb->xceiv)) {
 425                ret = -EPROBE_DEFER;
 426                goto fail;
 427        }
 428
 429        setup_timer(&otg_workaround, otg_timer, (unsigned long)musb);
 430
 431        /* Reset the controller */
 432        musb_writel(reg_base, DA8XX_USB_CTRL_REG, DA8XX_SOFT_RESET_MASK);
 433
 434        /* Start the on-chip PHY and its PLL. */
 435        phy_on();
 436
 437        msleep(5);
 438
 439        /* NOTE: IRQs are in mixed mode, not bypass to pure MUSB */
 440        pr_debug("DA8xx OTG revision %08x, PHY %03x, control %02x\n",
 441                 rev, __raw_readl(CFGCHIP2),
 442                 musb_readb(reg_base, DA8XX_USB_CTRL_REG));
 443
 444        musb->isr = da8xx_musb_interrupt;
 445        return 0;
 446fail:
 447        return ret;
 448}
 449
 450static int da8xx_musb_exit(struct musb *musb)
 451{
 452        del_timer_sync(&otg_workaround);
 453
 454        phy_off();
 455
 456        usb_put_phy(musb->xceiv);
 457        usb_nop_xceiv_unregister();
 458
 459        return 0;
 460}
 461
 462static const struct musb_platform_ops da8xx_ops = {
 463        .init           = da8xx_musb_init,
 464        .exit           = da8xx_musb_exit,
 465
 466        .enable         = da8xx_musb_enable,
 467        .disable        = da8xx_musb_disable,
 468
 469        .set_mode       = da8xx_musb_set_mode,
 470        .try_idle       = da8xx_musb_try_idle,
 471
 472        .set_vbus       = da8xx_musb_set_vbus,
 473};
 474
 475static u64 da8xx_dmamask = DMA_BIT_MASK(32);
 476
 477static int da8xx_probe(struct platform_device *pdev)
 478{
 479        struct musb_hdrc_platform_data  *pdata = pdev->dev.platform_data;
 480        struct platform_device          *musb;
 481        struct da8xx_glue               *glue;
 482
 483        struct clk                      *clk;
 484
 485        int                             ret = -ENOMEM;
 486
 487        glue = kzalloc(sizeof(*glue), GFP_KERNEL);
 488        if (!glue) {
 489                dev_err(&pdev->dev, "failed to allocate glue context\n");
 490                goto err0;
 491        }
 492
 493        musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
 494        if (!musb) {
 495                dev_err(&pdev->dev, "failed to allocate musb device\n");
 496                goto err1;
 497        }
 498
 499        clk = clk_get(&pdev->dev, "usb20");
 500        if (IS_ERR(clk)) {
 501                dev_err(&pdev->dev, "failed to get clock\n");
 502                ret = PTR_ERR(clk);
 503                goto err3;
 504        }
 505
 506        ret = clk_enable(clk);
 507        if (ret) {
 508                dev_err(&pdev->dev, "failed to enable clock\n");
 509                goto err4;
 510        }
 511
 512        musb->dev.parent                = &pdev->dev;
 513        musb->dev.dma_mask              = &da8xx_dmamask;
 514        musb->dev.coherent_dma_mask     = da8xx_dmamask;
 515
 516        glue->dev                       = &pdev->dev;
 517        glue->musb                      = musb;
 518        glue->clk                       = clk;
 519
 520        pdata->platform_ops             = &da8xx_ops;
 521
 522        platform_set_drvdata(pdev, glue);
 523
 524        ret = platform_device_add_resources(musb, pdev->resource,
 525                        pdev->num_resources);
 526        if (ret) {
 527                dev_err(&pdev->dev, "failed to add resources\n");
 528                goto err5;
 529        }
 530
 531        ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
 532        if (ret) {
 533                dev_err(&pdev->dev, "failed to add platform_data\n");
 534                goto err5;
 535        }
 536
 537        ret = platform_device_add(musb);
 538        if (ret) {
 539                dev_err(&pdev->dev, "failed to register musb device\n");
 540                goto err5;
 541        }
 542
 543        return 0;
 544
 545err5:
 546        clk_disable(clk);
 547
 548err4:
 549        clk_put(clk);
 550
 551err3:
 552        platform_device_put(musb);
 553
 554err1:
 555        kfree(glue);
 556
 557err0:
 558        return ret;
 559}
 560
 561static int da8xx_remove(struct platform_device *pdev)
 562{
 563        struct da8xx_glue               *glue = platform_get_drvdata(pdev);
 564
 565        platform_device_unregister(glue->musb);
 566        clk_disable(glue->clk);
 567        clk_put(glue->clk);
 568        kfree(glue);
 569
 570        return 0;
 571}
 572
 573static struct platform_driver da8xx_driver = {
 574        .probe          = da8xx_probe,
 575        .remove         = da8xx_remove,
 576        .driver         = {
 577                .name   = "musb-da8xx",
 578        },
 579};
 580
 581MODULE_DESCRIPTION("DA8xx/OMAP-L1x MUSB Glue Layer");
 582MODULE_AUTHOR("Sergei Shtylyov <sshtylyov@ru.mvista.com>");
 583MODULE_LICENSE("GPL v2");
 584module_platform_driver(da8xx_driver);
 585