Calling runtime pm APIs pm_runtime_put_sync() and pm_runtime_get_sync()
for enabling/disabling the clocks, sysconfig settings.
Enable clock, configure no-idle/standby when active and configure force idle/standby
and disable clock when idled. This is taken care by the runtime framework when
driver calls the pm_runtime_get_sync and pm_runtime_put_sync APIs.
Need to configure MUSB into force standby and force idle mode when usb not used
Signed-off-by: Hema HK <hemahk@ti.com>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Cousson, Benoit <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \
defined(CONFIG_ARCH_OMAP4)
#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \
defined(CONFIG_ARCH_OMAP4)
- u32 otg_sysconfig, otg_forcestandby;
#endif
u8 power;
u16 intrtxe, intrrxe;
#endif
u8 power;
u16 intrtxe, intrrxe;
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
+#include <linux/pm_runtime.h>
+#include <linux/err.h>
#include "musb_core.h"
#include "omap2430.h"
#include "musb_core.h"
#include "omap2430.h"
struct omap2430_glue {
struct device *dev;
struct platform_device *musb;
struct omap2430_glue {
struct device *dev;
struct platform_device *musb;
};
#define glue_to_musb(g) platform_get_drvdata(g->musb)
};
#define glue_to_musb(g) platform_get_drvdata(g->musb)
l = musb_readl(musb->mregs, OTG_FORCESTDBY);
l |= ENABLEFORCE; /* enable MSTANDBY */
musb_writel(musb->mregs, OTG_FORCESTDBY, l);
l = musb_readl(musb->mregs, OTG_FORCESTDBY);
l |= ENABLEFORCE; /* enable MSTANDBY */
musb_writel(musb->mregs, OTG_FORCESTDBY, l);
-
- l = musb_readl(musb->mregs, OTG_SYSCONFIG);
- l |= ENABLEWAKEUP; /* enable wakeup */
- musb_writel(musb->mregs, OTG_SYSCONFIG, l);
}
static inline void omap2430_low_level_init(struct musb *musb)
{
u32 l;
}
static inline void omap2430_low_level_init(struct musb *musb)
{
u32 l;
- l = musb_readl(musb->mregs, OTG_SYSCONFIG);
- l &= ~ENABLEWAKEUP; /* disable wakeup */
- musb_writel(musb->mregs, OTG_SYSCONFIG, l);
-
l = musb_readl(musb->mregs, OTG_FORCESTDBY);
l &= ~ENABLEFORCE; /* disable MSTANDBY */
musb_writel(musb->mregs, OTG_FORCESTDBY, l);
l = musb_readl(musb->mregs, OTG_FORCESTDBY);
l &= ~ENABLEFORCE; /* disable MSTANDBY */
musb_writel(musb->mregs, OTG_FORCESTDBY, l);
omap2430_low_level_init(musb);
omap2430_low_level_init(musb);
- l = musb_readl(musb->mregs, OTG_SYSCONFIG);
- l &= ~ENABLEWAKEUP; /* disable wakeup */
- l &= ~NOSTDBY; /* remove possible nostdby */
- l |= SMARTSTDBY; /* enable smart standby */
- l &= ~AUTOIDLE; /* disable auto idle */
- l &= ~NOIDLE; /* remove possible noidle */
- l |= SMARTIDLE; /* enable smart idle */
- /*
- * MUSB AUTOIDLE don't work in 3430.
- * Workaround by Richard Woodruff/TI
- */
- if (!cpu_is_omap3430())
- l |= AUTOIDLE; /* enable auto idle */
- musb_writel(musb->mregs, OTG_SYSCONFIG, l);
-
l = musb_readl(musb->mregs, OTG_INTERFSEL);
if (data->interface_type == MUSB_INTERFACE_UTMI) {
l = musb_readl(musb->mregs, OTG_INTERFSEL);
if (data->interface_type == MUSB_INTERFACE_UTMI) {
struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
struct platform_device *musb;
struct omap2430_glue *glue;
struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
struct platform_device *musb;
struct omap2430_glue *glue;
- clk = clk_get(&pdev->dev, "ick");
- if (IS_ERR(clk)) {
- dev_err(&pdev->dev, "failed to get clock\n");
- ret = PTR_ERR(clk);
- goto err2;
- }
-
- ret = clk_enable(clk);
- if (ret) {
- dev_err(&pdev->dev, "failed to enable clock\n");
- goto err3;
- }
-
musb->dev.parent = &pdev->dev;
musb->dev.dma_mask = &omap2430_dmamask;
musb->dev.coherent_dma_mask = omap2430_dmamask;
glue->dev = &pdev->dev;
glue->musb = musb;
musb->dev.parent = &pdev->dev;
musb->dev.dma_mask = &omap2430_dmamask;
musb->dev.coherent_dma_mask = omap2430_dmamask;
glue->dev = &pdev->dev;
glue->musb = musb;
pdata->platform_ops = &omap2430_ops;
pdata->platform_ops = &omap2430_ops;
pdev->num_resources);
if (ret) {
dev_err(&pdev->dev, "failed to add resources\n");
pdev->num_resources);
if (ret) {
dev_err(&pdev->dev, "failed to add resources\n");
}
ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
if (ret) {
dev_err(&pdev->dev, "failed to add platform_data\n");
}
ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
if (ret) {
dev_err(&pdev->dev, "failed to add platform_data\n");
}
ret = platform_device_add(musb);
if (ret) {
dev_err(&pdev->dev, "failed to register musb device\n");
}
ret = platform_device_add(musb);
if (ret) {
dev_err(&pdev->dev, "failed to register musb device\n");
+ pm_runtime_enable(&pdev->dev);
+ status = pm_runtime_get_sync(&pdev->dev);
+ if (status < 0) {
+ dev_err(&pdev->dev, "pm_runtime_get_sync FAILED");
+ goto err3;
+ }
-err4:
- clk_disable(clk);
+ pm_runtime_disable(&pdev->dev);
err2:
platform_device_put(musb);
err2:
platform_device_put(musb);
platform_device_del(glue->musb);
platform_device_put(glue->musb);
platform_device_del(glue->musb);
platform_device_put(glue->musb);
- clk_disable(glue->clk);
- clk_put(glue->clk);
+ pm_runtime_put(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
#ifdef CONFIG_PM
static void omap2430_save_context(struct musb *musb)
{
#ifdef CONFIG_PM
static void omap2430_save_context(struct musb *musb)
{
- musb->context.otg_sysconfig = musb_readl(musb->mregs, OTG_SYSCONFIG);
musb->context.otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY);
}
static void omap2430_restore_context(struct musb *musb)
{
musb->context.otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY);
}
static void omap2430_restore_context(struct musb *musb)
{
- musb_writel(musb->mregs, OTG_SYSCONFIG, musb->context.otg_sysconfig);
musb_writel(musb->mregs, OTG_FORCESTDBY, musb->context.otg_forcestandby);
}
musb_writel(musb->mregs, OTG_FORCESTDBY, musb->context.otg_forcestandby);
}
omap2430_low_level_exit(musb);
otg_set_suspend(musb->xceiv, 1);
omap2430_save_context(musb);
omap2430_low_level_exit(musb);
otg_set_suspend(musb->xceiv, 1);
omap2430_save_context(musb);
- clk_disable(glue->clk);
+
+ if (!pm_runtime_suspended(dev) && dev->bus && dev->bus->pm &&
+ dev->bus->pm->runtime_suspend)
+ dev->bus->pm->runtime_suspend(dev);
{
struct omap2430_glue *glue = dev_get_drvdata(dev);
struct musb *musb = glue_to_musb(glue);
{
struct omap2430_glue *glue = dev_get_drvdata(dev);
struct musb *musb = glue_to_musb(glue);
- ret = clk_enable(glue->clk);
- if (ret) {
- dev_err(dev, "faled to enable clock\n");
- return ret;
- }
+ if (!pm_runtime_suspended(dev) && dev->bus && dev->bus->pm &&
+ dev->bus->pm->runtime_resume)
+ dev->bus->pm->runtime_resume(dev);
omap2430_low_level_init(musb);
omap2430_restore_context(musb);
omap2430_low_level_init(musb);
omap2430_restore_context(musb);