uboot/drivers/usb/musb-new/musb_dsps.c
<<
>>
Prefs
   1/*
   2 * Texas Instruments DSPS platforms "glue layer"
   3 *
   4 * Copyright (C) 2012, by Texas Instruments
   5 *
   6 * Based on the am35x "glue layer" code.
   7 *
   8 * This file is part of the Inventra Controller Driver for Linux.
   9 *
  10 * The Inventra Controller Driver for Linux is free software; you
  11 * can redistribute it and/or modify it under the terms of the GNU
  12 * General Public License version 2 as published by the Free Software
  13 * Foundation.
  14 *
  15 * The Inventra Controller Driver for Linux is distributed in
  16 * the hope that it will be useful, but WITHOUT ANY WARRANTY;
  17 * without even the implied warranty of MERCHANTABILITY or
  18 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
  19 * License for more details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with The Inventra Controller Driver for Linux ; if not,
  23 * write to the Free Software Foundation, Inc., 59 Temple Place,
  24 * Suite 330, Boston, MA  02111-1307  USA
  25 *
  26 * musb_dsps.c will be a common file for all the TI DSPS platforms
  27 * such as dm64x, dm36x, dm35x, da8x, am35x and ti81x.
  28 * For now only ti81x is using this and in future davinci.c, am35x.c
  29 * da8xx.c would be merged to this file after testing.
  30 */
  31
  32#ifndef __UBOOT__
  33#include <linux/init.h>
  34#include <linux/io.h>
  35#include <linux/err.h>
  36#include <linux/platform_device.h>
  37#include <linux/dma-mapping.h>
  38#include <linux/pm_runtime.h>
  39#include <linux/module.h>
  40
  41#include <linux/of.h>
  42#include <linux/of_device.h>
  43#include <linux/of_address.h>
  44
  45#include <plat/usb.h>
  46#else
  47#include <common.h>
  48#include <asm/omap_musb.h>
  49#include "linux-compat.h"
  50#endif
  51
  52#include "musb_core.h"
  53
  54/**
  55 * avoid using musb_readx()/musb_writex() as glue layer should not be
  56 * dependent on musb core layer symbols.
  57 */
  58static inline u8 dsps_readb(const void __iomem *addr, unsigned offset)
  59        { return __raw_readb(addr + offset); }
  60
  61static inline u32 dsps_readl(const void __iomem *addr, unsigned offset)
  62        { return __raw_readl(addr + offset); }
  63
  64static inline void dsps_writeb(void __iomem *addr, unsigned offset, u8 data)
  65        { __raw_writeb(data, addr + offset); }
  66
  67static inline void dsps_writel(void __iomem *addr, unsigned offset, u32 data)
  68        { __raw_writel(data, addr + offset); }
  69
  70/**
  71 * DSPS musb wrapper register offset.
  72 * FIXME: This should be expanded to have all the wrapper registers from TI DSPS
  73 * musb ips.
  74 */
  75struct dsps_musb_wrapper {
  76        u16     revision;
  77        u16     control;
  78        u16     status;
  79        u16     eoi;
  80        u16     epintr_set;
  81        u16     epintr_clear;
  82        u16     epintr_status;
  83        u16     coreintr_set;
  84        u16     coreintr_clear;
  85        u16     coreintr_status;
  86        u16     phy_utmi;
  87        u16     mode;
  88
  89        /* bit positions for control */
  90        unsigned        reset:5;
  91
  92        /* bit positions for interrupt */
  93        unsigned        usb_shift:5;
  94        u32             usb_mask;
  95        u32             usb_bitmap;
  96        unsigned        drvvbus:5;
  97
  98        unsigned        txep_shift:5;
  99        u32             txep_mask;
 100        u32             txep_bitmap;
 101
 102        unsigned        rxep_shift:5;
 103        u32             rxep_mask;
 104        u32             rxep_bitmap;
 105
 106        /* bit positions for phy_utmi */
 107        unsigned        otg_disable:5;
 108
 109        /* bit positions for mode */
 110        unsigned        iddig:5;
 111        /* miscellaneous stuff */
 112        u32             musb_core_offset;
 113        u8              poll_seconds;
 114};
 115
 116static const struct dsps_musb_wrapper ti81xx_driver_data __devinitconst = {
 117        .revision               = 0x00,
 118        .control                = 0x14,
 119        .status                 = 0x18,
 120        .eoi                    = 0x24,
 121        .epintr_set             = 0x38,
 122        .epintr_clear           = 0x40,
 123        .epintr_status          = 0x30,
 124        .coreintr_set           = 0x3c,
 125        .coreintr_clear         = 0x44,
 126        .coreintr_status        = 0x34,
 127        .phy_utmi               = 0xe0,
 128        .mode                   = 0xe8,
 129        .reset                  = 0,
 130        .otg_disable            = 21,
 131        .iddig                  = 8,
 132        .usb_shift              = 0,
 133        .usb_mask               = 0x1ff,
 134        .usb_bitmap             = (0x1ff << 0),
 135        .drvvbus                = 8,
 136        .txep_shift             = 0,
 137        .txep_mask              = 0xffff,
 138        .txep_bitmap            = (0xffff << 0),
 139        .rxep_shift             = 16,
 140        .rxep_mask              = 0xfffe,
 141        .rxep_bitmap            = (0xfffe << 16),
 142        .musb_core_offset       = 0x400,
 143        .poll_seconds           = 2,
 144};
 145
 146/**
 147 * DSPS glue structure.
 148 */
 149struct dsps_glue {
 150        struct device *dev;
 151        struct platform_device *musb;   /* child musb pdev */
 152        const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
 153        struct timer_list timer;        /* otg_workaround timer */
 154};
 155
 156/**
 157 * dsps_musb_enable - enable interrupts
 158 */
 159static void dsps_musb_enable(struct musb *musb)
 160{
 161#ifndef __UBOOT__
 162        struct device *dev = musb->controller;
 163        struct platform_device *pdev = to_platform_device(dev->parent);
 164        struct dsps_glue *glue = platform_get_drvdata(pdev);
 165        const struct dsps_musb_wrapper *wrp = glue->wrp;
 166#else
 167        const struct dsps_musb_wrapper *wrp = &ti81xx_driver_data;
 168#endif
 169        void __iomem *reg_base = musb->ctrl_base;
 170        u32 epmask, coremask;
 171
 172        /* Workaround: setup IRQs through both register sets. */
 173        epmask = ((musb->epmask & wrp->txep_mask) << wrp->txep_shift) |
 174               ((musb->epmask & wrp->rxep_mask) << wrp->rxep_shift);
 175        coremask = (wrp->usb_bitmap & ~MUSB_INTR_SOF);
 176
 177        dsps_writel(reg_base, wrp->epintr_set, epmask);
 178        dsps_writel(reg_base, wrp->coreintr_set, coremask);
 179        /* Force the DRVVBUS IRQ so we can start polling for ID change. */
 180#ifndef __UBOOT__
 181        if (is_otg_enabled(musb))
 182                dsps_writel(reg_base, wrp->coreintr_set,
 183                            (1 << wrp->drvvbus) << wrp->usb_shift);
 184#endif
 185}
 186
 187/**
 188 * dsps_musb_disable - disable HDRC and flush interrupts
 189 */
 190static void dsps_musb_disable(struct musb *musb)
 191{
 192#ifndef __UBOOT__
 193        struct device *dev = musb->controller;
 194        struct platform_device *pdev = to_platform_device(dev->parent);
 195        struct dsps_glue *glue = platform_get_drvdata(pdev);
 196        const struct dsps_musb_wrapper *wrp = glue->wrp;
 197        void __iomem *reg_base = musb->ctrl_base;
 198
 199        dsps_writel(reg_base, wrp->coreintr_clear, wrp->usb_bitmap);
 200        dsps_writel(reg_base, wrp->epintr_clear,
 201                         wrp->txep_bitmap | wrp->rxep_bitmap);
 202        dsps_writeb(musb->mregs, MUSB_DEVCTL, 0);
 203        dsps_writel(reg_base, wrp->eoi, 0);
 204#endif
 205}
 206
 207#ifndef __UBOOT__
 208static void otg_timer(unsigned long _musb)
 209{
 210        struct musb *musb = (void *)_musb;
 211        void __iomem *mregs = musb->mregs;
 212        struct device *dev = musb->controller;
 213        struct platform_device *pdev = to_platform_device(dev->parent);
 214        struct dsps_glue *glue = platform_get_drvdata(pdev);
 215        const struct dsps_musb_wrapper *wrp = glue->wrp;
 216        u8 devctl;
 217        unsigned long flags;
 218
 219        /*
 220         * We poll because DSPS IP's won't expose several OTG-critical
 221         * status change events (from the transceiver) otherwise.
 222         */
 223        devctl = dsps_readb(mregs, MUSB_DEVCTL);
 224        dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl,
 225                                otg_state_string(musb->xceiv->state));
 226
 227        spin_lock_irqsave(&musb->lock, flags);
 228        switch (musb->xceiv->state) {
 229        case OTG_STATE_A_WAIT_BCON:
 230                devctl &= ~MUSB_DEVCTL_SESSION;
 231                dsps_writeb(musb->mregs, MUSB_DEVCTL, devctl);
 232
 233                devctl = dsps_readb(musb->mregs, MUSB_DEVCTL);
 234                if (devctl & MUSB_DEVCTL_BDEVICE) {
 235                        musb->xceiv->state = OTG_STATE_B_IDLE;
 236                        MUSB_DEV_MODE(musb);
 237                } else {
 238                        musb->xceiv->state = OTG_STATE_A_IDLE;
 239                        MUSB_HST_MODE(musb);
 240                }
 241                break;
 242        case OTG_STATE_A_WAIT_VFALL:
 243                musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
 244                dsps_writel(musb->ctrl_base, wrp->coreintr_set,
 245                            MUSB_INTR_VBUSERROR << wrp->usb_shift);
 246                break;
 247        case OTG_STATE_B_IDLE:
 248                if (!is_peripheral_enabled(musb))
 249                        break;
 250
 251                devctl = dsps_readb(mregs, MUSB_DEVCTL);
 252                if (devctl & MUSB_DEVCTL_BDEVICE)
 253                        mod_timer(&glue->timer,
 254                                        jiffies + wrp->poll_seconds * HZ);
 255                else
 256                        musb->xceiv->state = OTG_STATE_A_IDLE;
 257                break;
 258        default:
 259                break;
 260        }
 261        spin_unlock_irqrestore(&musb->lock, flags);
 262}
 263
 264static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
 265{
 266        struct device *dev = musb->controller;
 267        struct platform_device *pdev = to_platform_device(dev->parent);
 268        struct dsps_glue *glue = platform_get_drvdata(pdev);
 269        static unsigned long last_timer;
 270
 271        if (!is_otg_enabled(musb))
 272                return;
 273
 274        if (timeout == 0)
 275                timeout = jiffies + msecs_to_jiffies(3);
 276
 277        /* Never idle if active, or when VBUS timeout is not set as host */
 278        if (musb->is_active || (musb->a_wait_bcon == 0 &&
 279                                musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
 280                dev_dbg(musb->controller, "%s active, deleting timer\n",
 281                                otg_state_string(musb->xceiv->state));
 282                del_timer(&glue->timer);
 283                last_timer = jiffies;
 284                return;
 285        }
 286
 287        if (time_after(last_timer, timeout) && timer_pending(&glue->timer)) {
 288                dev_dbg(musb->controller,
 289                        "Longer idle timer already pending, ignoring...\n");
 290                return;
 291        }
 292        last_timer = timeout;
 293
 294        dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n",
 295                otg_state_string(musb->xceiv->state),
 296                        jiffies_to_msecs(timeout - jiffies));
 297        mod_timer(&glue->timer, timeout);
 298}
 299#endif
 300
 301static irqreturn_t dsps_interrupt(int irq, void *hci)
 302{
 303        struct musb  *musb = hci;
 304        void __iomem *reg_base = musb->ctrl_base;
 305#ifndef __UBOOT__
 306        struct device *dev = musb->controller;
 307        struct platform_device *pdev = to_platform_device(dev->parent);
 308        struct dsps_glue *glue = platform_get_drvdata(pdev);
 309        const struct dsps_musb_wrapper *wrp = glue->wrp;
 310#else
 311        const struct dsps_musb_wrapper *wrp = &ti81xx_driver_data;
 312#endif
 313        unsigned long flags;
 314        irqreturn_t ret = IRQ_NONE;
 315        u32 epintr, usbintr;
 316
 317        spin_lock_irqsave(&musb->lock, flags);
 318
 319        /* Get endpoint interrupts */
 320        epintr = dsps_readl(reg_base, wrp->epintr_status);
 321        musb->int_rx = (epintr & wrp->rxep_bitmap) >> wrp->rxep_shift;
 322        musb->int_tx = (epintr & wrp->txep_bitmap) >> wrp->txep_shift;
 323
 324        if (epintr)
 325                dsps_writel(reg_base, wrp->epintr_status, epintr);
 326
 327        /* Get usb core interrupts */
 328        usbintr = dsps_readl(reg_base, wrp->coreintr_status);
 329        if (!usbintr && !epintr)
 330                goto eoi;
 331
 332        musb->int_usb = (usbintr & wrp->usb_bitmap) >> wrp->usb_shift;
 333        if (usbintr)
 334                dsps_writel(reg_base, wrp->coreintr_status, usbintr);
 335
 336        dev_dbg(musb->controller, "usbintr (%x) epintr(%x)\n",
 337                        usbintr, epintr);
 338#ifndef __UBOOT__
 339        /*
 340         * DRVVBUS IRQs are the only proxy we have (a very poor one!) for
 341         * DSPS IP's missing ID change IRQ.  We need an ID change IRQ to
 342         * switch appropriately between halves of the OTG state machine.
 343         * Managing DEVCTL.SESSION per Mentor docs requires that we know its
 344         * value but DEVCTL.BDEVICE is invalid without DEVCTL.SESSION set.
 345         * Also, DRVVBUS pulses for SRP (but not at 5V) ...
 346         */
 347        if ((usbintr & MUSB_INTR_BABBLE) && is_host_enabled(musb))
 348                pr_info("CAUTION: musb: Babble Interrupt Occured\n");
 349
 350        if (usbintr & ((1 << wrp->drvvbus) << wrp->usb_shift)) {
 351                int drvvbus = dsps_readl(reg_base, wrp->status);
 352                void __iomem *mregs = musb->mregs;
 353                u8 devctl = dsps_readb(mregs, MUSB_DEVCTL);
 354                int err;
 355
 356                err = is_host_enabled(musb) && (musb->int_usb &
 357                                                MUSB_INTR_VBUSERROR);
 358                if (err) {
 359                        /*
 360                         * The Mentor core doesn't debounce VBUS as needed
 361                         * to cope with device connect current spikes. This
 362                         * means it's not uncommon for bus-powered devices
 363                         * to get VBUS errors during enumeration.
 364                         *
 365                         * This is a workaround, but newer RTL from Mentor
 366                         * seems to allow a better one: "re"-starting sessions
 367                         * without waiting for VBUS to stop registering in
 368                         * devctl.
 369                         */
 370                        musb->int_usb &= ~MUSB_INTR_VBUSERROR;
 371                        musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
 372                        mod_timer(&glue->timer,
 373                                        jiffies + wrp->poll_seconds * HZ);
 374                        WARNING("VBUS error workaround (delay coming)\n");
 375                } else if (is_host_enabled(musb) && drvvbus) {
 376                        musb->is_active = 1;
 377                        MUSB_HST_MODE(musb);
 378                        musb->xceiv->otg->default_a = 1;
 379                        musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
 380                        del_timer(&glue->timer);
 381                } else {
 382                        musb->is_active = 0;
 383                        MUSB_DEV_MODE(musb);
 384                        musb->xceiv->otg->default_a = 0;
 385                        musb->xceiv->state = OTG_STATE_B_IDLE;
 386                }
 387
 388                /* NOTE: this must complete power-on within 100 ms. */
 389                dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n",
 390                                drvvbus ? "on" : "off",
 391                                otg_state_string(musb->xceiv->state),
 392                                err ? " ERROR" : "",
 393                                devctl);
 394                ret = IRQ_HANDLED;
 395        }
 396#endif
 397
 398        if (musb->int_tx || musb->int_rx || musb->int_usb)
 399                ret |= musb_interrupt(musb);
 400
 401 eoi:
 402        /* EOI needs to be written for the IRQ to be re-asserted. */
 403        if (ret == IRQ_HANDLED || epintr || usbintr)
 404                dsps_writel(reg_base, wrp->eoi, 1);
 405
 406#ifndef __UBOOT__
 407        /* Poll for ID change */
 408        if (is_otg_enabled(musb) && musb->xceiv->state == OTG_STATE_B_IDLE)
 409                mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ);
 410#endif
 411
 412        spin_unlock_irqrestore(&musb->lock, flags);
 413
 414        return ret;
 415}
 416
 417static int dsps_musb_init(struct musb *musb)
 418{
 419#ifndef __UBOOT__
 420        struct device *dev = musb->controller;
 421        struct musb_hdrc_platform_data *plat = dev->platform_data;
 422        struct platform_device *pdev = to_platform_device(dev->parent);
 423        struct dsps_glue *glue = platform_get_drvdata(pdev);
 424        const struct dsps_musb_wrapper *wrp = glue->wrp;
 425        struct omap_musb_board_data *data = plat->board_data;
 426#else
 427        struct omap_musb_board_data *data =
 428                        (struct omap_musb_board_data *)musb->controller;
 429        const struct dsps_musb_wrapper *wrp = &ti81xx_driver_data;
 430#endif
 431        void __iomem *reg_base = musb->ctrl_base;
 432        u32 rev, val;
 433        int status;
 434
 435        /* mentor core register starts at offset of 0x400 from musb base */
 436        musb->mregs += wrp->musb_core_offset;
 437
 438#ifndef __UBOOT__
 439        /* NOP driver needs change if supporting dual instance */
 440        usb_nop_xceiv_register();
 441        musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
 442        if (IS_ERR_OR_NULL(musb->xceiv))
 443                return -ENODEV;
 444#endif
 445
 446        /* Returns zero if e.g. not clocked */
 447        rev = dsps_readl(reg_base, wrp->revision);
 448        if (!rev) {
 449                status = -ENODEV;
 450                goto err0;
 451        }
 452
 453#ifndef __UBOOT__
 454        if (is_host_enabled(musb))
 455                setup_timer(&glue->timer, otg_timer, (unsigned long) musb);
 456#endif
 457
 458        /* Reset the musb */
 459        dsps_writel(reg_base, wrp->control, (1 << wrp->reset));
 460
 461        /* Start the on-chip PHY and its PLL. */
 462        if (data->set_phy_power)
 463                data->set_phy_power(1);
 464
 465        musb->isr = dsps_interrupt;
 466
 467        /* reset the otgdisable bit, needed for host mode to work */
 468        val = dsps_readl(reg_base, wrp->phy_utmi);
 469        val &= ~(1 << wrp->otg_disable);
 470        dsps_writel(musb->ctrl_base, wrp->phy_utmi, val);
 471
 472        /* clear level interrupt */
 473        dsps_writel(reg_base, wrp->eoi, 0);
 474
 475        return 0;
 476err0:
 477#ifndef __UBOOT__
 478        usb_put_phy(musb->xceiv);
 479        usb_nop_xceiv_unregister();
 480#endif
 481        return status;
 482}
 483
 484static int dsps_musb_exit(struct musb *musb)
 485{
 486#ifndef __UBOOT__
 487        struct device *dev = musb->controller;
 488        struct musb_hdrc_platform_data *plat = dev->platform_data;
 489        struct omap_musb_board_data *data = plat->board_data;
 490        struct platform_device *pdev = to_platform_device(dev->parent);
 491        struct dsps_glue *glue = platform_get_drvdata(pdev);
 492#else
 493        struct omap_musb_board_data *data =
 494                        (struct omap_musb_board_data *)musb->controller;
 495#endif
 496
 497#ifndef __UBOOT__
 498        if (is_host_enabled(musb))
 499                del_timer_sync(&glue->timer);
 500#endif
 501
 502        /* Shutdown the on-chip PHY and its PLL. */
 503        if (data->set_phy_power)
 504                data->set_phy_power(0);
 505
 506#ifndef __UBOOT__
 507        /* NOP driver needs change if supporting dual instance */
 508        usb_put_phy(musb->xceiv);
 509        usb_nop_xceiv_unregister();
 510#endif
 511
 512        return 0;
 513}
 514
 515#ifndef __UBOOT__
 516static struct musb_platform_ops dsps_ops = {
 517#else
 518struct musb_platform_ops musb_dsps_ops = {
 519#endif
 520        .init           = dsps_musb_init,
 521        .exit           = dsps_musb_exit,
 522
 523        .enable         = dsps_musb_enable,
 524        .disable        = dsps_musb_disable,
 525
 526#ifndef __UBOOT__
 527        .try_idle       = dsps_musb_try_idle,
 528#endif
 529};
 530
 531#ifndef __UBOOT__
 532static u64 musb_dmamask = DMA_BIT_MASK(32);
 533#endif
 534
 535#ifndef __UBOOT__
 536static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
 537{
 538        struct device *dev = glue->dev;
 539        struct platform_device *pdev = to_platform_device(dev);
 540        struct musb_hdrc_platform_data  *pdata = dev->platform_data;
 541        struct platform_device  *musb;
 542        struct resource *res;
 543        struct resource resources[2];
 544        char res_name[10];
 545        int ret;
 546
 547        /* get memory resource */
 548        sprintf(res_name, "musb%d", id);
 549        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name);
 550        if (!res) {
 551                dev_err(dev, "%s get mem resource failed\n", res_name);
 552                ret = -ENODEV;
 553                goto err0;
 554        }
 555        res->parent = NULL;
 556        resources[0] = *res;
 557
 558        /* get irq resource */
 559        sprintf(res_name, "musb%d-irq", id);
 560        res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name);
 561        if (!res) {
 562                dev_err(dev, "%s get irq resource failed\n", res_name);
 563                ret = -ENODEV;
 564                goto err0;
 565        }
 566        res->parent = NULL;
 567        resources[1] = *res;
 568        resources[1].name = "mc";
 569
 570        /* allocate the child platform device */
 571        musb = platform_device_alloc("musb-hdrc", -1);
 572        if (!musb) {
 573                dev_err(dev, "failed to allocate musb device\n");
 574                ret = -ENOMEM;
 575                goto err0;
 576        }
 577
 578        musb->dev.parent                = dev;
 579        musb->dev.dma_mask              = &musb_dmamask;
 580        musb->dev.coherent_dma_mask     = musb_dmamask;
 581
 582        glue->musb                      = musb;
 583
 584        pdata->platform_ops             = &dsps_ops;
 585
 586        ret = platform_device_add_resources(musb, resources, 2);
 587        if (ret) {
 588                dev_err(dev, "failed to add resources\n");
 589                goto err1;
 590        }
 591
 592        ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
 593        if (ret) {
 594                dev_err(dev, "failed to add platform_data\n");
 595                goto err1;
 596        }
 597
 598        ret = platform_device_add(musb);
 599        if (ret) {
 600                dev_err(dev, "failed to register musb device\n");
 601                goto err1;
 602        }
 603
 604        return 0;
 605
 606err1:
 607        platform_device_put(musb);
 608err0:
 609        return ret;
 610}
 611
 612static void __devexit dsps_delete_musb_pdev(struct dsps_glue *glue)
 613{
 614        platform_device_del(glue->musb);
 615        platform_device_put(glue->musb);
 616}
 617
 618static int __devinit dsps_probe(struct platform_device *pdev)
 619{
 620        const struct platform_device_id *id = platform_get_device_id(pdev);
 621        const struct dsps_musb_wrapper *wrp =
 622                                (struct dsps_musb_wrapper *)id->driver_data;
 623        struct dsps_glue *glue;
 624        struct resource *iomem;
 625        int ret;
 626
 627        /* allocate glue */
 628        glue = kzalloc(sizeof(*glue), GFP_KERNEL);
 629        if (!glue) {
 630                dev_err(&pdev->dev, "unable to allocate glue memory\n");
 631                ret = -ENOMEM;
 632                goto err0;
 633        }
 634
 635        /* get memory resource */
 636        iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 637        if (!iomem) {
 638                dev_err(&pdev->dev, "failed to get usbss mem resourse\n");
 639                ret = -ENODEV;
 640                goto err1;
 641        }
 642
 643        glue->dev = &pdev->dev;
 644
 645        glue->wrp = kmemdup(wrp, sizeof(*wrp), GFP_KERNEL);
 646        if (!glue->wrp) {
 647                dev_err(&pdev->dev, "failed to duplicate wrapper struct memory\n");
 648                ret = -ENOMEM;
 649                goto err1;
 650        }
 651        platform_set_drvdata(pdev, glue);
 652
 653        /* enable the usbss clocks */
 654        pm_runtime_enable(&pdev->dev);
 655
 656        ret = pm_runtime_get_sync(&pdev->dev);
 657        if (ret < 0) {
 658                dev_err(&pdev->dev, "pm_runtime_get_sync FAILED");
 659                goto err2;
 660        }
 661
 662        /* create the child platform device for first instances of musb */
 663        ret = dsps_create_musb_pdev(glue, 0);
 664        if (ret != 0) {
 665                dev_err(&pdev->dev, "failed to create child pdev\n");
 666                goto err3;
 667        }
 668
 669        return 0;
 670
 671err3:
 672        pm_runtime_put(&pdev->dev);
 673err2:
 674        pm_runtime_disable(&pdev->dev);
 675        kfree(glue->wrp);
 676err1:
 677        kfree(glue);
 678err0:
 679        return ret;
 680}
 681static int __devexit dsps_remove(struct platform_device *pdev)
 682{
 683        struct dsps_glue *glue = platform_get_drvdata(pdev);
 684
 685        /* delete the child platform device */
 686        dsps_delete_musb_pdev(glue);
 687
 688        /* disable usbss clocks */
 689        pm_runtime_put(&pdev->dev);
 690        pm_runtime_disable(&pdev->dev);
 691        kfree(glue->wrp);
 692        kfree(glue);
 693        return 0;
 694}
 695
 696#ifdef CONFIG_PM_SLEEP
 697static int dsps_suspend(struct device *dev)
 698{
 699        struct musb_hdrc_platform_data *plat = dev->platform_data;
 700        struct omap_musb_board_data *data = plat->board_data;
 701
 702        /* Shutdown the on-chip PHY and its PLL. */
 703        if (data->set_phy_power)
 704                data->set_phy_power(0);
 705
 706        return 0;
 707}
 708
 709static int dsps_resume(struct device *dev)
 710{
 711        struct musb_hdrc_platform_data *plat = dev->platform_data;
 712        struct omap_musb_board_data *data = plat->board_data;
 713
 714        /* Start the on-chip PHY and its PLL. */
 715        if (data->set_phy_power)
 716                data->set_phy_power(1);
 717
 718        return 0;
 719}
 720#endif
 721
 722static SIMPLE_DEV_PM_OPS(dsps_pm_ops, dsps_suspend, dsps_resume);
 723#endif
 724
 725#ifndef __UBOOT__
 726static const struct platform_device_id musb_dsps_id_table[] __devinitconst = {
 727        {
 728                .name   = "musb-ti81xx",
 729                .driver_data    = (kernel_ulong_t) &ti81xx_driver_data,
 730        },
 731        {  },   /* Terminating Entry */
 732};
 733MODULE_DEVICE_TABLE(platform, musb_dsps_id_table);
 734
 735static const struct of_device_id musb_dsps_of_match[] __devinitconst = {
 736        { .compatible = "musb-ti81xx", },
 737        { .compatible = "ti,ti81xx-musb", },
 738        { .compatible = "ti,am335x-musb", },
 739        {  },
 740};
 741MODULE_DEVICE_TABLE(of, musb_dsps_of_match);
 742
 743static struct platform_driver dsps_usbss_driver = {
 744        .probe          = dsps_probe,
 745        .remove         = __devexit_p(dsps_remove),
 746        .driver         = {
 747                .name   = "musb-dsps",
 748                .pm     = &dsps_pm_ops,
 749                .of_match_table = musb_dsps_of_match,
 750        },
 751        .id_table       = musb_dsps_id_table,
 752};
 753
 754MODULE_DESCRIPTION("TI DSPS MUSB Glue Layer");
 755MODULE_AUTHOR("Ravi B <ravibabu@ti.com>");
 756MODULE_AUTHOR("Ajay Kumar Gupta <ajay.gupta@ti.com>");
 757MODULE_LICENSE("GPL v2");
 758
 759static int __init dsps_init(void)
 760{
 761        return platform_driver_register(&dsps_usbss_driver);
 762}
 763subsys_initcall(dsps_init);
 764
 765static void __exit dsps_exit(void)
 766{
 767        platform_driver_unregister(&dsps_usbss_driver);
 768}
 769module_exit(dsps_exit);
 770#endif
 771