|
@@ -33,6 +33,8 @@
|
|
#include <linux/io.h>
|
|
#include <linux/io.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/dma-mapping.h>
|
|
#include <linux/dma-mapping.h>
|
|
|
|
+#include <linux/pm_runtime.h>
|
|
|
|
+#include <linux/err.h>
|
|
|
|
|
|
#include "musb_core.h"
|
|
#include "musb_core.h"
|
|
#include "omap2430.h"
|
|
#include "omap2430.h"
|
|
@@ -40,7 +42,6 @@
|
|
struct omap2430_glue {
|
|
struct omap2430_glue {
|
|
struct device *dev;
|
|
struct device *dev;
|
|
struct platform_device *musb;
|
|
struct platform_device *musb;
|
|
- struct clk *clk;
|
|
|
|
};
|
|
};
|
|
#define glue_to_musb(g) platform_get_drvdata(g->musb)
|
|
#define glue_to_musb(g) platform_get_drvdata(g->musb)
|
|
|
|
|
|
@@ -216,20 +217,12 @@ static inline void omap2430_low_level_exit(struct musb *musb)
|
|
l = musb_readl(musb->mregs, OTG_FORCESTDBY);
|
|
l = musb_readl(musb->mregs, OTG_FORCESTDBY);
|
|
l |= ENABLEFORCE; /* enable MSTANDBY */
|
|
l |= ENABLEFORCE; /* enable MSTANDBY */
|
|
musb_writel(musb->mregs, OTG_FORCESTDBY, l);
|
|
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)
|
|
static inline void omap2430_low_level_init(struct musb *musb)
|
|
{
|
|
{
|
|
u32 l;
|
|
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 = musb_readl(musb->mregs, OTG_FORCESTDBY);
|
|
l &= ~ENABLEFORCE; /* disable MSTANDBY */
|
|
l &= ~ENABLEFORCE; /* disable MSTANDBY */
|
|
musb_writel(musb->mregs, OTG_FORCESTDBY, l);
|
|
musb_writel(musb->mregs, OTG_FORCESTDBY, l);
|
|
@@ -309,21 +302,6 @@ static int omap2430_musb_init(struct musb *musb)
|
|
|
|
|
|
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);
|
|
l = musb_readl(musb->mregs, OTG_INTERFSEL);
|
|
|
|
|
|
if (data->interface_type == MUSB_INTERFACE_UTMI) {
|
|
if (data->interface_type == MUSB_INTERFACE_UTMI) {
|
|
@@ -386,7 +364,7 @@ static int __init omap2430_probe(struct platform_device *pdev)
|
|
struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
|
|
struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
|
|
struct platform_device *musb;
|
|
struct platform_device *musb;
|
|
struct omap2430_glue *glue;
|
|
struct omap2430_glue *glue;
|
|
- struct clk *clk;
|
|
|
|
|
|
+ int status = 0;
|
|
|
|
|
|
int ret = -ENOMEM;
|
|
int ret = -ENOMEM;
|
|
|
|
|
|
@@ -402,26 +380,12 @@ static int __init omap2430_probe(struct platform_device *pdev)
|
|
goto err1;
|
|
goto err1;
|
|
}
|
|
}
|
|
|
|
|
|
- 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.parent = &pdev->dev;
|
|
musb->dev.dma_mask = &omap2430_dmamask;
|
|
musb->dev.dma_mask = &omap2430_dmamask;
|
|
musb->dev.coherent_dma_mask = omap2430_dmamask;
|
|
musb->dev.coherent_dma_mask = omap2430_dmamask;
|
|
|
|
|
|
glue->dev = &pdev->dev;
|
|
glue->dev = &pdev->dev;
|
|
glue->musb = musb;
|
|
glue->musb = musb;
|
|
- glue->clk = clk;
|
|
|
|
|
|
|
|
pdata->platform_ops = &omap2430_ops;
|
|
pdata->platform_ops = &omap2430_ops;
|
|
|
|
|
|
@@ -431,29 +395,32 @@ static int __init omap2430_probe(struct platform_device *pdev)
|
|
pdev->num_resources);
|
|
pdev->num_resources);
|
|
if (ret) {
|
|
if (ret) {
|
|
dev_err(&pdev->dev, "failed to add resources\n");
|
|
dev_err(&pdev->dev, "failed to add resources\n");
|
|
- goto err4;
|
|
|
|
|
|
+ goto err2;
|
|
}
|
|
}
|
|
|
|
|
|
ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
|
|
ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
|
|
if (ret) {
|
|
if (ret) {
|
|
dev_err(&pdev->dev, "failed to add platform_data\n");
|
|
dev_err(&pdev->dev, "failed to add platform_data\n");
|
|
- goto err4;
|
|
|
|
|
|
+ goto err2;
|
|
}
|
|
}
|
|
|
|
|
|
ret = platform_device_add(musb);
|
|
ret = platform_device_add(musb);
|
|
if (ret) {
|
|
if (ret) {
|
|
dev_err(&pdev->dev, "failed to register musb device\n");
|
|
dev_err(&pdev->dev, "failed to register musb device\n");
|
|
- goto err4;
|
|
|
|
|
|
+ goto err2;
|
|
}
|
|
}
|
|
|
|
|
|
- return 0;
|
|
|
|
|
|
+ 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);
|
|
|
|
|
|
+ return 0;
|
|
|
|
|
|
err3:
|
|
err3:
|
|
- clk_put(clk);
|
|
|
|
-
|
|
|
|
|
|
+ pm_runtime_disable(&pdev->dev);
|
|
err2:
|
|
err2:
|
|
platform_device_put(musb);
|
|
platform_device_put(musb);
|
|
|
|
|
|
@@ -470,8 +437,8 @@ static int __exit omap2430_remove(struct platform_device *pdev)
|
|
|
|
|
|
platform_device_del(glue->musb);
|
|
platform_device_del(glue->musb);
|
|
platform_device_put(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);
|
|
kfree(glue);
|
|
kfree(glue);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -480,13 +447,11 @@ static int __exit omap2430_remove(struct platform_device *pdev)
|
|
#ifdef CONFIG_PM
|
|
#ifdef CONFIG_PM
|
|
static void omap2430_save_context(struct musb *musb)
|
|
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);
|
|
musb->context.otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY);
|
|
}
|
|
}
|
|
|
|
|
|
static void omap2430_restore_context(struct musb *musb)
|
|
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);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -498,7 +463,10 @@ static int omap2430_suspend(struct device *dev)
|
|
omap2430_low_level_exit(musb);
|
|
omap2430_low_level_exit(musb);
|
|
otg_set_suspend(musb->xceiv, 1);
|
|
otg_set_suspend(musb->xceiv, 1);
|
|
omap2430_save_context(musb);
|
|
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);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -507,13 +475,10 @@ static int omap2430_resume(struct device *dev)
|
|
{
|
|
{
|
|
struct omap2430_glue *glue = dev_get_drvdata(dev);
|
|
struct omap2430_glue *glue = dev_get_drvdata(dev);
|
|
struct musb *musb = glue_to_musb(glue);
|
|
struct musb *musb = glue_to_musb(glue);
|
|
- int ret;
|
|
|
|
|
|
|
|
- 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_low_level_init(musb);
|
|
omap2430_restore_context(musb);
|
|
omap2430_restore_context(musb);
|