aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRuss Dill <Russ.Dill@gmail.com>2012-06-14 12:24:21 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2012-07-08 18:16:12 -0400
commit2761a63945164ef111062828858a80225222ecd7 (patch)
treebca5b58a646f2467d621d4fb4fc84d0a41bb0f64 /drivers
parent7f0f07ce25b62be9234998134f19e1511a9ad6c7 (diff)
mfd: USB: Fix the omap-usb EHCI ULPI PHY reset fix issues.
'ARM: OMAP3: USB: Fix the EHCI ULPI PHY reset issue' (1fcb57d0) fixes an issue where the ULPI PHYs were not held in reset while initializing the EHCI controller. However, it also changes behavior in omap-usb-host.c omap_usbhs_init by releasing reset while the configuration in that function was done. This change caused a regression on BB-xM where USB would not function if 'usb start' had been run from u-boot before booting. A change was made to release reset a little bit earlier which fixed the issue on BB-xM and did not cause any regressions on 3430 sdp, the board for which the fix was originally made. This new fix, 'USB: EHCI: OMAP: Finish ehci omap phy reset cycle before adding hcd.', (3aa2ae74) caused a regression on OMAP5. The original fix to hold the EHCI controller in reset during initialization was correct, however it appears that changing omap_usbhs_init to not hold the PHYs in reset during it's configuration was incorrect. This patch first reverts both fixes, and then changes ehci_hcd_omap_probe in ehci-omap.c to hold the PHYs in reset as the original patch had done. It also is sure to incorporate the _cansleep change that has been made in the meantime. I've tested this on Beagleboard xM, I'd really like to get an ack from the 3430 sdp and OMAP5 guys before getting this merged. v3 - Brown paper bag its too early in the morning actually run git commit amend fix v2 - Put cansleep gpiolib call outside of spinlock Acked-by: Mantesh Sarashetti <mantesh@ti.com> Tested-by: Mantesh Sarashetti <mantesh@ti.com> Acked-by: Keshava Munegowda <keshava_mgowda@ti.com> Tested-by: Keshava Munegowda <keshava_mgowda@ti.com> Signed-off-by: Russ Dill <Russ.Dill@gmail.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mfd/omap-usb-host.c48
-rw-r--r--drivers/usb/host/ehci-omap.c18
2 files changed, 55 insertions, 11 deletions
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 7e96bb229724..41088ecbb2a9 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -25,6 +25,7 @@
25#include <linux/clk.h> 25#include <linux/clk.h>
26#include <linux/dma-mapping.h> 26#include <linux/dma-mapping.h>
27#include <linux/spinlock.h> 27#include <linux/spinlock.h>
28#include <linux/gpio.h>
28#include <plat/cpu.h> 29#include <plat/cpu.h>
29#include <plat/usb.h> 30#include <plat/usb.h>
30#include <linux/pm_runtime.h> 31#include <linux/pm_runtime.h>
@@ -500,8 +501,21 @@ static void omap_usbhs_init(struct device *dev)
500 dev_dbg(dev, "starting TI HSUSB Controller\n"); 501 dev_dbg(dev, "starting TI HSUSB Controller\n");
501 502
502 pm_runtime_get_sync(dev); 503 pm_runtime_get_sync(dev);
503 spin_lock_irqsave(&omap->lock, flags);
504 504
505 if (pdata->ehci_data->phy_reset) {
506 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
507 gpio_request_one(pdata->ehci_data->reset_gpio_port[0],
508 GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
509
510 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
511 gpio_request_one(pdata->ehci_data->reset_gpio_port[1],
512 GPIOF_OUT_INIT_LOW, "USB2 PHY reset");
513
514 /* Hold the PHY in RESET for enough time till DIR is high */
515 udelay(10);
516 }
517
518 spin_lock_irqsave(&omap->lock, flags);
505 omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); 519 omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
506 dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); 520 dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
507 521
@@ -581,9 +595,39 @@ static void omap_usbhs_init(struct device *dev)
581 } 595 }
582 596
583 spin_unlock_irqrestore(&omap->lock, flags); 597 spin_unlock_irqrestore(&omap->lock, flags);
598
599 if (pdata->ehci_data->phy_reset) {
600 /* Hold the PHY in RESET for enough time till
601 * PHY is settled and ready
602 */
603 udelay(10);
604
605 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
606 gpio_set_value_cansleep
607 (pdata->ehci_data->reset_gpio_port[0], 1);
608
609 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
610 gpio_set_value_cansleep
611 (pdata->ehci_data->reset_gpio_port[1], 1);
612 }
613
584 pm_runtime_put_sync(dev); 614 pm_runtime_put_sync(dev);
585} 615}
586 616
617static void omap_usbhs_deinit(struct device *dev)
618{
619 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
620 struct usbhs_omap_platform_data *pdata = &omap->platdata;
621
622 if (pdata->ehci_data->phy_reset) {
623 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
624 gpio_free(pdata->ehci_data->reset_gpio_port[0]);
625
626 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
627 gpio_free(pdata->ehci_data->reset_gpio_port[1]);
628 }
629}
630
587 631
588/** 632/**
589 * usbhs_omap_probe - initialize TI-based HCDs 633 * usbhs_omap_probe - initialize TI-based HCDs
@@ -767,6 +811,7 @@ static int __devinit usbhs_omap_probe(struct platform_device *pdev)
767 goto end_probe; 811 goto end_probe;
768 812
769err_alloc: 813err_alloc:
814 omap_usbhs_deinit(&pdev->dev);
770 iounmap(omap->tll_base); 815 iounmap(omap->tll_base);
771 816
772err_tll: 817err_tll:
@@ -818,6 +863,7 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev)
818{ 863{
819 struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); 864 struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
820 865
866 omap_usbhs_deinit(&pdev->dev);
821 iounmap(omap->tll_base); 867 iounmap(omap->tll_base);
822 iounmap(omap->uhh_base); 868 iounmap(omap->uhh_base);
823 clk_put(omap->init_60m_fclk); 869 clk_put(omap->init_60m_fclk);
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 17cfb8a1131c..c30435499a02 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -281,14 +281,13 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
281 } 281 }
282 } 282 }
283 283
284 /* Hold PHYs in reset while initializing EHCI controller */
284 if (pdata->phy_reset) { 285 if (pdata->phy_reset) {
285 if (gpio_is_valid(pdata->reset_gpio_port[0])) 286 if (gpio_is_valid(pdata->reset_gpio_port[0]))
286 gpio_request_one(pdata->reset_gpio_port[0], 287 gpio_set_value_cansleep(pdata->reset_gpio_port[0], 0);
287 GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
288 288
289 if (gpio_is_valid(pdata->reset_gpio_port[1])) 289 if (gpio_is_valid(pdata->reset_gpio_port[1]))
290 gpio_request_one(pdata->reset_gpio_port[1], 290 gpio_set_value_cansleep(pdata->reset_gpio_port[1], 0);
291 GPIOF_OUT_INIT_LOW, "USB2 PHY reset");
292 291
293 /* Hold the PHY in RESET for enough time till DIR is high */ 292 /* Hold the PHY in RESET for enough time till DIR is high */
294 udelay(10); 293 udelay(10);
@@ -330,6 +329,11 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
330 omap_ehci->hcs_params = readl(&omap_ehci->caps->hcs_params); 329 omap_ehci->hcs_params = readl(&omap_ehci->caps->hcs_params);
331 330
332 ehci_reset(omap_ehci); 331 ehci_reset(omap_ehci);
332 ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
333 if (ret) {
334 dev_err(dev, "failed to add hcd with err %d\n", ret);
335 goto err_add_hcd;
336 }
333 337
334 if (pdata->phy_reset) { 338 if (pdata->phy_reset) {
335 /* Hold the PHY in RESET for enough time till 339 /* Hold the PHY in RESET for enough time till
@@ -344,12 +348,6 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
344 gpio_set_value_cansleep(pdata->reset_gpio_port[1], 1); 348 gpio_set_value_cansleep(pdata->reset_gpio_port[1], 1);
345 } 349 }
346 350
347 ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
348 if (ret) {
349 dev_err(dev, "failed to add hcd with err %d\n", ret);
350 goto err_add_hcd;
351 }
352
353 /* root ports should always stay powered */ 351 /* root ports should always stay powered */
354 ehci_port_power(omap_ehci, 1); 352 ehci_port_power(omap_ehci, 1);
355 353