@@ -35,6 +35,7 @@
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/delay.h>
+#include <linux/pm_runtime.h>
#include <asm/system.h>
#include <mach/hardware.h>
@@ -59,6 +60,7 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
static struct omap_system_dma_plat_info *p;
static struct omap_dma_dev_attr *d;
+static struct device *dev;
static int enable_1510_mode;
static u32 errata;
@@ -676,6 +678,7 @@ int omap_request_dma(int dev_id, const char *dev_name,
unsigned long flags;
struct omap_dma_lch *chan;
+ pm_runtime_get_sync(dev);
spin_lock_irqsave(&dma_chan_lock, flags);
for (ch = 0; ch < dma_chan_count; ch++) {
if (free_ch == -1 && dma_chan[ch].dev_id == -1) {
@@ -686,6 +689,7 @@ int omap_request_dma(int dev_id, const char *dev_name,
}
if (free_ch == -1) {
spin_unlock_irqrestore(&dma_chan_lock, flags);
+ pm_runtime_put_autosuspend(dev);
return -EBUSY;
}
chan = dma_chan + free_ch;
@@ -743,6 +747,7 @@ int omap_request_dma(int dev_id, const char *dev_name,
}
*dma_ch_out = free_ch;
+ pm_runtime_put_autosuspend(dev);
return 0;
}
@@ -871,6 +876,8 @@ void omap_start_dma(int lch)
{
u32 l;
+ pm_runtime_get_sync(dev);
+
/*
* The CPC/CDAC register needs to be initialized to zero
* before starting dma transfer.
@@ -1805,6 +1812,8 @@ static int omap1_dma_handle_ch(int ch)
if (likely(dma_chan[ch].callback != NULL))
dma_chan[ch].callback(ch, csr, dma_chan[ch].data);
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_put_autosuspend(dev);
return 1;
}
@@ -1899,6 +1908,8 @@ static int omap2_dma_handle_ch(int ch)
if (likely(dma_chan[ch].callback != NULL))
dma_chan[ch].callback(ch, status, dma_chan[ch].data);
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_put_autosuspend(dev);
return 0;
}
@@ -1978,6 +1989,7 @@ static int __devinit omap_system_dma_probe(struct platform_device *pdev)
return -EINVAL;
}
+ dev = &pdev->dev;
d = p->dma_attr;
errata = p->errata;
@@ -1999,6 +2011,11 @@ static int __devinit omap_system_dma_probe(struct platform_device *pdev)
}
}
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_set_autosuspend_delay(dev, 1000);
+ pm_runtime_enable(dev);
+ pm_runtime_get_sync(dev);
+
spin_lock_init(&dma_chan_lock);
for (ch = 0; ch < dma_chan_count; ch++) {
omap_clear_dma(ch);
@@ -2064,6 +2081,16 @@ static int __devinit omap_system_dma_probe(struct platform_device *pdev)
dma_chan[1].dev_id = 1;
}
p->show_dma_caps();
+
+ /*
+ * Note: If dma channels are reserved through boot paramters,
+ * then dma device is always enabled.
+ */
+ if (omap_dma_reserve_channels)
+ pm_runtime_get(dev);
+
+ pm_runtime_put_autosuspend(dev);
+
return 0;
exit_dma_irq_fail: