aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/coh901318.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/coh901318.c')
-rw-r--r--drivers/dma/coh901318.c153
1 files changed, 70 insertions, 83 deletions
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index e88588d8ecd3..fd22dd36985f 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -1690,7 +1690,7 @@ static u32 coh901318_get_bytes_left(struct dma_chan *chan)
1690 * Pauses a transfer without losing data. Enables power save. 1690 * Pauses a transfer without losing data. Enables power save.
1691 * Use this function in conjunction with coh901318_resume. 1691 * Use this function in conjunction with coh901318_resume.
1692 */ 1692 */
1693static void coh901318_pause(struct dma_chan *chan) 1693static int coh901318_pause(struct dma_chan *chan)
1694{ 1694{
1695 u32 val; 1695 u32 val;
1696 unsigned long flags; 1696 unsigned long flags;
@@ -1730,12 +1730,13 @@ static void coh901318_pause(struct dma_chan *chan)
1730 enable_powersave(cohc); 1730 enable_powersave(cohc);
1731 1731
1732 spin_unlock_irqrestore(&cohc->lock, flags); 1732 spin_unlock_irqrestore(&cohc->lock, flags);
1733 return 0;
1733} 1734}
1734 1735
1735/* Resumes a transfer that has been stopped via 300_dma_stop(..). 1736/* Resumes a transfer that has been stopped via 300_dma_stop(..).
1736 Power save is handled. 1737 Power save is handled.
1737*/ 1738*/
1738static void coh901318_resume(struct dma_chan *chan) 1739static int coh901318_resume(struct dma_chan *chan)
1739{ 1740{
1740 u32 val; 1741 u32 val;
1741 unsigned long flags; 1742 unsigned long flags;
@@ -1760,6 +1761,7 @@ static void coh901318_resume(struct dma_chan *chan)
1760 } 1761 }
1761 1762
1762 spin_unlock_irqrestore(&cohc->lock, flags); 1763 spin_unlock_irqrestore(&cohc->lock, flags);
1764 return 0;
1763} 1765}
1764 1766
1765bool coh901318_filter_id(struct dma_chan *chan, void *chan_id) 1767bool coh901318_filter_id(struct dma_chan *chan, void *chan_id)
@@ -2114,6 +2116,57 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
2114 return IRQ_HANDLED; 2116 return IRQ_HANDLED;
2115} 2117}
2116 2118
2119static int coh901318_terminate_all(struct dma_chan *chan)
2120{
2121 unsigned long flags;
2122 struct coh901318_chan *cohc = to_coh901318_chan(chan);
2123 struct coh901318_desc *cohd;
2124 void __iomem *virtbase = cohc->base->virtbase;
2125
2126 /* The remainder of this function terminates the transfer */
2127 coh901318_pause(chan);
2128 spin_lock_irqsave(&cohc->lock, flags);
2129
2130 /* Clear any pending BE or TC interrupt */
2131 if (cohc->id < 32) {
2132 writel(1 << cohc->id, virtbase + COH901318_BE_INT_CLEAR1);
2133 writel(1 << cohc->id, virtbase + COH901318_TC_INT_CLEAR1);
2134 } else {
2135 writel(1 << (cohc->id - 32), virtbase +
2136 COH901318_BE_INT_CLEAR2);
2137 writel(1 << (cohc->id - 32), virtbase +
2138 COH901318_TC_INT_CLEAR2);
2139 }
2140
2141 enable_powersave(cohc);
2142
2143 while ((cohd = coh901318_first_active_get(cohc))) {
2144 /* release the lli allocation*/
2145 coh901318_lli_free(&cohc->base->pool, &cohd->lli);
2146
2147 /* return desc to free-list */
2148 coh901318_desc_remove(cohd);
2149 coh901318_desc_free(cohc, cohd);
2150 }
2151
2152 while ((cohd = coh901318_first_queued(cohc))) {
2153 /* release the lli allocation*/
2154 coh901318_lli_free(&cohc->base->pool, &cohd->lli);
2155
2156 /* return desc to free-list */
2157 coh901318_desc_remove(cohd);
2158 coh901318_desc_free(cohc, cohd);
2159 }
2160
2161
2162 cohc->nbr_active_done = 0;
2163 cohc->busy = 0;
2164
2165 spin_unlock_irqrestore(&cohc->lock, flags);
2166
2167 return 0;
2168}
2169
2117static int coh901318_alloc_chan_resources(struct dma_chan *chan) 2170static int coh901318_alloc_chan_resources(struct dma_chan *chan)
2118{ 2171{
2119 struct coh901318_chan *cohc = to_coh901318_chan(chan); 2172 struct coh901318_chan *cohc = to_coh901318_chan(chan);
@@ -2156,7 +2209,7 @@ coh901318_free_chan_resources(struct dma_chan *chan)
2156 2209
2157 spin_unlock_irqrestore(&cohc->lock, flags); 2210 spin_unlock_irqrestore(&cohc->lock, flags);
2158 2211
2159 dmaengine_terminate_all(chan); 2212 coh901318_terminate_all(chan);
2160} 2213}
2161 2214
2162 2215
@@ -2461,8 +2514,8 @@ static const struct burst_table burst_sizes[] = {
2461 }, 2514 },
2462}; 2515};
2463 2516
2464static void coh901318_dma_set_runtimeconfig(struct dma_chan *chan, 2517static int coh901318_dma_set_runtimeconfig(struct dma_chan *chan,
2465 struct dma_slave_config *config) 2518 struct dma_slave_config *config)
2466{ 2519{
2467 struct coh901318_chan *cohc = to_coh901318_chan(chan); 2520 struct coh901318_chan *cohc = to_coh901318_chan(chan);
2468 dma_addr_t addr; 2521 dma_addr_t addr;
@@ -2482,7 +2535,7 @@ static void coh901318_dma_set_runtimeconfig(struct dma_chan *chan,
2482 maxburst = config->dst_maxburst; 2535 maxburst = config->dst_maxburst;
2483 } else { 2536 } else {
2484 dev_err(COHC_2_DEV(cohc), "illegal channel mode\n"); 2537 dev_err(COHC_2_DEV(cohc), "illegal channel mode\n");
2485 return; 2538 return -EINVAL;
2486 } 2539 }
2487 2540
2488 dev_dbg(COHC_2_DEV(cohc), "configure channel for %d byte transfers\n", 2541 dev_dbg(COHC_2_DEV(cohc), "configure channel for %d byte transfers\n",
@@ -2528,7 +2581,7 @@ static void coh901318_dma_set_runtimeconfig(struct dma_chan *chan,
2528 default: 2581 default:
2529 dev_err(COHC_2_DEV(cohc), 2582 dev_err(COHC_2_DEV(cohc),
2530 "bad runtimeconfig: alien address width\n"); 2583 "bad runtimeconfig: alien address width\n");
2531 return; 2584 return -EINVAL;
2532 } 2585 }
2533 2586
2534 ctrl |= burst_sizes[i].reg; 2587 ctrl |= burst_sizes[i].reg;
@@ -2538,84 +2591,12 @@ static void coh901318_dma_set_runtimeconfig(struct dma_chan *chan,
2538 2591
2539 cohc->addr = addr; 2592 cohc->addr = addr;
2540 cohc->ctrl = ctrl; 2593 cohc->ctrl = ctrl;
2541}
2542
2543static int
2544coh901318_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
2545 unsigned long arg)
2546{
2547 unsigned long flags;
2548 struct coh901318_chan *cohc = to_coh901318_chan(chan);
2549 struct coh901318_desc *cohd;
2550 void __iomem *virtbase = cohc->base->virtbase;
2551
2552 if (cmd == DMA_SLAVE_CONFIG) {
2553 struct dma_slave_config *config =
2554 (struct dma_slave_config *) arg;
2555
2556 coh901318_dma_set_runtimeconfig(chan, config);
2557 return 0;
2558 }
2559
2560 if (cmd == DMA_PAUSE) {
2561 coh901318_pause(chan);
2562 return 0;
2563 }
2564
2565 if (cmd == DMA_RESUME) {
2566 coh901318_resume(chan);
2567 return 0;
2568 }
2569
2570 if (cmd != DMA_TERMINATE_ALL)
2571 return -ENXIO;
2572
2573 /* The remainder of this function terminates the transfer */
2574 coh901318_pause(chan);
2575 spin_lock_irqsave(&cohc->lock, flags);
2576
2577 /* Clear any pending BE or TC interrupt */
2578 if (cohc->id < 32) {
2579 writel(1 << cohc->id, virtbase + COH901318_BE_INT_CLEAR1);
2580 writel(1 << cohc->id, virtbase + COH901318_TC_INT_CLEAR1);
2581 } else {
2582 writel(1 << (cohc->id - 32), virtbase +
2583 COH901318_BE_INT_CLEAR2);
2584 writel(1 << (cohc->id - 32), virtbase +
2585 COH901318_TC_INT_CLEAR2);
2586 }
2587
2588 enable_powersave(cohc);
2589
2590 while ((cohd = coh901318_first_active_get(cohc))) {
2591 /* release the lli allocation*/
2592 coh901318_lli_free(&cohc->base->pool, &cohd->lli);
2593
2594 /* return desc to free-list */
2595 coh901318_desc_remove(cohd);
2596 coh901318_desc_free(cohc, cohd);
2597 }
2598
2599 while ((cohd = coh901318_first_queued(cohc))) {
2600 /* release the lli allocation*/
2601 coh901318_lli_free(&cohc->base->pool, &cohd->lli);
2602
2603 /* return desc to free-list */
2604 coh901318_desc_remove(cohd);
2605 coh901318_desc_free(cohc, cohd);
2606 }
2607
2608
2609 cohc->nbr_active_done = 0;
2610 cohc->busy = 0;
2611
2612 spin_unlock_irqrestore(&cohc->lock, flags);
2613 2594
2614 return 0; 2595 return 0;
2615} 2596}
2616 2597
2617void coh901318_base_init(struct dma_device *dma, const int *pick_chans, 2598static void coh901318_base_init(struct dma_device *dma, const int *pick_chans,
2618 struct coh901318_base *base) 2599 struct coh901318_base *base)
2619{ 2600{
2620 int chans_i; 2601 int chans_i;
2621 int i = 0; 2602 int i = 0;
@@ -2717,7 +2698,10 @@ static int __init coh901318_probe(struct platform_device *pdev)
2717 base->dma_slave.device_prep_slave_sg = coh901318_prep_slave_sg; 2698 base->dma_slave.device_prep_slave_sg = coh901318_prep_slave_sg;
2718 base->dma_slave.device_tx_status = coh901318_tx_status; 2699 base->dma_slave.device_tx_status = coh901318_tx_status;
2719 base->dma_slave.device_issue_pending = coh901318_issue_pending; 2700 base->dma_slave.device_issue_pending = coh901318_issue_pending;
2720 base->dma_slave.device_control = coh901318_control; 2701 base->dma_slave.device_config = coh901318_dma_set_runtimeconfig;
2702 base->dma_slave.device_pause = coh901318_pause;
2703 base->dma_slave.device_resume = coh901318_resume;
2704 base->dma_slave.device_terminate_all = coh901318_terminate_all;
2721 base->dma_slave.dev = &pdev->dev; 2705 base->dma_slave.dev = &pdev->dev;
2722 2706
2723 err = dma_async_device_register(&base->dma_slave); 2707 err = dma_async_device_register(&base->dma_slave);
@@ -2737,7 +2721,10 @@ static int __init coh901318_probe(struct platform_device *pdev)
2737 base->dma_memcpy.device_prep_dma_memcpy = coh901318_prep_memcpy; 2721 base->dma_memcpy.device_prep_dma_memcpy = coh901318_prep_memcpy;
2738 base->dma_memcpy.device_tx_status = coh901318_tx_status; 2722 base->dma_memcpy.device_tx_status = coh901318_tx_status;
2739 base->dma_memcpy.device_issue_pending = coh901318_issue_pending; 2723 base->dma_memcpy.device_issue_pending = coh901318_issue_pending;
2740 base->dma_memcpy.device_control = coh901318_control; 2724 base->dma_memcpy.device_config = coh901318_dma_set_runtimeconfig;
2725 base->dma_memcpy.device_pause = coh901318_pause;
2726 base->dma_memcpy.device_resume = coh901318_resume;
2727 base->dma_memcpy.device_terminate_all = coh901318_terminate_all;
2741 base->dma_memcpy.dev = &pdev->dev; 2728 base->dma_memcpy.dev = &pdev->dev;
2742 /* 2729 /*
2743 * This controller can only access address at even 32bit boundaries, 2730 * This controller can only access address at even 32bit boundaries,