diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2012-07-20 04:01:08 -0400 |
---|---|---|
committer | Vinod Koul <vinod.koul@linux.intel.com> | 2012-08-13 00:45:22 -0400 |
commit | ffc493062ce9987156945aa21a677d83a179fc0a (patch) | |
tree | c8e9d7ec60ab132bd9a4edec903e0a4be062e94c | |
parent | f986ffedd7c60c76e72d63dda49a0c705d451d43 (diff) |
dma: tegra: enable/disable dma clock
Enable the DMA clock when allocating channel and
disable clock when freeing channels.
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
-rw-r--r-- | drivers/dma/tegra20-apb-dma.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index d52dbc6c54ab..24acd711e032 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c | |||
@@ -1119,15 +1119,21 @@ struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic( | |||
1119 | static int tegra_dma_alloc_chan_resources(struct dma_chan *dc) | 1119 | static int tegra_dma_alloc_chan_resources(struct dma_chan *dc) |
1120 | { | 1120 | { |
1121 | struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); | 1121 | struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); |
1122 | struct tegra_dma *tdma = tdc->tdma; | ||
1123 | int ret; | ||
1122 | 1124 | ||
1123 | dma_cookie_init(&tdc->dma_chan); | 1125 | dma_cookie_init(&tdc->dma_chan); |
1124 | tdc->config_init = false; | 1126 | tdc->config_init = false; |
1125 | return 0; | 1127 | ret = clk_prepare_enable(tdma->dma_clk); |
1128 | if (ret < 0) | ||
1129 | dev_err(tdc2dev(tdc), "clk_prepare_enable failed: %d\n", ret); | ||
1130 | return ret; | ||
1126 | } | 1131 | } |
1127 | 1132 | ||
1128 | static void tegra_dma_free_chan_resources(struct dma_chan *dc) | 1133 | static void tegra_dma_free_chan_resources(struct dma_chan *dc) |
1129 | { | 1134 | { |
1130 | struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); | 1135 | struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); |
1136 | struct tegra_dma *tdma = tdc->tdma; | ||
1131 | 1137 | ||
1132 | struct tegra_dma_desc *dma_desc; | 1138 | struct tegra_dma_desc *dma_desc; |
1133 | struct tegra_dma_sg_req *sg_req; | 1139 | struct tegra_dma_sg_req *sg_req; |
@@ -1163,6 +1169,7 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc) | |||
1163 | list_del(&sg_req->node); | 1169 | list_del(&sg_req->node); |
1164 | kfree(sg_req); | 1170 | kfree(sg_req); |
1165 | } | 1171 | } |
1172 | clk_disable_unprepare(tdma->dma_clk); | ||
1166 | } | 1173 | } |
1167 | 1174 | ||
1168 | /* Tegra20 specific DMA controller information */ | 1175 | /* Tegra20 specific DMA controller information */ |
@@ -1255,6 +1262,13 @@ static int __devinit tegra_dma_probe(struct platform_device *pdev) | |||
1255 | } | 1262 | } |
1256 | } | 1263 | } |
1257 | 1264 | ||
1265 | /* Enable clock before accessing registers */ | ||
1266 | ret = clk_prepare_enable(tdma->dma_clk); | ||
1267 | if (ret < 0) { | ||
1268 | dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret); | ||
1269 | goto err_pm_disable; | ||
1270 | } | ||
1271 | |||
1258 | /* Reset DMA controller */ | 1272 | /* Reset DMA controller */ |
1259 | tegra_periph_reset_assert(tdma->dma_clk); | 1273 | tegra_periph_reset_assert(tdma->dma_clk); |
1260 | udelay(2); | 1274 | udelay(2); |
@@ -1265,6 +1279,8 @@ static int __devinit tegra_dma_probe(struct platform_device *pdev) | |||
1265 | tdma_write(tdma, TEGRA_APBDMA_CONTROL, 0); | 1279 | tdma_write(tdma, TEGRA_APBDMA_CONTROL, 0); |
1266 | tdma_write(tdma, TEGRA_APBDMA_IRQ_MASK_SET, 0xFFFFFFFFul); | 1280 | tdma_write(tdma, TEGRA_APBDMA_IRQ_MASK_SET, 0xFFFFFFFFul); |
1267 | 1281 | ||
1282 | clk_disable_unprepare(tdma->dma_clk); | ||
1283 | |||
1268 | INIT_LIST_HEAD(&tdma->dma_dev.channels); | 1284 | INIT_LIST_HEAD(&tdma->dma_dev.channels); |
1269 | for (i = 0; i < cdata->nr_channels; i++) { | 1285 | for (i = 0; i < cdata->nr_channels; i++) { |
1270 | struct tegra_dma_channel *tdc = &tdma->channels[i]; | 1286 | struct tegra_dma_channel *tdc = &tdma->channels[i]; |