summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNarayanan G <narayanan.gopalakrishnan@stericsson.com>2011-10-10 15:44:51 +0530
committerRobert Marklund <robert.marklund@stericsson.com>2011-10-27 16:08:50 +0200
commit47932c41e0610a7d1cc7ed8e370bc89e9f6f6dbf (patch)
tree0cc4046e2cd11a727b5edcf81fe86f3e52d17b9b
parentaefbe3bca9c285b39c46c887c20aff2210ec3519 (diff)
dma40: Handle esram regulator in dma driver
If the esram is used for LCLA region, this patch will hold the regulator during when the DMA driver is active. The regulator will be disabled on a suspend and will be enabled again on resume. The dma driver initcall has been moved to subsys_initcall(), to ensure that the regulators are available before we do a regulator_get(). ST-Ericsson ID: 364165 ST-Ericsson FOSS-OUT ID: Trivial ST-Ericsson Linux next: NA Change-Id: Ieee3c329c26e9fb43f282716fa57810211f79d85 Signed-off-by: Narayanan G <narayanan.gopalakrishnan@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/33434 Reviewed-by: Rabin VINCENT <rabin.vincent@stericsson.com>
-rw-r--r--drivers/dma/ste_dma40.c46
-rw-r--r--drivers/mfd/db8500-prcmu.c1
2 files changed, 46 insertions, 1 deletions
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index d8901cb2455..9d8bb7997e5 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -15,6 +15,7 @@
#include <linux/version.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
#include <linux/err.h>
#include <plat/ste_dma40.h>
@@ -314,6 +315,7 @@ struct d40_chan {
* to phy_chans entries.
* @plat_data: Pointer to provided platform_data which is the driver
* configuration.
+ * @lcpa_regulator: Pointer to hold the regulator for the esram bank for lcla.
* @phy_res: Vector containing all physical channels.
* @lcla_pool: lcla pool settings and data.
* @lcpa_base: The virtual mapped address of LCPA.
@@ -350,6 +352,7 @@ struct d40_base {
struct d40_chan **lookup_log_chans;
struct d40_chan **lookup_phy_chans;
struct stedma40_platform_data *plat_data;
+ struct regulator *lcpa_regulator;
/* Physical half channels */
struct d40_phy_res *phy_res;
struct d40_lcla_pool lcla_pool;
@@ -3064,6 +3067,9 @@ static int dma40_pm_suspend(struct device *dev)
spin_unlock_irqrestore(&base->usage_lock, flags);
+ if (base->lcpa_regulator)
+ ret = regulator_disable(base->lcpa_regulator);
+
return ret;
}
@@ -3088,10 +3094,23 @@ static int dma40_runtime_resume(struct device *dev)
return 0;
}
+static int dma40_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct d40_base *base = platform_get_drvdata(pdev);
+ int ret = 0;
+
+ if (base->lcpa_regulator)
+ ret = regulator_enable(base->lcpa_regulator);
+
+ return ret;
+}
+
static const struct dev_pm_ops dma40_pm_ops = {
.suspend = dma40_pm_suspend,
.runtime_suspend = dma40_runtime_suspend,
.runtime_resume = dma40_runtime_resume,
+ .resume = dma40_resume,
};
#define DMA40_PM_OPS (&dma40_pm_ops)
#else
@@ -3580,6 +3599,7 @@ static int __init d40_probe(struct platform_device *pdev)
goto failure;
}
writel(res->start, base->virtbase + D40_DREG_LCLA);
+
} else {
ret = d40_lcla_allocate(base);
if (ret) {
@@ -3611,6 +3631,25 @@ static int __init d40_probe(struct platform_device *pdev)
pm_runtime_enable(base->dev);
pm_runtime_resume(base->dev);
+ if (base->plat_data->use_esram_lcla) {
+
+ base->lcpa_regulator = regulator_get(base->dev, "lcla_esram");
+ if (IS_ERR(base->lcpa_regulator)) {
+ d40_err(&pdev->dev, "Failed to get lcpa_regulator\n");
+ base->lcpa_regulator = NULL;
+ goto failure;
+ }
+
+ ret = regulator_enable(base->lcpa_regulator);
+ if (ret) {
+ d40_err(&pdev->dev,
+ "Failed to enable lcpa_regulator\n");
+ regulator_put(base->lcpa_regulator);
+ base->lcpa_regulator = NULL;
+ goto failure;
+ }
+ }
+
base->initialized = true;
err = d40_dmaengine_init(base, num_reserved_chans);
@@ -3659,6 +3698,11 @@ failure:
clk_put(base->clk);
}
+ if (base->lcpa_regulator) {
+ regulator_disable(base->lcpa_regulator);
+ regulator_put(base->lcpa_regulator);
+ }
+
kfree(base->lcla_pool.alloc_map);
kfree(base->lookup_log_chans);
kfree(base->lookup_phy_chans);
@@ -3682,4 +3726,4 @@ static int __init stedma40_init(void)
{
return platform_driver_probe(&d40_driver, d40_probe);
}
-arch_initcall(stedma40_init);
+subsys_initcall(stedma40_init);
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 930d56439fe..c9ccb8fd72c 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -2483,6 +2483,7 @@ static struct regulator_consumer_supply db8500_esram12_consumers[] = {
static struct regulator_consumer_supply db8500_esram34_consumers[] = {
REGULATOR_SUPPLY("v-esram34", "mcde"),
REGULATOR_SUPPLY("esram34", "cm_control"),
+ REGULATOR_SUPPLY("lcla_esram", "dma40.0"),
};
static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {