aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mfd/omap-usb-host.c558
-rw-r--r--drivers/mfd/omap-usb-tll.c243
-rw-r--r--drivers/usb/host/ehci-omap.c6
-rw-r--r--include/linux/platform_data/usb-omap.h1
4 files changed, 470 insertions, 338 deletions
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 05164d7f054b..6b5edf64de2b 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -23,7 +23,6 @@
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/clk.h> 24#include <linux/clk.h>
25#include <linux/dma-mapping.h> 25#include <linux/dma-mapping.h>
26#include <linux/spinlock.h>
27#include <linux/gpio.h> 26#include <linux/gpio.h>
28#include <linux/platform_device.h> 27#include <linux/platform_device.h>
29#include <linux/platform_data/usb-omap.h> 28#include <linux/platform_data/usb-omap.h>
@@ -91,21 +90,23 @@
91 90
92 91
93struct usbhs_hcd_omap { 92struct usbhs_hcd_omap {
93 int nports;
94 struct clk **utmi_clk;
95 struct clk **hsic60m_clk;
96 struct clk **hsic480m_clk;
97
94 struct clk *xclk60mhsp1_ck; 98 struct clk *xclk60mhsp1_ck;
95 struct clk *xclk60mhsp2_ck; 99 struct clk *xclk60mhsp2_ck;
96 struct clk *utmi_p1_fck; 100 struct clk *utmi_p1_gfclk;
97 struct clk *usbhost_p1_fck; 101 struct clk *utmi_p2_gfclk;
98 struct clk *utmi_p2_fck;
99 struct clk *usbhost_p2_fck;
100 struct clk *init_60m_fclk; 102 struct clk *init_60m_fclk;
101 struct clk *ehci_logic_fck; 103 struct clk *ehci_logic_fck;
102 104
103 void __iomem *uhh_base; 105 void __iomem *uhh_base;
104 106
105 struct usbhs_omap_platform_data platdata; 107 struct usbhs_omap_platform_data *pdata;
106 108
107 u32 usbhs_rev; 109 u32 usbhs_rev;
108 spinlock_t lock;
109}; 110};
110/*-------------------------------------------------------------------------*/ 111/*-------------------------------------------------------------------------*/
111 112
@@ -184,19 +185,13 @@ err_end:
184static int omap_usbhs_alloc_children(struct platform_device *pdev) 185static int omap_usbhs_alloc_children(struct platform_device *pdev)
185{ 186{
186 struct device *dev = &pdev->dev; 187 struct device *dev = &pdev->dev;
187 struct usbhs_hcd_omap *omap; 188 struct usbhs_omap_platform_data *pdata = dev->platform_data;
188 struct ehci_hcd_omap_platform_data *ehci_data;
189 struct ohci_hcd_omap_platform_data *ohci_data;
190 struct platform_device *ehci; 189 struct platform_device *ehci;
191 struct platform_device *ohci; 190 struct platform_device *ohci;
192 struct resource *res; 191 struct resource *res;
193 struct resource resources[2]; 192 struct resource resources[2];
194 int ret; 193 int ret;
195 194
196 omap = platform_get_drvdata(pdev);
197 ehci_data = omap->platdata.ehci_data;
198 ohci_data = omap->platdata.ohci_data;
199
200 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ehci"); 195 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ehci");
201 if (!res) { 196 if (!res) {
202 dev_err(dev, "EHCI get resource IORESOURCE_MEM failed\n"); 197 dev_err(dev, "EHCI get resource IORESOURCE_MEM failed\n");
@@ -213,8 +208,8 @@ static int omap_usbhs_alloc_children(struct platform_device *pdev)
213 } 208 }
214 resources[1] = *res; 209 resources[1] = *res;
215 210
216 ehci = omap_usbhs_alloc_child(OMAP_EHCI_DEVICE, resources, 2, ehci_data, 211 ehci = omap_usbhs_alloc_child(OMAP_EHCI_DEVICE, resources, 2, pdata,
217 sizeof(*ehci_data), dev); 212 sizeof(*pdata), dev);
218 213
219 if (!ehci) { 214 if (!ehci) {
220 dev_err(dev, "omap_usbhs_alloc_child failed\n"); 215 dev_err(dev, "omap_usbhs_alloc_child failed\n");
@@ -238,8 +233,8 @@ static int omap_usbhs_alloc_children(struct platform_device *pdev)
238 } 233 }
239 resources[1] = *res; 234 resources[1] = *res;
240 235
241 ohci = omap_usbhs_alloc_child(OMAP_OHCI_DEVICE, resources, 2, ohci_data, 236 ohci = omap_usbhs_alloc_child(OMAP_OHCI_DEVICE, resources, 2, pdata,
242 sizeof(*ohci_data), dev); 237 sizeof(*pdata), dev);
243 if (!ohci) { 238 if (!ohci) {
244 dev_err(dev, "omap_usbhs_alloc_child failed\n"); 239 dev_err(dev, "omap_usbhs_alloc_child failed\n");
245 ret = -ENOMEM; 240 ret = -ENOMEM;
@@ -278,31 +273,52 @@ static bool is_ohci_port(enum usbhs_omap_port_mode pmode)
278static int usbhs_runtime_resume(struct device *dev) 273static int usbhs_runtime_resume(struct device *dev)
279{ 274{
280 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); 275 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
281 struct usbhs_omap_platform_data *pdata = &omap->platdata; 276 struct usbhs_omap_platform_data *pdata = omap->pdata;
282 unsigned long flags; 277 int i, r;
283 278
284 dev_dbg(dev, "usbhs_runtime_resume\n"); 279 dev_dbg(dev, "usbhs_runtime_resume\n");
285 280
286 if (!pdata) {
287 dev_dbg(dev, "missing platform_data\n");
288 return -ENODEV;
289 }
290
291 omap_tll_enable(); 281 omap_tll_enable();
292 spin_lock_irqsave(&omap->lock, flags);
293 282
294 if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck)) 283 if (!IS_ERR(omap->ehci_logic_fck))
295 clk_enable(omap->ehci_logic_fck); 284 clk_enable(omap->ehci_logic_fck);
296 285
297 if (is_ehci_tll_mode(pdata->port_mode[0])) 286 for (i = 0; i < omap->nports; i++) {
298 clk_enable(omap->usbhost_p1_fck); 287 switch (pdata->port_mode[i]) {
299 if (is_ehci_tll_mode(pdata->port_mode[1])) 288 case OMAP_EHCI_PORT_MODE_HSIC:
300 clk_enable(omap->usbhost_p2_fck); 289 if (!IS_ERR(omap->hsic60m_clk[i])) {
301 290 r = clk_enable(omap->hsic60m_clk[i]);
302 clk_enable(omap->utmi_p1_fck); 291 if (r) {
303 clk_enable(omap->utmi_p2_fck); 292 dev_err(dev,
293 "Can't enable port %d hsic60m clk:%d\n",
294 i, r);
295 }
296 }
304 297
305 spin_unlock_irqrestore(&omap->lock, flags); 298 if (!IS_ERR(omap->hsic480m_clk[i])) {
299 r = clk_enable(omap->hsic480m_clk[i]);
300 if (r) {
301 dev_err(dev,
302 "Can't enable port %d hsic480m clk:%d\n",
303 i, r);
304 }
305 }
306 /* Fall through as HSIC mode needs utmi_clk */
307
308 case OMAP_EHCI_PORT_MODE_TLL:
309 if (!IS_ERR(omap->utmi_clk[i])) {
310 r = clk_enable(omap->utmi_clk[i]);
311 if (r) {
312 dev_err(dev,
313 "Can't enable port %d clk : %d\n",
314 i, r);
315 }
316 }
317 break;
318 default:
319 break;
320 }
321 }
306 322
307 return 0; 323 return 0;
308} 324}
@@ -310,51 +326,122 @@ static int usbhs_runtime_resume(struct device *dev)
310static int usbhs_runtime_suspend(struct device *dev) 326static int usbhs_runtime_suspend(struct device *dev)
311{ 327{
312 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); 328 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
313 struct usbhs_omap_platform_data *pdata = &omap->platdata; 329 struct usbhs_omap_platform_data *pdata = omap->pdata;
314 unsigned long flags; 330 int i;
315 331
316 dev_dbg(dev, "usbhs_runtime_suspend\n"); 332 dev_dbg(dev, "usbhs_runtime_suspend\n");
317 333
318 if (!pdata) { 334 for (i = 0; i < omap->nports; i++) {
319 dev_dbg(dev, "missing platform_data\n"); 335 switch (pdata->port_mode[i]) {
320 return -ENODEV; 336 case OMAP_EHCI_PORT_MODE_HSIC:
321 } 337 if (!IS_ERR(omap->hsic60m_clk[i]))
322 338 clk_disable(omap->hsic60m_clk[i]);
323 spin_lock_irqsave(&omap->lock, flags);
324 339
325 if (is_ehci_tll_mode(pdata->port_mode[0])) 340 if (!IS_ERR(omap->hsic480m_clk[i]))
326 clk_disable(omap->usbhost_p1_fck); 341 clk_disable(omap->hsic480m_clk[i]);
327 if (is_ehci_tll_mode(pdata->port_mode[1])) 342 /* Fall through as utmi_clks were used in HSIC mode */
328 clk_disable(omap->usbhost_p2_fck);
329 343
330 clk_disable(omap->utmi_p2_fck); 344 case OMAP_EHCI_PORT_MODE_TLL:
331 clk_disable(omap->utmi_p1_fck); 345 if (!IS_ERR(omap->utmi_clk[i]))
346 clk_disable(omap->utmi_clk[i]);
347 break;
348 default:
349 break;
350 }
351 }
332 352
333 if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck)) 353 if (!IS_ERR(omap->ehci_logic_fck))
334 clk_disable(omap->ehci_logic_fck); 354 clk_disable(omap->ehci_logic_fck);
335 355
336 spin_unlock_irqrestore(&omap->lock, flags);
337 omap_tll_disable(); 356 omap_tll_disable();
338 357
339 return 0; 358 return 0;
340} 359}
341 360
361static unsigned omap_usbhs_rev1_hostconfig(struct usbhs_hcd_omap *omap,
362 unsigned reg)
363{
364 struct usbhs_omap_platform_data *pdata = omap->pdata;
365 int i;
366
367 for (i = 0; i < omap->nports; i++) {
368 switch (pdata->port_mode[i]) {
369 case OMAP_USBHS_PORT_MODE_UNUSED:
370 reg &= ~(OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS << i);
371 break;
372 case OMAP_EHCI_PORT_MODE_PHY:
373 if (pdata->single_ulpi_bypass)
374 break;
375
376 if (i == 0)
377 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
378 else
379 reg &= ~(OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS
380 << (i-1));
381 break;
382 default:
383 if (pdata->single_ulpi_bypass)
384 break;
385
386 if (i == 0)
387 reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
388 else
389 reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS
390 << (i-1);
391 break;
392 }
393 }
394
395 if (pdata->single_ulpi_bypass) {
396 /* bypass ULPI only if none of the ports use PHY mode */
397 reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
398
399 for (i = 0; i < omap->nports; i++) {
400 if (is_ehci_phy_mode(pdata->port_mode[i])) {
401 reg &= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
402 break;
403 }
404 }
405 }
406
407 return reg;
408}
409
410static unsigned omap_usbhs_rev2_hostconfig(struct usbhs_hcd_omap *omap,
411 unsigned reg)
412{
413 struct usbhs_omap_platform_data *pdata = omap->pdata;
414 int i;
415
416 for (i = 0; i < omap->nports; i++) {
417 /* Clear port mode fields for PHY mode */
418 reg &= ~(OMAP4_P1_MODE_CLEAR << 2 * i);
419
420 if (is_ehci_tll_mode(pdata->port_mode[i]) ||
421 (is_ohci_port(pdata->port_mode[i])))
422 reg |= OMAP4_P1_MODE_TLL << 2 * i;
423 else if (is_ehci_hsic_mode(pdata->port_mode[i]))
424 reg |= OMAP4_P1_MODE_HSIC << 2 * i;
425 }
426
427 return reg;
428}
429
342static void omap_usbhs_init(struct device *dev) 430static void omap_usbhs_init(struct device *dev)
343{ 431{
344 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); 432 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
345 struct usbhs_omap_platform_data *pdata = &omap->platdata; 433 struct usbhs_omap_platform_data *pdata = omap->pdata;
346 unsigned long flags;
347 unsigned reg; 434 unsigned reg;
348 435
349 dev_dbg(dev, "starting TI HSUSB Controller\n"); 436 dev_dbg(dev, "starting TI HSUSB Controller\n");
350 437
351 if (pdata->ehci_data->phy_reset) { 438 if (pdata->phy_reset) {
352 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) 439 if (gpio_is_valid(pdata->reset_gpio_port[0]))
353 gpio_request_one(pdata->ehci_data->reset_gpio_port[0], 440 gpio_request_one(pdata->reset_gpio_port[0],
354 GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); 441 GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
355 442
356 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) 443 if (gpio_is_valid(pdata->reset_gpio_port[1]))
357 gpio_request_one(pdata->ehci_data->reset_gpio_port[1], 444 gpio_request_one(pdata->reset_gpio_port[1],
358 GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); 445 GPIOF_OUT_INIT_LOW, "USB2 PHY reset");
359 446
360 /* Hold the PHY in RESET for enough time till DIR is high */ 447 /* Hold the PHY in RESET for enough time till DIR is high */
@@ -362,9 +449,6 @@ static void omap_usbhs_init(struct device *dev)
362 } 449 }
363 450
364 pm_runtime_get_sync(dev); 451 pm_runtime_get_sync(dev);
365 spin_lock_irqsave(&omap->lock, flags);
366 omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
367 dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
368 452
369 reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG); 453 reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
370 /* setup ULPI bypass and burst configurations */ 454 /* setup ULPI bypass and burst configurations */
@@ -374,89 +458,51 @@ static void omap_usbhs_init(struct device *dev)
374 reg |= OMAP4_UHH_HOSTCONFIG_APP_START_CLK; 458 reg |= OMAP4_UHH_HOSTCONFIG_APP_START_CLK;
375 reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; 459 reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN;
376 460
377 if (is_omap_usbhs_rev1(omap)) { 461 switch (omap->usbhs_rev) {
378 if (pdata->port_mode[0] == OMAP_USBHS_PORT_MODE_UNUSED) 462 case OMAP_USBHS_REV1:
379 reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; 463 omap_usbhs_rev1_hostconfig(omap, reg);
380 if (pdata->port_mode[1] == OMAP_USBHS_PORT_MODE_UNUSED) 464 break;
381 reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS;
382 if (pdata->port_mode[2] == OMAP_USBHS_PORT_MODE_UNUSED)
383 reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS;
384
385 /* Bypass the TLL module for PHY mode operation */
386 if (pdata->single_ulpi_bypass) {
387 dev_dbg(dev, "OMAP3 ES version <= ES2.1\n");
388 if (is_ehci_phy_mode(pdata->port_mode[0]) ||
389 is_ehci_phy_mode(pdata->port_mode[1]) ||
390 is_ehci_phy_mode(pdata->port_mode[2]))
391 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
392 else
393 reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
394 } else {
395 dev_dbg(dev, "OMAP3 ES version > ES2.1\n");
396 if (is_ehci_phy_mode(pdata->port_mode[0]))
397 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
398 else
399 reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
400 if (is_ehci_phy_mode(pdata->port_mode[1]))
401 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS;
402 else
403 reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS;
404 if (is_ehci_phy_mode(pdata->port_mode[2]))
405 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS;
406 else
407 reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS;
408 }
409 } else if (is_omap_usbhs_rev2(omap)) {
410 /* Clear port mode fields for PHY mode*/
411 reg &= ~OMAP4_P1_MODE_CLEAR;
412 reg &= ~OMAP4_P2_MODE_CLEAR;
413 465
414 if (is_ehci_tll_mode(pdata->port_mode[0]) || 466 case OMAP_USBHS_REV2:
415 (is_ohci_port(pdata->port_mode[0]))) 467 omap_usbhs_rev2_hostconfig(omap, reg);
416 reg |= OMAP4_P1_MODE_TLL; 468 break;
417 else if (is_ehci_hsic_mode(pdata->port_mode[0]))
418 reg |= OMAP4_P1_MODE_HSIC;
419 469
420 if (is_ehci_tll_mode(pdata->port_mode[1]) || 470 default: /* newer revisions */
421 (is_ohci_port(pdata->port_mode[1]))) 471 omap_usbhs_rev2_hostconfig(omap, reg);
422 reg |= OMAP4_P2_MODE_TLL; 472 break;
423 else if (is_ehci_hsic_mode(pdata->port_mode[1]))
424 reg |= OMAP4_P2_MODE_HSIC;
425 } 473 }
426 474
427 usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); 475 usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg);
428 dev_dbg(dev, "UHH setup done, uhh_hostconfig=%x\n", reg); 476 dev_dbg(dev, "UHH setup done, uhh_hostconfig=%x\n", reg);
429 477
430 spin_unlock_irqrestore(&omap->lock, flags);
431
432 pm_runtime_put_sync(dev); 478 pm_runtime_put_sync(dev);
433 if (pdata->ehci_data->phy_reset) { 479 if (pdata->phy_reset) {
434 /* Hold the PHY in RESET for enough time till 480 /* Hold the PHY in RESET for enough time till
435 * PHY is settled and ready 481 * PHY is settled and ready
436 */ 482 */
437 udelay(10); 483 udelay(10);
438 484
439 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) 485 if (gpio_is_valid(pdata->reset_gpio_port[0]))
440 gpio_set_value_cansleep 486 gpio_set_value_cansleep
441 (pdata->ehci_data->reset_gpio_port[0], 1); 487 (pdata->reset_gpio_port[0], 1);
442 488
443 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) 489 if (gpio_is_valid(pdata->reset_gpio_port[1]))
444 gpio_set_value_cansleep 490 gpio_set_value_cansleep
445 (pdata->ehci_data->reset_gpio_port[1], 1); 491 (pdata->reset_gpio_port[1], 1);
446 } 492 }
447} 493}
448 494
449static void omap_usbhs_deinit(struct device *dev) 495static void omap_usbhs_deinit(struct device *dev)
450{ 496{
451 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); 497 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
452 struct usbhs_omap_platform_data *pdata = &omap->platdata; 498 struct usbhs_omap_platform_data *pdata = omap->pdata;
453 499
454 if (pdata->ehci_data->phy_reset) { 500 if (pdata->phy_reset) {
455 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) 501 if (gpio_is_valid(pdata->reset_gpio_port[0]))
456 gpio_free(pdata->ehci_data->reset_gpio_port[0]); 502 gpio_free(pdata->reset_gpio_port[0]);
457 503
458 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) 504 if (gpio_is_valid(pdata->reset_gpio_port[1]))
459 gpio_free(pdata->ehci_data->reset_gpio_port[1]); 505 gpio_free(pdata->reset_gpio_port[1]);
460 } 506 }
461} 507}
462 508
@@ -474,137 +520,185 @@ static int usbhs_omap_probe(struct platform_device *pdev)
474 struct resource *res; 520 struct resource *res;
475 int ret = 0; 521 int ret = 0;
476 int i; 522 int i;
523 bool need_logic_fck;
477 524
478 if (!pdata) { 525 if (!pdata) {
479 dev_err(dev, "Missing platform data\n"); 526 dev_err(dev, "Missing platform data\n");
480 ret = -ENOMEM; 527 return -ENODEV;
481 goto end_probe;
482 } 528 }
483 529
484 omap = kzalloc(sizeof(*omap), GFP_KERNEL); 530 omap = devm_kzalloc(dev, sizeof(*omap), GFP_KERNEL);
485 if (!omap) { 531 if (!omap) {
486 dev_err(dev, "Memory allocation failed\n"); 532 dev_err(dev, "Memory allocation failed\n");
487 ret = -ENOMEM; 533 return -ENOMEM;
488 goto end_probe;
489 } 534 }
490 535
491 spin_lock_init(&omap->lock); 536 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh");
492 537 omap->uhh_base = devm_request_and_ioremap(dev, res);
493 for (i = 0; i < OMAP3_HS_USB_PORTS; i++) 538 if (!omap->uhh_base) {
494 omap->platdata.port_mode[i] = pdata->port_mode[i]; 539 dev_err(dev, "Resource request/ioremap failed\n");
540 return -EADDRNOTAVAIL;
541 }
495 542
496 omap->platdata.ehci_data = pdata->ehci_data; 543 omap->pdata = pdata;
497 omap->platdata.ohci_data = pdata->ohci_data;
498 544
499 pm_runtime_enable(dev); 545 pm_runtime_enable(dev);
500 546
547 platform_set_drvdata(pdev, omap);
548 pm_runtime_get_sync(dev);
549
550 omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
501 551
502 for (i = 0; i < OMAP3_HS_USB_PORTS; i++) 552 /* we need to call runtime suspend before we update omap->nports
503 if (is_ehci_phy_mode(i) || is_ehci_tll_mode(i) || 553 * to prevent unbalanced clk_disable()
504 is_ehci_hsic_mode(i)) { 554 */
505 omap->ehci_logic_fck = clk_get(dev, "ehci_logic_fck"); 555 pm_runtime_put_sync(dev);
506 if (IS_ERR(omap->ehci_logic_fck)) { 556
507 ret = PTR_ERR(omap->ehci_logic_fck); 557 /*
508 dev_warn(dev, "ehci_logic_fck failed:%d\n", 558 * If platform data contains nports then use that
509 ret); 559 * else make out number of ports from USBHS revision
510 } 560 */
561 if (pdata->nports) {
562 omap->nports = pdata->nports;
563 } else {
564 switch (omap->usbhs_rev) {
565 case OMAP_USBHS_REV1:
566 omap->nports = 3;
567 break;
568 case OMAP_USBHS_REV2:
569 omap->nports = 2;
570 break;
571 default:
572 omap->nports = OMAP3_HS_USB_PORTS;
573 dev_dbg(dev,
574 "USB HOST Rev:0x%d not recognized, assuming %d ports\n",
575 omap->usbhs_rev, omap->nports);
511 break; 576 break;
512 } 577 }
578 }
513 579
514 omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); 580 i = sizeof(struct clk *) * omap->nports;
515 if (IS_ERR(omap->utmi_p1_fck)) { 581 omap->utmi_clk = devm_kzalloc(dev, i, GFP_KERNEL);
516 ret = PTR_ERR(omap->utmi_p1_fck); 582 omap->hsic480m_clk = devm_kzalloc(dev, i, GFP_KERNEL);
517 dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); 583 omap->hsic60m_clk = devm_kzalloc(dev, i, GFP_KERNEL);
518 goto err_end; 584
585 if (!omap->utmi_clk || !omap->hsic480m_clk || !omap->hsic60m_clk) {
586 dev_err(dev, "Memory allocation failed\n");
587 ret = -ENOMEM;
588 goto err_mem;
589 }
590
591 need_logic_fck = false;
592 for (i = 0; i < omap->nports; i++) {
593 if (is_ehci_phy_mode(i) || is_ehci_tll_mode(i) ||
594 is_ehci_hsic_mode(i))
595 need_logic_fck |= true;
596 }
597
598 omap->ehci_logic_fck = ERR_PTR(-EINVAL);
599 if (need_logic_fck) {
600 omap->ehci_logic_fck = clk_get(dev, "ehci_logic_fck");
601 if (IS_ERR(omap->ehci_logic_fck)) {
602 ret = PTR_ERR(omap->ehci_logic_fck);
603 dev_dbg(dev, "ehci_logic_fck failed:%d\n", ret);
604 }
605 }
606
607 omap->utmi_p1_gfclk = clk_get(dev, "utmi_p1_gfclk");
608 if (IS_ERR(omap->utmi_p1_gfclk)) {
609 ret = PTR_ERR(omap->utmi_p1_gfclk);
610 dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
611 goto err_p1_gfclk;
612 }
613
614 omap->utmi_p2_gfclk = clk_get(dev, "utmi_p2_gfclk");
615 if (IS_ERR(omap->utmi_p2_gfclk)) {
616 ret = PTR_ERR(omap->utmi_p2_gfclk);
617 dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
618 goto err_p2_gfclk;
519 } 619 }
520 620
521 omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); 621 omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
522 if (IS_ERR(omap->xclk60mhsp1_ck)) { 622 if (IS_ERR(omap->xclk60mhsp1_ck)) {
523 ret = PTR_ERR(omap->xclk60mhsp1_ck); 623 ret = PTR_ERR(omap->xclk60mhsp1_ck);
524 dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret); 624 dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
525 goto err_utmi_p1_fck; 625 goto err_xclk60mhsp1;
526 }
527
528 omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk");
529 if (IS_ERR(omap->utmi_p2_fck)) {
530 ret = PTR_ERR(omap->utmi_p2_fck);
531 dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
532 goto err_xclk60mhsp1_ck;
533 } 626 }
534 627
535 omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck"); 628 omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
536 if (IS_ERR(omap->xclk60mhsp2_ck)) { 629 if (IS_ERR(omap->xclk60mhsp2_ck)) {
537 ret = PTR_ERR(omap->xclk60mhsp2_ck); 630 ret = PTR_ERR(omap->xclk60mhsp2_ck);
538 dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret); 631 dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
539 goto err_utmi_p2_fck; 632 goto err_xclk60mhsp2;
540 }
541
542 omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk");
543 if (IS_ERR(omap->usbhost_p1_fck)) {
544 ret = PTR_ERR(omap->usbhost_p1_fck);
545 dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret);
546 goto err_xclk60mhsp2_ck;
547 }
548
549 omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
550 if (IS_ERR(omap->usbhost_p2_fck)) {
551 ret = PTR_ERR(omap->usbhost_p2_fck);
552 dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
553 goto err_usbhost_p1_fck;
554 } 633 }
555 634
556 omap->init_60m_fclk = clk_get(dev, "init_60m_fclk"); 635 omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
557 if (IS_ERR(omap->init_60m_fclk)) { 636 if (IS_ERR(omap->init_60m_fclk)) {
558 ret = PTR_ERR(omap->init_60m_fclk); 637 ret = PTR_ERR(omap->init_60m_fclk);
559 dev_err(dev, "init_60m_fclk failed error:%d\n", ret); 638 dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
560 goto err_usbhost_p2_fck; 639 goto err_init60m;
640 }
641
642 for (i = 0; i < omap->nports; i++) {
643 char clkname[30];
644
645 /* clock names are indexed from 1*/
646 snprintf(clkname, sizeof(clkname),
647 "usb_host_hs_utmi_p%d_clk", i + 1);
648
649 /* If a clock is not found we won't bail out as not all
650 * platforms have all clocks and we can function without
651 * them
652 */
653 omap->utmi_clk[i] = clk_get(dev, clkname);
654 if (IS_ERR(omap->utmi_clk[i]))
655 dev_dbg(dev, "Failed to get clock : %s : %ld\n",
656 clkname, PTR_ERR(omap->utmi_clk[i]));
657
658 snprintf(clkname, sizeof(clkname),
659 "usb_host_hs_hsic480m_p%d_clk", i + 1);
660 omap->hsic480m_clk[i] = clk_get(dev, clkname);
661 if (IS_ERR(omap->hsic480m_clk[i]))
662 dev_dbg(dev, "Failed to get clock : %s : %ld\n",
663 clkname, PTR_ERR(omap->hsic480m_clk[i]));
664
665 snprintf(clkname, sizeof(clkname),
666 "usb_host_hs_hsic60m_p%d_clk", i + 1);
667 omap->hsic60m_clk[i] = clk_get(dev, clkname);
668 if (IS_ERR(omap->hsic60m_clk[i]))
669 dev_dbg(dev, "Failed to get clock : %s : %ld\n",
670 clkname, PTR_ERR(omap->hsic60m_clk[i]));
561 } 671 }
562 672
563 if (is_ehci_phy_mode(pdata->port_mode[0])) { 673 if (is_ehci_phy_mode(pdata->port_mode[0])) {
564 /* for OMAP3 , the clk set paretn fails */ 674 /* for OMAP3, clk_set_parent fails */
565 ret = clk_set_parent(omap->utmi_p1_fck, 675 ret = clk_set_parent(omap->utmi_p1_gfclk,
566 omap->xclk60mhsp1_ck); 676 omap->xclk60mhsp1_ck);
567 if (ret != 0) 677 if (ret != 0)
568 dev_err(dev, "xclk60mhsp1_ck set parent" 678 dev_dbg(dev, "xclk60mhsp1_ck set parent failed: %d\n",
569 "failed error:%d\n", ret); 679 ret);
570 } else if (is_ehci_tll_mode(pdata->port_mode[0])) { 680 } else if (is_ehci_tll_mode(pdata->port_mode[0])) {
571 ret = clk_set_parent(omap->utmi_p1_fck, 681 ret = clk_set_parent(omap->utmi_p1_gfclk,
572 omap->init_60m_fclk); 682 omap->init_60m_fclk);
573 if (ret != 0) 683 if (ret != 0)
574 dev_err(dev, "init_60m_fclk set parent" 684 dev_dbg(dev, "P0 init_60m_fclk set parent failed: %d\n",
575 "failed error:%d\n", ret); 685 ret);
576 } 686 }
577 687
578 if (is_ehci_phy_mode(pdata->port_mode[1])) { 688 if (is_ehci_phy_mode(pdata->port_mode[1])) {
579 ret = clk_set_parent(omap->utmi_p2_fck, 689 ret = clk_set_parent(omap->utmi_p2_gfclk,
580 omap->xclk60mhsp2_ck); 690 omap->xclk60mhsp2_ck);
581 if (ret != 0) 691 if (ret != 0)
582 dev_err(dev, "xclk60mhsp2_ck set parent" 692 dev_dbg(dev, "xclk60mhsp2_ck set parent failed: %d\n",
583 "failed error:%d\n", ret); 693 ret);
584 } else if (is_ehci_tll_mode(pdata->port_mode[1])) { 694 } else if (is_ehci_tll_mode(pdata->port_mode[1])) {
585 ret = clk_set_parent(omap->utmi_p2_fck, 695 ret = clk_set_parent(omap->utmi_p2_gfclk,
586 omap->init_60m_fclk); 696 omap->init_60m_fclk);
587 if (ret != 0) 697 if (ret != 0)
588 dev_err(dev, "init_60m_fclk set parent" 698 dev_dbg(dev, "P1 init_60m_fclk set parent failed: %d\n",
589 "failed error:%d\n", ret); 699 ret);
590 }
591
592 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh");
593 if (!res) {
594 dev_err(dev, "UHH EHCI get resource failed\n");
595 ret = -ENODEV;
596 goto err_init_60m_fclk;
597 }
598
599 omap->uhh_base = ioremap(res->start, resource_size(res));
600 if (!omap->uhh_base) {
601 dev_err(dev, "UHH ioremap failed\n");
602 ret = -ENOMEM;
603 goto err_init_60m_fclk;
604 } 700 }
605 701
606 platform_set_drvdata(pdev, omap);
607
608 omap_usbhs_init(dev); 702 omap_usbhs_init(dev);
609 ret = omap_usbhs_alloc_children(pdev); 703 ret = omap_usbhs_alloc_children(pdev);
610 if (ret) { 704 if (ret) {
@@ -612,39 +706,41 @@ static int usbhs_omap_probe(struct platform_device *pdev)
612 goto err_alloc; 706 goto err_alloc;
613 } 707 }
614 708
615 goto end_probe; 709 return 0;
616 710
617err_alloc: 711err_alloc:
618 omap_usbhs_deinit(&pdev->dev); 712 omap_usbhs_deinit(&pdev->dev);
619 iounmap(omap->uhh_base);
620
621err_init_60m_fclk:
622 clk_put(omap->init_60m_fclk);
623 713
624err_usbhost_p2_fck: 714 for (i = 0; i < omap->nports; i++) {
625 clk_put(omap->usbhost_p2_fck); 715 if (!IS_ERR(omap->utmi_clk[i]))
716 clk_put(omap->utmi_clk[i]);
717 if (!IS_ERR(omap->hsic60m_clk[i]))
718 clk_put(omap->hsic60m_clk[i]);
719 if (!IS_ERR(omap->hsic480m_clk[i]))
720 clk_put(omap->hsic480m_clk[i]);
721 }
626 722
627err_usbhost_p1_fck: 723 clk_put(omap->init_60m_fclk);
628 clk_put(omap->usbhost_p1_fck);
629 724
630err_xclk60mhsp2_ck: 725err_init60m:
631 clk_put(omap->xclk60mhsp2_ck); 726 clk_put(omap->xclk60mhsp2_ck);
632 727
633err_utmi_p2_fck: 728err_xclk60mhsp2:
634 clk_put(omap->utmi_p2_fck);
635
636err_xclk60mhsp1_ck:
637 clk_put(omap->xclk60mhsp1_ck); 729 clk_put(omap->xclk60mhsp1_ck);
638 730
639err_utmi_p1_fck: 731err_xclk60mhsp1:
640 clk_put(omap->utmi_p1_fck); 732 clk_put(omap->utmi_p2_gfclk);
641 733
642err_end: 734err_p2_gfclk:
643 clk_put(omap->ehci_logic_fck); 735 clk_put(omap->utmi_p1_gfclk);
736
737err_p1_gfclk:
738 if (!IS_ERR(omap->ehci_logic_fck))
739 clk_put(omap->ehci_logic_fck);
740
741err_mem:
644 pm_runtime_disable(dev); 742 pm_runtime_disable(dev);
645 kfree(omap);
646 743
647end_probe:
648 return ret; 744 return ret;
649} 745}
650 746
@@ -657,19 +753,29 @@ end_probe:
657static int usbhs_omap_remove(struct platform_device *pdev) 753static int usbhs_omap_remove(struct platform_device *pdev)
658{ 754{
659 struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); 755 struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
756 int i;
660 757
661 omap_usbhs_deinit(&pdev->dev); 758 omap_usbhs_deinit(&pdev->dev);
662 iounmap(omap->uhh_base); 759
760 for (i = 0; i < omap->nports; i++) {
761 if (!IS_ERR(omap->utmi_clk[i]))
762 clk_put(omap->utmi_clk[i]);
763 if (!IS_ERR(omap->hsic60m_clk[i]))
764 clk_put(omap->hsic60m_clk[i]);
765 if (!IS_ERR(omap->hsic480m_clk[i]))
766 clk_put(omap->hsic480m_clk[i]);
767 }
768
663 clk_put(omap->init_60m_fclk); 769 clk_put(omap->init_60m_fclk);
664 clk_put(omap->usbhost_p2_fck); 770 clk_put(omap->utmi_p1_gfclk);
665 clk_put(omap->usbhost_p1_fck); 771 clk_put(omap->utmi_p2_gfclk);
666 clk_put(omap->xclk60mhsp2_ck); 772 clk_put(omap->xclk60mhsp2_ck);
667 clk_put(omap->utmi_p2_fck);
668 clk_put(omap->xclk60mhsp1_ck); 773 clk_put(omap->xclk60mhsp1_ck);
669 clk_put(omap->utmi_p1_fck); 774
670 clk_put(omap->ehci_logic_fck); 775 if (!IS_ERR(omap->ehci_logic_fck))
776 clk_put(omap->ehci_logic_fck);
777
671 pm_runtime_disable(&pdev->dev); 778 pm_runtime_disable(&pdev->dev);
672 kfree(omap);
673 779
674 return 0; 780 return 0;
675} 781}
@@ -685,7 +791,7 @@ static struct platform_driver usbhs_omap_driver = {
685 .owner = THIS_MODULE, 791 .owner = THIS_MODULE,
686 .pm = &usbhsomap_dev_pm_ops, 792 .pm = &usbhsomap_dev_pm_ops,
687 }, 793 },
688 .remove = __exit_p(usbhs_omap_remove), 794 .remove = usbhs_omap_remove,
689}; 795};
690 796
691MODULE_AUTHOR("Keshava Munegowda <keshava_mgowda@ti.com>"); 797MODULE_AUTHOR("Keshava Munegowda <keshava_mgowda@ti.com>");
diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c
index eb869153206d..0aef1a768880 100644
--- a/drivers/mfd/omap-usb-tll.c
+++ b/drivers/mfd/omap-usb-tll.c
@@ -54,10 +54,13 @@
54 54
55#define OMAP_TLL_CHANNEL_CONF(num) (0x040 + 0x004 * num) 55#define OMAP_TLL_CHANNEL_CONF(num) (0x040 + 0x004 * num)
56#define OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT 24 56#define OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT 24
57#define OMAP_TLL_CHANNEL_CONF_DRVVBUS (1 << 16)
58#define OMAP_TLL_CHANNEL_CONF_CHRGVBUS (1 << 15)
57#define OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF (1 << 11) 59#define OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF (1 << 11)
58#define OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE (1 << 10) 60#define OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE (1 << 10)
59#define OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE (1 << 9) 61#define OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE (1 << 9)
60#define OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE (1 << 8) 62#define OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE (1 << 8)
63#define OMAP_TLL_CHANNEL_CONF_MODE_TRANSPARENT_UTMI (2 << 1)
61#define OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS (1 << 1) 64#define OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS (1 << 1)
62#define OMAP_TLL_CHANNEL_CONF_CHANEN (1 << 0) 65#define OMAP_TLL_CHANNEL_CONF_CHANEN (1 << 0)
63 66
@@ -92,21 +95,25 @@
92#define OMAP_USBTLL_REV1 0x00000015 /* OMAP3 */ 95#define OMAP_USBTLL_REV1 0x00000015 /* OMAP3 */
93#define OMAP_USBTLL_REV2 0x00000018 /* OMAP 3630 */ 96#define OMAP_USBTLL_REV2 0x00000018 /* OMAP 3630 */
94#define OMAP_USBTLL_REV3 0x00000004 /* OMAP4 */ 97#define OMAP_USBTLL_REV3 0x00000004 /* OMAP4 */
98#define OMAP_USBTLL_REV4 0x00000006 /* OMAP5 */
95 99
96#define is_ehci_tll_mode(x) (x == OMAP_EHCI_PORT_MODE_TLL) 100#define is_ehci_tll_mode(x) (x == OMAP_EHCI_PORT_MODE_TLL)
97 101
102/* only PHY and UNUSED modes don't need TLL */
103#define omap_usb_mode_needs_tll(x) ((x) != OMAP_USBHS_PORT_MODE_UNUSED &&\
104 (x) != OMAP_EHCI_PORT_MODE_PHY)
105
98struct usbtll_omap { 106struct usbtll_omap {
99 struct clk *usbtll_p1_fck; 107 int nch; /* num. of channels */
100 struct clk *usbtll_p2_fck; 108 struct usbhs_omap_platform_data *pdata;
101 struct usbtll_omap_platform_data platdata; 109 struct clk **ch_clk;
102 /* secure the register updates */
103 spinlock_t lock;
104}; 110};
105 111
106/*-------------------------------------------------------------------------*/ 112/*-------------------------------------------------------------------------*/
107 113
108const char usbtll_driver_name[] = USBTLL_DRIVER_NAME; 114static const char usbtll_driver_name[] = USBTLL_DRIVER_NAME;
109struct platform_device *tll_pdev; 115static struct device *tll_dev;
116static DEFINE_SPINLOCK(tll_lock); /* serialize access to tll_dev */
110 117
111/*-------------------------------------------------------------------------*/ 118/*-------------------------------------------------------------------------*/
112 119
@@ -203,84 +210,84 @@ static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode)
203static int usbtll_omap_probe(struct platform_device *pdev) 210static int usbtll_omap_probe(struct platform_device *pdev)
204{ 211{
205 struct device *dev = &pdev->dev; 212 struct device *dev = &pdev->dev;
206 struct usbtll_omap_platform_data *pdata = dev->platform_data; 213 struct usbhs_omap_platform_data *pdata = dev->platform_data;
207 void __iomem *base; 214 void __iomem *base;
208 struct resource *res; 215 struct resource *res;
209 struct usbtll_omap *tll; 216 struct usbtll_omap *tll;
210 unsigned reg; 217 unsigned reg;
211 unsigned long flags;
212 int ret = 0; 218 int ret = 0;
213 int i, ver, count; 219 int i, ver;
220 bool needs_tll;
214 221
215 dev_dbg(dev, "starting TI HSUSB TLL Controller\n"); 222 dev_dbg(dev, "starting TI HSUSB TLL Controller\n");
216 223
217 tll = kzalloc(sizeof(struct usbtll_omap), GFP_KERNEL); 224 tll = devm_kzalloc(dev, sizeof(struct usbtll_omap), GFP_KERNEL);
218 if (!tll) { 225 if (!tll) {
219 dev_err(dev, "Memory allocation failed\n"); 226 dev_err(dev, "Memory allocation failed\n");
220 ret = -ENOMEM; 227 return -ENOMEM;
221 goto end;
222 } 228 }
223 229
224 spin_lock_init(&tll->lock); 230 if (!pdata) {
225 231 dev_err(dev, "Platform data missing\n");
226 for (i = 0; i < OMAP3_HS_USB_PORTS; i++) 232 return -ENODEV;
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 } 233 }
235 234
236 tll->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk"); 235 tll->pdata = pdata;
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 236
243 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 237 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
244 if (!res) { 238 base = devm_request_and_ioremap(dev, 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) { 239 if (!base) {
252 dev_err(dev, "TLL ioremap failed\n"); 240 ret = -EADDRNOTAVAIL;
253 ret = -ENOMEM; 241 dev_err(dev, "Resource request/ioremap failed:%d\n", ret);
254 goto err_usbtll_p2_fck; 242 return ret;
255 } 243 }
256 244
257 platform_set_drvdata(pdev, tll); 245 platform_set_drvdata(pdev, tll);
258 pm_runtime_enable(dev); 246 pm_runtime_enable(dev);
259 pm_runtime_get_sync(dev); 247 pm_runtime_get_sync(dev);
260 248
261 spin_lock_irqsave(&tll->lock, flags);
262
263 ver = usbtll_read(base, OMAP_USBTLL_REVISION); 249 ver = usbtll_read(base, OMAP_USBTLL_REVISION);
264 switch (ver) { 250 switch (ver) {
265 case OMAP_USBTLL_REV1: 251 case OMAP_USBTLL_REV1:
266 case OMAP_USBTLL_REV2: 252 case OMAP_USBTLL_REV4:
267 count = OMAP_TLL_CHANNEL_COUNT; 253 tll->nch = OMAP_TLL_CHANNEL_COUNT;
268 break; 254 break;
255 case OMAP_USBTLL_REV2:
269 case OMAP_USBTLL_REV3: 256 case OMAP_USBTLL_REV3:
270 count = OMAP_REV2_TLL_CHANNEL_COUNT; 257 tll->nch = OMAP_REV2_TLL_CHANNEL_COUNT;
271 break; 258 break;
272 default: 259 default:
273 dev_err(dev, "TLL version failed\n"); 260 tll->nch = OMAP_TLL_CHANNEL_COUNT;
274 ret = -ENODEV; 261 dev_dbg(dev,
275 goto err_ioremap; 262 "USB TLL Rev : 0x%x not recognized, assuming %d channels\n",
263 ver, tll->nch);
264 break;
276 } 265 }
277 266
278 if (is_ehci_tll_mode(pdata->port_mode[0]) || 267 tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk * [tll->nch]),
279 is_ehci_tll_mode(pdata->port_mode[1]) || 268 GFP_KERNEL);
280 is_ehci_tll_mode(pdata->port_mode[2]) || 269 if (!tll->ch_clk) {
281 is_ohci_port(pdata->port_mode[0]) || 270 ret = -ENOMEM;
282 is_ohci_port(pdata->port_mode[1]) || 271 dev_err(dev, "Couldn't allocate memory for channel clocks\n");
283 is_ohci_port(pdata->port_mode[2])) { 272 goto err_clk_alloc;
273 }
274
275 for (i = 0; i < tll->nch; i++) {
276 char clkname[] = "usb_tll_hs_usb_chx_clk";
277
278 snprintf(clkname, sizeof(clkname),
279 "usb_tll_hs_usb_ch%d_clk", i);
280 tll->ch_clk[i] = clk_get(dev, clkname);
281
282 if (IS_ERR(tll->ch_clk[i]))
283 dev_dbg(dev, "can't get clock : %s\n", clkname);
284 }
285
286 needs_tll = false;
287 for (i = 0; i < tll->nch; i++)
288 needs_tll |= omap_usb_mode_needs_tll(pdata->port_mode[i]);
289
290 if (needs_tll) {
284 291
285 /* Program Common TLL register */ 292 /* Program Common TLL register */
286 reg = usbtll_read(base, OMAP_TLL_SHARED_CONF); 293 reg = usbtll_read(base, OMAP_TLL_SHARED_CONF);
@@ -292,7 +299,7 @@ static int usbtll_omap_probe(struct platform_device *pdev)
292 usbtll_write(base, OMAP_TLL_SHARED_CONF, reg); 299 usbtll_write(base, OMAP_TLL_SHARED_CONF, reg);
293 300
294 /* Enable channels now */ 301 /* Enable channels now */
295 for (i = 0; i < count; i++) { 302 for (i = 0; i < tll->nch; i++) {
296 reg = usbtll_read(base, OMAP_TLL_CHANNEL_CONF(i)); 303 reg = usbtll_read(base, OMAP_TLL_CHANNEL_CONF(i));
297 304
298 if (is_ohci_port(pdata->port_mode[i])) { 305 if (is_ohci_port(pdata->port_mode[i])) {
@@ -308,6 +315,15 @@ static int usbtll_omap_probe(struct platform_device *pdev)
308 reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE 315 reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE
309 | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF 316 | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF
310 | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE); 317 | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE);
318 } else if (pdata->port_mode[i] ==
319 OMAP_EHCI_PORT_MODE_HSIC) {
320 /*
321 * HSIC Mode requires UTMI port configurations
322 */
323 reg |= OMAP_TLL_CHANNEL_CONF_DRVVBUS
324 | OMAP_TLL_CHANNEL_CONF_CHRGVBUS
325 | OMAP_TLL_CHANNEL_CONF_MODE_TRANSPARENT_UTMI
326 | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF;
311 } else { 327 } else {
312 continue; 328 continue;
313 } 329 }
@@ -320,25 +336,18 @@ static int usbtll_omap_probe(struct platform_device *pdev)
320 } 336 }
321 } 337 }
322 338
323err_ioremap:
324 spin_unlock_irqrestore(&tll->lock, flags);
325 iounmap(base);
326 pm_runtime_put_sync(dev); 339 pm_runtime_put_sync(dev);
327 tll_pdev = pdev; 340 /* only after this can omap_tll_enable/disable work */
328 if (!ret) 341 spin_lock(&tll_lock);
329 goto end; 342 tll_dev = dev;
330 pm_runtime_disable(dev); 343 spin_unlock(&tll_lock);
331 344
332err_usbtll_p2_fck: 345 return 0;
333 clk_put(tll->usbtll_p2_fck);
334
335err_usbtll_p1_fck:
336 clk_put(tll->usbtll_p1_fck);
337 346
338err_tll: 347err_clk_alloc:
339 kfree(tll); 348 pm_runtime_put_sync(dev);
349 pm_runtime_disable(dev);
340 350
341end:
342 return ret; 351 return ret;
343} 352}
344 353
@@ -351,36 +360,42 @@ end:
351static int usbtll_omap_remove(struct platform_device *pdev) 360static int usbtll_omap_remove(struct platform_device *pdev)
352{ 361{
353 struct usbtll_omap *tll = platform_get_drvdata(pdev); 362 struct usbtll_omap *tll = platform_get_drvdata(pdev);
363 int i;
364
365 spin_lock(&tll_lock);
366 tll_dev = NULL;
367 spin_unlock(&tll_lock);
368
369 for (i = 0; i < tll->nch; i++)
370 if (!IS_ERR(tll->ch_clk[i]))
371 clk_put(tll->ch_clk[i]);
354 372
355 clk_put(tll->usbtll_p2_fck);
356 clk_put(tll->usbtll_p1_fck);
357 pm_runtime_disable(&pdev->dev); 373 pm_runtime_disable(&pdev->dev);
358 kfree(tll);
359 return 0; 374 return 0;
360} 375}
361 376
362static int usbtll_runtime_resume(struct device *dev) 377static int usbtll_runtime_resume(struct device *dev)
363{ 378{
364 struct usbtll_omap *tll = dev_get_drvdata(dev); 379 struct usbtll_omap *tll = dev_get_drvdata(dev);
365 struct usbtll_omap_platform_data *pdata = &tll->platdata; 380 struct usbhs_omap_platform_data *pdata = tll->pdata;
366 unsigned long flags; 381 int i;
367 382
368 dev_dbg(dev, "usbtll_runtime_resume\n"); 383 dev_dbg(dev, "usbtll_runtime_resume\n");
369 384
370 if (!pdata) { 385 for (i = 0; i < tll->nch; i++) {
371 dev_dbg(dev, "missing platform_data\n"); 386 if (omap_usb_mode_needs_tll(pdata->port_mode[i])) {
372 return -ENODEV; 387 int r;
373 }
374
375 spin_lock_irqsave(&tll->lock, flags);
376 388
377 if (is_ehci_tll_mode(pdata->port_mode[0])) 389 if (IS_ERR(tll->ch_clk[i]))
378 clk_enable(tll->usbtll_p1_fck); 390 continue;
379
380 if (is_ehci_tll_mode(pdata->port_mode[1]))
381 clk_enable(tll->usbtll_p2_fck);
382 391
383 spin_unlock_irqrestore(&tll->lock, flags); 392 r = clk_enable(tll->ch_clk[i]);
393 if (r) {
394 dev_err(dev,
395 "Error enabling ch %d clock: %d\n", i, r);
396 }
397 }
398 }
384 399
385 return 0; 400 return 0;
386} 401}
@@ -388,26 +403,18 @@ static int usbtll_runtime_resume(struct device *dev)
388static int usbtll_runtime_suspend(struct device *dev) 403static int usbtll_runtime_suspend(struct device *dev)
389{ 404{
390 struct usbtll_omap *tll = dev_get_drvdata(dev); 405 struct usbtll_omap *tll = dev_get_drvdata(dev);
391 struct usbtll_omap_platform_data *pdata = &tll->platdata; 406 struct usbhs_omap_platform_data *pdata = tll->pdata;
392 unsigned long flags; 407 int i;
393 408
394 dev_dbg(dev, "usbtll_runtime_suspend\n"); 409 dev_dbg(dev, "usbtll_runtime_suspend\n");
395 410
396 if (!pdata) { 411 for (i = 0; i < tll->nch; i++) {
397 dev_dbg(dev, "missing platform_data\n"); 412 if (omap_usb_mode_needs_tll(pdata->port_mode[i])) {
398 return -ENODEV; 413 if (!IS_ERR(tll->ch_clk[i]))
414 clk_disable(tll->ch_clk[i]);
415 }
399 } 416 }
400 417
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; 418 return 0;
412} 419}
413 420
@@ -429,21 +436,39 @@ static struct platform_driver usbtll_omap_driver = {
429 436
430int omap_tll_enable(void) 437int omap_tll_enable(void)
431{ 438{
432 if (!tll_pdev) { 439 int ret;
433 pr_err("missing omap usbhs tll platform_data\n"); 440
434 return -ENODEV; 441 spin_lock(&tll_lock);
442
443 if (!tll_dev) {
444 pr_err("%s: OMAP USB TLL not initialized\n", __func__);
445 ret = -ENODEV;
446 } else {
447 ret = pm_runtime_get_sync(tll_dev);
435 } 448 }
436 return pm_runtime_get_sync(&tll_pdev->dev); 449
450 spin_unlock(&tll_lock);
451
452 return ret;
437} 453}
438EXPORT_SYMBOL_GPL(omap_tll_enable); 454EXPORT_SYMBOL_GPL(omap_tll_enable);
439 455
440int omap_tll_disable(void) 456int omap_tll_disable(void)
441{ 457{
442 if (!tll_pdev) { 458 int ret;
443 pr_err("missing omap usbhs tll platform_data\n"); 459
444 return -ENODEV; 460 spin_lock(&tll_lock);
461
462 if (!tll_dev) {
463 pr_err("%s: OMAP USB TLL not initialized\n", __func__);
464 ret = -ENODEV;
465 } else {
466 ret = pm_runtime_put_sync(tll_dev);
445 } 467 }
446 return pm_runtime_put_sync(&tll_pdev->dev); 468
469 spin_unlock(&tll_lock);
470
471 return ret;
447} 472}
448EXPORT_SYMBOL_GPL(omap_tll_disable); 473EXPORT_SYMBOL_GPL(omap_tll_disable);
449 474
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index ac17a7c3a0cd..5d954d7b290d 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -107,7 +107,7 @@ static int omap_ehci_init(struct usb_hcd *hcd)
107{ 107{
108 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 108 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
109 int rc; 109 int rc;
110 struct ehci_hcd_omap_platform_data *pdata; 110 struct usbhs_omap_platform_data *pdata;
111 111
112 pdata = hcd->self.controller->platform_data; 112 pdata = hcd->self.controller->platform_data;
113 113
@@ -151,7 +151,7 @@ static int omap_ehci_init(struct usb_hcd *hcd)
151} 151}
152 152
153static void disable_put_regulator( 153static void disable_put_regulator(
154 struct ehci_hcd_omap_platform_data *pdata) 154 struct usbhs_omap_platform_data *pdata)
155{ 155{
156 int i; 156 int i;
157 157
@@ -176,7 +176,7 @@ static void disable_put_regulator(
176static int ehci_hcd_omap_probe(struct platform_device *pdev) 176static int ehci_hcd_omap_probe(struct platform_device *pdev)
177{ 177{
178 struct device *dev = &pdev->dev; 178 struct device *dev = &pdev->dev;
179 struct ehci_hcd_omap_platform_data *pdata = dev->platform_data; 179 struct usbhs_omap_platform_data *pdata = dev->platform_data;
180 struct resource *res; 180 struct resource *res;
181 struct usb_hcd *hcd; 181 struct usb_hcd *hcd;
182 void __iomem *regs; 182 void __iomem *regs;
diff --git a/include/linux/platform_data/usb-omap.h b/include/linux/platform_data/usb-omap.h
index e697c85ad3bc..fa579b4c666b 100644
--- a/include/linux/platform_data/usb-omap.h
+++ b/include/linux/platform_data/usb-omap.h
@@ -55,6 +55,7 @@ struct ohci_hcd_omap_platform_data {
55}; 55};
56 56
57struct usbhs_omap_platform_data { 57struct usbhs_omap_platform_data {
58 int nports;
58 enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS]; 59 enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS];
59 int reset_gpio_port[OMAP3_HS_USB_PORTS]; 60 int reset_gpio_port[OMAP3_HS_USB_PORTS];
60 struct regulator *regulator[OMAP3_HS_USB_PORTS]; 61 struct regulator *regulator[OMAP3_HS_USB_PORTS];