Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: omap-usb-tll: HOST TLL platform driver

The platform driver for the TLL component of the OMAP USB host controller
is implemented. Depending on the TLL hardware revision , the TLL channels
are configured. The USB HS core driver uses this driver through exported
APIs from the TLL platform driver.
usb_tll_enable and usb_tll_disble are the exported APIs of the USB TLL
platform driver.

Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
Reviewed-by: Partha Basak <parthab@india.ti.com>
Acked-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Keshava Munegowda and committed by
Samuel Ortiz
16fa3dc7 99de1cc5

+479 -2
+6
arch/arm/plat-omap/include/plat/usb.h
··· 64 64 struct ehci_hcd_omap_platform_data *ehci_data; 65 65 struct ohci_hcd_omap_platform_data *ohci_data; 66 66 }; 67 + 68 + struct usbtll_omap_platform_data { 69 + enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS]; 70 + }; 67 71 /*-------------------------------------------------------------------------*/ 68 72 69 73 struct omap_musb_board_data { ··· 86 82 extern void usb_musb_init(struct omap_musb_board_data *board_data); 87 83 88 84 extern void usbhs_init(const struct usbhs_omap_board_data *pdata); 85 + extern int omap_tll_enable(void); 86 + extern int omap_tll_disable(void); 89 87 90 88 extern int omap4430_phy_power(struct device *dev, int ID, int on); 91 89 extern int omap4430_phy_set_clk(struct device *dev, int on);
+1 -1
drivers/mfd/Kconfig
··· 897 897 audio codec. 898 898 899 899 config MFD_OMAP_USB_HOST 900 - bool "Support OMAP USBHS core driver" 900 + bool "Support OMAP USBHS core and TLL driver" 901 901 depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3 902 902 default y 903 903 help
+1 -1
drivers/mfd/Makefile
··· 120 120 obj-$(CONFIG_MFD_VX855) += vx855.o 121 121 obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o 122 122 obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o 123 - obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o 123 + obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o 124 124 obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o 125 125 obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o 126 126 obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
+471
drivers/mfd/omap-usb-tll.c
··· 1 + /** 2 + * omap-usb-tll.c - The USB TLL driver for OMAP EHCI & OHCI 3 + * 4 + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com 5 + * Author: Keshava Munegowda <keshava_mgowda@ti.com> 6 + * 7 + * This program is free software: you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 of 9 + * the License as published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + #include <linux/kernel.h> 20 + #include <linux/module.h> 21 + #include <linux/types.h> 22 + #include <linux/slab.h> 23 + #include <linux/spinlock.h> 24 + #include <linux/platform_device.h> 25 + #include <linux/clk.h> 26 + #include <linux/io.h> 27 + #include <linux/err.h> 28 + #include <plat/usb.h> 29 + #include <linux/pm_runtime.h> 30 + 31 + #define USBTLL_DRIVER_NAME "usbhs_tll" 32 + 33 + /* TLL Register Set */ 34 + #define OMAP_USBTLL_REVISION (0x00) 35 + #define OMAP_USBTLL_SYSCONFIG (0x10) 36 + #define OMAP_USBTLL_SYSCONFIG_CACTIVITY (1 << 8) 37 + #define OMAP_USBTLL_SYSCONFIG_SIDLEMODE (1 << 3) 38 + #define OMAP_USBTLL_SYSCONFIG_ENAWAKEUP (1 << 2) 39 + #define OMAP_USBTLL_SYSCONFIG_SOFTRESET (1 << 1) 40 + #define OMAP_USBTLL_SYSCONFIG_AUTOIDLE (1 << 0) 41 + 42 + #define OMAP_USBTLL_SYSSTATUS (0x14) 43 + #define OMAP_USBTLL_SYSSTATUS_RESETDONE (1 << 0) 44 + 45 + #define OMAP_USBTLL_IRQSTATUS (0x18) 46 + #define OMAP_USBTLL_IRQENABLE (0x1C) 47 + 48 + #define OMAP_TLL_SHARED_CONF (0x30) 49 + #define OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN (1 << 6) 50 + #define OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN (1 << 5) 51 + #define OMAP_TLL_SHARED_CONF_USB_DIVRATION (1 << 2) 52 + #define OMAP_TLL_SHARED_CONF_FCLK_REQ (1 << 1) 53 + #define OMAP_TLL_SHARED_CONF_FCLK_IS_ON (1 << 0) 54 + 55 + #define OMAP_TLL_CHANNEL_CONF(num) (0x040 + 0x004 * num) 56 + #define OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT 24 57 + #define OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF (1 << 11) 58 + #define OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE (1 << 10) 59 + #define OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE (1 << 9) 60 + #define OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE (1 << 8) 61 + #define OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS (1 << 1) 62 + #define OMAP_TLL_CHANNEL_CONF_CHANEN (1 << 0) 63 + 64 + #define OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0 0x0 65 + #define OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM 0x1 66 + #define OMAP_TLL_FSLSMODE_3PIN_PHY 0x2 67 + #define OMAP_TLL_FSLSMODE_4PIN_PHY 0x3 68 + #define OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0 0x4 69 + #define OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM 0x5 70 + #define OMAP_TLL_FSLSMODE_3PIN_TLL 0x6 71 + #define OMAP_TLL_FSLSMODE_4PIN_TLL 0x7 72 + #define OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0 0xA 73 + #define OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM 0xB 74 + 75 + #define OMAP_TLL_ULPI_FUNCTION_CTRL(num) (0x804 + 0x100 * num) 76 + #define OMAP_TLL_ULPI_INTERFACE_CTRL(num) (0x807 + 0x100 * num) 77 + #define OMAP_TLL_ULPI_OTG_CTRL(num) (0x80A + 0x100 * num) 78 + #define OMAP_TLL_ULPI_INT_EN_RISE(num) (0x80D + 0x100 * num) 79 + #define OMAP_TLL_ULPI_INT_EN_FALL(num) (0x810 + 0x100 * num) 80 + #define OMAP_TLL_ULPI_INT_STATUS(num) (0x813 + 0x100 * num) 81 + #define OMAP_TLL_ULPI_INT_LATCH(num) (0x814 + 0x100 * num) 82 + #define OMAP_TLL_ULPI_DEBUG(num) (0x815 + 0x100 * num) 83 + #define OMAP_TLL_ULPI_SCRATCH_REGISTER(num) (0x816 + 0x100 * num) 84 + 85 + #define OMAP_REV2_TLL_CHANNEL_COUNT 2 86 + #define OMAP_TLL_CHANNEL_COUNT 3 87 + #define OMAP_TLL_CHANNEL_1_EN_MASK (1 << 0) 88 + #define OMAP_TLL_CHANNEL_2_EN_MASK (1 << 1) 89 + #define OMAP_TLL_CHANNEL_3_EN_MASK (1 << 2) 90 + 91 + /* Values of USBTLL_REVISION - Note: these are not given in the TRM */ 92 + #define OMAP_USBTLL_REV1 0x00000015 /* OMAP3 */ 93 + #define OMAP_USBTLL_REV2 0x00000018 /* OMAP 3630 */ 94 + #define OMAP_USBTLL_REV3 0x00000004 /* OMAP4 */ 95 + 96 + #define is_ehci_tll_mode(x) (x == OMAP_EHCI_PORT_MODE_TLL) 97 + 98 + struct usbtll_omap { 99 + struct clk *usbtll_p1_fck; 100 + struct clk *usbtll_p2_fck; 101 + struct usbtll_omap_platform_data platdata; 102 + /* secure the register updates */ 103 + spinlock_t lock; 104 + }; 105 + 106 + /*-------------------------------------------------------------------------*/ 107 + 108 + const char usbtll_driver_name[] = USBTLL_DRIVER_NAME; 109 + struct platform_device *tll_pdev; 110 + 111 + /*-------------------------------------------------------------------------*/ 112 + 113 + static inline void usbtll_write(void __iomem *base, u32 reg, u32 val) 114 + { 115 + __raw_writel(val, base + reg); 116 + } 117 + 118 + static inline u32 usbtll_read(void __iomem *base, u32 reg) 119 + { 120 + return __raw_readl(base + reg); 121 + } 122 + 123 + static inline void usbtll_writeb(void __iomem *base, u8 reg, u8 val) 124 + { 125 + __raw_writeb(val, base + reg); 126 + } 127 + 128 + static inline u8 usbtll_readb(void __iomem *base, u8 reg) 129 + { 130 + return __raw_readb(base + reg); 131 + } 132 + 133 + /*-------------------------------------------------------------------------*/ 134 + 135 + static bool is_ohci_port(enum usbhs_omap_port_mode pmode) 136 + { 137 + switch (pmode) { 138 + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: 139 + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: 140 + case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: 141 + case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: 142 + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: 143 + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: 144 + case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: 145 + case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: 146 + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: 147 + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: 148 + return true; 149 + 150 + default: 151 + return false; 152 + } 153 + } 154 + 155 + /* 156 + * convert the port-mode enum to a value we can use in the FSLSMODE 157 + * field of USBTLL_CHANNEL_CONF 158 + */ 159 + static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode) 160 + { 161 + switch (mode) { 162 + case OMAP_USBHS_PORT_MODE_UNUSED: 163 + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: 164 + return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0; 165 + 166 + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: 167 + return OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM; 168 + 169 + case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: 170 + return OMAP_TLL_FSLSMODE_3PIN_PHY; 171 + 172 + case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: 173 + return OMAP_TLL_FSLSMODE_4PIN_PHY; 174 + 175 + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: 176 + return OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0; 177 + 178 + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: 179 + return OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM; 180 + 181 + case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: 182 + return OMAP_TLL_FSLSMODE_3PIN_TLL; 183 + 184 + case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: 185 + return OMAP_TLL_FSLSMODE_4PIN_TLL; 186 + 187 + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: 188 + return OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0; 189 + 190 + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: 191 + return OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM; 192 + default: 193 + pr_warn("Invalid port mode, using default\n"); 194 + return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0; 195 + } 196 + } 197 + 198 + /** 199 + * usbtll_omap_probe - initialize TI-based HCDs 200 + * 201 + * Allocates basic resources for this USB host controller. 202 + */ 203 + static int __devinit usbtll_omap_probe(struct platform_device *pdev) 204 + { 205 + struct device *dev = &pdev->dev; 206 + struct usbtll_omap_platform_data *pdata = dev->platform_data; 207 + void __iomem *base; 208 + struct resource *res; 209 + struct usbtll_omap *tll; 210 + unsigned reg; 211 + unsigned long flags; 212 + int ret = 0; 213 + int i, ver, count; 214 + 215 + dev_dbg(dev, "starting TI HSUSB TLL Controller\n"); 216 + 217 + tll = kzalloc(sizeof(struct usbtll_omap), GFP_KERNEL); 218 + if (!tll) { 219 + dev_err(dev, "Memory allocation failed\n"); 220 + ret = -ENOMEM; 221 + goto end; 222 + } 223 + 224 + spin_lock_init(&tll->lock); 225 + 226 + for (i = 0; i < OMAP3_HS_USB_PORTS; i++) 227 + tll->platdata.port_mode[i] = pdata->port_mode[i]; 228 + 229 + tll->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk"); 230 + if (IS_ERR(tll->usbtll_p1_fck)) { 231 + ret = PTR_ERR(tll->usbtll_p1_fck); 232 + dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret); 233 + goto err_tll; 234 + } 235 + 236 + tll->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk"); 237 + if (IS_ERR(tll->usbtll_p2_fck)) { 238 + ret = PTR_ERR(tll->usbtll_p2_fck); 239 + dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret); 240 + goto err_usbtll_p1_fck; 241 + } 242 + 243 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 244 + if (!res) { 245 + dev_err(dev, "usb tll get resource failed\n"); 246 + ret = -ENODEV; 247 + goto err_usbtll_p2_fck; 248 + } 249 + 250 + base = ioremap(res->start, resource_size(res)); 251 + if (!base) { 252 + dev_err(dev, "TLL ioremap failed\n"); 253 + ret = -ENOMEM; 254 + goto err_usbtll_p2_fck; 255 + } 256 + 257 + platform_set_drvdata(pdev, tll); 258 + pm_runtime_enable(dev); 259 + pm_runtime_get_sync(dev); 260 + 261 + spin_lock_irqsave(&tll->lock, flags); 262 + 263 + ver = usbtll_read(base, OMAP_USBTLL_REVISION); 264 + switch (ver) { 265 + case OMAP_USBTLL_REV1: 266 + case OMAP_USBTLL_REV2: 267 + count = OMAP_TLL_CHANNEL_COUNT; 268 + break; 269 + case OMAP_USBTLL_REV3: 270 + count = OMAP_REV2_TLL_CHANNEL_COUNT; 271 + break; 272 + default: 273 + dev_err(dev, "TLL version failed\n"); 274 + ret = -ENODEV; 275 + goto err_ioremap; 276 + } 277 + 278 + if (is_ehci_tll_mode(pdata->port_mode[0]) || 279 + is_ehci_tll_mode(pdata->port_mode[1]) || 280 + is_ehci_tll_mode(pdata->port_mode[2]) || 281 + is_ohci_port(pdata->port_mode[0]) || 282 + is_ohci_port(pdata->port_mode[1]) || 283 + is_ohci_port(pdata->port_mode[2])) { 284 + 285 + /* Program Common TLL register */ 286 + reg = usbtll_read(base, OMAP_TLL_SHARED_CONF); 287 + reg |= (OMAP_TLL_SHARED_CONF_FCLK_IS_ON 288 + | OMAP_TLL_SHARED_CONF_USB_DIVRATION); 289 + reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN; 290 + reg &= ~OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN; 291 + 292 + usbtll_write(base, OMAP_TLL_SHARED_CONF, reg); 293 + 294 + /* Enable channels now */ 295 + for (i = 0; i < count; i++) { 296 + reg = usbtll_read(base, OMAP_TLL_CHANNEL_CONF(i)); 297 + 298 + if (is_ohci_port(pdata->port_mode[i])) { 299 + reg |= ohci_omap3_fslsmode(pdata->port_mode[i]) 300 + << OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT; 301 + reg |= OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS; 302 + } else if (pdata->port_mode[i] == 303 + OMAP_EHCI_PORT_MODE_TLL) { 304 + /* 305 + * Disable AutoIdle, BitStuffing 306 + * and use SDR Mode 307 + */ 308 + reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE 309 + | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF 310 + | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE); 311 + } else { 312 + continue; 313 + } 314 + reg |= OMAP_TLL_CHANNEL_CONF_CHANEN; 315 + usbtll_write(base, OMAP_TLL_CHANNEL_CONF(i), reg); 316 + 317 + usbtll_writeb(base, 318 + OMAP_TLL_ULPI_SCRATCH_REGISTER(i), 319 + 0xbe); 320 + } 321 + } 322 + 323 + err_ioremap: 324 + spin_unlock_irqrestore(&tll->lock, flags); 325 + iounmap(base); 326 + pm_runtime_put_sync(dev); 327 + tll_pdev = pdev; 328 + if (!ret) 329 + goto end; 330 + pm_runtime_disable(dev); 331 + 332 + err_usbtll_p2_fck: 333 + clk_put(tll->usbtll_p2_fck); 334 + 335 + err_usbtll_p1_fck: 336 + clk_put(tll->usbtll_p1_fck); 337 + 338 + err_tll: 339 + kfree(tll); 340 + 341 + end: 342 + return ret; 343 + } 344 + 345 + /** 346 + * usbtll_omap_remove - shutdown processing for UHH & TLL HCDs 347 + * @pdev: USB Host Controller being removed 348 + * 349 + * Reverses the effect of usbtll_omap_probe(). 350 + */ 351 + static int __devexit usbtll_omap_remove(struct platform_device *pdev) 352 + { 353 + struct usbtll_omap *tll = platform_get_drvdata(pdev); 354 + 355 + clk_put(tll->usbtll_p2_fck); 356 + clk_put(tll->usbtll_p1_fck); 357 + pm_runtime_disable(&pdev->dev); 358 + kfree(tll); 359 + return 0; 360 + } 361 + 362 + static int usbtll_runtime_resume(struct device *dev) 363 + { 364 + struct usbtll_omap *tll = dev_get_drvdata(dev); 365 + struct usbtll_omap_platform_data *pdata = &tll->platdata; 366 + unsigned long flags; 367 + 368 + dev_dbg(dev, "usbtll_runtime_resume\n"); 369 + 370 + if (!pdata) { 371 + dev_dbg(dev, "missing platform_data\n"); 372 + return -ENODEV; 373 + } 374 + 375 + spin_lock_irqsave(&tll->lock, flags); 376 + 377 + if (is_ehci_tll_mode(pdata->port_mode[0])) 378 + clk_enable(tll->usbtll_p1_fck); 379 + 380 + if (is_ehci_tll_mode(pdata->port_mode[1])) 381 + clk_enable(tll->usbtll_p2_fck); 382 + 383 + spin_unlock_irqrestore(&tll->lock, flags); 384 + 385 + return 0; 386 + } 387 + 388 + static int usbtll_runtime_suspend(struct device *dev) 389 + { 390 + struct usbtll_omap *tll = dev_get_drvdata(dev); 391 + struct usbtll_omap_platform_data *pdata = &tll->platdata; 392 + unsigned long flags; 393 + 394 + dev_dbg(dev, "usbtll_runtime_suspend\n"); 395 + 396 + if (!pdata) { 397 + dev_dbg(dev, "missing platform_data\n"); 398 + return -ENODEV; 399 + } 400 + 401 + spin_lock_irqsave(&tll->lock, flags); 402 + 403 + if (is_ehci_tll_mode(pdata->port_mode[0])) 404 + clk_disable(tll->usbtll_p1_fck); 405 + 406 + if (is_ehci_tll_mode(pdata->port_mode[1])) 407 + clk_disable(tll->usbtll_p2_fck); 408 + 409 + spin_unlock_irqrestore(&tll->lock, flags); 410 + 411 + return 0; 412 + } 413 + 414 + static const struct dev_pm_ops usbtllomap_dev_pm_ops = { 415 + SET_RUNTIME_PM_OPS(usbtll_runtime_suspend, 416 + usbtll_runtime_resume, 417 + NULL) 418 + }; 419 + 420 + static struct platform_driver usbtll_omap_driver = { 421 + .driver = { 422 + .name = (char *)usbtll_driver_name, 423 + .owner = THIS_MODULE, 424 + .pm = &usbtllomap_dev_pm_ops, 425 + }, 426 + .probe = usbtll_omap_probe, 427 + .remove = __devexit_p(usbtll_omap_remove), 428 + }; 429 + 430 + int omap_tll_enable(void) 431 + { 432 + if (!tll_pdev) { 433 + pr_err("missing omap usbhs tll platform_data\n"); 434 + return -ENODEV; 435 + } 436 + return pm_runtime_get_sync(&tll_pdev->dev); 437 + } 438 + EXPORT_SYMBOL_GPL(omap_tll_enable); 439 + 440 + int omap_tll_disable(void) 441 + { 442 + if (!tll_pdev) { 443 + pr_err("missing omap usbhs tll platform_data\n"); 444 + return -ENODEV; 445 + } 446 + return pm_runtime_put_sync(&tll_pdev->dev); 447 + } 448 + EXPORT_SYMBOL_GPL(omap_tll_disable); 449 + 450 + MODULE_AUTHOR("Keshava Munegowda <keshava_mgowda@ti.com>"); 451 + MODULE_ALIAS("platform:" USBHS_DRIVER_NAME); 452 + MODULE_LICENSE("GPL v2"); 453 + MODULE_DESCRIPTION("usb tll driver for TI OMAP EHCI and OHCI controllers"); 454 + 455 + static int __init omap_usbtll_drvinit(void) 456 + { 457 + return platform_driver_register(&usbtll_omap_driver); 458 + } 459 + 460 + /* 461 + * init before usbhs core driver; 462 + * The usbtll driver should be initialized before 463 + * the usbhs core driver probe function is called. 464 + */ 465 + fs_initcall(omap_usbtll_drvinit); 466 + 467 + static void __exit omap_usbtll_drvexit(void) 468 + { 469 + platform_driver_unregister(&usbtll_omap_driver); 470 + } 471 + module_exit(omap_usbtll_drvexit);