* [PATCH v7] ARM: omap: edma: add suspend suspend/resume hooks
@ 2013-11-27 13:56 Daniel Mack
2013-11-29 8:08 ` Brian Murphy
0 siblings, 1 reply; 3+ messages in thread
From: Daniel Mack @ 2013-11-27 13:56 UTC (permalink / raw)
To: nsekhar, linux-omap, joelf, gururaja.hebbar, balajitk
Cc: s.neumann, Russ.Dill, nm, vaibhav.bedia, linux-arm-kernel,
khilman, Daniel Mack
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>
---
v6 -> v7:
* Addressed comments from Sekhar Nori:
* pm_runtime_get_sync() returns negative errors, so do not use
IS_ERR_VALUE()
* Several style fixes
arch/arm/common/edma.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 92 insertions(+), 3 deletions(-)
diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c
index 41bca32..dece66d 100644
--- a/arch/arm/common/edma.c
+++ b/arch/arm/common/edma.c
@@ -239,6 +239,8 @@ struct edma {
/* list of channels with no even trigger; terminated by "-1" */
const s8 *noevent;
+ struct edma_soc_info *info;
+
/* The edma_inuse bit for each PaRAM slot is clear unless the
* channel is in use ... by ARM or DSP, for QDMA, or whatever.
*/
@@ -290,13 +292,13 @@ static void map_dmach_queue(unsigned ctlr, unsigned ch_no,
~(0x7 << bit), queue_no << bit);
}
-static void __init map_queue_tc(unsigned ctlr, int queue_no, int tc_no)
+static void map_queue_tc(unsigned ctlr, int queue_no, int tc_no)
{
int bit = queue_no * 4;
edma_modify(ctlr, EDMA_QUETCMAP, ~(0x7 << bit), ((tc_no & 0x7) << bit));
}
-static void __init assign_priority_to_queue(unsigned ctlr, int queue_no,
+static void assign_priority_to_queue(unsigned ctlr, int queue_no,
int priority)
{
int bit = queue_no * 4;
@@ -315,7 +317,7 @@ static void __init assign_priority_to_queue(unsigned ctlr, int queue_no,
* included in that particular EDMA variant (Eg : dm646x)
*
*/
-static void __init map_dmach_param(unsigned ctlr)
+static void map_dmach_param(unsigned ctlr)
{
int i;
for (i = 0; i < EDMA_MAX_DMACH; i++)
@@ -1785,15 +1787,102 @@ static int edma_probe(struct platform_device *pdev)
edma_write_array2(j, EDMA_DRAE, i, 1, 0x0);
edma_write_array(j, EDMA_QRAE, i, 0x0);
}
+ edma_cc[j]->info = info[j];
arch_num_cc++;
}
return 0;
}
+static int edma_pm_suspend(struct device *dev)
+{
+ int j, r;
+
+ r = pm_runtime_get_sync(dev);
+ if (r < 0) {
+ dev_err(dev, "%s: get_sync returned %d\n", __func__, r);
+ return r;
+ }
+
+ for (j = 0; j < arch_num_cc; j++) {
+ struct edma *ecc = edma_cc[j];
+
+ disable_irq(ecc->irq_res_start);
+ disable_irq(ecc->irq_res_end);
+ }
+
+ pm_runtime_put_sync(dev);
+
+ return 0;
+}
+
+static int edma_pm_resume(struct device *dev)
+{
+ int i, j, r;
+
+ r = pm_runtime_get_sync(dev);
+ if (r < 0) {
+ dev_err(dev, "%s: get_sync returned %d\n", __func__, r);
+ return r;
+ }
+
+ for (j = 0; j < arch_num_cc; j++) {
+ struct edma *cc = edma_cc[j];
+
+ s8 (*queue_priority_mapping)[2];
+ s8 (*queue_tc_mapping)[2];
+
+ queue_tc_mapping = cc->info->queue_tc_mapping;
+ queue_priority_mapping = cc->info->queue_priority_mapping;
+
+ /* Event queue to TC mapping */
+ for (i = 0; queue_tc_mapping[i][0] != -1; i++)
+ map_queue_tc(j, queue_tc_mapping[i][0],
+ queue_tc_mapping[i][1]);
+
+ /* Event queue priority mapping */
+ for (i = 0; queue_priority_mapping[i][0] != -1; i++)
+ assign_priority_to_queue(j,
+ queue_priority_mapping[i][0],
+ queue_priority_mapping[i][1]);
+
+ /*
+ * Map the channel to param entry if channel mapping logic
+ * exist
+ */
+ if (edma_read(j, EDMA_CCCFG) & CHMAP_EXIST)
+ map_dmach_param(j);
+
+ for (i = 0; i < cc->num_channels; i++) {
+ if (test_bit(i, cc->edma_inuse)) {
+ /* ensure access through shadow region 0 */
+ edma_or_array2(j, EDMA_DRAE, 0, i >> 5,
+ BIT(i & 0x1f));
+
+ setup_dma_interrupt(i,
+ cc->intr_data[i].callback,
+ cc->intr_data[i].data);
+ }
+ }
+
+ enable_irq(cc->irq_res_start);
+ enable_irq(cc->irq_res_end);
+ }
+
+ pm_runtime_put_sync(dev);
+
+ return 0;
+}
+
+static const struct dev_pm_ops edma_pm_ops = {
+ .suspend_late = edma_pm_suspend,
+ .resume_early = edma_pm_resume,
+};
+
static struct platform_driver edma_driver = {
.driver = {
.name = "edma",
+ .pm = &edma_pm_ops,
.of_match_table = edma_of_ids,
},
.probe = edma_probe,
--
1.8.4.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v7] ARM: omap: edma: add suspend suspend/resume hooks
2013-11-27 13:56 [PATCH v7] ARM: omap: edma: add suspend suspend/resume hooks Daniel Mack
@ 2013-11-29 8:08 ` Brian Murphy
2013-11-29 8:57 ` Daniel Mack
0 siblings, 1 reply; 3+ messages in thread
From: Brian Murphy @ 2013-11-29 8:08 UTC (permalink / raw)
To: Daniel Mack; +Cc: linux-omap
On 11/27/2013 02:56 PM, Daniel Mack wrote:
> This patch makes the edma driver resume correctly after suspend. Tested
> on an AM33xx platform with cyclic audio streams and omap_hsmmc.
Can I ask which git this patch is relative to? There is no
suspend/resume support for AM33xx in Linus Torvalds kernel as far as I
can see.
/Brian
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v7] ARM: omap: edma: add suspend suspend/resume hooks
2013-11-29 8:08 ` Brian Murphy
@ 2013-11-29 8:57 ` Daniel Mack
0 siblings, 0 replies; 3+ messages in thread
From: Daniel Mack @ 2013-11-29 8:57 UTC (permalink / raw)
To: Brian Murphy; +Cc: linux-omap
On 11/29/2013 09:08 AM, Brian Murphy wrote:
> On 11/27/2013 02:56 PM, Daniel Mack wrote:
>> This patch makes the edma driver resume correctly after suspend. Tested
>> on an AM33xx platform with cyclic audio streams and omap_hsmmc.
>
> Can I ask which git this patch is relative to? There is no
> suspend/resume support for AM33xx in Linus Torvalds kernel as far as I
> can see.
I am based on 3.13-rc1 with some patches from Suman Anna, Vaibhav Bedia
and Dave Gerlach that have been posted on arm-linux some month ago.
This patch can be merged independently as it has no dependency on those.
We already did the same for cppi41, musb, mcasp and some other drivers,
which gradually learn support for suspend in mainline now. Only the core
bits are missing, but I'm sure someone from TI is pushing them forward :)
Daniel
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-11-29 8:57 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-27 13:56 [PATCH v7] ARM: omap: edma: add suspend suspend/resume hooks Daniel Mack
2013-11-29 8:08 ` Brian Murphy
2013-11-29 8:57 ` Daniel Mack
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).