diff options
author | Narayanan G <narayanan.gopalakrishnan@stericsson.com> | 2011-10-10 15:44:51 +0530 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@stericsson.com> | 2011-12-06 10:57:42 +0100 |
commit | 75bf23fa0dd7781ecca5d3b3bdf05b81dfc2cc4c (patch) | |
tree | abe66944eaa209173c87af68f5abcd9178ab00b9 /drivers/dma | |
parent | 207230e075495ddcac86e6bef67d7a526db23f7a (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>
Diffstat (limited to 'drivers/dma')
-rw-r--r-- | drivers/dma/ste_dma40.c | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index c34b8a91ebb..3608ee72557 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -16,6 +16,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> @@ -315,6 +316,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. @@ -351,6 +353,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; @@ -3065,6 +3068,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; } @@ -3089,10 +3095,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 @@ -3581,6 +3600,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) { @@ -3612,6 +3632,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); @@ -3660,6 +3699,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); @@ -3683,4 +3727,4 @@ static int __init stedma40_init(void) { return platform_driver_probe(&d40_driver, d40_probe); } -arch_initcall(stedma40_init); +subsys_initcall(stedma40_init); |