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/module.h>
  30#include <linux/clk.h>
  31#include <linux/err.h>
  32#include <linux/io.h>
  33#include <linux/platform_device.h>
  34#include <linux/dma-mapping.h>
  35#include <linux/usb/usb_phy_generic.h>
  36
  37#include <mach/da8xx.h>
  38#include <linux/platform_data/usb-davinci.h>
  39
  40#include "musb_core.h"
  41
  42/*
  43 * DA8XX specific definitions
  44 */
  45
  46/* USB 2.0 OTG module registers */
  47#define DA8XX_USB_REVISION_REG  0x00
  48#define DA8XX_USB_CTRL_REG      0x04
  49#define DA8XX_USB_STAT_REG      0x08
  50#define DA8XX_USB_EMULATION_REG 0x0c
  51#define DA8XX_USB_MODE_REG      0x10    /* Transparent, CDC, [Generic] RNDIS */
  52#define DA8XX_USB_AUTOREQ_REG   0x14
  53#define DA8XX_USB_SRP_FIX_TIME_REG 0x18
  54#define DA8XX_USB_TEARDOWN_REG  0x1c
  55#define DA8XX_USB_INTR_SRC_REG  0x20
  56#define DA8XX_USB_INTR_SRC_SET_REG 0x24
  57#define DA8XX_USB_INTR_SRC_CLEAR_REG 0x28
  58#define DA8XX_USB_INTR_MASK_REG 0x2c
  59#define DA8XX_USB_INTR_MASK_SET_REG 0x30
  60#define DA8XX_USB_INTR_MASK_CLEAR_REG 0x34
  61#define DA8XX_USB_INTR_SRC_MASKED_REG 0x38
  62#define DA8XX_USB_END_OF_INTR_REG 0x3c
  63#define DA8XX_USB_GENERIC_RNDIS_EP_SIZE_REG(n) (0x50 + (((n) - 1) << 2))
  64
  65/* Control register bits */
  66#define DA8XX_SOFT_RESET_MASK   1
  67
  68#define DA8XX_USB_TX_EP_MASK    0x1f            /* EP0 + 4 Tx EPs */
  69#define DA8XX_USB_RX_EP_MASK    0x1e            /* 4 Rx EPs */
  70
  71/* USB interrupt register bits */
  72#define DA8XX_INTR_USB_SHIFT    16
  73#define DA8XX_INTR_USB_MASK     (0x1ff << DA8XX_INTR_USB_SHIFT) /* 8 Mentor */
  74                                        /* interrupts and DRVVBUS interrupt */
  75#define DA8XX_INTR_DRVVBUS      0x100
  76#define DA8XX_INTR_RX_SHIFT     8
  77#define DA8XX_INTR_RX_MASK      (DA8XX_USB_RX_EP_MASK << DA8XX_INTR_RX_SHIFT)
  78#define DA8XX_INTR_TX_SHIFT     0
  79#define DA8XX_INTR_TX_MASK      (DA8XX_USB_TX_EP_MASK << DA8XX_INTR_TX_SHIFT)
  80
  81#define DA8XX_MENTOR_CORE_OFFSET 0x400
  82
  83#define CFGCHIP2        IO_ADDRESS(DA8XX_SYSCFG0_BASE + DA8XX_CFGCHIP2_REG)
  84
  85struct da8xx_glue {
  86        struct device           *dev;
  87        struct platform_device  *musb;
  88        struct platform_device  *phy;
  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                usb_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                        usb_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                usb_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                                usb_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        musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
 423        if (IS_ERR_OR_NULL(musb->xceiv)) {
 424                ret = -EPROBE_DEFER;
 425                goto fail;
 426        }
 427
 428        setup_timer(&otg_workaround, otg_timer, (unsigned long)musb);
 429
 430        /* Reset the controller */
 431        musb_writel(reg_base, DA8XX_USB_CTRL_REG, DA8XX_SOFT_RESET_MASK);
 432
 433        /* Start the on-chip PHY and its PLL. */
 434        phy_on();
 435
 436        msleep(5);
 437
 438        /* NOTE: IRQs are in mixed mode, not bypass to pure MUSB */
 439        pr_debug("DA8xx OTG revision %08x, PHY %03x, control %02x\n",
 440                 rev, __raw_readl(CFGCHIP2),
 441                 musb_readb(reg_base, DA8XX_USB_CTRL_REG));
 442
 443        musb->isr = da8xx_musb_interrupt;
 444        return 0;
 445fail:
 446        return ret;
 447}
 448
 449static int da8xx_musb_exit(struct musb *musb)
 450{
 451        del_timer_sync(&otg_workaround);
 452
 453        phy_off();
 454
 455        usb_put_phy(musb->xceiv);
 456
 457        return 0;
 458}
 459
 460static const struct musb_platform_ops da8xx_ops = {
 461        .init           = da8xx_musb_init,
 462        .exit           = da8xx_musb_exit,
 463
 464        .enable         = da8xx_musb_enable,
 465        .disable        = da8xx_musb_disable,
 466
 467        .set_mode       = da8xx_musb_set_mode,
 468        .try_idle       = da8xx_musb_try_idle,
 469
 470        .set_vbus       = da8xx_musb_set_vbus,
 471};
 472
 473static const struct platform_device_info da8xx_dev_info = {
 474        .name           = "musb-hdrc",
 475        .id             = PLATFORM_DEVID_AUTO,
 476        .dma_mask       = DMA_BIT_MASK(32),
 477};
 478
 479static int da8xx_probe(struct platform_device *pdev)
 480{
 481        struct resource musb_resources[2];
 482        struct musb_hdrc_platform_data  *pdata = dev_get_platdata(&pdev->dev);
 483        struct platform_device          *musb;
 484        struct da8xx_glue               *glue;
 485        struct platform_device_info     pinfo;
 486        struct clk                      *clk;
 487
 488        int                             ret = -ENOMEM;
 489
 490        glue = kzalloc(sizeof(*glue), GFP_KERNEL);
 491        if (!glue) {
 492                dev_err(&pdev->dev, "failed to allocate glue context\n");
 493                goto err0;
 494        }
 495
 496        clk = clk_get(&pdev->dev, "usb20");
 497        if (IS_ERR(clk)) {
 498                dev_err(&pdev->dev, "failed to get clock\n");
 499                ret = PTR_ERR(clk);
 500                goto err3;
 501        }
 502
 503        ret = clk_enable(clk);
 504        if (ret) {
 505                dev_err(&pdev->dev, "failed to enable clock\n");
 506                goto err4;
 507        }
 508
 509        glue->dev                       = &pdev->dev;
 510        glue->clk                       = clk;
 511
 512        pdata->platform_ops             = &da8xx_ops;
 513
 514        glue->phy = usb_phy_generic_register();
 515        if (IS_ERR(glue->phy)) {
 516                ret = PTR_ERR(glue->phy);
 517                goto err5;
 518        }
 519        platform_set_drvdata(pdev, glue);
 520
 521        memset(musb_resources, 0x00, sizeof(*musb_resources) *
 522                        ARRAY_SIZE(musb_resources));
 523
 524        musb_resources[0].name = pdev->resource[0].name;
 525        musb_resources[0].start = pdev->resource[0].start;
 526        musb_resources[0].end = pdev->resource[0].end;
 527        musb_resources[0].flags = pdev->resource[0].flags;
 528
 529        musb_resources[1].name = pdev->resource[1].name;
 530        musb_resources[1].start = pdev->resource[1].start;
 531        musb_resources[1].end = pdev->resource[1].end;
 532        musb_resources[1].flags = pdev->resource[1].flags;
 533
 534        pinfo = da8xx_dev_info;
 535        pinfo.parent = &pdev->dev;
 536        pinfo.res = musb_resources;
 537        pinfo.num_res = ARRAY_SIZE(musb_resources);
 538        pinfo.data = pdata;
 539        pinfo.size_data = sizeof(*pdata);
 540
 541        glue->musb = musb = platform_device_register_full(&pinfo);
 542        if (IS_ERR(musb)) {
 543                ret = PTR_ERR(musb);
 544                dev_err(&pdev->dev, "failed to register musb device: %d\n", ret);
 545                goto err6;
 546        }
 547
 548        return 0;
 549
 550err6:
 551        usb_phy_generic_unregister(glue->phy);
 552
 553err5:
 554        clk_disable(clk);
 555
 556err4:
 557        clk_put(clk);
 558
 559err3:
 560        kfree(glue);
 561
 562err0:
 563        return ret;
 564}
 565
 566static int da8xx_remove(struct platform_device *pdev)
 567{
 568        struct da8xx_glue               *glue = platform_get_drvdata(pdev);
 569
 570        platform_device_unregister(glue->musb);
 571        usb_phy_generic_unregister(glue->phy);
 572        clk_disable(glue->clk);
 573        clk_put(glue->clk);
 574        kfree(glue);
 575
 576        return 0;
 577}
 578
 579static struct platform_driver da8xx_driver = {
 580        .probe          = da8xx_probe,
 581        .remove         = da8xx_remove,
 582        .driver         = {
 583                .name   = "musb-da8xx",
 584        },
 585};
 586
 587MODULE_DESCRIPTION("DA8xx/OMAP-L1x MUSB Glue Layer");
 588MODULE_AUTHOR("Sergei Shtylyov <sshtylyov@ru.mvista.com>");
 589MODULE_LICENSE("GPL v2");
 590module_platform_driver(da8xx_driver);
 591