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