From patchwork Thu Jul 8 10:28:36 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Kalliguddi, Hema" X-Patchwork-Id: 110818 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o68ASlIc013159 for ; Thu, 8 Jul 2010 10:28:47 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753513Ab0GHK2p (ORCPT ); Thu, 8 Jul 2010 06:28:45 -0400 Received: from devils.ext.ti.com ([198.47.26.153]:50843 "EHLO devils.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752832Ab0GHK2o (ORCPT ); Thu, 8 Jul 2010 06:28:44 -0400 Received: from dbdp31.itg.ti.com ([172.24.170.98]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id o68ASbs7014584 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 8 Jul 2010 05:28:39 -0500 Received: from linfarm476.india.ti.com (localhost [127.0.0.1]) by dbdp31.itg.ti.com (8.13.8/8.13.8) with ESMTP id o68ASaa5024618; Thu, 8 Jul 2010 15:58:36 +0530 (IST) Received: from linfarm476.india.ti.com (localhost [127.0.0.1]) by linfarm476.india.ti.com (8.12.11/8.12.11) with ESMTP id o68ASaZH021906; Thu, 8 Jul 2010 15:58:36 +0530 Received: (from a0876481@localhost) by linfarm476.india.ti.com (8.12.11/8.12.11/Submit) id o68ASaDi021904; Thu, 8 Jul 2010 15:58:36 +0530 From: Hema HK To: linux-usb@vger.kernel.org, linux-omap@vger.kernel.org Cc: Hema HK , Maulik Mankad , Felipe Balbi , Tony Lindgren , Kevin Hilman Subject: [PATCH] usb: musb: Offmode fix for idle path Date: Thu, 8 Jul 2010 15:58:36 +0530 Message-Id: <1278584916-21288-1-git-send-email-hemahk@ti.com> X-Mailer: git-send-email 1.5.6.6 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 08 Jul 2010 10:28:48 +0000 (UTC) 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 @@ -431,6 +431,8 @@ void omap_sram_idle(void) if (core_next_state == PWRDM_POWER_OFF) { omap3_core_save_context(); omap3_prcm_save_context(); + /* Save MUSB context */ + musb_context_save_restore(1); } } @@ -479,6 +481,8 @@ void omap_sram_idle(void) omap3_prcm_restore_context(); omap3_sram_restore_context(); omap2_sms_restore_context(); + /* Restore MUSB context */ + musb_context_save_restore(0); /* * Errata 1.164 fix : OTG autoidle can prevent * sleep 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 @@ -177,6 +177,21 @@ void __init usb_musb_init(struct omap_mu usb_musb_pm_init(); } +void musb_context_save_restore(int save) +{ + struct device *dev = &musb_device.dev; + struct device_driver *drv = dev->driver; + if (dev->driver) { + + const struct dev_pm_ops *pm = drv->pm; + + if (save) + pm->suspend(dev); + else + pm->resume_noirq(dev); + } +} + #else void __init usb_musb_init(struct omap_musb_board_data *board_data) { Index: linux-omap-pm/arch/arm/plat-omap/include/plat/usb.h =================================================================== --- linux-omap-pm.orig/arch/arm/plat-omap/include/plat/usb.h +++ linux-omap-pm/arch/arm/plat-omap/include/plat/usb.h @@ -82,6 +82,8 @@ extern void usb_ohci_init(const struct o /* This is needed for OMAP3 errata 1.164: enabled autoidle can prevent sleep */ extern void usb_musb_disable_autoidle(void); +/* For saving and restoring the musb context during off/wakeup*/ +extern void musb_context_save_restore(int save); #endif void omap_usb_init(struct omap_usb_config *pdata); 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 @@ -2430,11 +2430,6 @@ static int musb_suspend(struct device *d } musb_save_context(musb); - - if (musb->set_clock) - musb->set_clock(musb->clock, 0); - else - clk_disable(musb->clock); spin_unlock_irqrestore(&musb->lock, flags); return 0; } @@ -2446,12 +2441,6 @@ static int musb_resume_noirq(struct devi if (!musb->clock) return 0; - - if (musb->set_clock) - musb->set_clock(musb->clock, 1); - else - clk_enable(musb->clock); - musb_restore_context(musb); /* for static cmos like DaVinci, register values were preserved Index: linux-omap-pm/drivers/usb/musb/omap2430.c =================================================================== --- linux-omap-pm.orig/drivers/usb/musb/omap2430.c +++ linux-omap-pm/drivers/usb/musb/omap2430.c @@ -257,15 +257,39 @@ int __init musb_platform_init(struct mus void musb_platform_save_context(struct musb *musb, struct musb_context_registers *musb_context) { - musb_context->otg_sysconfig = musb_readl(musb->mregs, OTG_SYSCONFIG); - musb_context->otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY); + /* + * As per the specification, configure it to forced standby + * and force idle mode when no activity on usb. + */ + void __iomem *musb_base = musb->mregs; + musb_writel(musb_base, OTG_FORCESTDBY, 0); + musb_writel(musb_base, OTG_SYSCONFIG, musb_readl(musb_base, + OTG_SYSCONFIG) & ~(NOSTDBY | SMARTSTDBY)); + + musb_writel(musb_base, OTG_SYSCONFIG, musb_readl(musb_base, + OTG_SYSCONFIG) & ~(AUTOIDLE)); + + musb_writel(musb_base, OTG_SYSCONFIG, musb_readl(musb_base, + OTG_SYSCONFIG) & ~(NOIDLE | SMARTIDLE)); + + musb_writel(musb_base, OTG_FORCESTDBY, 1); } void musb_platform_restore_context(struct musb *musb, struct musb_context_registers *musb_context) { - musb_writel(musb->mregs, OTG_SYSCONFIG, musb_context->otg_sysconfig); - musb_writel(musb->mregs, OTG_FORCESTDBY, musb_context->otg_forcestandby); + /* + * As per the specification, configure it smart standby + * and smart idle during operation. + */ + void __iomem *musb_base = musb->mregs; + musb_writel(musb_base, OTG_FORCESTDBY, 0); + + musb_writel(musb_base, OTG_SYSCONFIG, musb_readl(musb_base, + OTG_SYSCONFIG) | (SMARTSTDBY)); + + musb_writel(musb_base, OTG_SYSCONFIG, musb_readl(musb_base, + OTG_SYSCONFIG) | (SMARTIDLE)); } #endif