aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Mack <zonque@gmail.com>2014-08-26 04:52:53 -0400
committerSekhar Nori <nsekhar@ti.com>2014-11-18 10:56:02 -0500
commita2b1175131ccb5d4a15456f4f31836356abbce09 (patch)
tree4e5feb3d5f95c01dfcf21e8184e810fd7a5aea9c
parentf114040e3ea6e07372334ade75d1ee0775c355e1 (diff)
ARM: common: edma: add suspend resume hook
This patch makes the edma driver resume correctly after suspend. Tested on an AM33xx platform with cyclic audio streams and omap_hsmmc. All information can be reconstructed by already known runtime information. As we now use some functions that were previously only used from __init context, annotations had to be dropped. [nm@ti.com: added error handling for runtime + suspend_late/early_resume] Signed-off-by: Nishanth Menon <nm@ti.com> Signed-off-by: Daniel Mack <zonque@gmail.com> Tested-by: Joel Fernandes <joelf@ti.com> Acked-by: Joel Fernandes <joelf@ti.com> [nsekhar@ti.com: remove unneeded pm_runtime_get_sync() from resume] Signed-off-by: Sekhar Nori <nsekhar@ti.com>
-rw-r--r--arch/arm/common/edma.c52
1 files changed, 50 insertions, 2 deletions
diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c
index d86771abbf57..79de6a23047b 100644
--- a/arch/arm/common/edma.c
+++ b/arch/arm/common/edma.c
@@ -244,6 +244,8 @@ struct edma {
244 /* list of channels with no even trigger; terminated by "-1" */ 244 /* list of channels with no even trigger; terminated by "-1" */
245 const s8 *noevent; 245 const s8 *noevent;
246 246
247 struct edma_soc_info *info;
248
247 /* The edma_inuse bit for each PaRAM slot is clear unless the 249 /* The edma_inuse bit for each PaRAM slot is clear unless the
248 * channel is in use ... by ARM or DSP, for QDMA, or whatever. 250 * channel is in use ... by ARM or DSP, for QDMA, or whatever.
249 */ 251 */
@@ -295,7 +297,7 @@ static void map_dmach_queue(unsigned ctlr, unsigned ch_no,
295 ~(0x7 << bit), queue_no << bit); 297 ~(0x7 << bit), queue_no << bit);
296} 298}
297 299
298static void __init assign_priority_to_queue(unsigned ctlr, int queue_no, 300static void assign_priority_to_queue(unsigned ctlr, int queue_no,
299 int priority) 301 int priority)
300{ 302{
301 int bit = queue_no * 4; 303 int bit = queue_no * 4;
@@ -314,7 +316,7 @@ static void __init assign_priority_to_queue(unsigned ctlr, int queue_no,
314 * included in that particular EDMA variant (Eg : dm646x) 316 * included in that particular EDMA variant (Eg : dm646x)
315 * 317 *
316 */ 318 */
317static void __init map_dmach_param(unsigned ctlr) 319static void map_dmach_param(unsigned ctlr)
318{ 320{
319 int i; 321 int i;
320 for (i = 0; i < EDMA_MAX_DMACH; i++) 322 for (i = 0; i < EDMA_MAX_DMACH; i++)
@@ -1792,15 +1794,61 @@ static int edma_probe(struct platform_device *pdev)
1792 edma_write_array2(j, EDMA_DRAE, i, 1, 0x0); 1794 edma_write_array2(j, EDMA_DRAE, i, 1, 0x0);
1793 edma_write_array(j, EDMA_QRAE, i, 0x0); 1795 edma_write_array(j, EDMA_QRAE, i, 0x0);
1794 } 1796 }
1797 edma_cc[j]->info = info[j];
1795 arch_num_cc++; 1798 arch_num_cc++;
1796 } 1799 }
1797 1800
1798 return 0; 1801 return 0;
1799} 1802}
1800 1803
1804static int edma_pm_resume(struct device *dev)
1805{
1806 int i, j;
1807
1808 for (j = 0; j < arch_num_cc; j++) {
1809 struct edma *cc = edma_cc[j];
1810
1811 s8 (*queue_priority_mapping)[2];
1812
1813 queue_priority_mapping = cc->info->queue_priority_mapping;
1814
1815 /* Event queue priority mapping */
1816 for (i = 0; queue_priority_mapping[i][0] != -1; i++)
1817 assign_priority_to_queue(j,
1818 queue_priority_mapping[i][0],
1819 queue_priority_mapping[i][1]);
1820
1821 /*
1822 * Map the channel to param entry if channel mapping logic
1823 * exist
1824 */
1825 if (edma_read(j, EDMA_CCCFG) & CHMAP_EXIST)
1826 map_dmach_param(j);
1827
1828 for (i = 0; i < cc->num_channels; i++) {
1829 if (test_bit(i, cc->edma_inuse)) {
1830 /* ensure access through shadow region 0 */
1831 edma_or_array2(j, EDMA_DRAE, 0, i >> 5,
1832 BIT(i & 0x1f));
1833
1834 setup_dma_interrupt(i,
1835 cc->intr_data[i].callback,
1836 cc->intr_data[i].data);
1837 }
1838 }
1839 }
1840
1841 return 0;
1842}
1843
1844static const struct dev_pm_ops edma_pm_ops = {
1845 SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, edma_pm_resume)
1846};
1847
1801static struct platform_driver edma_driver = { 1848static struct platform_driver edma_driver = {
1802 .driver = { 1849 .driver = {
1803 .name = "edma", 1850 .name = "edma",
1851 .pm = &edma_pm_ops,
1804 .of_match_table = edma_of_ids, 1852 .of_match_table = edma_of_ids,
1805 }, 1853 },
1806 .probe = edma_probe, 1854 .probe = edma_probe,