Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 
0003 /*
0004  * Texas Instruments AM35x "glue layer"
0005  *
0006  * Copyright (c) 2010, by Texas Instruments
0007  *
0008  * Based on the DA8xx "glue layer" code.
0009  * Copyright (c) 2008-2009, MontaVista Software, Inc. <source@mvista.com>
0010  *
0011  * This file is part of the Inventra Controller Driver for Linux.
0012  */
0013 
0014 #include <linux/module.h>
0015 #include <linux/clk.h>
0016 #include <linux/err.h>
0017 #include <linux/io.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/dma-mapping.h>
0020 #include <linux/usb/usb_phy_generic.h>
0021 #include <linux/platform_data/usb-omap.h>
0022 
0023 #include "musb_core.h"
0024 
0025 /*
0026  * AM35x specific definitions
0027  */
0028 /* USB 2.0 OTG module registers */
0029 #define USB_REVISION_REG    0x00
0030 #define USB_CTRL_REG        0x04
0031 #define USB_STAT_REG        0x08
0032 #define USB_EMULATION_REG   0x0c
0033 /* 0x10 Reserved */
0034 #define USB_AUTOREQ_REG     0x14
0035 #define USB_SRP_FIX_TIME_REG    0x18
0036 #define USB_TEARDOWN_REG    0x1c
0037 #define EP_INTR_SRC_REG     0x20
0038 #define EP_INTR_SRC_SET_REG 0x24
0039 #define EP_INTR_SRC_CLEAR_REG   0x28
0040 #define EP_INTR_MASK_REG    0x2c
0041 #define EP_INTR_MASK_SET_REG    0x30
0042 #define EP_INTR_MASK_CLEAR_REG  0x34
0043 #define EP_INTR_SRC_MASKED_REG  0x38
0044 #define CORE_INTR_SRC_REG   0x40
0045 #define CORE_INTR_SRC_SET_REG   0x44
0046 #define CORE_INTR_SRC_CLEAR_REG 0x48
0047 #define CORE_INTR_MASK_REG  0x4c
0048 #define CORE_INTR_MASK_SET_REG  0x50
0049 #define CORE_INTR_MASK_CLEAR_REG 0x54
0050 #define CORE_INTR_SRC_MASKED_REG 0x58
0051 /* 0x5c Reserved */
0052 #define USB_END_OF_INTR_REG 0x60
0053 
0054 /* Control register bits */
0055 #define AM35X_SOFT_RESET_MASK   1
0056 
0057 /* USB interrupt register bits */
0058 #define AM35X_INTR_USB_SHIFT    16
0059 #define AM35X_INTR_USB_MASK (0x1ff << AM35X_INTR_USB_SHIFT)
0060 #define AM35X_INTR_DRVVBUS  0x100
0061 #define AM35X_INTR_RX_SHIFT 16
0062 #define AM35X_INTR_TX_SHIFT 0
0063 #define AM35X_TX_EP_MASK    0xffff      /* EP0 + 15 Tx EPs */
0064 #define AM35X_RX_EP_MASK    0xfffe      /* 15 Rx EPs */
0065 #define AM35X_TX_INTR_MASK  (AM35X_TX_EP_MASK << AM35X_INTR_TX_SHIFT)
0066 #define AM35X_RX_INTR_MASK  (AM35X_RX_EP_MASK << AM35X_INTR_RX_SHIFT)
0067 
0068 #define USB_MENTOR_CORE_OFFSET  0x400
0069 
0070 struct am35x_glue {
0071     struct device       *dev;
0072     struct platform_device  *musb;
0073     struct platform_device  *phy;
0074     struct clk      *phy_clk;
0075     struct clk      *clk;
0076 };
0077 
0078 /*
0079  * am35x_musb_enable - enable interrupts
0080  */
0081 static void am35x_musb_enable(struct musb *musb)
0082 {
0083     void __iomem *reg_base = musb->ctrl_base;
0084     u32 epmask;
0085 
0086     /* Workaround: setup IRQs through both register sets. */
0087     epmask = ((musb->epmask & AM35X_TX_EP_MASK) << AM35X_INTR_TX_SHIFT) |
0088            ((musb->epmask & AM35X_RX_EP_MASK) << AM35X_INTR_RX_SHIFT);
0089 
0090     musb_writel(reg_base, EP_INTR_MASK_SET_REG, epmask);
0091     musb_writel(reg_base, CORE_INTR_MASK_SET_REG, AM35X_INTR_USB_MASK);
0092 
0093     /* Force the DRVVBUS IRQ so we can start polling for ID change. */
0094     musb_writel(reg_base, CORE_INTR_SRC_SET_REG,
0095             AM35X_INTR_DRVVBUS << AM35X_INTR_USB_SHIFT);
0096 }
0097 
0098 /*
0099  * am35x_musb_disable - disable HDRC and flush interrupts
0100  */
0101 static void am35x_musb_disable(struct musb *musb)
0102 {
0103     void __iomem *reg_base = musb->ctrl_base;
0104 
0105     musb_writel(reg_base, CORE_INTR_MASK_CLEAR_REG, AM35X_INTR_USB_MASK);
0106     musb_writel(reg_base, EP_INTR_MASK_CLEAR_REG,
0107              AM35X_TX_INTR_MASK | AM35X_RX_INTR_MASK);
0108     musb_writel(reg_base, USB_END_OF_INTR_REG, 0);
0109 }
0110 
0111 #define portstate(stmt)     stmt
0112 
0113 static void am35x_musb_set_vbus(struct musb *musb, int is_on)
0114 {
0115     WARN_ON(is_on && is_peripheral_active(musb));
0116 }
0117 
0118 #define POLL_SECONDS    2
0119 
0120 static void otg_timer(struct timer_list *t)
0121 {
0122     struct musb     *musb = from_timer(musb, t, dev_timer);
0123     void __iomem        *mregs = musb->mregs;
0124     u8          devctl;
0125     unsigned long       flags;
0126 
0127     /*
0128      * We poll because AM35x's won't expose several OTG-critical
0129      * status change events (from the transceiver) otherwise.
0130      */
0131     devctl = musb_readb(mregs, MUSB_DEVCTL);
0132     dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl,
0133         usb_otg_state_string(musb->xceiv->otg->state));
0134 
0135     spin_lock_irqsave(&musb->lock, flags);
0136     switch (musb->xceiv->otg->state) {
0137     case OTG_STATE_A_WAIT_BCON:
0138         devctl &= ~MUSB_DEVCTL_SESSION;
0139         musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
0140 
0141         devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
0142         if (devctl & MUSB_DEVCTL_BDEVICE) {
0143             musb->xceiv->otg->state = OTG_STATE_B_IDLE;
0144             MUSB_DEV_MODE(musb);
0145         } else {
0146             musb->xceiv->otg->state = OTG_STATE_A_IDLE;
0147             MUSB_HST_MODE(musb);
0148         }
0149         break;
0150     case OTG_STATE_A_WAIT_VFALL:
0151         musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
0152         musb_writel(musb->ctrl_base, CORE_INTR_SRC_SET_REG,
0153                 MUSB_INTR_VBUSERROR << AM35X_INTR_USB_SHIFT);
0154         break;
0155     case OTG_STATE_B_IDLE:
0156         devctl = musb_readb(mregs, MUSB_DEVCTL);
0157         if (devctl & MUSB_DEVCTL_BDEVICE)
0158             mod_timer(&musb->dev_timer, jiffies + POLL_SECONDS * HZ);
0159         else
0160             musb->xceiv->otg->state = OTG_STATE_A_IDLE;
0161         break;
0162     default:
0163         break;
0164     }
0165     spin_unlock_irqrestore(&musb->lock, flags);
0166 }
0167 
0168 static void am35x_musb_try_idle(struct musb *musb, unsigned long timeout)
0169 {
0170     static unsigned long last_timer;
0171 
0172     if (timeout == 0)
0173         timeout = jiffies + msecs_to_jiffies(3);
0174 
0175     /* Never idle if active, or when VBUS timeout is not set as host */
0176     if (musb->is_active || (musb->a_wait_bcon == 0 &&
0177                 musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON)) {
0178         dev_dbg(musb->controller, "%s active, deleting timer\n",
0179             usb_otg_state_string(musb->xceiv->otg->state));
0180         del_timer(&musb->dev_timer);
0181         last_timer = jiffies;
0182         return;
0183     }
0184 
0185     if (time_after(last_timer, timeout) && timer_pending(&musb->dev_timer)) {
0186         dev_dbg(musb->controller, "Longer idle timer already pending, ignoring...\n");
0187         return;
0188     }
0189     last_timer = timeout;
0190 
0191     dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n",
0192         usb_otg_state_string(musb->xceiv->otg->state),
0193         jiffies_to_msecs(timeout - jiffies));
0194     mod_timer(&musb->dev_timer, timeout);
0195 }
0196 
0197 static irqreturn_t am35x_musb_interrupt(int irq, void *hci)
0198 {
0199     struct musb  *musb = hci;
0200     void __iomem *reg_base = musb->ctrl_base;
0201     struct device *dev = musb->controller;
0202     struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
0203     struct omap_musb_board_data *data = plat->board_data;
0204     unsigned long flags;
0205     irqreturn_t ret = IRQ_NONE;
0206     u32 epintr, usbintr;
0207 
0208     spin_lock_irqsave(&musb->lock, flags);
0209 
0210     /* Get endpoint interrupts */
0211     epintr = musb_readl(reg_base, EP_INTR_SRC_MASKED_REG);
0212 
0213     if (epintr) {
0214         musb_writel(reg_base, EP_INTR_SRC_CLEAR_REG, epintr);
0215 
0216         musb->int_rx =
0217             (epintr & AM35X_RX_INTR_MASK) >> AM35X_INTR_RX_SHIFT;
0218         musb->int_tx =
0219             (epintr & AM35X_TX_INTR_MASK) >> AM35X_INTR_TX_SHIFT;
0220     }
0221 
0222     /* Get usb core interrupts */
0223     usbintr = musb_readl(reg_base, CORE_INTR_SRC_MASKED_REG);
0224     if (!usbintr && !epintr)
0225         goto eoi;
0226 
0227     if (usbintr) {
0228         musb_writel(reg_base, CORE_INTR_SRC_CLEAR_REG, usbintr);
0229 
0230         musb->int_usb =
0231             (usbintr & AM35X_INTR_USB_MASK) >> AM35X_INTR_USB_SHIFT;
0232     }
0233     /*
0234      * DRVVBUS IRQs are the only proxy we have (a very poor one!) for
0235      * AM35x's missing ID change IRQ.  We need an ID change IRQ to
0236      * switch appropriately between halves of the OTG state machine.
0237      * Managing DEVCTL.SESSION per Mentor docs requires that we know its
0238      * value but DEVCTL.BDEVICE is invalid without DEVCTL.SESSION set.
0239      * Also, DRVVBUS pulses for SRP (but not at 5V) ...
0240      */
0241     if (usbintr & (AM35X_INTR_DRVVBUS << AM35X_INTR_USB_SHIFT)) {
0242         int drvvbus = musb_readl(reg_base, USB_STAT_REG);
0243         void __iomem *mregs = musb->mregs;
0244         u8 devctl = musb_readb(mregs, MUSB_DEVCTL);
0245         int err;
0246 
0247         err = musb->int_usb & MUSB_INTR_VBUSERROR;
0248         if (err) {
0249             /*
0250              * The Mentor core doesn't debounce VBUS as needed
0251              * to cope with device connect current spikes. This
0252              * means it's not uncommon for bus-powered devices
0253              * to get VBUS errors during enumeration.
0254              *
0255              * This is a workaround, but newer RTL from Mentor
0256              * seems to allow a better one: "re"-starting sessions
0257              * without waiting for VBUS to stop registering in
0258              * devctl.
0259              */
0260             musb->int_usb &= ~MUSB_INTR_VBUSERROR;
0261             musb->xceiv->otg->state = OTG_STATE_A_WAIT_VFALL;
0262             mod_timer(&musb->dev_timer, jiffies + POLL_SECONDS * HZ);
0263             WARNING("VBUS error workaround (delay coming)\n");
0264         } else if (drvvbus) {
0265             MUSB_HST_MODE(musb);
0266             musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
0267             portstate(musb->port1_status |= USB_PORT_STAT_POWER);
0268             del_timer(&musb->dev_timer);
0269         } else {
0270             musb->is_active = 0;
0271             MUSB_DEV_MODE(musb);
0272             musb->xceiv->otg->state = OTG_STATE_B_IDLE;
0273             portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
0274         }
0275 
0276         /* NOTE: this must complete power-on within 100 ms. */
0277         dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n",
0278                 drvvbus ? "on" : "off",
0279                 usb_otg_state_string(musb->xceiv->otg->state),
0280                 err ? " ERROR" : "",
0281                 devctl);
0282         ret = IRQ_HANDLED;
0283     }
0284 
0285     /* Drop spurious RX and TX if device is disconnected */
0286     if (musb->int_usb & MUSB_INTR_DISCONNECT) {
0287         musb->int_tx = 0;
0288         musb->int_rx = 0;
0289     }
0290 
0291     if (musb->int_tx || musb->int_rx || musb->int_usb)
0292         ret |= musb_interrupt(musb);
0293 
0294 eoi:
0295     /* EOI needs to be written for the IRQ to be re-asserted. */
0296     if (ret == IRQ_HANDLED || epintr || usbintr) {
0297         /* clear level interrupt */
0298         if (data->clear_irq)
0299             data->clear_irq();
0300         /* write EOI */
0301         musb_writel(reg_base, USB_END_OF_INTR_REG, 0);
0302     }
0303 
0304     /* Poll for ID change */
0305     if (musb->xceiv->otg->state == OTG_STATE_B_IDLE)
0306         mod_timer(&musb->dev_timer, jiffies + POLL_SECONDS * HZ);
0307 
0308     spin_unlock_irqrestore(&musb->lock, flags);
0309 
0310     return ret;
0311 }
0312 
0313 static int am35x_musb_set_mode(struct musb *musb, u8 musb_mode)
0314 {
0315     struct device *dev = musb->controller;
0316     struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
0317     struct omap_musb_board_data *data = plat->board_data;
0318     int     retval = 0;
0319 
0320     if (data->set_mode)
0321         data->set_mode(musb_mode);
0322     else
0323         retval = -EIO;
0324 
0325     return retval;
0326 }
0327 
0328 static int am35x_musb_init(struct musb *musb)
0329 {
0330     struct device *dev = musb->controller;
0331     struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
0332     struct omap_musb_board_data *data = plat->board_data;
0333     void __iomem *reg_base = musb->ctrl_base;
0334     u32 rev;
0335 
0336     musb->mregs += USB_MENTOR_CORE_OFFSET;
0337 
0338     /* Returns zero if e.g. not clocked */
0339     rev = musb_readl(reg_base, USB_REVISION_REG);
0340     if (!rev)
0341         return -ENODEV;
0342 
0343     musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
0344     if (IS_ERR_OR_NULL(musb->xceiv))
0345         return -EPROBE_DEFER;
0346 
0347     timer_setup(&musb->dev_timer, otg_timer, 0);
0348 
0349     /* Reset the musb */
0350     if (data->reset)
0351         data->reset();
0352 
0353     /* Reset the controller */
0354     musb_writel(reg_base, USB_CTRL_REG, AM35X_SOFT_RESET_MASK);
0355 
0356     /* Start the on-chip PHY and its PLL. */
0357     if (data->set_phy_power)
0358         data->set_phy_power(1);
0359 
0360     msleep(5);
0361 
0362     musb->isr = am35x_musb_interrupt;
0363 
0364     /* clear level interrupt */
0365     if (data->clear_irq)
0366         data->clear_irq();
0367 
0368     return 0;
0369 }
0370 
0371 static int am35x_musb_exit(struct musb *musb)
0372 {
0373     struct device *dev = musb->controller;
0374     struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
0375     struct omap_musb_board_data *data = plat->board_data;
0376 
0377     del_timer_sync(&musb->dev_timer);
0378 
0379     /* Shutdown the on-chip PHY and its PLL. */
0380     if (data->set_phy_power)
0381         data->set_phy_power(0);
0382 
0383     usb_put_phy(musb->xceiv);
0384 
0385     return 0;
0386 }
0387 
0388 /* AM35x supports only 32bit read operation */
0389 static void am35x_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
0390 {
0391     void __iomem *fifo = hw_ep->fifo;
0392     u32     val;
0393     int     i;
0394 
0395     /* Read for 32bit-aligned destination address */
0396     if (likely((0x03 & (unsigned long) dst) == 0) && len >= 4) {
0397         readsl(fifo, dst, len >> 2);
0398         dst += len & ~0x03;
0399         len &= 0x03;
0400     }
0401     /*
0402      * Now read the remaining 1 to 3 byte or complete length if
0403      * unaligned address.
0404      */
0405     if (len > 4) {
0406         for (i = 0; i < (len >> 2); i++) {
0407             *(u32 *) dst = musb_readl(fifo, 0);
0408             dst += 4;
0409         }
0410         len &= 0x03;
0411     }
0412     if (len > 0) {
0413         val = musb_readl(fifo, 0);
0414         memcpy(dst, &val, len);
0415     }
0416 }
0417 
0418 static const struct musb_platform_ops am35x_ops = {
0419     .quirks     = MUSB_DMA_INVENTRA | MUSB_INDEXED_EP,
0420     .init       = am35x_musb_init,
0421     .exit       = am35x_musb_exit,
0422 
0423     .read_fifo  = am35x_read_fifo,
0424 #ifdef CONFIG_USB_INVENTRA_DMA
0425     .dma_init   = musbhs_dma_controller_create,
0426     .dma_exit   = musbhs_dma_controller_destroy,
0427 #endif
0428     .enable     = am35x_musb_enable,
0429     .disable    = am35x_musb_disable,
0430 
0431     .set_mode   = am35x_musb_set_mode,
0432     .try_idle   = am35x_musb_try_idle,
0433 
0434     .set_vbus   = am35x_musb_set_vbus,
0435 };
0436 
0437 static const struct platform_device_info am35x_dev_info = {
0438     .name       = "musb-hdrc",
0439     .id     = PLATFORM_DEVID_AUTO,
0440     .dma_mask   = DMA_BIT_MASK(32),
0441 };
0442 
0443 static int am35x_probe(struct platform_device *pdev)
0444 {
0445     struct musb_hdrc_platform_data  *pdata = dev_get_platdata(&pdev->dev);
0446     struct platform_device      *musb;
0447     struct am35x_glue       *glue;
0448     struct platform_device_info pinfo;
0449     struct clk          *phy_clk;
0450     struct clk          *clk;
0451 
0452     int             ret = -ENOMEM;
0453 
0454     glue = kzalloc(sizeof(*glue), GFP_KERNEL);
0455     if (!glue)
0456         goto err0;
0457 
0458     phy_clk = clk_get(&pdev->dev, "fck");
0459     if (IS_ERR(phy_clk)) {
0460         dev_err(&pdev->dev, "failed to get PHY clock\n");
0461         ret = PTR_ERR(phy_clk);
0462         goto err3;
0463     }
0464 
0465     clk = clk_get(&pdev->dev, "ick");
0466     if (IS_ERR(clk)) {
0467         dev_err(&pdev->dev, "failed to get clock\n");
0468         ret = PTR_ERR(clk);
0469         goto err4;
0470     }
0471 
0472     ret = clk_enable(phy_clk);
0473     if (ret) {
0474         dev_err(&pdev->dev, "failed to enable PHY clock\n");
0475         goto err5;
0476     }
0477 
0478     ret = clk_enable(clk);
0479     if (ret) {
0480         dev_err(&pdev->dev, "failed to enable clock\n");
0481         goto err6;
0482     }
0483 
0484     glue->dev           = &pdev->dev;
0485     glue->phy_clk           = phy_clk;
0486     glue->clk           = clk;
0487 
0488     pdata->platform_ops     = &am35x_ops;
0489 
0490     glue->phy = usb_phy_generic_register();
0491     if (IS_ERR(glue->phy)) {
0492         ret = PTR_ERR(glue->phy);
0493         goto err7;
0494     }
0495     platform_set_drvdata(pdev, glue);
0496 
0497     pinfo = am35x_dev_info;
0498     pinfo.parent = &pdev->dev;
0499     pinfo.res = pdev->resource;
0500     pinfo.num_res = pdev->num_resources;
0501     pinfo.data = pdata;
0502     pinfo.size_data = sizeof(*pdata);
0503     pinfo.fwnode = of_fwnode_handle(pdev->dev.of_node);
0504     pinfo.of_node_reused = true;
0505 
0506     glue->musb = musb = platform_device_register_full(&pinfo);
0507     if (IS_ERR(musb)) {
0508         ret = PTR_ERR(musb);
0509         dev_err(&pdev->dev, "failed to register musb device: %d\n", ret);
0510         goto err8;
0511     }
0512 
0513     return 0;
0514 
0515 err8:
0516     usb_phy_generic_unregister(glue->phy);
0517 
0518 err7:
0519     clk_disable(clk);
0520 
0521 err6:
0522     clk_disable(phy_clk);
0523 
0524 err5:
0525     clk_put(clk);
0526 
0527 err4:
0528     clk_put(phy_clk);
0529 
0530 err3:
0531     kfree(glue);
0532 
0533 err0:
0534     return ret;
0535 }
0536 
0537 static int am35x_remove(struct platform_device *pdev)
0538 {
0539     struct am35x_glue   *glue = platform_get_drvdata(pdev);
0540 
0541     platform_device_unregister(glue->musb);
0542     usb_phy_generic_unregister(glue->phy);
0543     clk_disable(glue->clk);
0544     clk_disable(glue->phy_clk);
0545     clk_put(glue->clk);
0546     clk_put(glue->phy_clk);
0547     kfree(glue);
0548 
0549     return 0;
0550 }
0551 
0552 #ifdef CONFIG_PM_SLEEP
0553 static int am35x_suspend(struct device *dev)
0554 {
0555     struct am35x_glue   *glue = dev_get_drvdata(dev);
0556     struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
0557     struct omap_musb_board_data *data = plat->board_data;
0558 
0559     /* Shutdown the on-chip PHY and its PLL. */
0560     if (data->set_phy_power)
0561         data->set_phy_power(0);
0562 
0563     clk_disable(glue->phy_clk);
0564     clk_disable(glue->clk);
0565 
0566     return 0;
0567 }
0568 
0569 static int am35x_resume(struct device *dev)
0570 {
0571     struct am35x_glue   *glue = dev_get_drvdata(dev);
0572     struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
0573     struct omap_musb_board_data *data = plat->board_data;
0574     int         ret;
0575 
0576     /* Start the on-chip PHY and its PLL. */
0577     if (data->set_phy_power)
0578         data->set_phy_power(1);
0579 
0580     ret = clk_enable(glue->phy_clk);
0581     if (ret) {
0582         dev_err(dev, "failed to enable PHY clock\n");
0583         return ret;
0584     }
0585 
0586     ret = clk_enable(glue->clk);
0587     if (ret) {
0588         dev_err(dev, "failed to enable clock\n");
0589         return ret;
0590     }
0591 
0592     return 0;
0593 }
0594 #endif
0595 
0596 static SIMPLE_DEV_PM_OPS(am35x_pm_ops, am35x_suspend, am35x_resume);
0597 
0598 static struct platform_driver am35x_driver = {
0599     .probe      = am35x_probe,
0600     .remove     = am35x_remove,
0601     .driver     = {
0602         .name   = "musb-am35x",
0603         .pm = &am35x_pm_ops,
0604     },
0605 };
0606 
0607 MODULE_DESCRIPTION("AM35x MUSB Glue Layer");
0608 MODULE_AUTHOR("Ajay Kumar Gupta <ajay.gupta@ti.com>");
0609 MODULE_LICENSE("GPL v2");
0610 module_platform_driver(am35x_driver);