[v2] OMAP: PM: DMA: Enable runtime pm
diff mbox

Message ID 1297082286-8449-1-git-send-email-manjugk@ti.com
State Changes Requested
Delegated to: Kevin Hilman
Headers show

Commit Message

manjugk manjugk Feb. 7, 2011, 12:38 p.m. UTC
None

Patch
diff mbox

diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 2ec3b5d..6bfe25c 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -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: