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

mfd: Add omap-usbhs runtime PM support

The usbhs core driver does not enable/disable the interface and
functional clocks; These clocks are handled by hwmod and runtime pm,
hence insted of the clock enable/disable, the runtime pm APIS are
used. however,the port clocks and tll clocks are handled
by the usbhs core.

Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Keshava Munegowda and committed by
Samuel Ortiz
7e6502d5 74e32d1b

+9 -122
+9 -122
drivers/mfd/omap-usb-host.c
··· 26 26 #include <linux/spinlock.h> 27 27 #include <linux/gpio.h> 28 28 #include <plat/usb.h> 29 + #include <linux/pm_runtime.h> 29 30 30 31 #define USBHS_DRIVER_NAME "usbhs-omap" 31 32 #define OMAP_EHCI_DEVICE "ehci-omap" ··· 147 146 148 147 149 148 struct usbhs_hcd_omap { 150 - struct clk *usbhost_ick; 151 - struct clk *usbhost_hs_fck; 152 - struct clk *usbhost_fs_fck; 153 149 struct clk *xclk60mhsp1_ck; 154 150 struct clk *xclk60mhsp2_ck; 155 151 struct clk *utmi_p1_fck; ··· 156 158 struct clk *usbhost_p2_fck; 157 159 struct clk *usbtll_p2_fck; 158 160 struct clk *init_60m_fclk; 159 - struct clk *usbtll_fck; 160 - struct clk *usbtll_ick; 161 161 162 162 void __iomem *uhh_base; 163 163 void __iomem *tll_base; ··· 349 353 omap->platdata.ehci_data = pdata->ehci_data; 350 354 omap->platdata.ohci_data = pdata->ohci_data; 351 355 352 - omap->usbhost_ick = clk_get(dev, "usbhost_ick"); 353 - if (IS_ERR(omap->usbhost_ick)) { 354 - ret = PTR_ERR(omap->usbhost_ick); 355 - dev_err(dev, "usbhost_ick failed error:%d\n", ret); 356 - goto err_end; 357 - } 358 - 359 - omap->usbhost_hs_fck = clk_get(dev, "hs_fck"); 360 - if (IS_ERR(omap->usbhost_hs_fck)) { 361 - ret = PTR_ERR(omap->usbhost_hs_fck); 362 - dev_err(dev, "usbhost_hs_fck failed error:%d\n", ret); 363 - goto err_usbhost_ick; 364 - } 365 - 366 - omap->usbhost_fs_fck = clk_get(dev, "fs_fck"); 367 - if (IS_ERR(omap->usbhost_fs_fck)) { 368 - ret = PTR_ERR(omap->usbhost_fs_fck); 369 - dev_err(dev, "usbhost_fs_fck failed error:%d\n", ret); 370 - goto err_usbhost_hs_fck; 371 - } 372 - 373 - omap->usbtll_fck = clk_get(dev, "usbtll_fck"); 374 - if (IS_ERR(omap->usbtll_fck)) { 375 - ret = PTR_ERR(omap->usbtll_fck); 376 - dev_err(dev, "usbtll_fck failed error:%d\n", ret); 377 - goto err_usbhost_fs_fck; 378 - } 379 - 380 - omap->usbtll_ick = clk_get(dev, "usbtll_ick"); 381 - if (IS_ERR(omap->usbtll_ick)) { 382 - ret = PTR_ERR(omap->usbtll_ick); 383 - dev_err(dev, "usbtll_ick failed error:%d\n", ret); 384 - goto err_usbtll_fck; 385 - } 356 + pm_runtime_enable(&pdev->dev); 386 357 387 358 omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); 388 359 if (IS_ERR(omap->utmi_p1_fck)) { 389 360 ret = PTR_ERR(omap->utmi_p1_fck); 390 361 dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); 391 - goto err_usbtll_ick; 362 + goto err_end; 392 363 } 393 364 394 365 omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); ··· 485 522 err_utmi_p1_fck: 486 523 clk_put(omap->utmi_p1_fck); 487 524 488 - err_usbtll_ick: 489 - clk_put(omap->usbtll_ick); 490 - 491 - err_usbtll_fck: 492 - clk_put(omap->usbtll_fck); 493 - 494 - err_usbhost_fs_fck: 495 - clk_put(omap->usbhost_fs_fck); 496 - 497 - err_usbhost_hs_fck: 498 - clk_put(omap->usbhost_hs_fck); 499 - 500 - err_usbhost_ick: 501 - clk_put(omap->usbhost_ick); 502 - 503 525 err_end: 526 + pm_runtime_disable(&pdev->dev); 504 527 kfree(omap); 505 528 506 529 end_probe: ··· 520 571 clk_put(omap->utmi_p2_fck); 521 572 clk_put(omap->xclk60mhsp1_ck); 522 573 clk_put(omap->utmi_p1_fck); 523 - clk_put(omap->usbtll_ick); 524 - clk_put(omap->usbtll_fck); 525 - clk_put(omap->usbhost_fs_fck); 526 - clk_put(omap->usbhost_hs_fck); 527 - clk_put(omap->usbhost_ick); 574 + pm_runtime_disable(&pdev->dev); 528 575 kfree(omap); 529 576 530 577 return 0; ··· 640 695 struct usbhs_omap_platform_data *pdata = &omap->platdata; 641 696 unsigned long flags = 0; 642 697 int ret = 0; 643 - unsigned long timeout; 644 698 unsigned reg; 645 699 646 700 dev_dbg(dev, "starting TI HSUSB Controller\n"); ··· 652 708 if (omap->count > 0) 653 709 goto end_count; 654 710 655 - clk_enable(omap->usbhost_ick); 656 - clk_enable(omap->usbhost_hs_fck); 657 - clk_enable(omap->usbhost_fs_fck); 658 - clk_enable(omap->usbtll_fck); 659 - clk_enable(omap->usbtll_ick); 711 + pm_runtime_get_sync(dev); 660 712 661 713 if (pdata->ehci_data->phy_reset) { 662 714 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) { ··· 675 735 676 736 omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); 677 737 dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); 678 - 679 - /* perform TLL soft reset, and wait until reset is complete */ 680 - usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, 681 - OMAP_USBTLL_SYSCONFIG_SOFTRESET); 682 - 683 - /* Wait for TLL reset to complete */ 684 - timeout = jiffies + msecs_to_jiffies(1000); 685 - while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS) 686 - & OMAP_USBTLL_SYSSTATUS_RESETDONE)) { 687 - cpu_relax(); 688 - 689 - if (time_after(jiffies, timeout)) { 690 - dev_dbg(dev, "operation timed out\n"); 691 - ret = -EINVAL; 692 - goto err_tll; 693 - } 694 - } 695 - 696 - dev_dbg(dev, "TLL RESET DONE\n"); 697 - 698 - /* (1<<3) = no idle mode only for initial debugging */ 699 - usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, 700 - OMAP_USBTLL_SYSCONFIG_ENAWAKEUP | 701 - OMAP_USBTLL_SYSCONFIG_SIDLEMODE | 702 - OMAP_USBTLL_SYSCONFIG_AUTOIDLE); 703 - 704 - /* Put UHH in NoIdle/NoStandby mode */ 705 - reg = usbhs_read(omap->uhh_base, OMAP_UHH_SYSCONFIG); 706 - if (is_omap_usbhs_rev1(omap)) { 707 - reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP 708 - | OMAP_UHH_SYSCONFIG_SIDLEMODE 709 - | OMAP_UHH_SYSCONFIG_CACTIVITY 710 - | OMAP_UHH_SYSCONFIG_MIDLEMODE); 711 - reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; 712 - 713 - 714 - } else if (is_omap_usbhs_rev2(omap)) { 715 - reg &= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR; 716 - reg |= OMAP4_UHH_SYSCONFIG_NOIDLE; 717 - reg &= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR; 718 - reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY; 719 - } 720 - 721 - usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); 722 738 723 739 reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG); 724 740 /* setup ULPI bypass and burst configurations */ ··· 815 919 return 0; 816 920 817 921 err_tll: 922 + pm_runtime_put_sync(dev); 923 + spin_unlock_irqrestore(&omap->lock, flags); 818 924 if (pdata->ehci_data->phy_reset) { 819 925 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) 820 926 gpio_free(pdata->ehci_data->reset_gpio_port[0]); ··· 824 926 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) 825 927 gpio_free(pdata->ehci_data->reset_gpio_port[1]); 826 928 } 827 - 828 - clk_disable(omap->usbtll_ick); 829 - clk_disable(omap->usbtll_fck); 830 - clk_disable(omap->usbhost_fs_fck); 831 - clk_disable(omap->usbhost_hs_fck); 832 - clk_disable(omap->usbhost_ick); 833 - spin_unlock_irqrestore(&omap->lock, flags); 834 929 return ret; 835 930 } 836 931 ··· 896 1005 clk_disable(omap->utmi_p1_fck); 897 1006 } 898 1007 899 - clk_disable(omap->usbtll_ick); 900 - clk_disable(omap->usbtll_fck); 901 - clk_disable(omap->usbhost_fs_fck); 902 - clk_disable(omap->usbhost_hs_fck); 903 - clk_disable(omap->usbhost_ick); 1008 + pm_runtime_put_sync(dev); 904 1009 905 1010 /* The gpio_free migh sleep; so unlock the spinlock */ 906 1011 spin_unlock_irqrestore(&omap->lock, flags);