From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757854Ab1FANyY (ORCPT ); Wed, 1 Jun 2011 09:54:24 -0400 Received: from ogre.sisk.pl ([217.79.144.158]:48473 "EHLO ogre.sisk.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755441Ab1FANyU (ORCPT ); Wed, 1 Jun 2011 09:54:20 -0400 From: "Rafael J. Wysocki" To: Keshava Munegowda Subject: Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci Date: Wed, 1 Jun 2011 15:54:38 +0200 User-Agent: KMail/1.13.6 (Linux/2.6.39+; KDE/4.6.0; x86_64; ; ) Cc: linux-usb@vger.kernel.org, linux-omap@vger.kernel.org, linux-kernel@vger.kernel.org, balbi@ti.com, gadiyar@ti.com, sameo@linux.intel.com, parthab@india.ti.com, tony@atomide.com, khilman@ti.com, b-cousson@ti.com, paul@pwsan.com References: <1306934847-6098-1-git-send-email-keshava_mgowda@ti.com> <1306934847-6098-4-git-send-email-keshava_mgowda@ti.com> <1306934847-6098-5-git-send-email-keshava_mgowda@ti.com> In-Reply-To: <1306934847-6098-5-git-send-email-keshava_mgowda@ti.com> MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-2" Content-Transfer-Encoding: 7bit Message-Id: <201106011554.38415.rjw@sisk.pl> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wednesday, June 01, 2011, Keshava Munegowda wrote: > From: Keshava Munegowda > > The global suspend and resume functions for usbhs core driver > are implemented.These routine are called when the global suspend > and resume occurs. Before calling these functions, the > bus suspend and resume of ehci and ohci drivers are called > from runtime pm. > > Signed-off-by: Keshava Munegowda > --- > drivers/mfd/omap-usb-host.c | 103 +++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 103 insertions(+), 0 deletions(-) > > diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c > index 43de12a..32d19e2 100644 > --- a/drivers/mfd/omap-usb-host.c > +++ b/drivers/mfd/omap-usb-host.c > @@ -146,6 +146,10 @@ > #define is_ehci_hsic_mode(x) (x == OMAP_EHCI_PORT_MODE_HSIC) > > > +/* USBHS state bits */ > +#define OMAP_USBHS_INIT 0 > +#define OMAP_USBHS_SUSPEND 4 > + > struct usbhs_hcd_omap { > struct clk *xclk60mhsp1_ck; > struct clk *xclk60mhsp2_ck; > @@ -165,6 +169,7 @@ struct usbhs_hcd_omap { > u32 usbhs_rev; > spinlock_t lock; > int count; > + unsigned long state; > }; > /*-------------------------------------------------------------------------*/ > > @@ -809,6 +814,8 @@ static int usbhs_enable(struct device *dev) > (pdata->ehci_data->reset_gpio_port[1], 1); > } > > + set_bit(OMAP_USBHS_INIT, &omap->state); > + > end_count: > omap->count++; > spin_unlock_irqrestore(&omap->lock, flags); > @@ -897,6 +904,7 @@ static void usbhs_disable(struct device *dev) > } > > pm_runtime_put_sync(dev); > + clear_bit(OMAP_USBHS_INIT, &omap->state); > > /* The gpio_free migh sleep; so unlock the spinlock */ > spin_unlock_irqrestore(&omap->lock, flags); > @@ -926,10 +934,105 @@ void omap_usbhs_disable(struct device *dev) > } > EXPORT_SYMBOL_GPL(omap_usbhs_disable); > > +#ifdef CONFIG_PM > + > +static int usbhs_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; > + > + dev_dbg(dev, "Resuming TI HSUSB Controller\n"); > + > + if (!pdata) { > + dev_dbg(dev, "missing platform_data\n"); > + return -ENODEV; > + } > + > + spin_lock_irqsave(&omap->lock, flags); > + > + if (!test_bit(OMAP_USBHS_INIT, &omap->state) || > + !test_bit(OMAP_USBHS_SUSPEND, &omap->state)) > + goto end_resume; > + > + pm_runtime_get_sync(dev); > + > + if (is_omap_usbhs_rev2(omap)) { > + 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); > + } > + clear_bit(OMAP_USBHS_SUSPEND, &omap->state); > + > +end_resume: > + spin_unlock_irqrestore(&omap->lock, flags); > + return 0; > +} > + > + > +static int usbhs_suspend(struct device *dev) > +{ > + struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); > + struct usbhs_omap_platform_data *pdata = &omap->platdata; > + unsigned long flags = 0; > + > + dev_dbg(dev, "Suspending TI HSUSB Controller\n"); > + > + if (!pdata) { > + dev_dbg(dev, "missing platform_data\n"); > + return -ENODEV; > + } > + > + spin_lock_irqsave(&omap->lock, flags); > + > + if (!test_bit(OMAP_USBHS_INIT, &omap->state) || > + test_bit(OMAP_USBHS_SUSPEND, &omap->state)) > + goto end_suspend; > + > + if (is_omap_usbhs_rev2(omap)) { > + 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); > + } > + > + set_bit(OMAP_USBHS_SUSPEND, &omap->state); > + pm_runtime_put_sync(dev); > + > +end_suspend: > + spin_unlock_irqrestore(&omap->lock, flags); > + return 0; > +} > + > + > +static const struct dev_pm_ops usbhsomap_dev_pm_ops = { > + .suspend = usbhs_suspend, > + .resume = usbhs_resume, > +}; Please add .freeze()/.thaw() and .poweroff()/.restore() callbacks too. They may point to the same routines, but must be present. You can actually use the SIMPLE_DEV_PM_OPS() convenience macro for this purpose. > + > +#define USBHS_OMAP_DEV_PM_OPS (&usbhsomap_dev_pm_ops) > +#else > +#define USBHS_OMAP_DEV_PM_OPS NULL > +#endif > + > static struct platform_driver usbhs_omap_driver = { > .driver = { > .name = (char *)usbhs_driver_name, > .owner = THIS_MODULE, > + .pm = USBHS_OMAP_DEV_PM_OPS, > }, > .remove = __exit_p(usbhs_omap_remove), > }; > Thanks, Rafael