> -----Original Message-----
> From: Hema HK [mailto:[email protected]]
> Sent: Thursday, September 23, 2010 6:01 AM
> To: [email protected]; [email protected]
> Cc: Hema HK; Maulik Mankad; Felipe Balbi; Tony Lindgren; Kevin Hilman;
> Cousson, Benoit; Paul Walmsley
> Subject: [PATCH 9/9 v3] usb : musb: Offmode fix for idle path
> 
> 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
> 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.
> 
> 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 <[email protected]>
> Signed-off-by: Maulik Mankad <[email protected]>
> Cc: Felipe Balbi <[email protected]>
> Cc: Tony Lindgren <[email protected]>
> Cc: Kevin Hilman <[email protected]>
> Cc: Cousson, Benoit <[email protected]>
> Cc: Paul Walmsley <[email protected]>
> 
> ---
>  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");
>       oh = omap_hwmod_lookup(oh_name);
> 
>       if (!oh) {
> @@ -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)


Don't you need a start brace here?
Also a tab is required if this if condition is under if (dev->driver)

        
> +             if (!pdata->is_usb_active(dev)) {
> +                     if (core_next_state == PWRDM_POWER_OFF) {
> +                             pdata->save_context = 1;
> +                             pm_runtime_put_sync(dev);
> +                     } else if  (core_next_state == PWRDM_POWER_RET) {
> +                             pdata->save_context = 0;
> +                             pm_runtime_put_sync(dev);
> +                     }
> +             }
> +     }
> +}
> +
> +void musb_wakeup_from_idle()
> +{
> +     int core_next_state;
> +     int core_prev_state;
> +     struct omap_hwmod *oh = oh_p;
> +     struct omap_device *od;
> +     struct platform_device *pdev;
> +     struct device *dev;
> +     struct musb_hdrc_platform_data *pdata;
> +
> +     if (!core_pwrdm)
> +             return;
> +
> +     core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
> +
> +     if (core_next_state >= PWRDM_POWER_INACTIVE)
> +             return;
> +      core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm);
> +
> +      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)

Braces needed for this if condition?

> +                     if (!pdata->is_usb_active(dev)) {
> +                             if (core_prev_state == PWRDM_POWER_OFF) {
> +                                     pdata->restore_context = 1;
> +                                      pm_runtime_get_sync(dev);
> +                             } else {
> +                                      pdata->restore_context = 0;
> +                                      pm_runtime_get_sync(dev);
> +                             }
> +                      }
> +      }
> +}

Regards,
Maulik

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to