Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 286118
b: refs/heads/master
c: 28c7a19
h: refs/heads/master
v: v3
  • Loading branch information
Narayanan G authored and Vinod Koul committed Nov 28, 2011
1 parent 8f2cfa3 commit 49f686c
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d5613947addb1e1096a3be29dfe817905e385469
refs/heads/master: 28c7a19d230228ab9ae61c300c5003a2400fadd3
1 change: 1 addition & 0 deletions trunk/arch/arm/plat-nomadik/include/plat/ste_dma40.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ struct stedma40_platform_data {
struct stedma40_chan_cfg *memcpy_conf_phy;
struct stedma40_chan_cfg *memcpy_conf_log;
int disabled_channels[STEDMA40_MAX_PHYS];
bool use_esram_lcla;
};

#ifdef CONFIG_STE_DMA40
Expand Down
95 changes: 85 additions & 10 deletions trunk/drivers/dma/ste_dma40.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,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.
Expand Down Expand Up @@ -338,6 +339,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;
Expand Down Expand Up @@ -605,6 +607,7 @@ static void d40_log_lli_to_lcxa(struct d40_chan *chan, struct d40_desc *desc)
bool cyclic = desc->cyclic;
int curr_lcla = -EINVAL;
int first_lcla = 0;
bool use_esram_lcla = chan->base->plat_data->use_esram_lcla;
bool linkback;

/*
Expand Down Expand Up @@ -677,11 +680,16 @@ static void d40_log_lli_to_lcxa(struct d40_chan *chan, struct d40_desc *desc)
&lli->src[lli_current],
next_lcla, flags);

dma_sync_single_range_for_device(chan->base->dev,
pool->dma_addr, lcla_offset,
2 * sizeof(struct d40_log_lli),
DMA_TO_DEVICE);

/*
* Cache maintenance is not needed if lcla is
* mapped in esram
*/
if (!use_esram_lcla) {
dma_sync_single_range_for_device(chan->base->dev,
pool->dma_addr, lcla_offset,
2 * sizeof(struct d40_log_lli),
DMA_TO_DEVICE);
}
curr_lcla = next_lcla;

if (curr_lcla == -EINVAL || curr_lcla == first_lcla) {
Expand Down Expand Up @@ -2668,10 +2676,15 @@ static int __init d40_dmaengine_init(struct d40_base *base,
#ifdef CONFIG_PM
static int dma40_pm_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct d40_base *base = platform_get_drvdata(pdev);
int ret = 0;
if (!pm_runtime_suspended(dev))
return -EBUSY;

return 0;
if (base->lcpa_regulator)
ret = regulator_disable(base->lcpa_regulator);
return ret;
}

static int dma40_runtime_suspend(struct device *dev)
Expand Down Expand Up @@ -2702,11 +2715,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
Expand Down Expand Up @@ -3165,11 +3190,31 @@ static int __init d40_probe(struct platform_device *pdev)
d40_err(&pdev->dev, "Failed to ioremap LCPA region\n");
goto failure;
}
/* If lcla has to be located in ESRAM we don't need to allocate */
if (base->plat_data->use_esram_lcla) {
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"lcla_esram");
if (!res) {
ret = -ENOENT;
d40_err(&pdev->dev,
"No \"lcla_esram\" memory resource\n");
goto failure;
}
base->lcla_pool.base = ioremap(res->start,
resource_size(res));
if (!base->lcla_pool.base) {
ret = -ENOMEM;
d40_err(&pdev->dev, "Failed to ioremap LCLA region\n");
goto failure;
}
writel(res->start, base->virtbase + D40_DREG_LCLA);

ret = d40_lcla_allocate(base);
if (ret) {
d40_err(&pdev->dev, "Failed to allocate LCLA area\n");
goto failure;
} else {
ret = d40_lcla_allocate(base);
if (ret) {
d40_err(&pdev->dev, "Failed to allocate LCLA area\n");
goto failure;
}
}

spin_lock_init(&base->lcla_pool.lock);
Expand All @@ -3187,6 +3232,26 @@ static int __init d40_probe(struct platform_device *pdev)
pm_runtime_use_autosuspend(base->dev);
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);
if (err)
Expand All @@ -3204,6 +3269,11 @@ static int __init d40_probe(struct platform_device *pdev)
if (base->virtbase)
iounmap(base->virtbase);

if (base->lcla_pool.base && base->plat_data->use_esram_lcla) {
iounmap(base->lcla_pool.base);
base->lcla_pool.base = NULL;
}

if (base->lcla_pool.dma_addr)
dma_unmap_single(base->dev, base->lcla_pool.dma_addr,
SZ_1K * base->num_phy_chans,
Expand All @@ -3226,6 +3296,11 @@ static int __init d40_probe(struct platform_device *pdev)
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);
Expand Down

0 comments on commit 49f686c

Please sign in to comment.