[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CAP05o4JLUBAsxYeDpxB4=ceoVAEGEzZHyWsSdJ-VwXMLnRO4dQ@mail.gmail.com>
Date: Thu, 25 Aug 2011 12:08:29 +0530
From: "Munegowda, Keshava" <keshava_mgowda@...com>
To: Shubhrajyoti <shubhrajyoti@...com>
Cc: linux-usb@...r.kernel.org, linux-omap@...r.kernel.org,
linux-kernel@...r.kernel.org, balbi@...com, gadiyar@...com,
sameo@...ux.intel.com, parthab@...ia.ti.com, tony@...mide.com,
khilman@...com, b-cousson@...com, paul@...an.com,
johnstul@...ibm.com, vishwanath.bs@...com, rogerq@...com
Subject: Re: [PATCH 5/5 v7] mfd: omap: usb: Runtime PM support
On Thu, Aug 25, 2011 at 12:03 PM, Shubhrajyoti <shubhrajyoti@...com> wrote:
> Hi Keshav,
> Some minor comments
>
> On Wednesday 24 August 2011 08:01 PM, Keshava Munegowda wrote:
>>
>> From: Keshava Munegowda<Keshava_mgowda@...com>
>>
>> The usbhs core driver does not enable/disable the interface and
>> functional clocks; These clocks are handled by hwmod and runtime pm,
>> hence instead of the clock enable/disable, the runtime pm APIS are
>> used. however,the port clocks are handled by the usbhs core.
>>
>> Signed-off-by: Keshava Munegowda<keshava_mgowda@...com>
>> ---
>> arch/arm/plat-omap/include/plat/usb.h | 3 -
>> drivers/mfd/omap-usb-host.c | 731
>> +++++++++++++--------------------
>> drivers/usb/host/ehci-omap.c | 17 +-
>> drivers/usb/host/ohci-omap3.c | 18 +-
>> 4 files changed, 295 insertions(+), 474 deletions(-)
>>
>> diff --git a/arch/arm/plat-omap/include/plat/usb.h
>> b/arch/arm/plat-omap/include/plat/usb.h
>> index 17d3c93..2b66dc2 100644
>> --- a/arch/arm/plat-omap/include/plat/usb.h
>> +++ b/arch/arm/plat-omap/include/plat/usb.h
>> @@ -100,9 +100,6 @@ extern void usb_musb_init(struct omap_musb_board_data
>> *board_data);
>>
>> extern void usbhs_init(const struct usbhs_omap_board_data *pdata);
>>
>> -extern int omap_usbhs_enable(struct device *dev);
>> -extern void omap_usbhs_disable(struct device *dev);
>> -
>> extern int omap4430_phy_power(struct device *dev, int ID, int on);
>> extern int omap4430_phy_set_clk(struct device *dev, int on);
>> extern int omap4430_phy_init(struct device *dev);
>> diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
>> index 9c2da29..e6f3b01 100644
>> --- a/drivers/mfd/omap-usb-host.c
>> +++ b/drivers/mfd/omap-usb-host.c
>> @@ -26,6 +26,7 @@
>> #include<linux/spinlock.h>
>> #include<linux/gpio.h>
>> #include<plat/usb.h>
>> +#include<linux/pm_runtime.h>
>>
>> #define USBHS_DRIVER_NAME "usbhs_omap"
>> #define OMAP_EHCI_DEVICE "ehci-omap"
>> @@ -146,9 +147,6 @@
>>
>>
>> struct usbhs_hcd_omap {
>> - struct clk *usbhost_ick;
>> - struct clk *usbhost_hs_fck;
>> - struct clk *usbhost_fs_fck;
>> struct clk *xclk60mhsp1_ck;
>> struct clk *xclk60mhsp2_ck;
>> struct clk *utmi_p1_fck;
>> @@ -158,8 +156,6 @@ struct usbhs_hcd_omap {
>> struct clk *usbhost_p2_fck;
>> struct clk *usbtll_p2_fck;
>> struct clk *init_60m_fclk;
>> - struct clk *usbtll_fck;
>> - struct clk *usbtll_ick;
>>
>> void __iomem *uhh_base;
>> void __iomem *tll_base;
>> @@ -168,7 +164,6 @@ struct usbhs_hcd_omap {
>>
>> u32 usbhs_rev;
>> spinlock_t lock;
>> - int count;
>> };
>>
>> /*-------------------------------------------------------------------------*/
>>
>> @@ -318,269 +313,6 @@ err_end:
>> return ret;
>> }
>>
>> -/**
>> - * usbhs_omap_probe - initialize TI-based HCDs
>> - *
>> - * Allocates basic resources for this USB host controller.
>> - */
>> -static int __devinit usbhs_omap_probe(struct platform_device *pdev)
>> -{
>> - struct device *dev =&pdev->dev;
>> - struct usbhs_omap_platform_data *pdata = dev->platform_data;
>> - struct usbhs_hcd_omap *omap;
>> - struct resource *res;
>> - int ret = 0;
>> - int i;
>> -
>> - if (!pdata) {
>> - dev_err(dev, "Missing platform data\n");
>> - ret = -ENOMEM;
>> - goto end_probe;
>> - }
>> -
>> - omap = kzalloc(sizeof(*omap), GFP_KERNEL);
>> - if (!omap) {
>> - dev_err(dev, "Memory allocation failed\n");
>> - ret = -ENOMEM;
>> - goto end_probe;
>> - }
>> -
>> - spin_lock_init(&omap->lock);
>> -
>> - for (i = 0; i< OMAP3_HS_USB_PORTS; i++)
>> - omap->platdata.port_mode[i] = pdata->port_mode[i];
>> -
>> - omap->platdata.ehci_data = pdata->ehci_data;
>> - omap->platdata.ohci_data = pdata->ohci_data;
>> -
>> - omap->usbhost_ick = clk_get(dev, "usbhost_ick");
>> - if (IS_ERR(omap->usbhost_ick)) {
>> - ret = PTR_ERR(omap->usbhost_ick);
>> - dev_err(dev, "usbhost_ick failed error:%d\n", ret);
>> - goto err_end;
>> - }
>> -
>> - omap->usbhost_hs_fck = clk_get(dev, "hs_fck");
>> - if (IS_ERR(omap->usbhost_hs_fck)) {
>> - ret = PTR_ERR(omap->usbhost_hs_fck);
>> - dev_err(dev, "usbhost_hs_fck failed error:%d\n", ret);
>> - goto err_usbhost_ick;
>> - }
>> -
>> - omap->usbhost_fs_fck = clk_get(dev, "fs_fck");
>> - if (IS_ERR(omap->usbhost_fs_fck)) {
>> - ret = PTR_ERR(omap->usbhost_fs_fck);
>> - dev_err(dev, "usbhost_fs_fck failed error:%d\n", ret);
>> - goto err_usbhost_hs_fck;
>> - }
>> -
>> - omap->usbtll_fck = clk_get(dev, "usbtll_fck");
>> - if (IS_ERR(omap->usbtll_fck)) {
>> - ret = PTR_ERR(omap->usbtll_fck);
>> - dev_err(dev, "usbtll_fck failed error:%d\n", ret);
>> - goto err_usbhost_fs_fck;
>> - }
>> -
>> - omap->usbtll_ick = clk_get(dev, "usbtll_ick");
>> - if (IS_ERR(omap->usbtll_ick)) {
>> - ret = PTR_ERR(omap->usbtll_ick);
>> - dev_err(dev, "usbtll_ick failed error:%d\n", ret);
>> - goto err_usbtll_fck;
>> - }
>> -
>> - omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk");
>> - if (IS_ERR(omap->utmi_p1_fck)) {
>> - ret = PTR_ERR(omap->utmi_p1_fck);
>> - dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
>> - goto err_usbtll_ick;
>> - }
>> -
>> - omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
>> - if (IS_ERR(omap->xclk60mhsp1_ck)) {
>> - ret = PTR_ERR(omap->xclk60mhsp1_ck);
>> - dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
>> - goto err_utmi_p1_fck;
>> - }
>> -
>> - omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk");
>> - if (IS_ERR(omap->utmi_p2_fck)) {
>> - ret = PTR_ERR(omap->utmi_p2_fck);
>> - dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
>> - goto err_xclk60mhsp1_ck;
>> - }
>> -
>> - omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
>> - if (IS_ERR(omap->xclk60mhsp2_ck)) {
>> - ret = PTR_ERR(omap->xclk60mhsp2_ck);
>> - dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
>> - goto err_utmi_p2_fck;
>> - }
>> -
>> - omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk");
>> - if (IS_ERR(omap->usbhost_p1_fck)) {
>> - ret = PTR_ERR(omap->usbhost_p1_fck);
>> - dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret);
>> - goto err_xclk60mhsp2_ck;
>> - }
>> -
>> - omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
>> - if (IS_ERR(omap->usbtll_p1_fck)) {
>> - ret = PTR_ERR(omap->usbtll_p1_fck);
>> - dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
>> - goto err_usbhost_p1_fck;
>> - }
>> -
>> - omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
>> - if (IS_ERR(omap->usbhost_p2_fck)) {
>> - ret = PTR_ERR(omap->usbhost_p2_fck);
>> - dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
>> - goto err_usbtll_p1_fck;
>> - }
>> -
>> - omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
>> - if (IS_ERR(omap->usbtll_p2_fck)) {
>> - ret = PTR_ERR(omap->usbtll_p2_fck);
>> - dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
>> - goto err_usbhost_p2_fck;
>> - }
>> -
>> - omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
>> - if (IS_ERR(omap->init_60m_fclk)) {
>> - ret = PTR_ERR(omap->init_60m_fclk);
>> - dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
>> - goto err_usbtll_p2_fck;
>> - }
>> -
>> - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh");
>> - if (!res) {
>> - dev_err(dev, "UHH EHCI get resource failed\n");
>> - ret = -ENODEV;
>> - goto err_init_60m_fclk;
>> - }
>> -
>> - omap->uhh_base = ioremap(res->start, resource_size(res));
>> - if (!omap->uhh_base) {
>> - dev_err(dev, "UHH ioremap failed\n");
>> - ret = -ENOMEM;
>> - goto err_init_60m_fclk;
>> - }
>> -
>> - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll");
>> - if (!res) {
>> - dev_err(dev, "UHH EHCI get resource failed\n");
>> - ret = -ENODEV;
>> - goto err_tll;
>> - }
>> -
>> - omap->tll_base = ioremap(res->start, resource_size(res));
>> - if (!omap->tll_base) {
>> - dev_err(dev, "TLL ioremap failed\n");
>> - ret = -ENOMEM;
>> - goto err_tll;
>> - }
>> -
>> - platform_set_drvdata(pdev, omap);
>> -
>> - ret = omap_usbhs_alloc_children(pdev);
>> - if (ret) {
>> - dev_err(dev, "omap_usbhs_alloc_children failed\n");
>> - goto err_alloc;
>> - }
>> -
>> - goto end_probe;
>> -
>> -err_alloc:
>> - iounmap(omap->tll_base);
>> -
>> -err_tll:
>> - iounmap(omap->uhh_base);
>> -
>> -err_init_60m_fclk:
>> - clk_put(omap->init_60m_fclk);
>> -
>> -err_usbtll_p2_fck:
>> - clk_put(omap->usbtll_p2_fck);
>> -
>> -err_usbhost_p2_fck:
>> - clk_put(omap->usbhost_p2_fck);
>> -
>> -err_usbtll_p1_fck:
>> - clk_put(omap->usbtll_p1_fck);
>> -
>> -err_usbhost_p1_fck:
>> - clk_put(omap->usbhost_p1_fck);
>> -
>> -err_xclk60mhsp2_ck:
>> - clk_put(omap->xclk60mhsp2_ck);
>> -
>> -err_utmi_p2_fck:
>> - clk_put(omap->utmi_p2_fck);
>> -
>> -err_xclk60mhsp1_ck:
>> - clk_put(omap->xclk60mhsp1_ck);
>> -
>> -err_utmi_p1_fck:
>> - clk_put(omap->utmi_p1_fck);
>> -
>> -err_usbtll_ick:
>> - clk_put(omap->usbtll_ick);
>> -
>> -err_usbtll_fck:
>> - clk_put(omap->usbtll_fck);
>> -
>> -err_usbhost_fs_fck:
>> - clk_put(omap->usbhost_fs_fck);
>> -
>> -err_usbhost_hs_fck:
>> - clk_put(omap->usbhost_hs_fck);
>> -
>> -err_usbhost_ick:
>> - clk_put(omap->usbhost_ick);
>> -
>> -err_end:
>> - kfree(omap);
>> -
>> -end_probe:
>> - return ret;
>> -}
>> -
>> -/**
>> - * usbhs_omap_remove - shutdown processing for UHH& TLL HCDs
>> - * @pdev: USB Host Controller being removed
>> - *
>> - * Reverses the effect of usbhs_omap_probe().
>> - */
>> -static int __devexit usbhs_omap_remove(struct platform_device *pdev)
>> -{
>> - struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
>> -
>> - if (omap->count != 0) {
>> - dev_err(&pdev->dev,
>> - "Either EHCI or OHCI is still using usbhs
>> core\n");
>> - return -EBUSY;
>> - }
>> -
>> - iounmap(omap->tll_base);
>> - iounmap(omap->uhh_base);
>> - clk_put(omap->init_60m_fclk);
>> - clk_put(omap->usbtll_p2_fck);
>> - clk_put(omap->usbhost_p2_fck);
>> - clk_put(omap->usbtll_p1_fck);
>> - clk_put(omap->usbhost_p1_fck);
>> - clk_put(omap->xclk60mhsp2_ck);
>> - clk_put(omap->utmi_p2_fck);
>> - clk_put(omap->xclk60mhsp1_ck);
>> - clk_put(omap->utmi_p1_fck);
>> - clk_put(omap->usbtll_ick);
>> - clk_put(omap->usbtll_fck);
>> - clk_put(omap->usbhost_fs_fck);
>> - clk_put(omap->usbhost_hs_fck);
>> - clk_put(omap->usbhost_ick);
>> - kfree(omap);
>> -
>> - return 0;
>> -}
>> -
>> static bool is_ohci_port(enum usbhs_omap_port_mode pmode)
>> {
>> switch (pmode) {
>> @@ -687,30 +419,79 @@ static void usbhs_omap_tll_init(struct device *dev,
>> u8 tll_channel_count)
>> }
>> }
>>
>> -static int usbhs_enable(struct device *dev)
>> +static int usbhs_runtime_resume(struct device *dev)
>> {
>> struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
>> struct usbhs_omap_platform_data *pdata =&omap->platdata;
>> - unsigned long flags = 0;
>> - int ret = 0;
>> - unsigned long timeout;
>> - unsigned reg;
>> + unsigned long flags;
>> +
>> + dev_dbg(dev, "usbhs_runtime_resume\n");
>> +
>> + if (!pdata) {
>> + dev_dbg(dev, "missing platform_data\n");
>> + return -ENODEV;
>> + }
>> +
>> + spin_lock_irqsave(&omap->lock, flags);
>> +
>> + if (is_ehci_tll_mode(pdata->port_mode[0])) {
>> + clk_enable(omap->usbhost_p1_fck);
>> + clk_enable(omap->usbtll_p1_fck);
>> + }
>> + if (is_ehci_tll_mode(pdata->port_mode[1])) {
>> + clk_enable(omap->usbhost_p2_fck);
>> + clk_enable(omap->usbtll_p2_fck);
>> + }
>> + clk_enable(omap->utmi_p1_fck);
>> + clk_enable(omap->utmi_p2_fck);
>> +
>> + spin_unlock_irqrestore(&omap->lock, flags);
>> +
>> + return 0;
>> +}
>> +
>> +static int usbhs_runtime_suspend(struct device *dev)
>> +{
>> + struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
>> + struct usbhs_omap_platform_data *pdata =&omap->platdata;
>> + unsigned long flags;
>> +
>> + dev_dbg(dev, "usbhs_runtime_suspend\n");
>>
>> - dev_dbg(dev, "starting TI HSUSB Controller\n");
>> if (!pdata) {
>> dev_dbg(dev, "missing platform_data\n");
>> return -ENODEV;
>> }
>>
>> spin_lock_irqsave(&omap->lock, flags);
>> - if (omap->count> 0)
>> - goto end_count;
>>
>> - clk_enable(omap->usbhost_ick);
>> - clk_enable(omap->usbhost_hs_fck);
>> - clk_enable(omap->usbhost_fs_fck);
>> - clk_enable(omap->usbtll_fck);
>> - clk_enable(omap->usbtll_ick);
>> + if (is_ehci_tll_mode(pdata->port_mode[0])) {
>> + clk_disable(omap->usbhost_p1_fck);
>> + clk_disable(omap->usbtll_p1_fck);
>> + }
>> + if (is_ehci_tll_mode(pdata->port_mode[1])) {
>> + clk_disable(omap->usbhost_p2_fck);
>> + clk_disable(omap->usbtll_p2_fck);
>> + }
>> + clk_disable(omap->utmi_p2_fck);
>> + clk_disable(omap->utmi_p1_fck);
>> +
>> + spin_unlock_irqrestore(&omap->lock, flags);
>> +
>> + return 0;
>> +}
>> +
>> +static void omap_usbhs_init(struct device *dev)
>
> Since it is called only at init the it could be placed in init section.
>>
>> +{
>> + struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
>> + struct usbhs_omap_platform_data *pdata =&omap->platdata;
>> + unsigned long flags;
>> + unsigned reg;
>> +
>> + dev_dbg(dev, "starting TI HSUSB Controller\n");
>> +
>> + pm_runtime_get_sync(dev);
>> + spin_lock_irqsave(&omap->lock, flags);
>>
>> if (pdata->ehci_data->phy_reset) {
>> if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) {
>> @@ -734,50 +515,6 @@ static int usbhs_enable(struct device *dev)
>> omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
>> dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
>>
>> - /* perform TLL soft reset, and wait until reset is complete */
>> - usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
>> - OMAP_USBTLL_SYSCONFIG_SOFTRESET);
>> -
>> - /* Wait for TLL reset to complete */
>> - timeout = jiffies + msecs_to_jiffies(1000);
>> - while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS)
>> - & OMAP_USBTLL_SYSSTATUS_RESETDONE)) {
>> - cpu_relax();
>> -
>> - if (time_after(jiffies, timeout)) {
>> - dev_dbg(dev, "operation timed out\n");
>> - ret = -EINVAL;
>> - goto err_tll;
>> - }
>> - }
>> -
>> - dev_dbg(dev, "TLL RESET DONE\n");
>> -
>> - /* (1<<3) = no idle mode only for initial debugging */
>> - usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
>> - OMAP_USBTLL_SYSCONFIG_ENAWAKEUP |
>> - OMAP_USBTLL_SYSCONFIG_SIDLEMODE |
>> - OMAP_USBTLL_SYSCONFIG_AUTOIDLE);
>> -
>> - /* Put UHH in NoIdle/NoStandby mode */
>> - reg = usbhs_read(omap->uhh_base, OMAP_UHH_SYSCONFIG);
>> - if (is_omap_usbhs_rev1(omap)) {
>> - reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP
>> - | OMAP_UHH_SYSCONFIG_SIDLEMODE
>> - | OMAP_UHH_SYSCONFIG_CACTIVITY
>> - | OMAP_UHH_SYSCONFIG_MIDLEMODE);
>> - reg&= ~OMAP_UHH_SYSCONFIG_AUTOIDLE;
>> -
>> -
>> - } else if (is_omap_usbhs_rev2(omap)) {
>> - reg&= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR;
>> - reg |= OMAP4_UHH_SYSCONFIG_NOIDLE;
>> - reg&= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR;
>> - reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY;
>> - }
>> -
>> - usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg);
>> -
>> reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
>> /* setup ULPI bypass and burst configurations */
>> reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN
>> @@ -823,49 +560,6 @@ static int usbhs_enable(struct device *dev)
>> reg&= ~OMAP4_P1_MODE_CLEAR;
>> reg&= ~OMAP4_P2_MODE_CLEAR;
>>
>> - if (is_ehci_phy_mode(pdata->port_mode[0])) {
>> - ret = clk_set_parent(omap->utmi_p1_fck,
>> - omap->xclk60mhsp1_ck);
>> - if (ret != 0) {
>> - dev_err(dev, "xclk60mhsp1_ck set parent"
>> - "failed error:%d\n", ret);
>> - goto err_tll;
>> - }
>> - } else if (is_ehci_tll_mode(pdata->port_mode[0])) {
>> - ret = clk_set_parent(omap->utmi_p1_fck,
>> - omap->init_60m_fclk);
>> - if (ret != 0) {
>> - dev_err(dev, "init_60m_fclk set parent"
>> - "failed error:%d\n", ret);
>> - goto err_tll;
>> - }
>> - clk_enable(omap->usbhost_p1_fck);
>> - clk_enable(omap->usbtll_p1_fck);
>> - }
>> -
>> - if (is_ehci_phy_mode(pdata->port_mode[1])) {
>> - ret = clk_set_parent(omap->utmi_p2_fck,
>> - omap->xclk60mhsp2_ck);
>> - if (ret != 0) {
>> - dev_err(dev, "xclk60mhsp1_ck set parent"
>> - "failed error:%d\n", ret);
>> - goto err_tll;
>> - }
>> - } else if (is_ehci_tll_mode(pdata->port_mode[1])) {
>> - ret = clk_set_parent(omap->utmi_p2_fck,
>> - omap->init_60m_fclk);
>> - if (ret != 0) {
>> - dev_err(dev, "init_60m_fclk set parent"
>> - "failed error:%d\n", ret);
>> - goto err_tll;
>> - }
>> - clk_enable(omap->usbhost_p2_fck);
>> - clk_enable(omap->usbtll_p2_fck);
>> - }
>> -
>> - clk_enable(omap->utmi_p1_fck);
>> - clk_enable(omap->utmi_p2_fck);
>> -
>> if (is_ehci_tll_mode(pdata->port_mode[0]) ||
>> (is_ohci_port(pdata->port_mode[0])))
>> reg |= OMAP4_P1_MODE_TLL;
>> @@ -911,12 +605,15 @@ static int usbhs_enable(struct device *dev)
>> (pdata->ehci_data->reset_gpio_port[1], 1);
>> }
>>
>> -end_count:
>> - omap->count++;
>> spin_unlock_irqrestore(&omap->lock, flags);
>> - return 0;
>> + pm_runtime_put_sync(dev);
>> +}
>> +
>> +static void omap_usbhs_deinit(struct device *dev)
>> +{
>> + struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
>> + struct usbhs_omap_platform_data *pdata =&omap->platdata;
>>
>> -err_tll:
>> if (pdata->ehci_data->phy_reset) {
>> if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
>> gpio_free(pdata->ehci_data->reset_gpio_port[0]);
>> @@ -924,123 +621,257 @@ err_tll:
>> if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
>> gpio_free(pdata->ehci_data->reset_gpio_port[1]);
>> }
>> -
>> - clk_disable(omap->usbtll_ick);
>> - clk_disable(omap->usbtll_fck);
>> - clk_disable(omap->usbhost_fs_fck);
>> - clk_disable(omap->usbhost_hs_fck);
>> - clk_disable(omap->usbhost_ick);
>> - spin_unlock_irqrestore(&omap->lock, flags);
>> - return ret;
>> }
>>
>> -static void usbhs_disable(struct device *dev)
>> +
>> +/**
>> + * usbhs_omap_probe - initialize TI-based HCDs
>> + *
>> + * Allocates basic resources for this USB host controller.
>> + */
>> +static int __devinit usbhs_omap_probe(struct platform_device *pdev)
>> {
>> - struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
>> - struct usbhs_omap_platform_data *pdata =&omap->platdata;
>> - unsigned long flags = 0;
>> - unsigned long timeout;
>> + struct device *dev =&pdev->dev;
>> + struct usbhs_omap_platform_data *pdata = dev->platform_data;
>> + struct usbhs_hcd_omap *omap;
>> + struct resource *res;
>> + int ret = 0;
>> + int i;
>>
>> - dev_dbg(dev, "stopping TI HSUSB Controller\n");
>> + if (!pdata) {
>> + dev_err(dev, "Missing platform data\n");
>> + ret = -ENOMEM;
>> + goto end_probe;
>> + }
>>
>> - spin_lock_irqsave(&omap->lock, flags);
>> + omap = kzalloc(sizeof(*omap), GFP_KERNEL);
>> + if (!omap) {
>> + dev_err(dev, "Memory allocation failed\n");
>> + ret = -ENOMEM;
>> + goto end_probe;
>> + }
>>
>> - if (omap->count == 0)
>> - goto end_disble;
>> + spin_lock_init(&omap->lock);
>>
>> - omap->count--;
>> + for (i = 0; i< OMAP3_HS_USB_PORTS; i++)
>> + omap->platdata.port_mode[i] = pdata->port_mode[i];
>>
>> - if (omap->count != 0)
>> - goto end_disble;
>> + omap->platdata.ehci_data = pdata->ehci_data;
>> + omap->platdata.ohci_data = pdata->ohci_data;
>>
>> - /* Reset OMAP modules for insmod/rmmod to work */
>> - usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG,
>> - is_omap_usbhs_rev2(omap) ?
>> - OMAP4_UHH_SYSCONFIG_SOFTRESET :
>> - OMAP_UHH_SYSCONFIG_SOFTRESET);
>> + pm_runtime_enable(dev);
>>
>> - timeout = jiffies + msecs_to_jiffies(100);
>> - while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS)
>> - & (1<< 0))) {
>> - cpu_relax();
>> + omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk");
>> + if (IS_ERR(omap->utmi_p1_fck)) {
>> + ret = PTR_ERR(omap->utmi_p1_fck);
>> + dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
>> + goto err_end;
>> + }
>>
>> - if (time_after(jiffies, timeout))
>> - dev_dbg(dev, "operation timed out\n");
>> + omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
>> + if (IS_ERR(omap->xclk60mhsp1_ck)) {
>> + ret = PTR_ERR(omap->xclk60mhsp1_ck);
>> + dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
>> + goto err_utmi_p1_fck;
>> + }
>> +
>> + omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk");
>> + if (IS_ERR(omap->utmi_p2_fck)) {
>> + ret = PTR_ERR(omap->utmi_p2_fck);
>> + dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
>> + goto err_xclk60mhsp1_ck;
>> + }
>> +
>> + omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
>> + if (IS_ERR(omap->xclk60mhsp2_ck)) {
>> + ret = PTR_ERR(omap->xclk60mhsp2_ck);
>> + dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
>> + goto err_utmi_p2_fck;
>> }
>>
>> - while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS)
>> - & (1<< 1))) {
>> - cpu_relax();
>> + omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk");
>> + if (IS_ERR(omap->usbhost_p1_fck)) {
>> + ret = PTR_ERR(omap->usbhost_p1_fck);
>> + dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret);
>> + goto err_xclk60mhsp2_ck;
>> + }
>>
>> - if (time_after(jiffies, timeout))
>> - dev_dbg(dev, "operation timed out\n");
>> + omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
>> + if (IS_ERR(omap->usbtll_p1_fck)) {
>> + ret = PTR_ERR(omap->usbtll_p1_fck);
>> + dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
>> + goto err_usbhost_p1_fck;
>> + }
>> +
>> + omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
>> + if (IS_ERR(omap->usbhost_p2_fck)) {
>> + ret = PTR_ERR(omap->usbhost_p2_fck);
>> + dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
>> + goto err_usbtll_p1_fck;
>> }
>>
>> - while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS)
>> - & (1<< 2))) {
>> - cpu_relax();
>> + omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
>> + if (IS_ERR(omap->usbtll_p2_fck)) {
>> + ret = PTR_ERR(omap->usbtll_p2_fck);
>> + dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
>> + goto err_usbhost_p2_fck;
>> + }
>>
>> - if (time_after(jiffies, timeout))
>> - dev_dbg(dev, "operation timed out\n");
>> + omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
>> + if (IS_ERR(omap->init_60m_fclk)) {
>> + ret = PTR_ERR(omap->init_60m_fclk);
>> + dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
>> + goto err_usbtll_p2_fck;
>> }
>>
>> - usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, (1<< 1));
>> + if (is_ehci_phy_mode(pdata->port_mode[0])) {
>> + /* for OMAP3 , the clk set paretn fails */
>> + ret = clk_set_parent(omap->utmi_p1_fck,
>> + omap->xclk60mhsp1_ck);
>> + if (ret != 0)
>> + dev_err(dev, "xclk60mhsp1_ck set parent"
>> + "failed error:%d\n", ret);
>> + } else if (is_ehci_tll_mode(pdata->port_mode[0])) {
>> + ret = clk_set_parent(omap->utmi_p1_fck,
>> + omap->init_60m_fclk);
>> + if (ret != 0)
>> + dev_err(dev, "init_60m_fclk set parent"
>> + "failed error:%d\n", ret);
>> + }
>>
>> - while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS)
>> - & (1<< 0))) {
>> - cpu_relax();
>> + if (is_ehci_phy_mode(pdata->port_mode[1])) {
>> + ret = clk_set_parent(omap->utmi_p2_fck,
>> + omap->xclk60mhsp2_ck);
>> + if (ret != 0)
>> + dev_err(dev, "xclk60mhsp2_ck set parent"
>> + "failed error:%d\n", ret);
>> + } else if (is_ehci_tll_mode(pdata->port_mode[1])) {
>> + ret = clk_set_parent(omap->utmi_p2_fck,
>> + omap->init_60m_fclk);
>> + if (ret != 0)
>> + dev_err(dev, "init_60m_fclk set parent"
>> + "failed error:%d\n", ret);
>> + }
>>
>> - if (time_after(jiffies, timeout))
>> - dev_dbg(dev, "operation timed out\n");
>> + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh");
>> + if (!res) {
>> + dev_err(dev, "UHH EHCI get resource failed\n");
>> + ret = -ENODEV;
>> + goto err_init_60m_fclk;
>> }
>>
>> - if (is_omap_usbhs_rev2(omap)) {
>> - if (is_ehci_tll_mode(pdata->port_mode[0]))
>> - clk_disable(omap->usbtll_p1_fck);
>> - if (is_ehci_tll_mode(pdata->port_mode[1]))
>> - clk_disable(omap->usbtll_p2_fck);
>> - clk_disable(omap->utmi_p2_fck);
>> - clk_disable(omap->utmi_p1_fck);
>> + omap->uhh_base = ioremap(res->start, resource_size(res));
>> + if (!omap->uhh_base) {
>> + dev_err(dev, "UHH ioremap failed\n");
>> + ret = -ENOMEM;
>> + goto err_init_60m_fclk;
>> }
>>
>> - clk_disable(omap->usbtll_ick);
>> - clk_disable(omap->usbtll_fck);
>> - clk_disable(omap->usbhost_fs_fck);
>> - clk_disable(omap->usbhost_hs_fck);
>> - clk_disable(omap->usbhost_ick);
>> + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll");
>> + if (!res) {
>> + dev_err(dev, "UHH EHCI get resource failed\n");
>> + ret = -ENODEV;
>> + goto err_tll;
>> + }
>>
>> - /* The gpio_free migh sleep; so unlock the spinlock */
>> - spin_unlock_irqrestore(&omap->lock, flags);
>> + omap->tll_base = ioremap(res->start, resource_size(res));
>> + if (!omap->tll_base) {
>> + dev_err(dev, "TLL ioremap failed\n");
>> + ret = -ENOMEM;
>> + goto err_tll;
>> + }
>>
>> - if (pdata->ehci_data->phy_reset) {
>> - if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
>> - gpio_free(pdata->ehci_data->reset_gpio_port[0]);
>> + platform_set_drvdata(pdev, omap);
>>
>> - if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
>> - gpio_free(pdata->ehci_data->reset_gpio_port[1]);
>> + ret = omap_usbhs_alloc_children(pdev);
>> + if (ret) {
>> + dev_err(dev, "omap_usbhs_alloc_children failed\n");
>> + goto err_alloc;
>> }
>> - return;
>>
>> -end_disble:
>> - spin_unlock_irqrestore(&omap->lock, flags);
>> -}
>> + omap_usbhs_init(dev);
>>
>> -int omap_usbhs_enable(struct device *dev)
>> -{
>> - return usbhs_enable(dev->parent);
>> + goto end_probe;
>> +
>> +err_alloc:
>> + iounmap(omap->tll_base);
>> +
>> +err_tll:
>> + iounmap(omap->uhh_base);
>> +
>> +err_init_60m_fclk:
>> + clk_put(omap->init_60m_fclk);
>> +
>> +err_usbtll_p2_fck:
>> + clk_put(omap->usbtll_p2_fck);
>> +
>> +err_usbhost_p2_fck:
>> + clk_put(omap->usbhost_p2_fck);
>> +
>> +err_usbtll_p1_fck:
>> + clk_put(omap->usbtll_p1_fck);
>> +
>> +err_usbhost_p1_fck:
>> + clk_put(omap->usbhost_p1_fck);
>> +
>> +err_xclk60mhsp2_ck:
>> + clk_put(omap->xclk60mhsp2_ck);
>> +
>> +err_utmi_p2_fck:
>> + clk_put(omap->utmi_p2_fck);
>> +
>> +err_xclk60mhsp1_ck:
>> + clk_put(omap->xclk60mhsp1_ck);
>> +
>> +err_utmi_p1_fck:
>> + clk_put(omap->utmi_p1_fck);
>> +
>> +err_end:
>> + pm_runtime_disable(dev);
>> + kfree(omap);
>> +
>> +end_probe:
>> + return ret;
>> }
>> -EXPORT_SYMBOL_GPL(omap_usbhs_enable);
>>
>> -void omap_usbhs_disable(struct device *dev)
>> +/**
>> + * usbhs_omap_remove - shutdown processing for UHH& TLL HCDs
>> + * @pdev: USB Host Controller being removed
>> + *
>> + * Reverses the effect of usbhs_omap_probe().
>> + */
>> +static int __devexit usbhs_omap_remove(struct platform_device *pdev)
>> {
>> - usbhs_disable(dev->parent);
>> + struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
>> +
>> + omap_usbhs_deinit(&pdev->dev);
>> + iounmap(omap->tll_base);
>> + iounmap(omap->uhh_base);
>> + clk_put(omap->init_60m_fclk);
>> + clk_put(omap->usbtll_p2_fck);
>> + clk_put(omap->usbhost_p2_fck);
>> + clk_put(omap->usbtll_p1_fck);
>> + clk_put(omap->usbhost_p1_fck);
>> + clk_put(omap->xclk60mhsp2_ck);
>> + clk_put(omap->utmi_p2_fck);
>> + clk_put(omap->xclk60mhsp1_ck);
>> + clk_put(omap->utmi_p1_fck);
>> + pm_runtime_disable(&pdev->dev);
>> + kfree(omap);
>> +
>> + return 0;
>> }
>> -EXPORT_SYMBOL_GPL(omap_usbhs_disable);
>> +
>> +static const struct dev_pm_ops usbhsomap_dev_pm_ops = {
>> + .runtime_suspend = usbhs_runtime_suspend,
>> + .runtime_resume = usbhs_runtime_resume,
>> +};
>
> Could these be placed under a PM flag.
No, you should not, these functions enable the port clocks for omap4 usbhs
so, it should be default.
>
>>
>> static struct platform_driver usbhs_omap_driver = {
>> .driver = {
>> .name = (char *)usbhs_driver_name,
>> .owner = THIS_MODULE,
>> + .pm =&usbhsomap_dev_pm_ops,
>> },
>> .remove = __exit_p(usbhs_omap_remove),
>> };
>> diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
>> index 4524032..82cd3ea 100644
>> --- a/drivers/usb/host/ehci-omap.c
>> +++ b/drivers/usb/host/ehci-omap.c
>> @@ -41,6 +41,7 @@
>> #include<linux/usb/ulpi.h>
>> #include<plat/usb.h>
>> #include<linux/regulator/consumer.h>
>> +#include<linux/pm_runtime.h>
>>
>> /* EHCI Register Set */
>> #define EHCI_INSNREG04 (0xA0)
>> @@ -190,11 +191,8 @@ static int ehci_hcd_omap_probe(struct platform_device
>> *pdev)
>> }
>> }
>>
>> - ret = omap_usbhs_enable(dev);
>> - if (ret) {
>> - dev_err(dev, "failed to start usbhs with err %d\n", ret);
>> - goto err_enable;
>> - }
>> + pm_runtime_enable(dev);
>> + pm_runtime_get_sync(dev);
>>
>> /*
>> * An undocumented "feature" in the OMAP3 EHCI controller,
>> @@ -240,11 +238,8 @@ static int ehci_hcd_omap_probe(struct platform_device
>> *pdev)
>> return 0;
>>
>> err_add_hcd:
>> - omap_usbhs_disable(dev);
>> -
>> -err_enable:
>> disable_put_regulator(pdata);
>> - usb_put_hcd(hcd);
>> + pm_runtime_put_sync(dev);
>>
>> err_io:
>> iounmap(regs);
>> @@ -266,10 +261,12 @@ static int ehci_hcd_omap_remove(struct
>> platform_device *pdev)
>> struct usb_hcd *hcd = dev_get_drvdata(dev);
>>
>> usb_remove_hcd(hcd);
>> - omap_usbhs_disable(dev);
>> disable_put_regulator(dev->platform_data);
>> iounmap(hcd->regs);
>> usb_put_hcd(hcd);
>> + pm_runtime_put_sync(dev);
>> + pm_runtime_disable(dev);
>> +
>> return 0;
>> }
>>
>> diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c
>> index 6048f2f..6cfedaf 100644
>> --- a/drivers/usb/host/ohci-omap3.c
>> +++ b/drivers/usb/host/ohci-omap3.c
>> @@ -31,6 +31,7 @@
>>
>> #include<linux/platform_device.h>
>> #include<plat/usb.h>
>> +#include<linux/pm_runtime.h>
>>
>>
>> /*-------------------------------------------------------------------------*/
>>
>> @@ -134,7 +135,7 @@ static int __devinit ohci_hcd_omap3_probe(struct
>> platform_device *pdev)
>> int irq;
>>
>> if (usb_disabled())
>> - goto err_end;
>> + return -ENODEV;
>>
>> if (!dev->parent) {
>> dev_err(dev, "Missing parent device\n");
>> @@ -172,11 +173,8 @@ static int __devinit ohci_hcd_omap3_probe(struct
>> platform_device *pdev)
>> hcd->rsrc_len = resource_size(res);
>> hcd->regs = regs;
>>
>> - ret = omap_usbhs_enable(dev);
>> - if (ret) {
>> - dev_dbg(dev, "failed to start ohci\n");
>> - goto err_end;
>> - }
>> + pm_runtime_enable(dev);
>> + pm_runtime_get_sync(dev);
>>
>> ohci_hcd_init(hcd_to_ohci(hcd));
>>
>> @@ -189,9 +187,7 @@ static int __devinit ohci_hcd_omap3_probe(struct
>> platform_device *pdev)
>> return 0;
>>
>> err_add_hcd:
>> - omap_usbhs_disable(dev);
>> -
>> -err_end:
>> + pm_runtime_put_sync(dev);
>> usb_put_hcd(hcd);
>>
>> err_io:
>> @@ -220,9 +216,9 @@ static int __devexit ohci_hcd_omap3_remove(struct
>> platform_device *pdev)
>>
>> iounmap(hcd->regs);
>> usb_remove_hcd(hcd);
>> - omap_usbhs_disable(dev);
>> + pm_runtime_put_sync(dev);
>> + pm_runtime_disable(dev);
>> usb_put_hcd(hcd);
>> -
>> return 0;
>> }
>>
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists