summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNarayanan G <narayanan.gopalakrishnan@stericsson.com>2011-10-10 15:44:51 +0530
committerRabin VINCENT <rabin.vincent@stericsson.com>2011-10-13 13:12:03 +0200
commitb5e9d16402c73be06ffa61fcb9ff59131f680c01 (patch)
treef5b60cd3488c587de613eec9f7f19e9f60ea3bd6
parent39b1d2617e604db307b237c8347f90be8cc00c74 (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] = {