RE: [PATCH 9/9 v3] usb : musb: Offmode fix for idle path

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



 Kevin,


>-----Original Message-----
>From: linux-usb-owner@xxxxxxxxxxxxxxx 
>[mailto:linux-usb-owner@xxxxxxxxxxxxxxx] On Behalf Of Kalliguddi, Hema
>Sent: Thursday, September 23, 2010 1:29 PM
>To: Balbi, Felipe
>Cc: linux-omap@xxxxxxxxxxxxxxx; linux-usb@xxxxxxxxxxxxxxx; 
>Mankad, Maulik Ojas; Tony Lindgren; Kevin Hilman; Cousson, 
>Benoit; Paul Walmsley
>Subject: RE: [PATCH 9/9 v3] usb : musb: Offmode fix for idle path
>
> Hi,
>
>>-----Original Message-----
>>From: Balbi, Felipe 
>>Sent: Thursday, September 23, 2010 12:19 PM
>>To: Kalliguddi, Hema
>>Cc: linux-omap@xxxxxxxxxxxxxxx; linux-usb@xxxxxxxxxxxxxxx; 
>>Mankad, Maulik Ojas; Balbi, Felipe; Tony Lindgren; Kevin 
>>Hilman; Cousson, Benoit; Paul Walmsley
>>Subject: Re: [PATCH 9/9 v3] usb : musb: Offmode fix for idle path
>>
>>Hi,
>>
>>On Wed, Sep 22, 2010 at 07:30:46PM -0500, Kalliguddi, Hema wrote:
>>>With OMAP core-off support musb was not functional as context 
>>was getting
>>>lost after wakeup from core-off. And also musb was blocking 
>>the core-off
>>>after loading the gadget driver even with no cable connected 
>>sometimes.
>>>
>>>Added the idle and wakeup APIs in the platform layer which will
>>>be called in the idle and wakeup path.
>>>
>>>Used the pm_runtime_put_sysc API to configure the
>>
>>pm_runtime_put_sync(), typo.
>>
>>>musb to force idle/standby modes, saving the context and 
>>disable the clk in
>>>while idling if there is no activity on the usb bus.
>>
>>this part is a bit fuzzy, care to re-phrase ?
>>
>Ok. I will re-phrase it. 
>
>>>Used the pm_runtime_get_sync API to configure the musb to
>>>no idle/standby modes, enable the clock and restore the context
>>>after wakeup when there is no activity on the usb bus.
>>>
>>>Signed-off-by: Hema HK <hemahk@xxxxxx>
>>>Signed-off-by: Maulik Mankad <x0082077@xxxxxx>
>>>Cc: Felipe Balbi <balbi@xxxxxx>
>>>Cc: Tony Lindgren <tony@xxxxxxxxxxx>
>>>Cc: Kevin Hilman <khilman@xxxxxxxxxxxxxxxxxxx>
>>>Cc: Cousson, Benoit <b-cousson@xxxxxx>
>>>Cc: Paul Walmsley <paul@xxxxxxxxx>
>>>
>>>---
>>> arch/arm/mach-omap2/cpuidle34xx.c     |    1
>>> arch/arm/mach-omap2/pm34xx.c          |    3
>>> arch/arm/mach-omap2/usb-musb.c        |  107 
>>++++++++++++++++++++++++++++++++++
>>> arch/arm/plat-omap/include/plat/usb.h |    2
>>> drivers/usb/musb/musb_core.c          |   15 ++++
>>> drivers/usb/musb/omap2430.c           |   14 ++++
>>> include/linux/usb/musb.h              |    9 ++
>>> 7 files changed, 149 insertions(+), 2 deletions(-)
>>>
>>>Index: linux-omap-pm/arch/arm/mach-omap2/cpuidle34xx.c
>>>===================================================================
>>>--- linux-omap-pm.orig/arch/arm/mach-omap2/cpuidle34xx.c
>>>+++ linux-omap-pm/arch/arm/mach-omap2/cpuidle34xx.c
>>>@@ -31,6 +31,7 @@
>>> #include <plat/clockdomain.h>
>>> #include <plat/control.h>
>>> #include <plat/serial.h>
>>>+#include <plat/usb.h>
>>>
>>> #include "pm.h"
>>>
>>>Index: linux-omap-pm/arch/arm/mach-omap2/pm34xx.c
>>>===================================================================
>>>--- linux-omap-pm.orig/arch/arm/mach-omap2/pm34xx.c
>>>+++ linux-omap-pm/arch/arm/mach-omap2/pm34xx.c
>>>@@ -38,6 +38,7 @@
>>> #include <plat/prcm.h>
>>> #include <plat/gpmc.h>
>>> #include <plat/dma.h>
>>>+#include <plat/usb.h>
>>>
>>> #include <asm/tlbflush.h>
>>>
>>>@@ -324,11 +325,13 @@ static void restore_table_entry(void)
>>> void omap3_device_idle(void)
>>> {
>>> 	omap2_gpio_prepare_for_idle();
>>>+	musb_prepare_for_idle();
>>> }
>>>
>>> void omap3_device_resume(void)
>>> {
>>> 	omap2_gpio_resume_after_idle();
>>>+	musb_wakeup_from_idle();
>>> }
>>>
>>> void omap_sram_idle(void)
>>>Index: linux-omap-pm/arch/arm/mach-omap2/usb-musb.c
>>>===================================================================
>>>--- linux-omap-pm.orig/arch/arm/mach-omap2/usb-musb.c
>>>+++ linux-omap-pm/arch/arm/mach-omap2/usb-musb.c
>>>@@ -25,16 +25,21 @@
>>> #include <linux/io.h>
>>>
>>> #include <linux/usb/musb.h>
>>>+#include <linux/pm_runtime.h>
>>>
>>> #include <mach/hardware.h>
>>> #include <mach/irqs.h>
>>> #include <plat/usb.h>
>>> #include <plat/omap_device.h>
>>>+#include <plat/powerdomain.h>
>>>
>>> #ifdef CONFIG_USB_MUSB_SOC
>>> static const char name[] = "musb_hdrc";
>>> #define MAX_OMAP_MUSB_HWMOD_NAME_LEN	16
>>>
>>>+struct omap_hwmod *oh_p;
>>>+static struct powerdomain *core_pwrdm;
>>>+
>>> static struct musb_hdrc_config musb_config = {
>>> 	.multipoint	= 1,
>>> 	.dyn_fifo	= 1,
>>>@@ -58,6 +63,10 @@ static struct musb_hdrc_platform_data mu
>>> 	 * "mode", and should be passed to usb_musb_init().
>>> 	 */
>>> 	.power		= 50,			/* up to 100 mA */
>>>+
>>>+	/* OMAP supports offmode */
>>>+	.save_context	= 1,
>>>+	.restore_context	= 1,
>>> };
>>>
>>> static u64 musb_dmamask = DMA_BIT_MASK(32);
>>>@@ -80,6 +89,7 @@ void __init usb_musb_init(struct omap_mu
>>> 	const char *oh_name = "usb_otg_hs";
>>> 	struct musb_hdrc_platform_data *pdata;
>>>
>>>+	core_pwrdm = pwrdm_lookup("per_pwrdm");
>>
>>per or core ???
>>
>Oh! It should be core. Now I understand why save/restore 
>counts were not matching with
>Core-off counts.
>Thanks for pointing this out.

If I call pm_runtime_put_sync and pm_runtime_get_sync based on the core domain state then
the USB connect/reset interrupt is not triggered once the core hits off.

In omap3_enter_idle_bm() there is no core next state being programmed to PRCM register,
but the drivers functions which are called from omap3_device_idle are suppose to read the
core next state from the PRCM register.
I am missing something here?

If I use the per_pwrdm states to save the context and restore everything works fine.

>
>>>@@ -97,6 +107,7 @@ void __init usb_musb_init(struct omap_mu
>>> 	musb_plat.extvbus = board_data->extvbus;
>>>
>>> 	pdata = &musb_plat;
>>>+	oh_p = oh;
>>>
>>> 	od = omap_device_build(name, bus_id, oh, pdata,
>>> 			       sizeof(struct musb_hdrc_platform_data),
>>>@@ -115,8 +126,101 @@ void __init usb_musb_init(struct omap_mu
>>> 	put_device(dev);
>>> }
>>>
>>>+void musb_prepare_for_idle()
>>>+{
>>>+	int core_next_state;
>>>+	struct omap_hwmod *oh = oh_p;
>>>+	struct omap_device *od;
>>>+	struct platform_device *pdev;
>>>+	struct musb_hdrc_platform_data *pdata;
>>>+	struct device *dev;
>>>+
>>>+	if (!core_pwrdm)
>>>+		return;
>>>+
>>>+	core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
>>>+	if (core_next_state >= PWRDM_POWER_INACTIVE)
>>>+		return;
>>>+	if (!oh)
>>>+		return;
>>>+
>>>+	od = oh->od;
>>>+	pdev = &od->pdev;
>>>+
>>>+	if (!pdev)
>>>+		return;
>>>+	dev = &pdev->dev;
>>>+
>>>+	if (dev->driver) {
>>>+		pdata = dev->platform_data;
>>>+
>>>+	if (pdata->is_usb_active)
>>
>>indentation is wrong. And you can save some of it:
>
>Maulik is pointed this out and I will fixing it.
>>
>>	if (!dev->driver)
>>		return;
>>	
>>	pdata = dev->platform_data;
>>
>>	if (!pdata->is_usb_active)
>>		return;
>>	
>>	if (!pdata->is_usb_active(dev)) {
>>		switch (core_next_state) {
>>		case PWRDM_POWER_OFF:
>>			pdata->save_context = 1;
>>			pm_runtime_put_sync(dev);
>>			break;
>>		case PWRDM_POWER_RET:
>>			pdata->save_context = 0;
>>			pm_runtime_put_sync(dev);
>>			break;
>>		default:
>>			pr_debug("what ??\n");
>>		}
>>	}
>>
>>>Index: linux-omap-pm/drivers/usb/musb/musb_core.c
>>>===================================================================
>>>--- linux-omap-pm.orig/drivers/usb/musb/musb_core.c
>>>+++ linux-omap-pm/drivers/usb/musb/musb_core.c
>>>@@ -2410,6 +2410,7 @@ static int musb_suspend(struct device *d
>>> 	struct platform_device *pdev = to_platform_device(dev);
>>> 	unsigned long	flags;
>>> 	struct musb	*musb = dev_to_musb(&pdev->dev);
>>>+	struct musb_hdrc_platform_data *plat = dev->platform_data;
>>>
>>> 	if (!musb->clock)
>>> 		return 0;
>>>@@ -2425,6 +2426,9 @@ static int musb_suspend(struct device *d
>>> 		 * they will even be wakeup-enabled.
>>> 		 */
>>> 	}
>>>+
>>>+	if (plat->save_context)
>>>+		plat->save_context = 1;
>>
>>what ??
>>
>>if plat->save_context is 1, then set it to 1 ???
>>
>This is mistake. I messed it up. I had another flag
>for offmode support, which I removed later.
>i will correct this.
>
>>>@@ -2443,10 +2447,13 @@ static int musb_resume_noirq(struct devi
>>> {
>>> 	struct platform_device *pdev = to_platform_device(dev);
>>> 	struct musb	*musb = dev_to_musb(&pdev->dev);
>>
>>just now I notice these, hah, funny :-p pdev isn't even 
>>needed. Has been
>>there for quite a while I believe.
>>
>>Commit 48fea965 should have changed that line, but that's ok, we will
>>clean it later.
>>
>Yehh :-)
>If it is OK, I can clean it up with this patch only.
>
>>>+	struct musb_hdrc_platform_data *plat = dev->platform_data;
>>>
>>> 	if (!musb->clock)
>>> 		return 0;
>>>
>>>+	if (plat->restore_context)
>>>+		plat->restore_context = 1;
>>
>>also here?? there's something wrong.
>>
>Yes...
>
>>>@@ -2468,16 +2475,20 @@ static int musb_resume_noirq(struct devi
>>> static int musb_runtime_suspend(struct device *dev)
>>> {
>>> 	struct musb	*musb = dev_to_musb(dev);
>>>+	struct musb_hdrc_platform_data *plat = dev->platform_data;
>>>
>>>-	musb_save_context(musb);
>>>+	if (plat->save_context)
>>>+		musb_save_context(musb);
>>
>>this looks better.
>>
>>>@@ -126,6 +128,17 @@ struct musb_hdrc_platform_data {
>>>
>>> 	/* Architecture specific board data	*/
>>> 	void		*board_data;
>>>+
>>>+	/* check usb device active state*/
>>>+	int		(*is_usb_active)(struct device *dev);
>>
>>where is it used ??
>>
>This you got it already.
>>-- 
>>balbi
>>--
>To unsubscribe from this list: send the line "unsubscribe linux-usb" in
>the body of a message to majordomo@xxxxxxxxxxxxxxx
>More majordomo info at  http://vger.kernel.org/majordomo-info.html
>--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux