summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2011-04-18 16:35:41 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2011-04-26 15:56:18 -0700
commit89aa98edfb250b54549580a6b0261a23af3d7c0c (patch)
tree697162362c6f98a278de324f86397e778a1fb314
parent5047a0f6d0b6c1c44d0f692531396f1c5b541c74 (diff)
arm: tegra: dma: Adding client name with dma allocation.
By changing the dma allocation API to take the client name, it is easy to track who is allocated the DMA channels when we run out of the DMA channels. Original-Change-Id: I016011cfd74089fed0da1bc0f121800017ce124a Reviewed-on: http://git-master/r/28031 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com> Change-Id: I048bcb87f95ee6d8ad2fdce993a1758dc5071666
-rw-r--r--arch/arm/mach-tegra/apbio.c2
-rw-r--r--arch/arm/mach-tegra/dma.c24
-rw-r--r--arch/arm/mach-tegra/include/mach/dma.h2
-rw-r--r--arch/arm/mach-tegra/spi_tegra_slave.c6
-rw-r--r--arch/arm/mach-tegra/tegra_i2s_audio.c6
-rw-r--r--arch/arm/mach-tegra/tegra_spdif_audio.c3
-rw-r--r--drivers/serial/tegra_hsuart.c6
-rw-r--r--drivers/spi/spi_slave_tegra.c6
-rw-r--r--drivers/spi/spi_tegra.c6
-rw-r--r--sound/soc/tegra/tegra_pcm.c3
10 files changed, 49 insertions, 15 deletions
diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
index 2d83ae3a51c2..7a2df58929fb 100644
--- a/arch/arm/mach-tegra/apbio.c
+++ b/arch/arm/mach-tegra/apbio.c
@@ -138,7 +138,7 @@ void tegra_init_apb_dma(void)
{
#ifdef CONFIG_TEGRA_SYSTEM_DMA
tegra_apb_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT |
- TEGRA_DMA_SHARED);
+ TEGRA_DMA_SHARED, "apbio");
if (!tegra_apb_dma) {
pr_err("%s: can not allocate dma channel\n", __func__);
return;
diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c
index e534c1867e76..15e909c3e8dc 100644
--- a/arch/arm/mach-tegra/dma.c
+++ b/arch/arm/mach-tegra/dma.c
@@ -122,6 +122,7 @@ struct tegra_dma_channel {
int id;
spinlock_t lock;
char name[TEGRA_DMA_NAME_SIZE];
+ char client_name[TEGRA_DMA_NAME_SIZE];
void __iomem *addr;
int mode;
int irq;
@@ -445,10 +446,23 @@ int tegra_dma_enqueue_req(struct tegra_dma_channel *ch,
}
EXPORT_SYMBOL(tegra_dma_enqueue_req);
-struct tegra_dma_channel *tegra_dma_allocate_channel(int mode)
+static void tegra_dma_dump_channel_usage(void)
+{
+ int i;
+ pr_info("DMA channel allocation dump:\n");
+ for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) {
+ struct tegra_dma_channel *ch = &dma_channels[i];
+ pr_warn("dma %d used by %s\n", i, ch->client_name);
+ }
+ return;
+}
+
+struct tegra_dma_channel *tegra_dma_allocate_channel(int mode,
+ const char namefmt [ ],...)
{
int channel;
struct tegra_dma_channel *ch = NULL;
+ va_list args;
mutex_lock(&tegra_dma_lock);
@@ -461,12 +475,17 @@ struct tegra_dma_channel *tegra_dma_allocate_channel(int mode)
if (channel >= ARRAY_SIZE(dma_channels)) {
pr_err("%s: failed to allocate a DMA channel",
__func__);
+ tegra_dma_dump_channel_usage();
goto out;
}
}
__set_bit(channel, channel_usage);
ch = &dma_channels[channel];
ch->mode = mode;
+ va_start(args, namefmt);
+ vsnprintf(ch->client_name, sizeof(ch->client_name),
+ namefmt, args);
+ va_end(args);
out:
mutex_unlock(&tegra_dma_lock);
@@ -481,6 +500,7 @@ void tegra_dma_free_channel(struct tegra_dma_channel *ch)
tegra_dma_cancel(ch);
mutex_lock(&tegra_dma_lock);
__clear_bit(ch->id, channel_usage);
+ memset(ch->client_name, 0, sizeof(ch->client_name));
mutex_unlock(&tegra_dma_lock);
}
EXPORT_SYMBOL(tegra_dma_free_channel);
@@ -910,6 +930,8 @@ int __init tegra_dma_init(void)
ch->id = i;
snprintf(ch->name, TEGRA_DMA_NAME_SIZE, "dma_channel_%d", i);
+ memset(ch->client_name, 0, sizeof(ch->client_name));
+
ch->addr = IO_ADDRESS(TEGRA_APB_DMA_CH0_BASE +
TEGRA_APB_DMA_CH0_SIZE * i);
diff --git a/arch/arm/mach-tegra/include/mach/dma.h b/arch/arm/mach-tegra/include/mach/dma.h
index a1a73d96f1e4..42084b697b7f 100644
--- a/arch/arm/mach-tegra/include/mach/dma.h
+++ b/arch/arm/mach-tegra/include/mach/dma.h
@@ -161,7 +161,7 @@ int tegra_dma_get_transfer_count(struct tegra_dma_channel *ch,
bool tegra_dma_is_empty(struct tegra_dma_channel *ch);
bool tegra_dma_is_stopped(struct tegra_dma_channel *ch);
-struct tegra_dma_channel *tegra_dma_allocate_channel(int mode);
+struct tegra_dma_channel *tegra_dma_allocate_channel(int mode, const char namefmt [ ],...);
void tegra_dma_free_channel(struct tegra_dma_channel *ch);
int tegra_dma_cancel(struct tegra_dma_channel *ch);
diff --git a/arch/arm/mach-tegra/spi_tegra_slave.c b/arch/arm/mach-tegra/spi_tegra_slave.c
index c4b7ab1ee400..6086c5598860 100644
--- a/arch/arm/mach-tegra/spi_tegra_slave.c
+++ b/arch/arm/mach-tegra/spi_tegra_slave.c
@@ -757,7 +757,8 @@ static int __init spi_tegra_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&tspi->queue);
- tspi->rx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT);
+ tspi->rx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT,
+ "spi_rx_%d", pdev->id);
if (!tspi->rx_dma) {
dev_err(&pdev->dev, "can not allocate rx dma channel\n");
ret = -ENODEV;
@@ -785,7 +786,8 @@ static int __init spi_tegra_probe(struct platform_device *pdev)
tspi->rx_dma_req.req_sel = spi_tegra_req_sels[pdev->id];
tspi->rx_dma_req.dev = tspi;
- tspi->tx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT);
+ tspi->tx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT,
+ "spi_tx_%d", pdev->id);
if (IS_ERR(tspi->tx_dma)) {
dev_err(&pdev->dev, "can not allocate tx dma channel\n");
ret = PTR_ERR(tspi->tx_dma);
diff --git a/arch/arm/mach-tegra/tegra_i2s_audio.c b/arch/arm/mach-tegra/tegra_i2s_audio.c
index 16897bb79e63..f5a4a8bffba6 100644
--- a/arch/arm/mach-tegra/tegra_i2s_audio.c
+++ b/arch/arm/mach-tegra/tegra_i2s_audio.c
@@ -735,7 +735,8 @@ static int setup_dma(struct audio_driver_state *ads, int mask)
ads->out.dma_req[i].source_addr = ads->out.buf_phy[i];
}
ads->out.dma_chan = tegra_dma_allocate_channel(
- TEGRA_DMA_MODE_CONTINUOUS_SINGLE);
+ TEGRA_DMA_MODE_CONTINUOUS_SINGLE,
+ "i2s_tx_req_%d", ads->dma_req_sel);
if (!ads->out.dma_chan) {
pr_err("%s: error alloc output DMA channel: %ld\n",
__func__, PTR_ERR(ads->out.dma_chan));
@@ -756,7 +757,8 @@ static int setup_dma(struct audio_driver_state *ads, int mask)
ads->in.dma_req[i].dest_addr = ads->in.buf_phy[i];
}
ads->in.dma_chan = tegra_dma_allocate_channel(
- TEGRA_DMA_MODE_CONTINUOUS_SINGLE);
+ TEGRA_DMA_MODE_CONTINUOUS_SINGLE,
+ "i2s_rx_req_%d", ads->dma_req_sel);
if (!ads->in.dma_chan) {
pr_err("%s: error allocating input DMA channel: %ld\n",
__func__, PTR_ERR(ads->in.dma_chan));
diff --git a/arch/arm/mach-tegra/tegra_spdif_audio.c b/arch/arm/mach-tegra/tegra_spdif_audio.c
index 555d347d1581..8044c237587c 100644
--- a/arch/arm/mach-tegra/tegra_spdif_audio.c
+++ b/arch/arm/mach-tegra/tegra_spdif_audio.c
@@ -350,7 +350,8 @@ static int setup_dma(struct audio_driver_state *ads)
ads->out.dma_req[i].source_addr = ads->out.buf_phy[i];
}
ads->out.dma_chan =
- tegra_dma_allocate_channel(TEGRA_DMA_MODE_CONTINUOUS_SINGLE);
+ tegra_dma_allocate_channel(TEGRA_DMA_MODE_CONTINUOUS_SINGLE,
+ "spdif_tx_req_%d", ads->dma_req_sel);
if (!ads->out.dma_chan) {
pr_err("%s: error alloc output DMA channel: %ld\n",
__func__, PTR_ERR(ads->out.dma_chan));
diff --git a/drivers/serial/tegra_hsuart.c b/drivers/serial/tegra_hsuart.c
index 4a303ce32a80..c45833547bb6 100644
--- a/drivers/serial/tegra_hsuart.c
+++ b/drivers/serial/tegra_hsuart.c
@@ -739,7 +739,8 @@ static int tegra_uart_init_rx_dma(struct tegra_uart_port *t)
dma_addr_t rx_dma_phys;
void *rx_dma_virt;
- t->rx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_CONTINUOUS);
+ t->rx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_CONTINUOUS,
+ "uart_rx_%d", t->uport.line);
if (!t->rx_dma) {
dev_err(t->uport.dev, "%s: failed to allocate RX DMA.\n", __func__);
return -ENODEV;
@@ -783,7 +784,8 @@ static int tegra_startup(struct uart_port *u)
t->use_tx_dma = false;
if (!TX_FORCE_PIO) {
- t->tx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT);
+ t->tx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT,
+ "uart_tx_%d", u->line);
if (t->tx_dma)
t->use_tx_dma = true;
else
diff --git a/drivers/spi/spi_slave_tegra.c b/drivers/spi/spi_slave_tegra.c
index 568c987ff744..c95c852d94bb 100644
--- a/drivers/spi/spi_slave_tegra.c
+++ b/drivers/spi/spi_slave_tegra.c
@@ -1097,7 +1097,8 @@ static int __init spi_tegra_probe(struct platform_device *pdev)
init_completion(&tspi->rx_dma_complete);
- tspi->rx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT);
+ tspi->rx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT,
+ "spi_rx_%d", pdev->id);
if (!tspi->rx_dma) {
dev_err(&pdev->dev, "can not allocate rx dma channel\n");
ret = -ENODEV;
@@ -1125,7 +1126,8 @@ static int __init spi_tegra_probe(struct platform_device *pdev)
tspi->rx_dma_req.req_sel = spi_tegra_req_sels[pdev->id];
tspi->rx_dma_req.dev = tspi;
- tspi->tx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT);
+ tspi->tx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT,
+ "spi_tx_%d", pdev->id);
if (!tspi->tx_dma) {
dev_err(&pdev->dev, "can not allocate tx dma channel\n");
ret = -ENODEV;
diff --git a/drivers/spi/spi_tegra.c b/drivers/spi/spi_tegra.c
index eef541ce69d2..bb169ca4dd61 100644
--- a/drivers/spi/spi_tegra.c
+++ b/drivers/spi/spi_tegra.c
@@ -1126,7 +1126,8 @@ static int __init spi_tegra_probe(struct platform_device *pdev)
init_completion(&tspi->rx_dma_complete);
- tspi->rx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT);
+ tspi->rx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT,
+ "spi_rx_%d", pdev->id);
if (!tspi->rx_dma) {
dev_err(&pdev->dev, "can not allocate rx dma channel\n");
ret = -ENODEV;
@@ -1154,7 +1155,8 @@ static int __init spi_tegra_probe(struct platform_device *pdev)
tspi->rx_dma_req.req_sel = spi_tegra_req_sels[pdev->id];
tspi->rx_dma_req.dev = tspi;
- tspi->tx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT);
+ tspi->tx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT,
+ "spi_tx_%d", pdev->id);
if (!tspi->tx_dma) {
dev_err(&pdev->dev, "can not allocate tx dma channel\n");
ret = -ENODEV;
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index d75848741038..369e50743ace 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -270,7 +270,8 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream)
}
}
- prtd->dma_chan = tegra_dma_allocate_channel(TEGRA_DMA_MODE_CONTINUOUS_DOUBLE);
+ prtd->dma_chan = tegra_dma_allocate_channel(
+ TEGRA_DMA_MODE_CONTINUOUS_DOUBLE, "pcm");
if (prtd->dma_chan == NULL) {
pr_err("%s: could not allocate DMA channel for PCM:\n",
__func__);