1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Texas Instruments AM35x "glue layer" 4 * 5 * Copyright (c) 2010, by Texas Instruments 6 * 7 * Based on the DA8xx "glue layer" code. 8 * Copyright (c) 2008-2009, MontaVista Software, Inc. <source@mvista.com> 9 * 10 * This file is part of the Inventra Controller Driver for Linux. 11 * 12 */ 13 14 #ifndef __UBOOT__ 15 #include <linux/init.h> 16 #include <linux/module.h> 17 #include <linux/clk.h> 18 #include <linux/err.h> 19 #include <linux/io.h> 20 #include <linux/platform_device.h> 21 #include <linux/dma-mapping.h> 22 23 #include <plat/usb.h> 24 #else 25 #include <common.h> 26 #include <asm/omap_musb.h> 27 #include "linux-compat.h" 28 #endif 29 30 #include "musb_core.h" 31 32 /* 33 * AM35x specific definitions 34 */ 35 /* USB 2.0 OTG module registers */ 36 #define USB_REVISION_REG 0x00 37 #define USB_CTRL_REG 0x04 38 #define USB_STAT_REG 0x08 39 #define USB_EMULATION_REG 0x0c 40 /* 0x10 Reserved */ 41 #define USB_AUTOREQ_REG 0x14 42 #define USB_SRP_FIX_TIME_REG 0x18 43 #define USB_TEARDOWN_REG 0x1c 44 #define EP_INTR_SRC_REG 0x20 45 #define EP_INTR_SRC_SET_REG 0x24 46 #define EP_INTR_SRC_CLEAR_REG 0x28 47 #define EP_INTR_MASK_REG 0x2c 48 #define EP_INTR_MASK_SET_REG 0x30 49 #define EP_INTR_MASK_CLEAR_REG 0x34 50 #define EP_INTR_SRC_MASKED_REG 0x38 51 #define CORE_INTR_SRC_REG 0x40 52 #define CORE_INTR_SRC_SET_REG 0x44 53 #define CORE_INTR_SRC_CLEAR_REG 0x48 54 #define CORE_INTR_MASK_REG 0x4c 55 #define CORE_INTR_MASK_SET_REG 0x50 56 #define CORE_INTR_MASK_CLEAR_REG 0x54 57 #define CORE_INTR_SRC_MASKED_REG 0x58 58 /* 0x5c Reserved */ 59 #define USB_END_OF_INTR_REG 0x60 60 61 /* Control register bits */ 62 #define AM35X_SOFT_RESET_MASK 1 63 64 /* USB interrupt register bits */ 65 #define AM35X_INTR_USB_SHIFT 16 66 #define AM35X_INTR_USB_MASK (0x1ff << AM35X_INTR_USB_SHIFT) 67 #define AM35X_INTR_DRVVBUS 0x100 68 #define AM35X_INTR_RX_SHIFT 16 69 #define AM35X_INTR_TX_SHIFT 0 70 #define AM35X_TX_EP_MASK 0xffff /* EP0 + 15 Tx EPs */ 71 #define AM35X_RX_EP_MASK 0xfffe /* 15 Rx EPs */ 72 #define AM35X_TX_INTR_MASK (AM35X_TX_EP_MASK << AM35X_INTR_TX_SHIFT) 73 #define AM35X_RX_INTR_MASK (AM35X_RX_EP_MASK << AM35X_INTR_RX_SHIFT) 74 75 #define USB_MENTOR_CORE_OFFSET 0x400 76 77 struct am35x_glue { 78 struct device *dev; 79 struct platform_device *musb; 80 struct clk *phy_clk; 81 struct clk *clk; 82 }; 83 #define glue_to_musb(g) platform_get_drvdata(g->musb) 84 85 /* 86 * am35x_musb_enable - enable interrupts 87 */ 88 #ifndef __UBOOT__ 89 static void am35x_musb_enable(struct musb *musb) 90 #else 91 static int am35x_musb_enable(struct musb *musb) 92 #endif 93 { 94 void __iomem *reg_base = musb->ctrl_base; 95 u32 epmask; 96 97 /* Workaround: setup IRQs through both register sets. */ 98 epmask = ((musb->epmask & AM35X_TX_EP_MASK) << AM35X_INTR_TX_SHIFT) | 99 ((musb->epmask & AM35X_RX_EP_MASK) << AM35X_INTR_RX_SHIFT); 100 101 musb_writel(reg_base, EP_INTR_MASK_SET_REG, epmask); 102 musb_writel(reg_base, CORE_INTR_MASK_SET_REG, AM35X_INTR_USB_MASK); 103 104 /* Force the DRVVBUS IRQ so we can start polling for ID change. */ 105 if (is_otg_enabled(musb)) 106 musb_writel(reg_base, CORE_INTR_SRC_SET_REG, 107 AM35X_INTR_DRVVBUS << AM35X_INTR_USB_SHIFT); 108 #ifdef __UBOOT__ 109 return 0; 110 #endif 111 } 112 113 /* 114 * am35x_musb_disable - disable HDRC and flush interrupts 115 */ 116 static void am35x_musb_disable(struct musb *musb) 117 { 118 void __iomem *reg_base = musb->ctrl_base; 119 120 musb_writel(reg_base, CORE_INTR_MASK_CLEAR_REG, AM35X_INTR_USB_MASK); 121 musb_writel(reg_base, EP_INTR_MASK_CLEAR_REG, 122 AM35X_TX_INTR_MASK | AM35X_RX_INTR_MASK); 123 musb_writeb(musb->mregs, MUSB_DEVCTL, 0); 124 musb_writel(reg_base, USB_END_OF_INTR_REG, 0); 125 } 126 127 #ifndef __UBOOT__ 128 #define portstate(stmt) stmt 129 130 static void am35x_musb_set_vbus(struct musb *musb, int is_on) 131 { 132 WARN_ON(is_on && is_peripheral_active(musb)); 133 } 134 135 #define POLL_SECONDS 2 136 137 static struct timer_list otg_workaround; 138 139 static void otg_timer(unsigned long _musb) 140 { 141 struct musb *musb = (void *)_musb; 142 void __iomem *mregs = musb->mregs; 143 u8 devctl; 144 unsigned long flags; 145 146 /* 147 * We poll because AM35x's won't expose several OTG-critical 148 * status change events (from the transceiver) otherwise. 149 */ 150 devctl = musb_readb(mregs, MUSB_DEVCTL); 151 dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl, 152 otg_state_string(musb->xceiv->state)); 153 154 spin_lock_irqsave(&musb->lock, flags); 155 switch (musb->xceiv->state) { 156 case OTG_STATE_A_WAIT_BCON: 157 devctl &= ~MUSB_DEVCTL_SESSION; 158 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); 159 160 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); 161 if (devctl & MUSB_DEVCTL_BDEVICE) { 162 musb->xceiv->state = OTG_STATE_B_IDLE; 163 MUSB_DEV_MODE(musb); 164 } else { 165 musb->xceiv->state = OTG_STATE_A_IDLE; 166 MUSB_HST_MODE(musb); 167 } 168 break; 169 case OTG_STATE_A_WAIT_VFALL: 170 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; 171 musb_writel(musb->ctrl_base, CORE_INTR_SRC_SET_REG, 172 MUSB_INTR_VBUSERROR << AM35X_INTR_USB_SHIFT); 173 break; 174 case OTG_STATE_B_IDLE: 175 if (!is_peripheral_enabled(musb)) 176 break; 177 178 devctl = musb_readb(mregs, MUSB_DEVCTL); 179 if (devctl & MUSB_DEVCTL_BDEVICE) 180 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); 181 else 182 musb->xceiv->state = OTG_STATE_A_IDLE; 183 break; 184 default: 185 break; 186 } 187 spin_unlock_irqrestore(&musb->lock, flags); 188 } 189 190 static void am35x_musb_try_idle(struct musb *musb, unsigned long timeout) 191 { 192 static unsigned long last_timer; 193 194 if (!is_otg_enabled(musb)) 195 return; 196 197 if (timeout == 0) 198 timeout = jiffies + msecs_to_jiffies(3); 199 200 /* Never idle if active, or when VBUS timeout is not set as host */ 201 if (musb->is_active || (musb->a_wait_bcon == 0 && 202 musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { 203 dev_dbg(musb->controller, "%s active, deleting timer\n", 204 otg_state_string(musb->xceiv->state)); 205 del_timer(&otg_workaround); 206 last_timer = jiffies; 207 return; 208 } 209 210 if (time_after(last_timer, timeout) && timer_pending(&otg_workaround)) { 211 dev_dbg(musb->controller, "Longer idle timer already pending, ignoring...\n"); 212 return; 213 } 214 last_timer = timeout; 215 216 dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n", 217 otg_state_string(musb->xceiv->state), 218 jiffies_to_msecs(timeout - jiffies)); 219 mod_timer(&otg_workaround, timeout); 220 } 221 #endif 222 223 static irqreturn_t am35x_musb_interrupt(int irq, void *hci) 224 { 225 struct musb *musb = hci; 226 void __iomem *reg_base = musb->ctrl_base; 227 #ifndef __UBOOT__ 228 struct device *dev = musb->controller; 229 struct musb_hdrc_platform_data *plat = dev->platform_data; 230 struct omap_musb_board_data *data = plat->board_data; 231 struct usb_otg *otg = musb->xceiv->otg; 232 #else 233 struct omap_musb_board_data *data = 234 (struct omap_musb_board_data *)musb->controller; 235 #endif 236 unsigned long flags; 237 irqreturn_t ret = IRQ_NONE; 238 u32 epintr, usbintr; 239 240 #ifdef __UBOOT__ 241 /* 242 * It seems that on AM35X interrupt registers can be updated 243 * before core registers. This confuses the code. 244 * As a workaround add a small delay here. 245 */ 246 udelay(10); 247 #endif 248 spin_lock_irqsave(&musb->lock, flags); 249 250 /* Get endpoint interrupts */ 251 epintr = musb_readl(reg_base, EP_INTR_SRC_MASKED_REG); 252 253 if (epintr) { 254 musb_writel(reg_base, EP_INTR_SRC_CLEAR_REG, epintr); 255 256 musb->int_rx = 257 (epintr & AM35X_RX_INTR_MASK) >> AM35X_INTR_RX_SHIFT; 258 musb->int_tx = 259 (epintr & AM35X_TX_INTR_MASK) >> AM35X_INTR_TX_SHIFT; 260 } 261 262 /* Get usb core interrupts */ 263 usbintr = musb_readl(reg_base, CORE_INTR_SRC_MASKED_REG); 264 if (!usbintr && !epintr) 265 goto eoi; 266 267 if (usbintr) { 268 musb_writel(reg_base, CORE_INTR_SRC_CLEAR_REG, usbintr); 269 270 musb->int_usb = 271 (usbintr & AM35X_INTR_USB_MASK) >> AM35X_INTR_USB_SHIFT; 272 } 273 #ifndef __UBOOT__ 274 /* 275 * DRVVBUS IRQs are the only proxy we have (a very poor one!) for 276 * AM35x's missing ID change IRQ. We need an ID change IRQ to 277 * switch appropriately between halves of the OTG state machine. 278 * Managing DEVCTL.SESSION per Mentor docs requires that we know its 279 * value but DEVCTL.BDEVICE is invalid without DEVCTL.SESSION set. 280 * Also, DRVVBUS pulses for SRP (but not at 5V) ... 281 */ 282 if (usbintr & (AM35X_INTR_DRVVBUS << AM35X_INTR_USB_SHIFT)) { 283 int drvvbus = musb_readl(reg_base, USB_STAT_REG); 284 void __iomem *mregs = musb->mregs; 285 u8 devctl = musb_readb(mregs, MUSB_DEVCTL); 286 int err; 287 288 err = is_host_enabled(musb) && (musb->int_usb & 289 MUSB_INTR_VBUSERROR); 290 if (err) { 291 /* 292 * The Mentor core doesn't debounce VBUS as needed 293 * to cope with device connect current spikes. This 294 * means it's not uncommon for bus-powered devices 295 * to get VBUS errors during enumeration. 296 * 297 * This is a workaround, but newer RTL from Mentor 298 * seems to allow a better one: "re"-starting sessions 299 * without waiting for VBUS to stop registering in 300 * devctl. 301 */ 302 musb->int_usb &= ~MUSB_INTR_VBUSERROR; 303 musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; 304 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); 305 WARNING("VBUS error workaround (delay coming)\n"); 306 } else if (is_host_enabled(musb) && drvvbus) { 307 MUSB_HST_MODE(musb); 308 otg->default_a = 1; 309 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; 310 portstate(musb->port1_status |= USB_PORT_STAT_POWER); 311 del_timer(&otg_workaround); 312 } else { 313 musb->is_active = 0; 314 MUSB_DEV_MODE(musb); 315 otg->default_a = 0; 316 musb->xceiv->state = OTG_STATE_B_IDLE; 317 portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); 318 } 319 320 /* NOTE: this must complete power-on within 100 ms. */ 321 dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n", 322 drvvbus ? "on" : "off", 323 otg_state_string(musb->xceiv->state), 324 err ? " ERROR" : "", 325 devctl); 326 ret = IRQ_HANDLED; 327 } 328 #endif 329 330 if (musb->int_tx || musb->int_rx || musb->int_usb) 331 ret |= musb_interrupt(musb); 332 333 eoi: 334 /* EOI needs to be written for the IRQ to be re-asserted. */ 335 if (ret == IRQ_HANDLED || epintr || usbintr) { 336 /* clear level interrupt */ 337 if (data->clear_irq) 338 data->clear_irq(data->dev); 339 /* write EOI */ 340 musb_writel(reg_base, USB_END_OF_INTR_REG, 0); 341 } 342 343 #ifndef __UBOOT__ 344 /* Poll for ID change */ 345 if (is_otg_enabled(musb) && musb->xceiv->state == OTG_STATE_B_IDLE) 346 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); 347 #endif 348 349 spin_unlock_irqrestore(&musb->lock, flags); 350 351 return ret; 352 } 353 354 #ifndef __UBOOT__ 355 static int am35x_musb_set_mode(struct musb *musb, u8 musb_mode) 356 { 357 struct device *dev = musb->controller; 358 struct musb_hdrc_platform_data *plat = dev->platform_data; 359 struct omap_musb_board_data *data = plat->board_data; 360 int retval = 0; 361 362 if (data->set_mode) 363 data->set_mode(musb_mode); 364 else 365 retval = -EIO; 366 367 return retval; 368 } 369 #endif 370 371 static int am35x_musb_init(struct musb *musb) 372 { 373 #ifndef __UBOOT__ 374 struct device *dev = musb->controller; 375 struct musb_hdrc_platform_data *plat = dev->platform_data; 376 struct omap_musb_board_data *data = plat->board_data; 377 #else 378 struct omap_musb_board_data *data = 379 (struct omap_musb_board_data *)musb->controller; 380 #endif 381 void __iomem *reg_base = musb->ctrl_base; 382 u32 rev; 383 384 musb->mregs += USB_MENTOR_CORE_OFFSET; 385 386 /* Returns zero if e.g. not clocked */ 387 rev = musb_readl(reg_base, USB_REVISION_REG); 388 if (!rev) 389 return -ENODEV; 390 391 #ifndef __UBOOT__ 392 usb_nop_xceiv_register(); 393 musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); 394 if (IS_ERR_OR_NULL(musb->xceiv)) 395 return -ENODEV; 396 397 if (is_host_enabled(musb)) 398 setup_timer(&otg_workaround, otg_timer, (unsigned long) musb); 399 #endif 400 401 /* Reset the musb */ 402 if (data->reset) 403 data->reset(data->dev); 404 405 /* Reset the controller */ 406 musb_writel(reg_base, USB_CTRL_REG, AM35X_SOFT_RESET_MASK); 407 408 /* Start the on-chip PHY and its PLL. */ 409 if (data && data->set_phy_power) 410 data->set_phy_power(data->dev, 1); 411 412 msleep(5); 413 414 musb->isr = am35x_musb_interrupt; 415 416 /* clear level interrupt */ 417 if (data->clear_irq) 418 data->clear_irq(data->dev); 419 420 return 0; 421 } 422 423 static int am35x_musb_exit(struct musb *musb) 424 { 425 #ifndef __UBOOT__ 426 struct device *dev = musb->controller; 427 struct musb_hdrc_platform_data *plat = dev->platform_data; 428 struct omap_musb_board_data *data = plat->board_data; 429 #else 430 struct omap_musb_board_data *data = 431 (struct omap_musb_board_data *)musb->controller; 432 #endif 433 434 #ifndef __UBOOT__ 435 if (is_host_enabled(musb)) 436 del_timer_sync(&otg_workaround); 437 #endif 438 439 /* Shutdown the on-chip PHY and its PLL. */ 440 if (data && data->set_phy_power) 441 data->set_phy_power(data->dev, 0); 442 443 #ifndef __UBOOT__ 444 usb_put_phy(musb->xceiv); 445 usb_nop_xceiv_unregister(); 446 #endif 447 448 return 0; 449 } 450 451 /* AM35x supports only 32bit read operation */ 452 void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) 453 { 454 void __iomem *fifo = hw_ep->fifo; 455 u32 val; 456 int i; 457 458 /* Read for 32bit-aligned destination address */ 459 if (likely((0x03 & (unsigned long) dst) == 0) && len >= 4) { 460 readsl(fifo, dst, len >> 2); 461 dst += len & ~0x03; 462 len &= 0x03; 463 } 464 /* 465 * Now read the remaining 1 to 3 byte or complete length if 466 * unaligned address. 467 */ 468 if (len > 4) { 469 for (i = 0; i < (len >> 2); i++) { 470 *(u32 *) dst = musb_readl(fifo, 0); 471 dst += 4; 472 } 473 len &= 0x03; 474 } 475 if (len > 0) { 476 val = musb_readl(fifo, 0); 477 memcpy(dst, &val, len); 478 } 479 } 480 481 #ifndef __UBOOT__ 482 static const struct musb_platform_ops am35x_ops = { 483 #else 484 const struct musb_platform_ops am35x_ops = { 485 #endif 486 .init = am35x_musb_init, 487 .exit = am35x_musb_exit, 488 489 .enable = am35x_musb_enable, 490 .disable = am35x_musb_disable, 491 492 #ifndef __UBOOT__ 493 .set_mode = am35x_musb_set_mode, 494 .try_idle = am35x_musb_try_idle, 495 496 .set_vbus = am35x_musb_set_vbus, 497 #endif 498 }; 499 500 #ifndef __UBOOT__ 501 static u64 am35x_dmamask = DMA_BIT_MASK(32); 502 503 static int __devinit am35x_probe(struct platform_device *pdev) 504 { 505 struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; 506 struct platform_device *musb; 507 struct am35x_glue *glue; 508 509 struct clk *phy_clk; 510 struct clk *clk; 511 512 int ret = -ENOMEM; 513 514 glue = kzalloc(sizeof(*glue), GFP_KERNEL); 515 if (!glue) { 516 dev_err(&pdev->dev, "failed to allocate glue context\n"); 517 goto err0; 518 } 519 520 musb = platform_device_alloc("musb-hdrc", -1); 521 if (!musb) { 522 dev_err(&pdev->dev, "failed to allocate musb device\n"); 523 goto err1; 524 } 525 526 phy_clk = clk_get(&pdev->dev, "fck"); 527 if (IS_ERR(phy_clk)) { 528 dev_err(&pdev->dev, "failed to get PHY clock\n"); 529 ret = PTR_ERR(phy_clk); 530 goto err2; 531 } 532 533 clk = clk_get(&pdev->dev, "ick"); 534 if (IS_ERR(clk)) { 535 dev_err(&pdev->dev, "failed to get clock\n"); 536 ret = PTR_ERR(clk); 537 goto err3; 538 } 539 540 ret = clk_enable(phy_clk); 541 if (ret) { 542 dev_err(&pdev->dev, "failed to enable PHY clock\n"); 543 goto err4; 544 } 545 546 ret = clk_enable(clk); 547 if (ret) { 548 dev_err(&pdev->dev, "failed to enable clock\n"); 549 goto err5; 550 } 551 552 musb->dev.parent = &pdev->dev; 553 musb->dev.dma_mask = &am35x_dmamask; 554 musb->dev.coherent_dma_mask = am35x_dmamask; 555 556 glue->dev = &pdev->dev; 557 glue->musb = musb; 558 glue->phy_clk = phy_clk; 559 glue->clk = clk; 560 561 pdata->platform_ops = &am35x_ops; 562 563 platform_set_drvdata(pdev, glue); 564 565 ret = platform_device_add_resources(musb, pdev->resource, 566 pdev->num_resources); 567 if (ret) { 568 dev_err(&pdev->dev, "failed to add resources\n"); 569 goto err6; 570 } 571 572 ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); 573 if (ret) { 574 dev_err(&pdev->dev, "failed to add platform_data\n"); 575 goto err6; 576 } 577 578 ret = platform_device_add(musb); 579 if (ret) { 580 dev_err(&pdev->dev, "failed to register musb device\n"); 581 goto err6; 582 } 583 584 return 0; 585 586 err6: 587 clk_disable(clk); 588 589 err5: 590 clk_disable(phy_clk); 591 592 err4: 593 clk_put(clk); 594 595 err3: 596 clk_put(phy_clk); 597 598 err2: 599 platform_device_put(musb); 600 601 err1: 602 kfree(glue); 603 604 err0: 605 return ret; 606 } 607 608 static int __devexit am35x_remove(struct platform_device *pdev) 609 { 610 struct am35x_glue *glue = platform_get_drvdata(pdev); 611 612 platform_device_del(glue->musb); 613 platform_device_put(glue->musb); 614 clk_disable(glue->clk); 615 clk_disable(glue->phy_clk); 616 clk_put(glue->clk); 617 clk_put(glue->phy_clk); 618 kfree(glue); 619 620 return 0; 621 } 622 623 #ifdef CONFIG_PM 624 static int am35x_suspend(struct device *dev) 625 { 626 struct am35x_glue *glue = dev_get_drvdata(dev); 627 struct musb_hdrc_platform_data *plat = dev->platform_data; 628 struct omap_musb_board_data *data = plat->board_data; 629 630 /* Shutdown the on-chip PHY and its PLL. */ 631 if (data && data->set_phy_power) 632 data->set_phy_power(data->dev, 0); 633 634 clk_disable(glue->phy_clk); 635 clk_disable(glue->clk); 636 637 return 0; 638 } 639 640 static int am35x_resume(struct device *dev) 641 { 642 struct am35x_glue *glue = dev_get_drvdata(dev); 643 struct musb_hdrc_platform_data *plat = dev->platform_data; 644 struct omap_musb_board_data *data = plat->board_data; 645 int ret; 646 647 /* Start the on-chip PHY and its PLL. */ 648 if (data && data->set_phy_power) 649 data->set_phy_power(data->dev, 1); 650 651 ret = clk_enable(glue->phy_clk); 652 if (ret) { 653 dev_err(dev, "failed to enable PHY clock\n"); 654 return ret; 655 } 656 657 ret = clk_enable(glue->clk); 658 if (ret) { 659 dev_err(dev, "failed to enable clock\n"); 660 return ret; 661 } 662 663 return 0; 664 } 665 666 static struct dev_pm_ops am35x_pm_ops = { 667 .suspend = am35x_suspend, 668 .resume = am35x_resume, 669 }; 670 671 #define DEV_PM_OPS &am35x_pm_ops 672 #else 673 #define DEV_PM_OPS NULL 674 #endif 675 676 static struct platform_driver am35x_driver = { 677 .probe = am35x_probe, 678 .remove = __devexit_p(am35x_remove), 679 .driver = { 680 .name = "musb-am35x", 681 .pm = DEV_PM_OPS, 682 }, 683 }; 684 685 MODULE_DESCRIPTION("AM35x MUSB Glue Layer"); 686 MODULE_AUTHOR("Ajay Kumar Gupta <ajay.gupta@ti.com>"); 687 MODULE_LICENSE("GPL v2"); 688 689 static int __init am35x_init(void) 690 { 691 return platform_driver_register(&am35x_driver); 692 } 693 module_init(am35x_init); 694 695 static void __exit am35x_exit(void) 696 { 697 platform_driver_unregister(&am35x_driver); 698 } 699 module_exit(am35x_exit); 700 #endif 701