linux/drivers/usb/musb/omap2430.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2005-2007 by Texas Instruments
   3 * Some code has been taken from tusb6010.c
   4 * Copyrights for that are attributable to:
   5 * Copyright (C) 2006 Nokia Corporation
   6 * Tony Lindgren <tony@atomide.com>
   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 */
  27#include <linux/module.h>
  28#include <linux/kernel.h>
  29#include <linux/sched.h>
  30#include <linux/init.h>
  31#include <linux/list.h>
  32#include <linux/io.h>
  33#include <linux/of.h>
  34#include <linux/platform_device.h>
  35#include <linux/dma-mapping.h>
  36#include <linux/pm_runtime.h>
  37#include <linux/err.h>
  38#include <linux/delay.h>
  39#include <linux/usb/musb-omap.h>
  40#include <linux/usb/omap_control_usb.h>
  41
  42#include "musb_core.h"
  43#include "omap2430.h"
  44
  45struct omap2430_glue {
  46        struct device           *dev;
  47        struct platform_device  *musb;
  48        enum omap_musb_vbus_id_status status;
  49        struct work_struct      omap_musb_mailbox_work;
  50        struct device           *control_otghs;
  51};
  52#define glue_to_musb(g)         platform_get_drvdata(g->musb)
  53
  54static struct omap2430_glue     *_glue;
  55
  56static struct timer_list musb_idle_timer;
  57
  58static void musb_do_idle(unsigned long _musb)
  59{
  60        struct musb     *musb = (void *)_musb;
  61        unsigned long   flags;
  62        u8      power;
  63        u8      devctl;
  64
  65        spin_lock_irqsave(&musb->lock, flags);
  66
  67        switch (musb->xceiv->state) {
  68        case OTG_STATE_A_WAIT_BCON:
  69
  70                devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
  71                if (devctl & MUSB_DEVCTL_BDEVICE) {
  72                        musb->xceiv->state = OTG_STATE_B_IDLE;
  73                        MUSB_DEV_MODE(musb);
  74                } else {
  75                        musb->xceiv->state = OTG_STATE_A_IDLE;
  76                        MUSB_HST_MODE(musb);
  77                }
  78                break;
  79        case OTG_STATE_A_SUSPEND:
  80                /* finish RESUME signaling? */
  81                if (musb->port1_status & MUSB_PORT_STAT_RESUME) {
  82                        power = musb_readb(musb->mregs, MUSB_POWER);
  83                        power &= ~MUSB_POWER_RESUME;
  84                        dev_dbg(musb->controller, "root port resume stopped, power %02x\n", power);
  85                        musb_writeb(musb->mregs, MUSB_POWER, power);
  86                        musb->is_active = 1;
  87                        musb->port1_status &= ~(USB_PORT_STAT_SUSPEND
  88                                                | MUSB_PORT_STAT_RESUME);
  89                        musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;
  90                        usb_hcd_poll_rh_status(musb_to_hcd(musb));
  91                        /* NOTE: it might really be A_WAIT_BCON ... */
  92                        musb->xceiv->state = OTG_STATE_A_HOST;
  93                }
  94                break;
  95        case OTG_STATE_A_HOST:
  96                devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
  97                if (devctl &  MUSB_DEVCTL_BDEVICE)
  98                        musb->xceiv->state = OTG_STATE_B_IDLE;
  99                else
 100                        musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
 101        default:
 102                break;
 103        }
 104        spin_unlock_irqrestore(&musb->lock, flags);
 105}
 106
 107
 108static void omap2430_musb_try_idle(struct musb *musb, unsigned long timeout)
 109{
 110        unsigned long           default_timeout = jiffies + msecs_to_jiffies(3);
 111        static unsigned long    last_timer;
 112
 113        if (timeout == 0)
 114                timeout = default_timeout;
 115
 116        /* Never idle if active, or when VBUS timeout is not set as host */
 117        if (musb->is_active || ((musb->a_wait_bcon == 0)
 118                        && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) {
 119                dev_dbg(musb->controller, "%s active, deleting timer\n",
 120                        otg_state_string(musb->xceiv->state));
 121                del_timer(&musb_idle_timer);
 122                last_timer = jiffies;
 123                return;
 124        }
 125
 126        if (time_after(last_timer, timeout)) {
 127                if (!timer_pending(&musb_idle_timer))
 128                        last_timer = timeout;
 129                else {
 130                        dev_dbg(musb->controller, "Longer idle timer already pending, ignoring\n");
 131                        return;
 132                }
 133        }
 134        last_timer = timeout;
 135
 136        dev_dbg(musb->controller, "%s inactive, for idle timer for %lu ms\n",
 137                otg_state_string(musb->xceiv->state),
 138                (unsigned long)jiffies_to_msecs(timeout - jiffies));
 139        mod_timer(&musb_idle_timer, timeout);
 140}
 141
 142static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
 143{
 144        struct usb_otg  *otg = musb->xceiv->otg;
 145        u8              devctl;
 146        unsigned long timeout = jiffies + msecs_to_jiffies(1000);
 147        /* HDRC controls CPEN, but beware current surges during device
 148         * connect.  They can trigger transient overcurrent conditions
 149         * that must be ignored.
 150         */
 151
 152        devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
 153
 154        if (is_on) {
 155                if (musb->xceiv->state == OTG_STATE_A_IDLE) {
 156                        int loops = 100;
 157                        /* start the session */
 158                        devctl |= MUSB_DEVCTL_SESSION;
 159                        musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
 160                        /*
 161                         * Wait for the musb to set as A device to enable the
 162                         * VBUS
 163                         */
 164                        while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) {
 165
 166                                mdelay(5);
 167                                cpu_relax();
 168
 169                                if (time_after(jiffies, timeout)
 170                                    || loops-- <= 0) {
 171                                        dev_err(musb->controller,
 172                                        "configured as A device timeout");
 173                                        break;
 174                                }
 175                        }
 176
 177                        if (otg->set_vbus)
 178                                otg_set_vbus(otg, 1);
 179                } else {
 180                        musb->is_active = 1;
 181                        otg->default_a = 1;
 182                        musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
 183                        devctl |= MUSB_DEVCTL_SESSION;
 184                        MUSB_HST_MODE(musb);
 185                }
 186        } else {
 187                musb->is_active = 0;
 188
 189                /* NOTE:  we're skipping A_WAIT_VFALL -> A_IDLE and
 190                 * jumping right to B_IDLE...
 191                 */
 192
 193                otg->default_a = 0;
 194                musb->xceiv->state = OTG_STATE_B_IDLE;
 195                devctl &= ~MUSB_DEVCTL_SESSION;
 196
 197                MUSB_DEV_MODE(musb);
 198        }
 199        musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
 200
 201        dev_dbg(musb->controller, "VBUS %s, devctl %02x "
 202                /* otg %3x conf %08x prcm %08x */ "\n",
 203                otg_state_string(musb->xceiv->state),
 204                musb_readb(musb->mregs, MUSB_DEVCTL));
 205}
 206
 207static int omap2430_musb_set_mode(struct musb *musb, u8 musb_mode)
 208{
 209        u8      devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
 210
 211        devctl |= MUSB_DEVCTL_SESSION;
 212        musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
 213
 214        return 0;
 215}
 216
 217static inline void omap2430_low_level_exit(struct musb *musb)
 218{
 219        u32 l;
 220
 221        /* in any role */
 222        l = musb_readl(musb->mregs, OTG_FORCESTDBY);
 223        l |= ENABLEFORCE;       /* enable MSTANDBY */
 224        musb_writel(musb->mregs, OTG_FORCESTDBY, l);
 225}
 226
 227static inline void omap2430_low_level_init(struct musb *musb)
 228{
 229        u32 l;
 230
 231        l = musb_readl(musb->mregs, OTG_FORCESTDBY);
 232        l &= ~ENABLEFORCE;      /* disable MSTANDBY */
 233        musb_writel(musb->mregs, OTG_FORCESTDBY, l);
 234}
 235
 236void omap_musb_mailbox(enum omap_musb_vbus_id_status status)
 237{
 238        struct omap2430_glue    *glue = _glue;
 239
 240        if (!glue) {
 241                pr_err("%s: musb core is not yet initialized\n", __func__);
 242                return;
 243        }
 244        glue->status = status;
 245
 246        if (!glue_to_musb(glue)) {
 247                pr_err("%s: musb core is not yet ready\n", __func__);
 248                return;
 249        }
 250
 251        schedule_work(&glue->omap_musb_mailbox_work);
 252}
 253EXPORT_SYMBOL_GPL(omap_musb_mailbox);
 254
 255static void omap_musb_set_mailbox(struct omap2430_glue *glue)
 256{
 257        struct musb *musb = glue_to_musb(glue);
 258        struct device *dev = musb->controller;
 259        struct musb_hdrc_platform_data *pdata = dev->platform_data;
 260        struct omap_musb_board_data *data = pdata->board_data;
 261        struct usb_otg *otg = musb->xceiv->otg;
 262
 263        switch (glue->status) {
 264        case OMAP_MUSB_ID_GROUND:
 265                dev_dbg(dev, "ID GND\n");
 266
 267                otg->default_a = true;
 268                musb->xceiv->state = OTG_STATE_A_IDLE;
 269                musb->xceiv->last_event = USB_EVENT_ID;
 270                if (musb->gadget_driver) {
 271                        pm_runtime_get_sync(dev);
 272                        omap_control_usb_set_mode(glue->control_otghs,
 273                                USB_MODE_HOST);
 274                        omap2430_musb_set_vbus(musb, 1);
 275                }
 276                break;
 277
 278        case OMAP_MUSB_VBUS_VALID:
 279                dev_dbg(dev, "VBUS Connect\n");
 280
 281                otg->default_a = false;
 282                musb->xceiv->state = OTG_STATE_B_IDLE;
 283                musb->xceiv->last_event = USB_EVENT_VBUS;
 284                if (musb->gadget_driver)
 285                        pm_runtime_get_sync(dev);
 286                omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE);
 287                break;
 288
 289        case OMAP_MUSB_ID_FLOAT:
 290        case OMAP_MUSB_VBUS_OFF:
 291                dev_dbg(dev, "VBUS Disconnect\n");
 292
 293                musb->xceiv->last_event = USB_EVENT_NONE;
 294                if (musb->gadget_driver) {
 295                        pm_runtime_mark_last_busy(dev);
 296                        pm_runtime_put_autosuspend(dev);
 297                }
 298
 299                if (data->interface_type == MUSB_INTERFACE_UTMI) {
 300                        if (musb->xceiv->otg->set_vbus)
 301                                otg_set_vbus(musb->xceiv->otg, 0);
 302                }
 303                omap_control_usb_set_mode(glue->control_otghs,
 304                        USB_MODE_DISCONNECT);
 305                break;
 306        default:
 307                dev_dbg(dev, "ID float\n");
 308        }
 309}
 310
 311
 312static void omap_musb_mailbox_work(struct work_struct *mailbox_work)
 313{
 314        struct omap2430_glue *glue = container_of(mailbox_work,
 315                                struct omap2430_glue, omap_musb_mailbox_work);
 316        omap_musb_set_mailbox(glue);
 317}
 318
 319static irqreturn_t omap2430_musb_interrupt(int irq, void *__hci)
 320{
 321        unsigned long   flags;
 322        irqreturn_t     retval = IRQ_NONE;
 323        struct musb     *musb = __hci;
 324
 325        spin_lock_irqsave(&musb->lock, flags);
 326
 327        musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
 328        musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
 329        musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
 330
 331        if (musb->int_usb || musb->int_tx || musb->int_rx)
 332                retval = musb_interrupt(musb);
 333
 334        spin_unlock_irqrestore(&musb->lock, flags);
 335
 336        return retval;
 337}
 338
 339static int omap2430_musb_init(struct musb *musb)
 340{
 341        u32 l;
 342        int status = 0;
 343        struct device *dev = musb->controller;
 344        struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
 345        struct musb_hdrc_platform_data *plat = dev->platform_data;
 346        struct omap_musb_board_data *data = plat->board_data;
 347
 348        /* We require some kind of external transceiver, hooked
 349         * up through ULPI.  TWL4030-family PMICs include one,
 350         * which needs a driver, drivers aren't always needed.
 351         */
 352        if (dev->parent->of_node)
 353                musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent,
 354                    "usb-phy", 0);
 355        else
 356                musb->xceiv = devm_usb_get_phy_dev(dev, 0);
 357
 358        if (IS_ERR_OR_NULL(musb->xceiv)) {
 359                pr_err("HS USB OTG: no transceiver configured\n");
 360                return -EPROBE_DEFER;
 361        }
 362
 363        musb->isr = omap2430_musb_interrupt;
 364
 365        status = pm_runtime_get_sync(dev);
 366        if (status < 0) {
 367                dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
 368                goto err1;
 369        }
 370
 371        l = musb_readl(musb->mregs, OTG_INTERFSEL);
 372
 373        if (data->interface_type == MUSB_INTERFACE_UTMI) {
 374                /* OMAP4 uses Internal PHY GS70 which uses UTMI interface */
 375                l &= ~ULPI_12PIN;       /* Disable ULPI */
 376                l |= UTMI_8BIT;         /* Enable UTMI  */
 377        } else {
 378                l |= ULPI_12PIN;
 379        }
 380
 381        musb_writel(musb->mregs, OTG_INTERFSEL, l);
 382
 383        pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, "
 384                        "sysstatus 0x%x, intrfsel 0x%x, simenable  0x%x\n",
 385                        musb_readl(musb->mregs, OTG_REVISION),
 386                        musb_readl(musb->mregs, OTG_SYSCONFIG),
 387                        musb_readl(musb->mregs, OTG_SYSSTATUS),
 388                        musb_readl(musb->mregs, OTG_INTERFSEL),
 389                        musb_readl(musb->mregs, OTG_SIMENABLE));
 390
 391        setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
 392
 393        if (glue->status != OMAP_MUSB_UNKNOWN)
 394                omap_musb_set_mailbox(glue);
 395
 396        pm_runtime_put_noidle(musb->controller);
 397        return 0;
 398
 399err1:
 400        return status;
 401}
 402
 403static void omap2430_musb_enable(struct musb *musb)
 404{
 405        u8              devctl;
 406        unsigned long timeout = jiffies + msecs_to_jiffies(1000);
 407        struct device *dev = musb->controller;
 408        struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
 409        struct musb_hdrc_platform_data *pdata = dev->platform_data;
 410        struct omap_musb_board_data *data = pdata->board_data;
 411
 412        switch (glue->status) {
 413
 414        case OMAP_MUSB_ID_GROUND:
 415                omap_control_usb_set_mode(glue->control_otghs, USB_MODE_HOST);
 416                if (data->interface_type != MUSB_INTERFACE_UTMI)
 417                        break;
 418                devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
 419                /* start the session */
 420                devctl |= MUSB_DEVCTL_SESSION;
 421                musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
 422                while (musb_readb(musb->mregs, MUSB_DEVCTL) &
 423                                MUSB_DEVCTL_BDEVICE) {
 424                        cpu_relax();
 425
 426                        if (time_after(jiffies, timeout)) {
 427                                dev_err(dev, "configured as A device timeout");
 428                                break;
 429                        }
 430                }
 431                break;
 432
 433        case OMAP_MUSB_VBUS_VALID:
 434                omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE);
 435                break;
 436
 437        default:
 438                break;
 439        }
 440}
 441
 442static void omap2430_musb_disable(struct musb *musb)
 443{
 444        struct device *dev = musb->controller;
 445        struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
 446
 447        if (glue->status != OMAP_MUSB_UNKNOWN)
 448                omap_control_usb_set_mode(glue->control_otghs,
 449                        USB_MODE_DISCONNECT);
 450}
 451
 452static int omap2430_musb_exit(struct musb *musb)
 453{
 454        del_timer_sync(&musb_idle_timer);
 455
 456        omap2430_low_level_exit(musb);
 457
 458        return 0;
 459}
 460
 461static const struct musb_platform_ops omap2430_ops = {
 462        .init           = omap2430_musb_init,
 463        .exit           = omap2430_musb_exit,
 464
 465        .set_mode       = omap2430_musb_set_mode,
 466        .try_idle       = omap2430_musb_try_idle,
 467
 468        .set_vbus       = omap2430_musb_set_vbus,
 469
 470        .enable         = omap2430_musb_enable,
 471        .disable        = omap2430_musb_disable,
 472};
 473
 474static u64 omap2430_dmamask = DMA_BIT_MASK(32);
 475
 476static int omap2430_probe(struct platform_device *pdev)
 477{
 478        struct musb_hdrc_platform_data  *pdata = pdev->dev.platform_data;
 479        struct omap_musb_board_data     *data;
 480        struct platform_device          *musb;
 481        struct omap2430_glue            *glue;
 482        struct device_node              *np = pdev->dev.of_node;
 483        struct musb_hdrc_config         *config;
 484        int                             ret = -ENOMEM;
 485
 486        glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
 487        if (!glue) {
 488                dev_err(&pdev->dev, "failed to allocate glue context\n");
 489                goto err0;
 490        }
 491
 492        musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
 493        if (!musb) {
 494                dev_err(&pdev->dev, "failed to allocate musb device\n");
 495                goto err0;
 496        }
 497
 498        musb->dev.parent                = &pdev->dev;
 499        musb->dev.dma_mask              = &omap2430_dmamask;
 500        musb->dev.coherent_dma_mask     = omap2430_dmamask;
 501
 502        glue->dev                       = &pdev->dev;
 503        glue->musb                      = musb;
 504        glue->status                    = OMAP_MUSB_UNKNOWN;
 505
 506        if (np) {
 507                pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 508                if (!pdata) {
 509                        dev_err(&pdev->dev,
 510                                "failed to allocate musb platfrom data\n");
 511                        goto err2;
 512                }
 513
 514                data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
 515                if (!data) {
 516                        dev_err(&pdev->dev,
 517                                "failed to allocate musb board data\n");
 518                        goto err2;
 519                }
 520
 521                config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL);
 522                if (!config) {
 523                        dev_err(&pdev->dev,
 524                                "failed to allocate musb hdrc config\n");
 525                        goto err2;
 526                }
 527
 528                of_property_read_u32(np, "mode", (u32 *)&pdata->mode);
 529                of_property_read_u32(np, "interface_type",
 530                                                (u32 *)&data->interface_type);
 531                of_property_read_u32(np, "num_eps", (u32 *)&config->num_eps);
 532                of_property_read_u32(np, "ram_bits", (u32 *)&config->ram_bits);
 533                of_property_read_u32(np, "power", (u32 *)&pdata->power);
 534                config->multipoint = of_property_read_bool(np, "multipoint");
 535                pdata->has_mailbox = of_property_read_bool(np,
 536                    "ti,has-mailbox");
 537
 538                pdata->board_data       = data;
 539                pdata->config           = config;
 540        }
 541
 542        if (pdata->has_mailbox) {
 543                glue->control_otghs = omap_get_control_dev();
 544                if (IS_ERR(glue->control_otghs)) {
 545                        dev_vdbg(&pdev->dev, "Failed to get control device\n");
 546                        return -ENODEV;
 547                }
 548        } else {
 549                glue->control_otghs = ERR_PTR(-ENODEV);
 550        }
 551        pdata->platform_ops             = &omap2430_ops;
 552
 553        platform_set_drvdata(pdev, glue);
 554
 555        /*
 556         * REVISIT if we ever have two instances of the wrapper, we will be
 557         * in big trouble
 558         */
 559        _glue   = glue;
 560
 561        INIT_WORK(&glue->omap_musb_mailbox_work, omap_musb_mailbox_work);
 562
 563        ret = platform_device_add_resources(musb, pdev->resource,
 564                        pdev->num_resources);
 565        if (ret) {
 566                dev_err(&pdev->dev, "failed to add resources\n");
 567                goto err2;
 568        }
 569
 570        ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
 571        if (ret) {
 572                dev_err(&pdev->dev, "failed to add platform_data\n");
 573                goto err2;
 574        }
 575
 576        pm_runtime_enable(&pdev->dev);
 577
 578        ret = platform_device_add(musb);
 579        if (ret) {
 580                dev_err(&pdev->dev, "failed to register musb device\n");
 581                goto err2;
 582        }
 583
 584        return 0;
 585
 586err2:
 587        platform_device_put(musb);
 588
 589err0:
 590        return ret;
 591}
 592
 593static int omap2430_remove(struct platform_device *pdev)
 594{
 595        struct omap2430_glue            *glue = platform_get_drvdata(pdev);
 596
 597        cancel_work_sync(&glue->omap_musb_mailbox_work);
 598        platform_device_unregister(glue->musb);
 599
 600        return 0;
 601}
 602
 603#ifdef CONFIG_PM
 604
 605static int omap2430_runtime_suspend(struct device *dev)
 606{
 607        struct omap2430_glue            *glue = dev_get_drvdata(dev);
 608        struct musb                     *musb = glue_to_musb(glue);
 609
 610        if (musb) {
 611                musb->context.otg_interfsel = musb_readl(musb->mregs,
 612                                OTG_INTERFSEL);
 613
 614                omap2430_low_level_exit(musb);
 615                usb_phy_set_suspend(musb->xceiv, 1);
 616        }
 617
 618        return 0;
 619}
 620
 621static int omap2430_runtime_resume(struct device *dev)
 622{
 623        struct omap2430_glue            *glue = dev_get_drvdata(dev);
 624        struct musb                     *musb = glue_to_musb(glue);
 625
 626        if (musb) {
 627                omap2430_low_level_init(musb);
 628                musb_writel(musb->mregs, OTG_INTERFSEL,
 629                                musb->context.otg_interfsel);
 630
 631                usb_phy_set_suspend(musb->xceiv, 0);
 632        }
 633
 634        return 0;
 635}
 636
 637static struct dev_pm_ops omap2430_pm_ops = {
 638        .runtime_suspend = omap2430_runtime_suspend,
 639        .runtime_resume = omap2430_runtime_resume,
 640};
 641
 642#define DEV_PM_OPS      (&omap2430_pm_ops)
 643#else
 644#define DEV_PM_OPS      NULL
 645#endif
 646
 647#ifdef CONFIG_OF
 648static const struct of_device_id omap2430_id_table[] = {
 649        {
 650                .compatible = "ti,omap4-musb"
 651        },
 652        {
 653                .compatible = "ti,omap3-musb"
 654        },
 655        {},
 656};
 657MODULE_DEVICE_TABLE(of, omap2430_id_table);
 658#endif
 659
 660static struct platform_driver omap2430_driver = {
 661        .probe          = omap2430_probe,
 662        .remove         = omap2430_remove,
 663        .driver         = {
 664                .name   = "musb-omap2430",
 665                .pm     = DEV_PM_OPS,
 666                .of_match_table = of_match_ptr(omap2430_id_table),
 667        },
 668};
 669
 670MODULE_DESCRIPTION("OMAP2PLUS MUSB Glue Layer");
 671MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
 672MODULE_LICENSE("GPL v2");
 673
 674static int __init omap2430_init(void)
 675{
 676        return platform_driver_register(&omap2430_driver);
 677}
 678subsys_initcall(omap2430_init);
 679
 680static void __exit omap2430_exit(void)
 681{
 682        platform_driver_unregister(&omap2430_driver);
 683}
 684module_exit(omap2430_exit);
 685
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.