From e327e21fb2099119c21e0b9ff7ee0847c19a6735 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sun, 22 Sep 2013 16:50:00 +0200 Subject: dma: cppi41: pass around device instead of platform_device Instead of passing around struct plafform_device, use struct device and save one level of dereferencing. This affects the following functions: * cppi41_add_chans * purge_descs * deinit_cpii41 * init_descs * init_cppi41 * cppi_glue_infos It's just a cosmetic cleanup that makes the code more readable. Signed-off-by: Daniel Mack Signed-off-by: Vinod Koul --- drivers/dma/cppi41.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers/dma/cppi41.c') diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c index 7c82b92f9b1..53d1d311557 100644 --- a/drivers/dma/cppi41.c +++ b/drivers/dma/cppi41.c @@ -674,14 +674,14 @@ static void cleanup_chans(struct cppi41_dd *cdd) } } -static int cppi41_add_chans(struct platform_device *pdev, struct cppi41_dd *cdd) +static int cppi41_add_chans(struct device *dev, struct cppi41_dd *cdd) { struct cppi41_channel *cchan; int i; int ret; u32 n_chans; - ret = of_property_read_u32(pdev->dev.of_node, "#dma-channels", + ret = of_property_read_u32(dev->of_node, "#dma-channels", &n_chans); if (ret) return ret; @@ -719,7 +719,7 @@ err: return -ENOMEM; } -static void purge_descs(struct platform_device *pdev, struct cppi41_dd *cdd) +static void purge_descs(struct device *dev, struct cppi41_dd *cdd) { unsigned int mem_decs; int i; @@ -731,7 +731,7 @@ static void purge_descs(struct platform_device *pdev, struct cppi41_dd *cdd) cppi_writel(0, cdd->qmgr_mem + QMGR_MEMBASE(i)); cppi_writel(0, cdd->qmgr_mem + QMGR_MEMCTRL(i)); - dma_free_coherent(&pdev->dev, mem_decs, cdd->cd, + dma_free_coherent(dev, mem_decs, cdd->cd, cdd->descs_phys); } } @@ -741,19 +741,19 @@ static void disable_sched(struct cppi41_dd *cdd) cppi_writel(0, cdd->sched_mem + DMA_SCHED_CTRL); } -static void deinit_cpii41(struct platform_device *pdev, struct cppi41_dd *cdd) +static void deinit_cpii41(struct device *dev, struct cppi41_dd *cdd) { disable_sched(cdd); - purge_descs(pdev, cdd); + purge_descs(dev, cdd); cppi_writel(0, cdd->qmgr_mem + QMGR_LRAM0_BASE); cppi_writel(0, cdd->qmgr_mem + QMGR_LRAM0_BASE); - dma_free_coherent(&pdev->dev, QMGR_SCRATCH_SIZE, cdd->qmgr_scratch, + dma_free_coherent(dev, QMGR_SCRATCH_SIZE, cdd->qmgr_scratch, cdd->scratch_phys); } -static int init_descs(struct platform_device *pdev, struct cppi41_dd *cdd) +static int init_descs(struct device *dev, struct cppi41_dd *cdd) { unsigned int desc_size; unsigned int mem_decs; @@ -777,7 +777,7 @@ static int init_descs(struct platform_device *pdev, struct cppi41_dd *cdd) reg |= ilog2(ALLOC_DECS_NUM) - 5; BUILD_BUG_ON(DESCS_AREAS != 1); - cdd->cd = dma_alloc_coherent(&pdev->dev, mem_decs, + cdd->cd = dma_alloc_coherent(dev, mem_decs, &cdd->descs_phys, GFP_KERNEL); if (!cdd->cd) return -ENOMEM; @@ -813,12 +813,12 @@ static void init_sched(struct cppi41_dd *cdd) cppi_writel(reg, cdd->sched_mem + DMA_SCHED_CTRL); } -static int init_cppi41(struct platform_device *pdev, struct cppi41_dd *cdd) +static int init_cppi41(struct device *dev, struct cppi41_dd *cdd) { int ret; BUILD_BUG_ON(QMGR_SCRATCH_SIZE > ((1 << 14) - 1)); - cdd->qmgr_scratch = dma_alloc_coherent(&pdev->dev, QMGR_SCRATCH_SIZE, + cdd->qmgr_scratch = dma_alloc_coherent(dev, QMGR_SCRATCH_SIZE, &cdd->scratch_phys, GFP_KERNEL); if (!cdd->qmgr_scratch) return -ENOMEM; @@ -827,7 +827,7 @@ static int init_cppi41(struct platform_device *pdev, struct cppi41_dd *cdd) cppi_writel(QMGR_SCRATCH_SIZE, cdd->qmgr_mem + QMGR_LRAM_SIZE); cppi_writel(0, cdd->qmgr_mem + QMGR_LRAM1_BASE); - ret = init_descs(pdev, cdd); + ret = init_descs(dev, cdd); if (ret) goto err_td; @@ -835,7 +835,7 @@ static int init_cppi41(struct platform_device *pdev, struct cppi41_dd *cdd) init_sched(cdd); return 0; err_td: - deinit_cpii41(pdev, cdd); + deinit_cpii41(dev, cdd); return ret; } @@ -914,11 +914,11 @@ static const struct of_device_id cppi41_dma_ids[] = { }; MODULE_DEVICE_TABLE(of, cppi41_dma_ids); -static const struct cppi_glue_infos *get_glue_info(struct platform_device *pdev) +static const struct cppi_glue_infos *get_glue_info(struct device *dev) { const struct of_device_id *of_id; - of_id = of_match_node(cppi41_dma_ids, pdev->dev.of_node); + of_id = of_match_node(cppi41_dma_ids, dev->of_node); if (!of_id) return NULL; return of_id->data; @@ -931,7 +931,7 @@ static int cppi41_dma_probe(struct platform_device *pdev) int irq; int ret; - glue_info = get_glue_info(pdev); + glue_info = get_glue_info(&pdev->dev); if (!glue_info) return -EINVAL; @@ -970,11 +970,11 @@ static int cppi41_dma_probe(struct platform_device *pdev) cdd->queues_tx = glue_info->queues_tx; cdd->td_queue = glue_info->td_queue; - ret = init_cppi41(pdev, cdd); + ret = init_cppi41(&pdev->dev, cdd); if (ret) goto err_init_cppi; - ret = cppi41_add_chans(pdev, cdd); + ret = cppi41_add_chans(&pdev->dev, cdd); if (ret) goto err_chans; @@ -1009,7 +1009,7 @@ err_irq: cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); cleanup_chans(cdd); err_chans: - deinit_cpii41(pdev, cdd); + deinit_cpii41(&pdev->dev, cdd); err_init_cppi: pm_runtime_put(&pdev->dev); err_get_sync: @@ -1033,7 +1033,7 @@ static int cppi41_dma_remove(struct platform_device *pdev) cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); free_irq(cdd->irq, cdd); cleanup_chans(cdd); - deinit_cpii41(pdev, cdd); + deinit_cpii41(&pdev->dev, cdd); iounmap(cdd->usbss_mem); iounmap(cdd->ctrl_mem); iounmap(cdd->sched_mem); -- cgit v1.2.3-70-g09d2 From b46ce4d01e1c6052809b13340cc8e62d361f7306 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sun, 22 Sep 2013 16:50:01 +0200 Subject: dma: cppi41: s/deinit_cpii41/deinit_cppi41/ Fix a misspelled function name. Signed-off-by: Daniel Mack Signed-off-by: Vinod Koul --- drivers/dma/cppi41.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/dma/cppi41.c') diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c index 53d1d311557..5469a15c7f8 100644 --- a/drivers/dma/cppi41.c +++ b/drivers/dma/cppi41.c @@ -741,7 +741,7 @@ static void disable_sched(struct cppi41_dd *cdd) cppi_writel(0, cdd->sched_mem + DMA_SCHED_CTRL); } -static void deinit_cpii41(struct device *dev, struct cppi41_dd *cdd) +static void deinit_cppi41(struct device *dev, struct cppi41_dd *cdd) { disable_sched(cdd); @@ -835,7 +835,7 @@ static int init_cppi41(struct device *dev, struct cppi41_dd *cdd) init_sched(cdd); return 0; err_td: - deinit_cpii41(dev, cdd); + deinit_cppi41(dev, cdd); return ret; } @@ -1009,7 +1009,7 @@ err_irq: cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); cleanup_chans(cdd); err_chans: - deinit_cpii41(&pdev->dev, cdd); + deinit_cppi41(&pdev->dev, cdd); err_init_cppi: pm_runtime_put(&pdev->dev); err_get_sync: @@ -1033,7 +1033,7 @@ static int cppi41_dma_remove(struct platform_device *pdev) cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); free_irq(cdd->irq, cdd); cleanup_chans(cdd); - deinit_cpii41(&pdev->dev, cdd); + deinit_cppi41(&pdev->dev, cdd); iounmap(cdd->usbss_mem); iounmap(cdd->ctrl_mem); iounmap(cdd->sched_mem); -- cgit v1.2.3-70-g09d2 From 717d818169e5d5672fb81bc7357e9bb265d1e228 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sun, 22 Sep 2013 16:50:02 +0200 Subject: dma: cppi41: add shortcut to &pdev->dev in cppi41_dma_probe() Makes the code more readable and compact. No functional change. Signed-off-by: Daniel Mack Signed-off-by: Vinod Koul --- drivers/dma/cppi41.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'drivers/dma/cppi41.c') diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c index 5469a15c7f8..d6897067e4c 100644 --- a/drivers/dma/cppi41.c +++ b/drivers/dma/cppi41.c @@ -927,11 +927,12 @@ static const struct cppi_glue_infos *get_glue_info(struct device *dev) static int cppi41_dma_probe(struct platform_device *pdev) { struct cppi41_dd *cdd; + struct device *dev = &pdev->dev; const struct cppi_glue_infos *glue_info; int irq; int ret; - glue_info = get_glue_info(&pdev->dev); + glue_info = get_glue_info(dev); if (!glue_info) return -EINVAL; @@ -946,14 +947,14 @@ static int cppi41_dma_probe(struct platform_device *pdev) cdd->ddev.device_issue_pending = cppi41_dma_issue_pending; cdd->ddev.device_prep_slave_sg = cppi41_dma_prep_slave_sg; cdd->ddev.device_control = cppi41_dma_control; - cdd->ddev.dev = &pdev->dev; + cdd->ddev.dev = dev; INIT_LIST_HEAD(&cdd->ddev.channels); cpp41_dma_info.dma_cap = cdd->ddev.cap_mask; - cdd->usbss_mem = of_iomap(pdev->dev.of_node, 0); - cdd->ctrl_mem = of_iomap(pdev->dev.of_node, 1); - cdd->sched_mem = of_iomap(pdev->dev.of_node, 2); - cdd->qmgr_mem = of_iomap(pdev->dev.of_node, 3); + cdd->usbss_mem = of_iomap(dev->of_node, 0); + cdd->ctrl_mem = of_iomap(dev->of_node, 1); + cdd->sched_mem = of_iomap(dev->of_node, 2); + cdd->qmgr_mem = of_iomap(dev->of_node, 3); if (!cdd->usbss_mem || !cdd->ctrl_mem || !cdd->sched_mem || !cdd->qmgr_mem) { @@ -961,8 +962,8 @@ static int cppi41_dma_probe(struct platform_device *pdev) goto err_remap; } - pm_runtime_enable(&pdev->dev); - ret = pm_runtime_get_sync(&pdev->dev); + pm_runtime_enable(dev); + ret = pm_runtime_get_sync(dev); if (ret) goto err_get_sync; @@ -970,22 +971,22 @@ static int cppi41_dma_probe(struct platform_device *pdev) cdd->queues_tx = glue_info->queues_tx; cdd->td_queue = glue_info->td_queue; - ret = init_cppi41(&pdev->dev, cdd); + ret = init_cppi41(dev, cdd); if (ret) goto err_init_cppi; - ret = cppi41_add_chans(&pdev->dev, cdd); + ret = cppi41_add_chans(dev, cdd); if (ret) goto err_chans; - irq = irq_of_parse_and_map(pdev->dev.of_node, 0); + irq = irq_of_parse_and_map(dev->of_node, 0); if (!irq) goto err_irq; cppi_writel(USBSS_IRQ_PD_COMP, cdd->usbss_mem + USBSS_IRQ_ENABLER); ret = request_irq(irq, glue_info->isr, IRQF_SHARED, - dev_name(&pdev->dev), cdd); + dev_name(dev), cdd); if (ret) goto err_irq; cdd->irq = irq; @@ -994,7 +995,7 @@ static int cppi41_dma_probe(struct platform_device *pdev) if (ret) goto err_dma_reg; - ret = of_dma_controller_register(pdev->dev.of_node, + ret = of_dma_controller_register(dev->of_node, cppi41_dma_xlate, &cpp41_dma_info); if (ret) goto err_of; @@ -1009,11 +1010,11 @@ err_irq: cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); cleanup_chans(cdd); err_chans: - deinit_cppi41(&pdev->dev, cdd); + deinit_cppi41(dev, cdd); err_init_cppi: - pm_runtime_put(&pdev->dev); + pm_runtime_put(dev); err_get_sync: - pm_runtime_disable(&pdev->dev); + pm_runtime_disable(dev); iounmap(cdd->usbss_mem); iounmap(cdd->ctrl_mem); iounmap(cdd->sched_mem); -- cgit v1.2.3-70-g09d2 From f97b98d6d02eea5301f86422ace06e5b53979a0c Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sun, 22 Sep 2013 16:50:04 +0200 Subject: dma: cppi41: add support for suspend and resume This patch adds support for suspend/resume functionality to the cppi41 DMA driver. The steps necessary to make the system resume properly were figured out by trial-and-error. The code as it stands now is the minimum that has to be done to put the musb host system on an AM33xx system into an operable state after resume. Signed-off-by: Daniel Mack Signed-off-by: Vinod Koul --- drivers/dma/cppi41.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'drivers/dma/cppi41.c') diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c index d6897067e4c..167c0223ae9 100644 --- a/drivers/dma/cppi41.c +++ b/drivers/dma/cppi41.c @@ -1045,12 +1045,41 @@ static int cppi41_dma_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_SLEEP +static int cppi41_suspend(struct device *dev) +{ + struct cppi41_dd *cdd = dev_get_drvdata(dev); + + cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); + disable_sched(cdd); + + return 0; +} + +static int cppi41_resume(struct device *dev) +{ + struct cppi41_dd *cdd = dev_get_drvdata(dev); + int i; + + for (i = 0; i < DESCS_AREAS; i++) + cppi_writel(cdd->descs_phys, cdd->qmgr_mem + QMGR_MEMBASE(i)); + + init_sched(cdd); + cppi_writel(USBSS_IRQ_PD_COMP, cdd->usbss_mem + USBSS_IRQ_ENABLER); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(cppi41_pm_ops, cppi41_suspend, cppi41_resume); + static struct platform_driver cpp41_dma_driver = { .probe = cppi41_dma_probe, .remove = cppi41_dma_remove, .driver = { .name = "cppi41-dma-engine", .owner = THIS_MODULE, + .pm = &cppi41_pm_ops, .of_match_table = of_match_ptr(cppi41_dma_ids), }, }; -- cgit v1.2.3-70-g09d2 From ed83c0c8c11b1c9583f29098a3ac906d9a19fe70 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 16 Oct 2013 13:36:28 +0530 Subject: dmaengine: cppi41: use DMA_COMPLETE for dma completion status Acked-by: Dan Williams Acked-by: Linus Walleij Signed-off-by: Vinod Koul --- drivers/dma/cppi41.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/dma/cppi41.c') diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c index 167c0223ae9..278b3058919 100644 --- a/drivers/dma/cppi41.c +++ b/drivers/dma/cppi41.c @@ -353,7 +353,7 @@ static enum dma_status cppi41_dma_tx_status(struct dma_chan *chan, /* lock */ ret = dma_cookie_status(chan, cookie, txstate); - if (txstate && ret == DMA_SUCCESS) + if (txstate && ret == DMA_COMPLETE) txstate->residue = c->residue; /* unlock */ -- cgit v1.2.3-70-g09d2 From f8964968ab841cb28b0999f346ee3c2491076257 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 22 Oct 2013 12:14:03 +0200 Subject: dma: cppi41: restore more registers With active users over suspend/resume cycles, it turns out that more registers, in particular DMA_TDFDQ and RXHPCRA0, have to be restored on resume. Signed-off-by: Daniel Mack Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Vinod Koul --- drivers/dma/cppi41.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers/dma/cppi41.c') diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c index 278b3058919..7a90317d2e7 100644 --- a/drivers/dma/cppi41.c +++ b/drivers/dma/cppi41.c @@ -141,6 +141,9 @@ struct cppi41_dd { const struct chan_queues *queues_rx; const struct chan_queues *queues_tx; struct chan_queues td_queue; + + /* context for suspend/resume */ + unsigned int dma_tdfdq; }; #define FIST_COMPLETION_QUEUE 93 @@ -1050,6 +1053,7 @@ static int cppi41_suspend(struct device *dev) { struct cppi41_dd *cdd = dev_get_drvdata(dev); + cdd->dma_tdfdq = cppi_readl(cdd->ctrl_mem + DMA_TDFDQ); cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); disable_sched(cdd); @@ -1059,12 +1063,23 @@ static int cppi41_suspend(struct device *dev) static int cppi41_resume(struct device *dev) { struct cppi41_dd *cdd = dev_get_drvdata(dev); + struct cppi41_channel *c; int i; for (i = 0; i < DESCS_AREAS; i++) cppi_writel(cdd->descs_phys, cdd->qmgr_mem + QMGR_MEMBASE(i)); + list_for_each_entry(c, &cdd->ddev.channels, chan.device_node) + if (!c->is_tx) + cppi_writel(c->q_num, c->gcr_reg + RXHPCRA0); + init_sched(cdd); + + cppi_writel(cdd->dma_tdfdq, cdd->ctrl_mem + DMA_TDFDQ); + cppi_writel(cdd->scratch_phys, cdd->qmgr_mem + QMGR_LRAM0_BASE); + cppi_writel(QMGR_SCRATCH_SIZE, cdd->qmgr_mem + QMGR_LRAM_SIZE); + cppi_writel(0, cdd->qmgr_mem + QMGR_LRAM1_BASE); + cppi_writel(USBSS_IRQ_PD_COMP, cdd->usbss_mem + USBSS_IRQ_ENABLER); return 0; -- cgit v1.2.3-70-g09d2 From 706ff628f0669f28e370d2ad30672e5032dc64b2 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 22 Oct 2013 12:14:04 +0200 Subject: dma: cppi41: use cppi41_pop_desc() where possible Use cppi41_pop_desc() when appropriate instead of open-coding the same functionality again. That makes the code more readable. The function has to be moved some lines up for this change. Signed-off-by: Daniel Mack Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Vinod Koul --- drivers/dma/cppi41.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'drivers/dma/cppi41.c') diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c index 7a90317d2e7..2500f60393f 100644 --- a/drivers/dma/cppi41.c +++ b/drivers/dma/cppi41.c @@ -266,6 +266,15 @@ static u32 pd_trans_len(u32 val) return val & ((1 << (DESC_LENGTH_BITS_NUM + 1)) - 1); } +static u32 cppi41_pop_desc(struct cppi41_dd *cdd, unsigned queue_num) +{ + u32 desc; + + desc = cppi_readl(cdd->qmgr_mem + QMGR_QUEUE_D(queue_num)); + desc &= ~0x1f; + return desc; +} + static irqreturn_t cppi41_irq(int irq, void *data) { struct cppi41_dd *cdd = data; @@ -303,8 +312,7 @@ static irqreturn_t cppi41_irq(int irq, void *data) q_num = __fls(val); val &= ~(1 << q_num); q_num += 32 * i; - desc = cppi_readl(cdd->qmgr_mem + QMGR_QUEUE_D(q_num)); - desc &= ~0x1f; + desc = cppi41_pop_desc(cdd, q_num); c = desc_to_chan(cdd, desc); if (WARN_ON(!c)) { pr_err("%s() q %d desc %08x\n", __func__, @@ -520,15 +528,6 @@ static void cppi41_compute_td_desc(struct cppi41_desc *d) d->pd0 = DESC_TYPE_TEARD << DESC_TYPE; } -static u32 cppi41_pop_desc(struct cppi41_dd *cdd, unsigned queue_num) -{ - u32 desc; - - desc = cppi_readl(cdd->qmgr_mem + QMGR_QUEUE_D(queue_num)); - desc &= ~0x1f; - return desc; -} - static int cppi41_tear_down_chan(struct cppi41_channel *c) { struct cppi41_dd *cdd = c->cdd; @@ -612,7 +611,7 @@ static int cppi41_tear_down_chan(struct cppi41_channel *c) WARN_ON(!c->td_retry); if (!c->td_desc_seen) { - desc_phys = cppi_readl(cdd->qmgr_mem + QMGR_QUEUE_D(c->q_num)); + desc_phys = cppi41_pop_desc(cdd, c->q_num); WARN_ON(!desc_phys); } -- cgit v1.2.3-70-g09d2 From 1e378a6d7789bf142319c6207398367336c49082 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 22 Oct 2013 12:14:05 +0200 Subject: dma: cppi41: redo descriptor collection in abort case Most of the logic here is try and error since what actually happens does not match the trm or I miss read it. My first assumption was that the queue on which the tear-down descriptor completes (their own complete queue vs "active descriptor" complete queue) depends on the transfer direction. This seems not to be true because I manage to trigger | WARN_ON(c->desc_phys != desc_phys); and the other few were fine means the tear-down descriptor was valid but on different queue. This patch changes the logic here to look on both queues for the descriptor. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Vinod Koul --- drivers/dma/cppi41.c | 42 ++++++++++++++++-------------------------- 1 file changed, 16 insertions(+), 26 deletions(-) (limited to 'drivers/dma/cppi41.c') diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c index 2500f60393f..ec87492cfb0 100644 --- a/drivers/dma/cppi41.c +++ b/drivers/dma/cppi41.c @@ -563,36 +563,26 @@ static int cppi41_tear_down_chan(struct cppi41_channel *c) c->td_retry = 100; } - if (!c->td_seen) { - unsigned td_comp_queue; + if (!c->td_seen || !c->td_desc_seen) { - if (c->is_tx) - td_comp_queue = cdd->td_queue.complete; - else - td_comp_queue = c->q_comp_num; + desc_phys = cppi41_pop_desc(cdd, cdd->td_queue.complete); + if (!desc_phys) + desc_phys = cppi41_pop_desc(cdd, c->q_comp_num); - desc_phys = cppi41_pop_desc(cdd, td_comp_queue); - if (desc_phys) { - __iormb(); + if (desc_phys == c->desc_phys) { + c->td_desc_seen = 1; + + } else if (desc_phys == td_desc_phys) { + u32 pd0; - if (desc_phys == td_desc_phys) { - u32 pd0; - pd0 = td->pd0; - WARN_ON((pd0 >> DESC_TYPE) != DESC_TYPE_TEARD); - WARN_ON(!c->is_tx && !(pd0 & TD_DESC_IS_RX)); - WARN_ON((pd0 & 0x1f) != c->port_num); - } else { - WARN_ON_ONCE(1); - } - c->td_seen = 1; - } - } - if (!c->td_desc_seen) { - desc_phys = cppi41_pop_desc(cdd, c->q_comp_num); - if (desc_phys) { __iormb(); - WARN_ON(c->desc_phys != desc_phys); - c->td_desc_seen = 1; + pd0 = td->pd0; + WARN_ON((pd0 >> DESC_TYPE) != DESC_TYPE_TEARD); + WARN_ON(!c->is_tx && !(pd0 & TD_DESC_IS_RX)); + WARN_ON((pd0 & 0x1f) != c->port_num); + c->td_seen = 1; + } else if (desc_phys) { + WARN_ON_ONCE(1); } } c->td_retry--; -- cgit v1.2.3-70-g09d2 From cbf1e56e6aa2fc116a9995d457e8f3cf2be20442 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 22 Oct 2013 12:14:06 +0200 Subject: dma: cppi41: return code > 0 of pm_runtime_get_sync() is not an error Return code of pm_runtime_get_sync() > 0 is not an error and may happen. Noticed during rmmod & modprobe testing. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Vinod Koul --- drivers/dma/cppi41.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/dma/cppi41.c') diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c index ec87492cfb0..c29dacff66f 100644 --- a/drivers/dma/cppi41.c +++ b/drivers/dma/cppi41.c @@ -956,7 +956,7 @@ static int cppi41_dma_probe(struct platform_device *pdev) pm_runtime_enable(dev); ret = pm_runtime_get_sync(dev); - if (ret) + if (ret < 0) goto err_get_sync; cdd->queues_rx = glue_info->queues_rx; -- cgit v1.2.3-70-g09d2