diff options
Diffstat (limited to 'drivers/dma/iop-adma.c')
-rw-r--r-- | drivers/dma/iop-adma.c | 60 |
1 files changed, 26 insertions, 34 deletions
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index f82b0906d466..762b729672e0 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c | |||
@@ -63,7 +63,6 @@ iop_adma_run_tx_complete_actions(struct iop_adma_desc_slot *desc, | |||
63 | struct iop_adma_chan *iop_chan, dma_cookie_t cookie) | 63 | struct iop_adma_chan *iop_chan, dma_cookie_t cookie) |
64 | { | 64 | { |
65 | BUG_ON(desc->async_tx.cookie < 0); | 65 | BUG_ON(desc->async_tx.cookie < 0); |
66 | spin_lock_bh(&desc->async_tx.lock); | ||
67 | if (desc->async_tx.cookie > 0) { | 66 | if (desc->async_tx.cookie > 0) { |
68 | cookie = desc->async_tx.cookie; | 67 | cookie = desc->async_tx.cookie; |
69 | desc->async_tx.cookie = 0; | 68 | desc->async_tx.cookie = 0; |
@@ -101,7 +100,6 @@ iop_adma_run_tx_complete_actions(struct iop_adma_desc_slot *desc, | |||
101 | 100 | ||
102 | /* run dependent operations */ | 101 | /* run dependent operations */ |
103 | async_tx_run_dependencies(&desc->async_tx); | 102 | async_tx_run_dependencies(&desc->async_tx); |
104 | spin_unlock_bh(&desc->async_tx.lock); | ||
105 | 103 | ||
106 | return cookie; | 104 | return cookie; |
107 | } | 105 | } |
@@ -113,7 +111,7 @@ iop_adma_clean_slot(struct iop_adma_desc_slot *desc, | |||
113 | /* the client is allowed to attach dependent operations | 111 | /* the client is allowed to attach dependent operations |
114 | * until 'ack' is set | 112 | * until 'ack' is set |
115 | */ | 113 | */ |
116 | if (!desc->async_tx.ack) | 114 | if (!async_tx_test_ack(&desc->async_tx)) |
117 | return 0; | 115 | return 0; |
118 | 116 | ||
119 | /* leave the last descriptor in the chain | 117 | /* leave the last descriptor in the chain |
@@ -150,7 +148,7 @@ static void __iop_adma_slot_cleanup(struct iop_adma_chan *iop_chan) | |||
150 | "this_desc: %#x next_desc: %#x ack: %d\n", | 148 | "this_desc: %#x next_desc: %#x ack: %d\n", |
151 | iter->async_tx.cookie, iter->idx, busy, | 149 | iter->async_tx.cookie, iter->idx, busy, |
152 | iter->async_tx.phys, iop_desc_get_next_desc(iter), | 150 | iter->async_tx.phys, iop_desc_get_next_desc(iter), |
153 | iter->async_tx.ack); | 151 | async_tx_test_ack(&iter->async_tx)); |
154 | prefetch(_iter); | 152 | prefetch(_iter); |
155 | prefetch(&_iter->async_tx); | 153 | prefetch(&_iter->async_tx); |
156 | 154 | ||
@@ -257,8 +255,6 @@ static void __iop_adma_slot_cleanup(struct iop_adma_chan *iop_chan) | |||
257 | 255 | ||
258 | BUG_ON(!seen_current); | 256 | BUG_ON(!seen_current); |
259 | 257 | ||
260 | iop_chan_idle(busy, iop_chan); | ||
261 | |||
262 | if (cookie > 0) { | 258 | if (cookie > 0) { |
263 | iop_chan->completed_cookie = cookie; | 259 | iop_chan->completed_cookie = cookie; |
264 | pr_debug("\tcompleted cookie %d\n", cookie); | 260 | pr_debug("\tcompleted cookie %d\n", cookie); |
@@ -275,8 +271,11 @@ iop_adma_slot_cleanup(struct iop_adma_chan *iop_chan) | |||
275 | 271 | ||
276 | static void iop_adma_tasklet(unsigned long data) | 272 | static void iop_adma_tasklet(unsigned long data) |
277 | { | 273 | { |
278 | struct iop_adma_chan *chan = (struct iop_adma_chan *) data; | 274 | struct iop_adma_chan *iop_chan = (struct iop_adma_chan *) data; |
279 | __iop_adma_slot_cleanup(chan); | 275 | |
276 | spin_lock(&iop_chan->lock); | ||
277 | __iop_adma_slot_cleanup(iop_chan); | ||
278 | spin_unlock(&iop_chan->lock); | ||
280 | } | 279 | } |
281 | 280 | ||
282 | static struct iop_adma_desc_slot * | 281 | static struct iop_adma_desc_slot * |
@@ -339,9 +338,7 @@ retry: | |||
339 | 338 | ||
340 | /* pre-ack all but the last descriptor */ | 339 | /* pre-ack all but the last descriptor */ |
341 | if (num_slots != slots_per_op) | 340 | if (num_slots != slots_per_op) |
342 | iter->async_tx.ack = 1; | 341 | async_tx_ack(&iter->async_tx); |
343 | else | ||
344 | iter->async_tx.ack = 0; | ||
345 | 342 | ||
346 | list_add_tail(&iter->chain_node, &chain); | 343 | list_add_tail(&iter->chain_node, &chain); |
347 | alloc_tail = iter; | 344 | alloc_tail = iter; |
@@ -514,7 +511,7 @@ static int iop_adma_alloc_chan_resources(struct dma_chan *chan) | |||
514 | } | 511 | } |
515 | 512 | ||
516 | static struct dma_async_tx_descriptor * | 513 | static struct dma_async_tx_descriptor * |
517 | iop_adma_prep_dma_interrupt(struct dma_chan *chan) | 514 | iop_adma_prep_dma_interrupt(struct dma_chan *chan, unsigned long flags) |
518 | { | 515 | { |
519 | struct iop_adma_chan *iop_chan = to_iop_adma_chan(chan); | 516 | struct iop_adma_chan *iop_chan = to_iop_adma_chan(chan); |
520 | struct iop_adma_desc_slot *sw_desc, *grp_start; | 517 | struct iop_adma_desc_slot *sw_desc, *grp_start; |
@@ -529,6 +526,7 @@ iop_adma_prep_dma_interrupt(struct dma_chan *chan) | |||
529 | grp_start = sw_desc->group_head; | 526 | grp_start = sw_desc->group_head; |
530 | iop_desc_init_interrupt(grp_start, iop_chan); | 527 | iop_desc_init_interrupt(grp_start, iop_chan); |
531 | grp_start->unmap_len = 0; | 528 | grp_start->unmap_len = 0; |
529 | sw_desc->async_tx.flags = flags; | ||
532 | } | 530 | } |
533 | spin_unlock_bh(&iop_chan->lock); | 531 | spin_unlock_bh(&iop_chan->lock); |
534 | 532 | ||
@@ -561,6 +559,7 @@ iop_adma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dma_dest, | |||
561 | iop_desc_set_memcpy_src_addr(grp_start, dma_src); | 559 | iop_desc_set_memcpy_src_addr(grp_start, dma_src); |
562 | sw_desc->unmap_src_cnt = 1; | 560 | sw_desc->unmap_src_cnt = 1; |
563 | sw_desc->unmap_len = len; | 561 | sw_desc->unmap_len = len; |
562 | sw_desc->async_tx.flags = flags; | ||
564 | } | 563 | } |
565 | spin_unlock_bh(&iop_chan->lock); | 564 | spin_unlock_bh(&iop_chan->lock); |
566 | 565 | ||
@@ -593,6 +592,7 @@ iop_adma_prep_dma_memset(struct dma_chan *chan, dma_addr_t dma_dest, | |||
593 | iop_desc_set_dest_addr(grp_start, iop_chan, dma_dest); | 592 | iop_desc_set_dest_addr(grp_start, iop_chan, dma_dest); |
594 | sw_desc->unmap_src_cnt = 1; | 593 | sw_desc->unmap_src_cnt = 1; |
595 | sw_desc->unmap_len = len; | 594 | sw_desc->unmap_len = len; |
595 | sw_desc->async_tx.flags = flags; | ||
596 | } | 596 | } |
597 | spin_unlock_bh(&iop_chan->lock); | 597 | spin_unlock_bh(&iop_chan->lock); |
598 | 598 | ||
@@ -626,6 +626,7 @@ iop_adma_prep_dma_xor(struct dma_chan *chan, dma_addr_t dma_dest, | |||
626 | iop_desc_set_dest_addr(grp_start, iop_chan, dma_dest); | 626 | iop_desc_set_dest_addr(grp_start, iop_chan, dma_dest); |
627 | sw_desc->unmap_src_cnt = src_cnt; | 627 | sw_desc->unmap_src_cnt = src_cnt; |
628 | sw_desc->unmap_len = len; | 628 | sw_desc->unmap_len = len; |
629 | sw_desc->async_tx.flags = flags; | ||
629 | while (src_cnt--) | 630 | while (src_cnt--) |
630 | iop_desc_set_xor_src_addr(grp_start, src_cnt, | 631 | iop_desc_set_xor_src_addr(grp_start, src_cnt, |
631 | dma_src[src_cnt]); | 632 | dma_src[src_cnt]); |
@@ -662,6 +663,7 @@ iop_adma_prep_dma_zero_sum(struct dma_chan *chan, dma_addr_t *dma_src, | |||
662 | __func__, grp_start->xor_check_result); | 663 | __func__, grp_start->xor_check_result); |
663 | sw_desc->unmap_src_cnt = src_cnt; | 664 | sw_desc->unmap_src_cnt = src_cnt; |
664 | sw_desc->unmap_len = len; | 665 | sw_desc->unmap_len = len; |
666 | sw_desc->async_tx.flags = flags; | ||
665 | while (src_cnt--) | 667 | while (src_cnt--) |
666 | iop_desc_set_zero_sum_src_addr(grp_start, src_cnt, | 668 | iop_desc_set_zero_sum_src_addr(grp_start, src_cnt, |
667 | dma_src[src_cnt]); | 669 | dma_src[src_cnt]); |
@@ -671,12 +673,6 @@ iop_adma_prep_dma_zero_sum(struct dma_chan *chan, dma_addr_t *dma_src, | |||
671 | return sw_desc ? &sw_desc->async_tx : NULL; | 673 | return sw_desc ? &sw_desc->async_tx : NULL; |
672 | } | 674 | } |
673 | 675 | ||
674 | static void iop_adma_dependency_added(struct dma_chan *chan) | ||
675 | { | ||
676 | struct iop_adma_chan *iop_chan = to_iop_adma_chan(chan); | ||
677 | tasklet_schedule(&iop_chan->irq_tasklet); | ||
678 | } | ||
679 | |||
680 | static void iop_adma_free_chan_resources(struct dma_chan *chan) | 676 | static void iop_adma_free_chan_resources(struct dma_chan *chan) |
681 | { | 677 | { |
682 | struct iop_adma_chan *iop_chan = to_iop_adma_chan(chan); | 678 | struct iop_adma_chan *iop_chan = to_iop_adma_chan(chan); |
@@ -854,11 +850,11 @@ static int __devinit iop_adma_memcpy_self_test(struct iop_adma_device *device) | |||
854 | src_dma = dma_map_single(dma_chan->device->dev, src, | 850 | src_dma = dma_map_single(dma_chan->device->dev, src, |
855 | IOP_ADMA_TEST_SIZE, DMA_TO_DEVICE); | 851 | IOP_ADMA_TEST_SIZE, DMA_TO_DEVICE); |
856 | tx = iop_adma_prep_dma_memcpy(dma_chan, dest_dma, src_dma, | 852 | tx = iop_adma_prep_dma_memcpy(dma_chan, dest_dma, src_dma, |
857 | IOP_ADMA_TEST_SIZE, 1); | 853 | IOP_ADMA_TEST_SIZE, |
854 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
858 | 855 | ||
859 | cookie = iop_adma_tx_submit(tx); | 856 | cookie = iop_adma_tx_submit(tx); |
860 | iop_adma_issue_pending(dma_chan); | 857 | iop_adma_issue_pending(dma_chan); |
861 | async_tx_ack(tx); | ||
862 | msleep(1); | 858 | msleep(1); |
863 | 859 | ||
864 | if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != | 860 | if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != |
@@ -954,11 +950,11 @@ iop_adma_xor_zero_sum_self_test(struct iop_adma_device *device) | |||
954 | dma_srcs[i] = dma_map_page(dma_chan->device->dev, xor_srcs[i], | 950 | dma_srcs[i] = dma_map_page(dma_chan->device->dev, xor_srcs[i], |
955 | 0, PAGE_SIZE, DMA_TO_DEVICE); | 951 | 0, PAGE_SIZE, DMA_TO_DEVICE); |
956 | tx = iop_adma_prep_dma_xor(dma_chan, dest_dma, dma_srcs, | 952 | tx = iop_adma_prep_dma_xor(dma_chan, dest_dma, dma_srcs, |
957 | IOP_ADMA_NUM_SRC_TEST, PAGE_SIZE, 1); | 953 | IOP_ADMA_NUM_SRC_TEST, PAGE_SIZE, |
954 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
958 | 955 | ||
959 | cookie = iop_adma_tx_submit(tx); | 956 | cookie = iop_adma_tx_submit(tx); |
960 | iop_adma_issue_pending(dma_chan); | 957 | iop_adma_issue_pending(dma_chan); |
961 | async_tx_ack(tx); | ||
962 | msleep(8); | 958 | msleep(8); |
963 | 959 | ||
964 | if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != | 960 | if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != |
@@ -1001,11 +997,11 @@ iop_adma_xor_zero_sum_self_test(struct iop_adma_device *device) | |||
1001 | DMA_TO_DEVICE); | 997 | DMA_TO_DEVICE); |
1002 | tx = iop_adma_prep_dma_zero_sum(dma_chan, dma_srcs, | 998 | tx = iop_adma_prep_dma_zero_sum(dma_chan, dma_srcs, |
1003 | IOP_ADMA_NUM_SRC_TEST + 1, PAGE_SIZE, | 999 | IOP_ADMA_NUM_SRC_TEST + 1, PAGE_SIZE, |
1004 | &zero_sum_result, 1); | 1000 | &zero_sum_result, |
1001 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
1005 | 1002 | ||
1006 | cookie = iop_adma_tx_submit(tx); | 1003 | cookie = iop_adma_tx_submit(tx); |
1007 | iop_adma_issue_pending(dma_chan); | 1004 | iop_adma_issue_pending(dma_chan); |
1008 | async_tx_ack(tx); | ||
1009 | msleep(8); | 1005 | msleep(8); |
1010 | 1006 | ||
1011 | if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { | 1007 | if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { |
@@ -1025,11 +1021,11 @@ iop_adma_xor_zero_sum_self_test(struct iop_adma_device *device) | |||
1025 | /* test memset */ | 1021 | /* test memset */ |
1026 | dma_addr = dma_map_page(dma_chan->device->dev, dest, 0, | 1022 | dma_addr = dma_map_page(dma_chan->device->dev, dest, 0, |
1027 | PAGE_SIZE, DMA_FROM_DEVICE); | 1023 | PAGE_SIZE, DMA_FROM_DEVICE); |
1028 | tx = iop_adma_prep_dma_memset(dma_chan, dma_addr, 0, PAGE_SIZE, 1); | 1024 | tx = iop_adma_prep_dma_memset(dma_chan, dma_addr, 0, PAGE_SIZE, |
1025 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
1029 | 1026 | ||
1030 | cookie = iop_adma_tx_submit(tx); | 1027 | cookie = iop_adma_tx_submit(tx); |
1031 | iop_adma_issue_pending(dma_chan); | 1028 | iop_adma_issue_pending(dma_chan); |
1032 | async_tx_ack(tx); | ||
1033 | msleep(8); | 1029 | msleep(8); |
1034 | 1030 | ||
1035 | if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { | 1031 | if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { |
@@ -1057,11 +1053,11 @@ iop_adma_xor_zero_sum_self_test(struct iop_adma_device *device) | |||
1057 | DMA_TO_DEVICE); | 1053 | DMA_TO_DEVICE); |
1058 | tx = iop_adma_prep_dma_zero_sum(dma_chan, dma_srcs, | 1054 | tx = iop_adma_prep_dma_zero_sum(dma_chan, dma_srcs, |
1059 | IOP_ADMA_NUM_SRC_TEST + 1, PAGE_SIZE, | 1055 | IOP_ADMA_NUM_SRC_TEST + 1, PAGE_SIZE, |
1060 | &zero_sum_result, 1); | 1056 | &zero_sum_result, |
1057 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
1061 | 1058 | ||
1062 | cookie = iop_adma_tx_submit(tx); | 1059 | cookie = iop_adma_tx_submit(tx); |
1063 | iop_adma_issue_pending(dma_chan); | 1060 | iop_adma_issue_pending(dma_chan); |
1064 | async_tx_ack(tx); | ||
1065 | msleep(8); | 1061 | msleep(8); |
1066 | 1062 | ||
1067 | if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { | 1063 | if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { |
@@ -1177,7 +1173,6 @@ static int __devinit iop_adma_probe(struct platform_device *pdev) | |||
1177 | dma_dev->device_free_chan_resources = iop_adma_free_chan_resources; | 1173 | dma_dev->device_free_chan_resources = iop_adma_free_chan_resources; |
1178 | dma_dev->device_is_tx_complete = iop_adma_is_complete; | 1174 | dma_dev->device_is_tx_complete = iop_adma_is_complete; |
1179 | dma_dev->device_issue_pending = iop_adma_issue_pending; | 1175 | dma_dev->device_issue_pending = iop_adma_issue_pending; |
1180 | dma_dev->device_dependency_added = iop_adma_dependency_added; | ||
1181 | dma_dev->dev = &pdev->dev; | 1176 | dma_dev->dev = &pdev->dev; |
1182 | 1177 | ||
1183 | /* set prep routines based on capability */ | 1178 | /* set prep routines based on capability */ |
@@ -1232,9 +1227,6 @@ static int __devinit iop_adma_probe(struct platform_device *pdev) | |||
1232 | } | 1227 | } |
1233 | 1228 | ||
1234 | spin_lock_init(&iop_chan->lock); | 1229 | spin_lock_init(&iop_chan->lock); |
1235 | init_timer(&iop_chan->cleanup_watchdog); | ||
1236 | iop_chan->cleanup_watchdog.data = (unsigned long) iop_chan; | ||
1237 | iop_chan->cleanup_watchdog.function = iop_adma_tasklet; | ||
1238 | INIT_LIST_HEAD(&iop_chan->chain); | 1230 | INIT_LIST_HEAD(&iop_chan->chain); |
1239 | INIT_LIST_HEAD(&iop_chan->all_slots); | 1231 | INIT_LIST_HEAD(&iop_chan->all_slots); |
1240 | INIT_RCU_HEAD(&iop_chan->common.rcu); | 1232 | INIT_RCU_HEAD(&iop_chan->common.rcu); |
@@ -1298,7 +1290,7 @@ static void iop_chan_start_null_memcpy(struct iop_adma_chan *iop_chan) | |||
1298 | grp_start = sw_desc->group_head; | 1290 | grp_start = sw_desc->group_head; |
1299 | 1291 | ||
1300 | list_splice_init(&sw_desc->async_tx.tx_list, &iop_chan->chain); | 1292 | list_splice_init(&sw_desc->async_tx.tx_list, &iop_chan->chain); |
1301 | sw_desc->async_tx.ack = 1; | 1293 | async_tx_ack(&sw_desc->async_tx); |
1302 | iop_desc_init_memcpy(grp_start, 0); | 1294 | iop_desc_init_memcpy(grp_start, 0); |
1303 | iop_desc_set_byte_count(grp_start, iop_chan, 0); | 1295 | iop_desc_set_byte_count(grp_start, iop_chan, 0); |
1304 | iop_desc_set_dest_addr(grp_start, iop_chan, 0); | 1296 | iop_desc_set_dest_addr(grp_start, iop_chan, 0); |
@@ -1354,7 +1346,7 @@ static void iop_chan_start_null_xor(struct iop_adma_chan *iop_chan) | |||
1354 | if (sw_desc) { | 1346 | if (sw_desc) { |
1355 | grp_start = sw_desc->group_head; | 1347 | grp_start = sw_desc->group_head; |
1356 | list_splice_init(&sw_desc->async_tx.tx_list, &iop_chan->chain); | 1348 | list_splice_init(&sw_desc->async_tx.tx_list, &iop_chan->chain); |
1357 | sw_desc->async_tx.ack = 1; | 1349 | async_tx_ack(&sw_desc->async_tx); |
1358 | iop_desc_init_null_xor(grp_start, 2, 0); | 1350 | iop_desc_init_null_xor(grp_start, 2, 0); |
1359 | iop_desc_set_byte_count(grp_start, iop_chan, 0); | 1351 | iop_desc_set_byte_count(grp_start, iop_chan, 0); |
1360 | iop_desc_set_dest_addr(grp_start, iop_chan, 0); | 1352 | iop_desc_set_dest_addr(grp_start, iop_chan, 0); |