1/* 2 * ohci-omap3.c - driver for OHCI on OMAP3 and later processors 3 * 4 * Bus Glue for OMAP3 USBHOST 3 port OHCI controller 5 * This controller is also used in later OMAPs and AM35x chips 6 * 7 * Copyright (C) 2007-2010 Texas Instruments, Inc. 8 * Author: Vikram Pandita <vikram.pandita@ti.com> 9 * Author: Anand Gadiyar <gadiyar@ti.com> 10 * 11 * Based on ehci-omap.c and some other ohci glue layers 12 * 13 * This program is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU General Public License as published by 15 * the Free Software Foundation; either version 2 of the License, or 16 * (at your option) any later version. 17 * 18 * This program is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU General Public License for more details. 22 * 23 * You should have received a copy of the GNU General Public License 24 * along with this program; if not, write to the Free Software 25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26 * 27 * TODO (last updated Mar 10th, 2010): 28 * - add kernel-doc 29 * - Factor out code common to EHCI to a separate file 30 * - Make EHCI and OHCI coexist together 31 * - needs newer silicon versions to actually work 32 * - the last one to be loaded currently steps on the other's toes 33 * - Add hooks for configuring transceivers, etc. at init/exit 34 * - Add aggressive clock-management code 35 */ 36 37#include <linux/platform_device.h> 38#include <linux/clk.h> 39 40#include <plat/usb.h> 41 42/* 43 * OMAP USBHOST Register addresses: VIRTUAL ADDRESSES 44 * Use ohci_omap_readl()/ohci_omap_writel() functions 45 */ 46 47/* TLL Register Set */ 48#define OMAP_USBTLL_REVISION (0x00) 49#define OMAP_USBTLL_SYSCONFIG (0x10) 50#define OMAP_USBTLL_SYSCONFIG_CACTIVITY (1 << 8) 51#define OMAP_USBTLL_SYSCONFIG_SIDLEMODE (1 << 3) 52#define OMAP_USBTLL_SYSCONFIG_ENAWAKEUP (1 << 2) 53#define OMAP_USBTLL_SYSCONFIG_SOFTRESET (1 << 1) 54#define OMAP_USBTLL_SYSCONFIG_AUTOIDLE (1 << 0) 55 56#define OMAP_USBTLL_SYSSTATUS (0x14) 57#define OMAP_USBTLL_SYSSTATUS_RESETDONE (1 << 0) 58 59#define OMAP_USBTLL_IRQSTATUS (0x18) 60#define OMAP_USBTLL_IRQENABLE (0x1C) 61 62#define OMAP_TLL_SHARED_CONF (0x30) 63#define OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN (1 << 6) 64#define OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN (1 << 5) 65#define OMAP_TLL_SHARED_CONF_USB_DIVRATION (1 << 2) 66#define OMAP_TLL_SHARED_CONF_FCLK_REQ (1 << 1) 67#define OMAP_TLL_SHARED_CONF_FCLK_IS_ON (1 << 0) 68 69#define OMAP_TLL_CHANNEL_CONF(num) (0x040 + 0x004 * num) 70#define OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT 24 71#define OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF (1 << 11) 72#define OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE (1 << 10) 73#define OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE (1 << 9) 74#define OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE (1 << 8) 75#define OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS (1 << 1) 76#define OMAP_TLL_CHANNEL_CONF_CHANEN (1 << 0) 77 78#define OMAP_TLL_CHANNEL_COUNT 3 79 80/* UHH Register Set */ 81#define OMAP_UHH_REVISION (0x00) 82#define OMAP_UHH_SYSCONFIG (0x10) 83#define OMAP_UHH_SYSCONFIG_MIDLEMODE (1 << 12) 84#define OMAP_UHH_SYSCONFIG_CACTIVITY (1 << 8) 85#define OMAP_UHH_SYSCONFIG_SIDLEMODE (1 << 3) 86#define OMAP_UHH_SYSCONFIG_ENAWAKEUP (1 << 2) 87#define OMAP_UHH_SYSCONFIG_SOFTRESET (1 << 1) 88#define OMAP_UHH_SYSCONFIG_AUTOIDLE (1 << 0) 89 90#define OMAP_UHH_SYSSTATUS (0x14) 91#define OMAP_UHH_SYSSTATUS_UHHRESETDONE (1 << 0) 92#define OMAP_UHH_SYSSTATUS_OHCIRESETDONE (1 << 1) 93#define OMAP_UHH_SYSSTATUS_EHCIRESETDONE (1 << 2) 94#define OMAP_UHH_HOSTCONFIG (0x40) 95#define OMAP_UHH_HOSTCONFIG_ULPI_BYPASS (1 << 0) 96#define OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS (1 << 0) 97#define OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS (1 << 11) 98#define OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS (1 << 12) 99#define OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN (1 << 2) 100#define OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN (1 << 3) 101#define OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN (1 << 4) 102#define OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN (1 << 5) 103#define OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS (1 << 8) 104#define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS (1 << 9) 105#define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS (1 << 10) 106 107#define OMAP_UHH_DEBUG_CSR (0x44) 108 109/*-------------------------------------------------------------------------*/ 110 111static inline void ohci_omap_writel(void __iomem *base, u32 reg, u32 val) 112{ 113 __raw_writel(val, base + reg); 114} 115 116static inline u32 ohci_omap_readl(void __iomem *base, u32 reg) 117{ 118 return __raw_readl(base + reg); 119} 120 121static inline void ohci_omap_writeb(void __iomem *base, u8 reg, u8 val) 122{ 123 __raw_writeb(val, base + reg); 124} 125 126static inline u8 ohci_omap_readb(void __iomem *base, u8 reg) 127{ 128 return __raw_readb(base + reg); 129} 130 131/*-------------------------------------------------------------------------*/ 132 133struct ohci_hcd_omap3 { 134 struct ohci_hcd *ohci; 135 struct device *dev; 136 137 struct clk *usbhost_ick; 138 struct clk *usbhost2_120m_fck; 139 struct clk *usbhost1_48m_fck; 140 struct clk *usbtll_fck; 141 struct clk *usbtll_ick; 142 143 /* port_mode: TLL/PHY, 2/3/4/6-PIN, DP-DM/DAT-SE0 */ 144 enum ohci_omap3_port_mode port_mode[OMAP3_HS_USB_PORTS]; 145 void __iomem *uhh_base; 146 void __iomem *tll_base; 147 void __iomem *ohci_base; 148 149 unsigned es2_compatibility:1; 150}; 151 152/*-------------------------------------------------------------------------*/ 153 154static void ohci_omap3_clock_power(struct ohci_hcd_omap3 *omap, int on) 155{ 156 if (on) { 157 clk_enable(omap->usbtll_ick); 158 clk_enable(omap->usbtll_fck); 159 clk_enable(omap->usbhost_ick); 160 clk_enable(omap->usbhost1_48m_fck); 161 clk_enable(omap->usbhost2_120m_fck); 162 } else { 163 clk_disable(omap->usbhost2_120m_fck); 164 clk_disable(omap->usbhost1_48m_fck); 165 clk_disable(omap->usbhost_ick); 166 clk_disable(omap->usbtll_fck); 167 clk_disable(omap->usbtll_ick); 168 } 169} 170 171static int ohci_omap3_init(struct usb_hcd *hcd) 172{ 173 dev_dbg(hcd->self.controller, "starting OHCI controller\n"); 174 175 return ohci_init(hcd_to_ohci(hcd)); 176} 177 178 179/*-------------------------------------------------------------------------*/ 180 181static int ohci_omap3_start(struct usb_hcd *hcd) 182{ 183 struct ohci_hcd *ohci = hcd_to_ohci(hcd); 184 int ret; 185 186 /* 187 * RemoteWakeupConnected has to be set explicitly before 188 * calling ohci_run. The reset value of RWC is 0. 189 */ 190 ohci->hc_control = OHCI_CTRL_RWC; 191 writel(OHCI_CTRL_RWC, &ohci->regs->control); 192 193 ret = ohci_run(ohci); 194 195 if (ret < 0) { 196 dev_err(hcd->self.controller, "can't start\n"); 197 ohci_stop(hcd); 198 } 199 200 return ret; 201} 202 203/*-------------------------------------------------------------------------*/ 204 205/* 206 * convert the port-mode enum to a value we can use in the FSLSMODE 207 * field of USBTLL_CHANNEL_CONF 208 */ 209static unsigned ohci_omap3_fslsmode(enum ohci_omap3_port_mode mode) 210{ 211 switch (mode) { 212 case OMAP_OHCI_PORT_MODE_UNUSED: 213 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: 214 return 0x0; 215 216 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: 217 return 0x1; 218 219 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: 220 return 0x2; 221 222 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: 223 return 0x3; 224 225 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: 226 return 0x4; 227 228 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: 229 return 0x5; 230 231 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: 232 return 0x6; 233 234 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: 235 return 0x7; 236 237 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: 238 return 0xA; 239 240 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: 241 return 0xB; 242 default: 243 pr_warning("Invalid port mode, using default\n"); 244 return 0x0; 245 } 246} 247 248static void ohci_omap3_tll_config(struct ohci_hcd_omap3 *omap) 249{ 250 u32 reg; 251 int i; 252 253 /* Program TLL SHARED CONF */ 254 reg = ohci_omap_readl(omap->tll_base, OMAP_TLL_SHARED_CONF); 255 reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN; 256 reg &= ~OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN; 257 reg |= OMAP_TLL_SHARED_CONF_USB_DIVRATION; 258 reg |= OMAP_TLL_SHARED_CONF_FCLK_IS_ON; 259 ohci_omap_writel(omap->tll_base, OMAP_TLL_SHARED_CONF, reg); 260 261 /* Program each TLL channel */ 262 /* 263 * REVISIT: Only the 3-pin and 4-pin PHY modes have 264 * actually been tested. 265 */ 266 for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) { 267 268 /* Enable only those channels that are actually used */ 269 if (omap->port_mode[i] == OMAP_OHCI_PORT_MODE_UNUSED) 270 continue; 271 272 reg = ohci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); 273 reg |= ohci_omap3_fslsmode(omap->port_mode[i]) 274 << OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT; 275 reg |= OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS; 276 reg |= OMAP_TLL_CHANNEL_CONF_CHANEN; 277 ohci_omap_writel(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i), reg); 278 } 279} 280 281/* omap3_start_ohci 282 * - Start the TI USBHOST controller 283 */ 284static int omap3_start_ohci(struct ohci_hcd_omap3 *omap, struct usb_hcd *hcd) 285{ 286 unsigned long timeout = jiffies + msecs_to_jiffies(1000); 287 u32 reg = 0; 288 int ret = 0; 289 290 dev_dbg(omap->dev, "starting TI OHCI USB Controller\n"); 291 292 /* Get all the clock handles we need */ 293 omap->usbhost_ick = clk_get(omap->dev, "usbhost_ick"); 294 if (IS_ERR(omap->usbhost_ick)) { 295 dev_err(omap->dev, "could not get usbhost_ick\n"); 296 ret = PTR_ERR(omap->usbhost_ick); 297 goto err_host_ick; 298 } 299 300 omap->usbhost2_120m_fck = clk_get(omap->dev, "usbhost_120m_fck"); 301 if (IS_ERR(omap->usbhost2_120m_fck)) { 302 dev_err(omap->dev, "could not get usbhost_120m_fck\n"); 303 ret = PTR_ERR(omap->usbhost2_120m_fck); 304 goto err_host_120m_fck; 305 } 306 307 omap->usbhost1_48m_fck = clk_get(omap->dev, "usbhost_48m_fck"); 308 if (IS_ERR(omap->usbhost1_48m_fck)) { 309 dev_err(omap->dev, "could not get usbhost_48m_fck\n"); 310 ret = PTR_ERR(omap->usbhost1_48m_fck); 311 goto err_host_48m_fck; 312 } 313 314 omap->usbtll_fck = clk_get(omap->dev, "usbtll_fck"); 315 if (IS_ERR(omap->usbtll_fck)) { 316 dev_err(omap->dev, "could not get usbtll_fck\n"); 317 ret = PTR_ERR(omap->usbtll_fck); 318 goto err_tll_fck; 319 } 320 321 omap->usbtll_ick = clk_get(omap->dev, "usbtll_ick"); 322 if (IS_ERR(omap->usbtll_ick)) { 323 dev_err(omap->dev, "could not get usbtll_ick\n"); 324 ret = PTR_ERR(omap->usbtll_ick); 325 goto err_tll_ick; 326 } 327 328 /* Now enable all the clocks in the correct order */ 329 ohci_omap3_clock_power(omap, 1); 330 331 /* perform TLL soft reset, and wait until reset is complete */ 332 ohci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, 333 OMAP_USBTLL_SYSCONFIG_SOFTRESET); 334 335 /* Wait for TLL reset to complete */ 336 while (!(ohci_omap_readl(omap->tll_base, OMAP_USBTLL_SYSSTATUS) 337 & OMAP_USBTLL_SYSSTATUS_RESETDONE)) { 338 cpu_relax(); 339 340 if (time_after(jiffies, timeout)) { 341 dev_dbg(omap->dev, "operation timed out\n"); 342 ret = -EINVAL; 343 goto err_sys_status; 344 } 345 } 346 347 dev_dbg(omap->dev, "TLL reset done\n"); 348 349 /* (1<<3) = no idle mode only for initial debugging */ 350 ohci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, 351 OMAP_USBTLL_SYSCONFIG_ENAWAKEUP | 352 OMAP_USBTLL_SYSCONFIG_SIDLEMODE | 353 OMAP_USBTLL_SYSCONFIG_CACTIVITY); 354 355 356 /* Put UHH in NoIdle/NoStandby mode */ 357 reg = ohci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG); 358 reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP 359 | OMAP_UHH_SYSCONFIG_SIDLEMODE 360 | OMAP_UHH_SYSCONFIG_CACTIVITY 361 | OMAP_UHH_SYSCONFIG_MIDLEMODE); 362 reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; 363 reg &= ~OMAP_UHH_SYSCONFIG_SOFTRESET; 364 365 ohci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); 366 367 reg = ohci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG); 368 369 /* setup ULPI bypass and burst configurations */ 370 reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN 371 | OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN 372 | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN); 373 reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; 374 375 /* 376 * REVISIT: Pi_CONNECT_STATUS controls MStandby 377 * assertion and Swakeup generation - let us not 378 * worry about this for now. OMAP HWMOD framework 379 * might take care of this later. If not, we can 380 * update these registers when adding aggressive 381 * clock management code. 382 * 383 * For now, turn off all the Pi_CONNECT_STATUS bits 384 * 385 if (omap->port_mode[0] == OMAP_OHCI_PORT_MODE_UNUSED) 386 reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; 387 if (omap->port_mode[1] == OMAP_OHCI_PORT_MODE_UNUSED) 388 reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; 389 if (omap->port_mode[2] == OMAP_OHCI_PORT_MODE_UNUSED) 390 reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; 391 */ 392 reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; 393 reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; 394 reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; 395 396 if (omap->es2_compatibility) { 397 /* 398 * All OHCI modes need to go through the TLL, 399 * unlike in the EHCI case. So use UTMI mode 400 * for all ports for OHCI, on ES2.x silicon 401 */ 402 dev_dbg(omap->dev, "OMAP3 ES version <= ES2.1\n"); 403 reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; 404 } else { 405 dev_dbg(omap->dev, "OMAP3 ES version > ES2.1\n"); 406 if (omap->port_mode[0] == OMAP_OHCI_PORT_MODE_UNUSED) 407 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; 408 else 409 reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; 410 411 if (omap->port_mode[1] == OMAP_OHCI_PORT_MODE_UNUSED) 412 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; 413 else 414 reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; 415 416 if (omap->port_mode[2] == OMAP_OHCI_PORT_MODE_UNUSED) 417 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; 418 else 419 reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; 420 421 } 422 ohci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); 423 dev_dbg(omap->dev, "UHH setup done, uhh_hostconfig=%x\n", reg); 424 425 ohci_omap3_tll_config(omap); 426 427 return 0; 428 429err_sys_status: 430 ohci_omap3_clock_power(omap, 0); 431 clk_put(omap->usbtll_ick); 432 433err_tll_ick: 434 clk_put(omap->usbtll_fck); 435 436err_tll_fck: 437 clk_put(omap->usbhost1_48m_fck); 438 439err_host_48m_fck: 440 clk_put(omap->usbhost2_120m_fck); 441 442err_host_120m_fck: 443 clk_put(omap->usbhost_ick); 444 445err_host_ick: 446 return ret; 447} 448 449static void omap3_stop_ohci(struct ohci_hcd_omap3 *omap, struct usb_hcd *hcd) 450{ 451 unsigned long timeout = jiffies + msecs_to_jiffies(100); 452 453 dev_dbg(omap->dev, "stopping TI EHCI USB Controller\n"); 454 455 /* Reset USBHOST for insmod/rmmod to work */ 456 ohci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, 457 OMAP_UHH_SYSCONFIG_SOFTRESET); 458 while (!(ohci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) 459 & OMAP_UHH_SYSSTATUS_UHHRESETDONE)) { 460 cpu_relax(); 461 462 if (time_after(jiffies, timeout)) 463 dev_dbg(omap->dev, "operation timed out\n"); 464 } 465 466 while (!(ohci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) 467 & OMAP_UHH_SYSSTATUS_OHCIRESETDONE)) { 468 cpu_relax(); 469 470 if (time_after(jiffies, timeout)) 471 dev_dbg(omap->dev, "operation timed out\n"); 472 } 473 474 while (!(ohci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) 475 & OMAP_UHH_SYSSTATUS_EHCIRESETDONE)) { 476 cpu_relax(); 477 478 if (time_after(jiffies, timeout)) 479 dev_dbg(omap->dev, "operation timed out\n"); 480 } 481 482 ohci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, (1 << 1)); 483 484 while (!(ohci_omap_readl(omap->tll_base, OMAP_USBTLL_SYSSTATUS) 485 & (1 << 0))) { 486 cpu_relax(); 487 488 if (time_after(jiffies, timeout)) 489 dev_dbg(omap->dev, "operation timed out\n"); 490 } 491 492 ohci_omap3_clock_power(omap, 0); 493 494 if (omap->usbtll_fck != NULL) { 495 clk_put(omap->usbtll_fck); 496 omap->usbtll_fck = NULL; 497 } 498 499 if (omap->usbhost_ick != NULL) { 500 clk_put(omap->usbhost_ick); 501 omap->usbhost_ick = NULL; 502 } 503 504 if (omap->usbhost1_48m_fck != NULL) { 505 clk_put(omap->usbhost1_48m_fck); 506 omap->usbhost1_48m_fck = NULL; 507 } 508 509 if (omap->usbhost2_120m_fck != NULL) { 510 clk_put(omap->usbhost2_120m_fck); 511 omap->usbhost2_120m_fck = NULL; 512 } 513 514 if (omap->usbtll_ick != NULL) { 515 clk_put(omap->usbtll_ick); 516 omap->usbtll_ick = NULL; 517 } 518 519 dev_dbg(omap->dev, "Clock to USB host has been disabled\n"); 520} 521 522/*-------------------------------------------------------------------------*/ 523 524static const struct hc_driver ohci_omap3_hc_driver = { 525 .description = hcd_name, 526 .product_desc = "OMAP3 OHCI Host Controller", 527 .hcd_priv_size = sizeof(struct ohci_hcd), 528 529 /* 530 * generic hardware linkage 531 */ 532 .irq = ohci_irq, 533 .flags = HCD_USB11 | HCD_MEMORY, 534 535 /* 536 * basic lifecycle operations 537 */ 538 .reset = ohci_omap3_init, 539 .start = ohci_omap3_start, 540 .stop = ohci_stop, 541 .shutdown = ohci_shutdown, 542 543 /* 544 * managing i/o requests and associated device resources 545 */ 546 .urb_enqueue = ohci_urb_enqueue, 547 .urb_dequeue = ohci_urb_dequeue, 548 .endpoint_disable = ohci_endpoint_disable, 549 550 /* 551 * scheduling support 552 */ 553 .get_frame_number = ohci_get_frame, 554 555 /* 556 * root hub support 557 */ 558 .hub_status_data = ohci_hub_status_data, 559 .hub_control = ohci_hub_control, 560#ifdef CONFIG_PM 561 .bus_suspend = ohci_bus_suspend, 562 .bus_resume = ohci_bus_resume, 563#endif 564 .start_port_reset = ohci_start_port_reset, 565}; 566 567/*-------------------------------------------------------------------------*/ 568 569/* 570 * configure so an HC device and id are always provided 571 * always called with process context; sleeping is OK 572 */ 573 574/** 575 * ohci_hcd_omap3_probe - initialize OMAP-based HCDs 576 * 577 * Allocates basic resources for this USB host controller, and 578 * then invokes the start() method for the HCD associated with it 579 * through the hotplug entry's driver_data. 580 */ 581static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev) 582{ 583 struct ohci_hcd_omap_platform_data *pdata = pdev->dev.platform_data; 584 struct ohci_hcd_omap3 *omap; 585 struct resource *res; 586 struct usb_hcd *hcd; 587 int ret = -ENODEV; 588 int irq; 589 590 if (usb_disabled()) 591 goto err_disabled; 592 593 if (!pdata) { 594 dev_dbg(&pdev->dev, "missing platform_data\n"); 595 goto err_pdata; 596 } 597 598 irq = platform_get_irq(pdev, 0); 599 600 omap = kzalloc(sizeof(*omap), GFP_KERNEL); 601 if (!omap) { 602 ret = -ENOMEM; 603 goto err_disabled; 604 } 605 606 hcd = usb_create_hcd(&ohci_omap3_hc_driver, &pdev->dev, 607 dev_name(&pdev->dev)); 608 if (!hcd) { 609 ret = -ENOMEM; 610 goto err_create_hcd; 611 } 612 613 platform_set_drvdata(pdev, omap); 614 omap->dev = &pdev->dev; 615 omap->port_mode[0] = pdata->port_mode[0]; 616 omap->port_mode[1] = pdata->port_mode[1]; 617 omap->port_mode[2] = pdata->port_mode[2]; 618 omap->es2_compatibility = pdata->es2_compatibility; 619 omap->ohci = hcd_to_ohci(hcd); 620 621 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 622 623 hcd->rsrc_start = res->start; 624 hcd->rsrc_len = resource_size(res); 625 626 hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); 627 if (!hcd->regs) { 628 dev_err(&pdev->dev, "OHCI ioremap failed\n"); 629 ret = -ENOMEM; 630 goto err_ioremap; 631 } 632 633 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 634 omap->uhh_base = ioremap(res->start, resource_size(res)); 635 if (!omap->uhh_base) { 636 dev_err(&pdev->dev, "UHH ioremap failed\n"); 637 ret = -ENOMEM; 638 goto err_uhh_ioremap; 639 } 640 641 res = platform_get_resource(pdev, IORESOURCE_MEM, 2); 642 omap->tll_base = ioremap(res->start, resource_size(res)); 643 if (!omap->tll_base) { 644 dev_err(&pdev->dev, "TLL ioremap failed\n"); 645 ret = -ENOMEM; 646 goto err_tll_ioremap; 647 } 648 649 ret = omap3_start_ohci(omap, hcd); 650 if (ret) { 651 dev_dbg(&pdev->dev, "failed to start ehci\n"); 652 goto err_start; 653 } 654 655 ohci_hcd_init(omap->ohci); 656 657 ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); 658 if (ret) { 659 dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); 660 goto err_add_hcd; 661 } 662 663 return 0; 664 665err_add_hcd: 666 omap3_stop_ohci(omap, hcd); 667 668err_start: 669 iounmap(omap->tll_base); 670 671err_tll_ioremap: 672 iounmap(omap->uhh_base); 673 674err_uhh_ioremap: 675 iounmap(hcd->regs); 676 677err_ioremap: 678 usb_put_hcd(hcd); 679 680err_create_hcd: 681 kfree(omap); 682err_pdata: 683err_disabled: 684 return ret; 685} 686 687/* 688 * may be called without controller electrically present 689 * may be called with controller, bus, and devices active 690 */ 691 692/** 693 * ohci_hcd_omap3_remove - shutdown processing for OHCI HCDs 694 * @pdev: USB Host Controller being removed 695 * 696 * Reverses the effect of ohci_hcd_omap3_probe(), first invoking 697 * the HCD's stop() method. It is always called from a thread 698 * context, normally "rmmod", "apmd", or something similar. 699 */ 700static int __devexit ohci_hcd_omap3_remove(struct platform_device *pdev) 701{ 702 struct ohci_hcd_omap3 *omap = platform_get_drvdata(pdev); 703 struct usb_hcd *hcd = ohci_to_hcd(omap->ohci); 704 705 usb_remove_hcd(hcd); 706 omap3_stop_ohci(omap, hcd); 707 iounmap(hcd->regs); 708 iounmap(omap->tll_base); 709 iounmap(omap->uhh_base); 710 usb_put_hcd(hcd); 711 kfree(omap); 712 713 return 0; 714} 715 716static void ohci_hcd_omap3_shutdown(struct platform_device *pdev) 717{ 718 struct ohci_hcd_omap3 *omap = platform_get_drvdata(pdev); 719 struct usb_hcd *hcd = ohci_to_hcd(omap->ohci); 720 721 if (hcd->driver->shutdown) 722 hcd->driver->shutdown(hcd); 723} 724 725static struct platform_driver ohci_hcd_omap3_driver = { 726 .probe = ohci_hcd_omap3_probe, 727 .remove = __devexit_p(ohci_hcd_omap3_remove), 728 .shutdown = ohci_hcd_omap3_shutdown, 729 .driver = { 730 .name = "ohci-omap3", 731 }, 732}; 733 734MODULE_ALIAS("platform:ohci-omap3"); 735MODULE_AUTHOR("Anand Gadiyar <gadiyar@ti.com>"); 736