| Linux kernel & device driver programming |
| [ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] |
1 /* 1
2 * offload engine driver for the Intel Xscale
3 * Copyright © 2006, Intel Corporation.
4 *
5 * This program is free software; you can redi
6 * under the terms and conditions of the GNU G
7 * version 2, as published by the Free Softwar
8 *
9 * This program is distributed in the hope it
10 * ANY WARRANTY; without even the implied warr
11 * FITNESS FOR A PARTICULAR PURPOSE. See the
12 * more details.
13 *
14 * You should have received a copy of the GNU
15 * this program; if not, write to the Free Sof
16 * 51 Franklin St - Fifth Floor, Boston, MA 02
17 *
18 */
19
20 /*
21 * This driver supports the asynchrounous DMA
22 * on the Intel Xscale(R) family of I/O Proces
23 */
24
25 #include <linux/init.h>
26 #include <linux/module.h>
27 #include <linux/async_tx.h>
28 #include <linux/delay.h>
29 #include <linux/dma-mapping.h>
30 #include <linux/spinlock.h>
31 #include <linux/interrupt.h>
32 #include <linux/platform_device.h>
33 #include <linux/memory.h>
34 #include <linux/ioport.h>
35
36 #include <asm/arch/adma.h>
37
38 #define to_iop_adma_chan(chan) container_of(ch
39 #define to_iop_adma_device(dev) \
40 container_of(dev, struct iop_adma_devi
41 #define tx_to_iop_adma_slot(tx) \
42 container_of(tx, struct iop_adma_desc_
43
44 /**
45 * iop_adma_free_slots - flags descriptor slot
46 * @slot: Slot to free
47 * Caller must hold &iop_chan->lock while call
48 */
49 static void iop_adma_free_slots(struct iop_adm
50 {
51 int stride = slot->slots_per_op;
52
53 while (stride--) {
54 slot->slots_per_op = 0;
55 slot = list_entry(slot->slot_n
56 struct iop_adm
57 slot_node);
58 }
59 }
60
61 static dma_cookie_t
62 iop_adma_run_tx_complete_actions(struct iop_ad
63 struct iop_adma_chan *iop_chan, dma_co
64 {
65 BUG_ON(desc->async_tx.cookie < 0);
66 spin_lock_bh(&desc->async_tx.lock);
67 if (desc->async_tx.cookie > 0) {
68 cookie = desc->async_tx.cookie
69 desc->async_tx.cookie = 0;
70
71 /* call the callback (must not
72 * operations to this channel)
73 */
74 if (desc->async_tx.callback)
75 desc->async_tx.callbac
76 desc->async_tx
77
78 /* unmap dma addresses
79 * (unmap_single vs unmap_page
80 */
81 if (desc->group_head && desc->
82 struct iop_adma_desc_s
83 struct device *dev =
84 &iop_chan->dev
85 u32 len = unmap->unmap
86 u32 src_cnt = unmap->u
87 dma_addr_t addr = iop_
88 iop_chan);
89
90 dma_unmap_page(dev, ad
91 while (src_cnt--) {
92 addr = iop_des
93
94
95 dma_unmap_page
96 DMA_TO
97 }
98 desc->group_head = NUL
99 }
100 }
101
102 /* run dependent operations */
103 async_tx_run_dependencies(&desc->async
104 spin_unlock_bh(&desc->async_tx.lock);
105
106 return cookie;
107 }
108
109 static int
110 iop_adma_clean_slot(struct iop_adma_desc_slot
111 struct iop_adma_chan *iop_chan)
112 {
113 /* the client is allowed to attach dep
114 * until 'ack' is set
115 */
116 if (!desc->async_tx.ack)
117 return 0;
118
119 /* leave the last descriptor in the ch
120 * so we can append to it
121 */
122 if (desc->chain_node.next == &iop_chan
123 return 1;
124
125 dev_dbg(iop_chan->device->common.dev,
126 "\tfree slot: %d slots_per_op:
127 desc->idx, desc->slots_per_op)
128
129 list_del(&desc->chain_node);
130 iop_adma_free_slots(desc);
131
132 return 0;
133 }
134
135 static void __iop_adma_slot_cleanup(struct iop
136 {
137 struct iop_adma_desc_slot *iter, *_ite
138 dma_cookie_t cookie = 0;
139 u32 current_desc = iop_chan_get_curren
140 int busy = iop_chan_is_busy(iop_chan);
141 int seen_current = 0, slot_cnt = 0, sl
142
143 dev_dbg(iop_chan->device->common.dev,
144 /* free completed slots from the chain
145 * the oldest descriptor
146 */
147 list_for_each_entry_safe(iter, _iter,
148 chain_
149 pr_debug("\tcookie: %d slot: %
150 "this_desc: %#x next_d
151 iter->async_tx.cookie,
152 iter->async_tx.phys, i
153 iter->async_tx.ack);
154 prefetch(_iter);
155 prefetch(&_iter->async_tx);
156
157 /* do not advance past the cur
158 * hardware channel, subsequen
159 * process or have not been su
160 */
161 if (seen_current)
162 break;
163
164 /* stop the search if we reach
165 * channel is busy, or if it a
166 * needs to be re-read (i.e. h
167 */
168 if (iter->async_tx.phys == cur
169 BUG_ON(seen_current++)
170 if (busy || iop_desc_g
171 break;
172 }
173
174 /* detect the start of a group
175 if (!slot_cnt && !slots_per_op
176 slot_cnt = iter->slot_
177 slots_per_op = iter->s
178 if (slot_cnt <= slots_
179 slot_cnt = 0;
180 slots_per_op =
181 }
182 }
183
184 if (slot_cnt) {
185 pr_debug("\tgroup++\n"
186 if (!grp_start)
187 grp_start = it
188 slot_cnt -= slots_per_
189 }
190
191 /* all the members of a group
192 if (slots_per_op != 0 && slot_
193 struct iop_adma_desc_s
194 int end_of_chain = 0;
195 pr_debug("\tgroup end\
196
197 /* collect the total r
198 if (grp_start->xor_che
199 u32 zero_sum_r
200 slot_cnt = grp
201 grp_iter = grp
202
203 list_for_each_
204 &iop_c
205 zero_s
206 io
207 pr
208 gr
209 slot_c
210 if (sl
211
212 }
213 pr_debug("\tgr
214 grp_st
215 *grp_start->xo
216 }
217
218 /* clean up the group
219 slot_cnt = grp_start->
220 grp_iter = grp_start;
221 list_for_each_entry_sa
222 &iop_chan->cha
223 cookie = iop_a
224 grp_it
225
226 slot_cnt -= sl
227 end_of_chain =
228 iop_ch
229
230 if (slot_cnt =
231 break;
232 }
233
234 /* the group should be
235 BUG_ON(slot_cnt);
236
237 slots_per_op = 0;
238 grp_start = NULL;
239 if (end_of_chain)
240 break;
241 else
242 continue;
243 } else if (slots_per_op) /* wa
244 continue;
245
246 /* write back zero sum results
247 if (iter->xor_check_result &&
248 *iter->xor_check_resul
249 iop_desc_get_z
250
251 cookie = iop_adma_run_tx_compl
252 iter,
253
254 if (iop_adma_clean_slot(iter,
255 break;
256 }
257
258 BUG_ON(!seen_current);
259
260 iop_chan_idle(busy, iop_chan);
261
262 if (cookie > 0) {
263 iop_chan->completed_cookie = c
264 pr_debug("\tcompleted cookie %
265 }
266 }
267
268 static void
269 iop_adma_slot_cleanup(struct iop_adma_chan *io
270 {
271 spin_lock_bh(&iop_chan->lock);
272 __iop_adma_slot_cleanup(iop_chan);
273 spin_unlock_bh(&iop_chan->lock);
274 }
275
276 static void iop_adma_tasklet(unsigned long dat
277 {
278 struct iop_adma_chan *chan = (struct i
279 __iop_adma_slot_cleanup(chan);
280 }
281
282 static struct iop_adma_desc_slot *
283 iop_adma_alloc_slots(struct iop_adma_chan *iop
284 int slots_per_op)
285 {
286 struct iop_adma_desc_slot *iter, *_ite
287 LIST_HEAD(chain);
288 int slots_found, retry = 0;
289
290 /* start search from the last allocate
291 * if a contiguous allocation can not
292 * from the beginning of the list
293 */
294 retry:
295 slots_found = 0;
296 if (retry == 0)
297 iter = iop_chan->last_used;
298 else
299 iter = list_entry(&iop_chan->a
300 struct iop_adma_desc_s
301 slot_node);
302
303 list_for_each_entry_safe_continue(
304 iter, _iter, &iop_chan->all_sl
305 prefetch(_iter);
306 prefetch(&_iter->async_tx);
307 if (iter->slots_per_op) {
308 /* give up after findi
309 * on the second pass
310 */
311 if (retry)
312 break;
313
314 slots_found = 0;
315 continue;
316 }
317
318 /* start the allocation if the
319 if (!slots_found++) {
320 if (iop_desc_is_aligne
321 alloc_start =
322 else {
323 slots_found =
324 continue;
325 }
326 }
327
328 if (slots_found == num_slots)
329 struct iop_adma_desc_s
330 struct iop_adma_desc_s
331 iter = alloc_start;
332 while (num_slots) {
333 int i;
334 dev_dbg(iop_ch
335 "alloc
336 "(desc
337 iter->
338 iter->
339
340 /* pre-ack all
341 if (num_slots
342 iter->
343 else
344 iter->
345
346 list_add_tail(
347 alloc_tail = i
348 iter->async_tx
349 iter->slot_cnt
350 iter->xor_chec
351 for (i = 0; i
352 iter->
353 last_u
354 iter =
355
356
357 }
358 num_slots -= s
359 }
360 alloc_tail->group_head
361 alloc_tail->async_tx.c
362 list_splice(&chain, &a
363 iop_chan->last_used =
364 iop_desc_clear_next_de
365 iop_desc_clear_next_de
366 return alloc_tail;
367 }
368 }
369 if (!retry++)
370 goto retry;
371
372 /* try to free some slots if the alloc
373 tasklet_schedule(&iop_chan->irq_taskle
374
375 return NULL;
376 }
377
378 static dma_cookie_t
379 iop_desc_assign_cookie(struct iop_adma_chan *i
380 struct iop_adma_desc_slot *desc)
381 {
382 dma_cookie_t cookie = iop_chan->common
383 cookie++;
384 if (cookie < 0)
385 cookie = 1;
386 iop_chan->common.cookie = desc->async_
387 return cookie;
388 }
389
390 static void iop_adma_check_threshold(struct io
391 {
392 dev_dbg(iop_chan->device->common.dev,
393 iop_chan->pending);
394
395 if (iop_chan->pending >= IOP_ADMA_THRE
396 iop_chan->pending = 0;
397 iop_chan_append(iop_chan);
398 }
399 }
400
401 static dma_cookie_t
402 iop_adma_tx_submit(struct dma_async_tx_descrip
403 {
404 struct iop_adma_desc_slot *sw_desc = t
405 struct iop_adma_chan *iop_chan = to_io
406 struct iop_adma_desc_slot *grp_start,
407 int slot_cnt;
408 int slots_per_op;
409 dma_cookie_t cookie;
410
411 grp_start = sw_desc->group_head;
412 slot_cnt = grp_start->slot_cnt;
413 slots_per_op = grp_start->slots_per_op
414
415 spin_lock_bh(&iop_chan->lock);
416 cookie = iop_desc_assign_cookie(iop_ch
417
418 old_chain_tail = list_entry(iop_chan->
419 struct iop_adma_desc_slot, cha
420 list_splice_init(&sw_desc->async_tx.tx
421 &old_chain_tail->chai
422
423 /* fix up the hardware chain */
424 iop_desc_set_next_desc(old_chain_tail,
425
426 /* 1/ don't add pre-chained descriptor
427 * 2/ dummy read to flush next_desc wr
428 */
429 BUG_ON(iop_desc_get_next_desc(sw_desc)
430
431 /* increment the pending count by the
432 * memcpy operations have a 1:1 (slot:
433 * other operations are heavier and wi
434 * more often.
435 */
436 iop_chan->pending += slot_cnt;
437 iop_adma_check_threshold(iop_chan);
438 spin_unlock_bh(&iop_chan->lock);
439
440 dev_dbg(iop_chan->device->common.dev,
441 __func__, sw_desc->async_tx.co
442
443 return cookie;
444 }
445
446 static void iop_chan_start_null_memcpy(struct
447 static void iop_chan_start_null_xor(struct iop
448
449 /* returns the number of allocated descriptors
450 static int iop_adma_alloc_chan_resources(struc
451 {
452 char *hw_desc;
453 int idx;
454 struct iop_adma_chan *iop_chan = to_io
455 struct iop_adma_desc_slot *slot = NULL
456 int init = iop_chan->slots_allocated ?
457 struct iop_adma_platform_data *plat_da
458 iop_chan->device->pdev->dev.pl
459 int num_descs_in_pool = plat_data->poo
460
461 /* Allocate descriptor slots */
462 do {
463 idx = iop_chan->slots_allocate
464 if (idx == num_descs_in_pool)
465 break;
466
467 slot = kzalloc(sizeof(*slot),
468 if (!slot) {
469 printk(KERN_INFO "IOP
470 " %d descripto
471 break;
472 }
473 hw_desc = (char *) iop_chan->d
474 slot->hw_desc = (void *) &hw_d
475
476 dma_async_tx_descriptor_init(&
477 slot->async_tx.tx_submit = iop
478 INIT_LIST_HEAD(&slot->chain_no
479 INIT_LIST_HEAD(&slot->slot_nod
480 INIT_LIST_HEAD(&slot->async_tx
481 hw_desc = (char *) iop_chan->d
482 slot->async_tx.phys =
483 (dma_addr_t) &hw_desc[
484 slot->idx = idx;
485
486 spin_lock_bh(&iop_chan->lock);
487 iop_chan->slots_allocated++;
488 list_add_tail(&slot->slot_node
489 spin_unlock_bh(&iop_chan->lock
490 } while (iop_chan->slots_allocated < n
491
492 if (idx && !iop_chan->last_used)
493 iop_chan->last_used = list_ent
494 struct
495 slot_n
496
497 dev_dbg(iop_chan->device->common.dev,
498 "allocated %d descriptor slots
499 iop_chan->slots_allocated, iop
500
501 /* initialize the channel and the chai
502 if (init) {
503 if (dma_has_cap(DMA_MEMCPY,
504 iop_chan->device->comm
505 iop_chan_start_null_me
506 else if (dma_has_cap(DMA_XOR,
507 iop_chan->device->comm
508 iop_chan_start_null_xo
509 else
510 BUG();
511 }
512
513 return (idx > 0) ? idx : -ENOMEM;
514 }
515
516 static struct dma_async_tx_descriptor *
517 iop_adma_prep_dma_interrupt(struct dma_chan *c
518 {
519 struct iop_adma_chan *iop_chan = to_io
520 struct iop_adma_desc_slot *sw_desc, *g
521 int slot_cnt, slots_per_op;
522
523 dev_dbg(iop_chan->device->common.dev,
524
525 spin_lock_bh(&iop_chan->lock);
526 slot_cnt = iop_chan_interrupt_slot_cou
527 sw_desc = iop_adma_alloc_slots(iop_cha
528 if (sw_desc) {
529 grp_start = sw_desc->group_hea
530 iop_desc_init_interrupt(grp_st
531 grp_start->unmap_len = 0;
532 }
533 spin_unlock_bh(&iop_chan->lock);
534
535 return sw_desc ? &sw_desc->async_tx :
536 }
537
538 static struct dma_async_tx_descriptor *
539 iop_adma_prep_dma_memcpy(struct dma_chan *chan
540 dma_addr_t dma_src, s
541 {
542 struct iop_adma_chan *iop_chan = to_io
543 struct iop_adma_desc_slot *sw_desc, *g
544 int slot_cnt, slots_per_op;
545
546 if (unlikely(!len))
547 return NULL;
548 BUG_ON(unlikely(len > IOP_ADMA_MAX_BYT
549
550 dev_dbg(iop_chan->device->common.dev,
551 __func__, len);
552
553 spin_lock_bh(&iop_chan->lock);
554 slot_cnt = iop_chan_memcpy_slot_count(
555 sw_desc = iop_adma_alloc_slots(iop_cha
556 if (sw_desc) {
557 grp_start = sw_desc->group_hea
558 iop_desc_init_memcpy(grp_start
559 iop_desc_set_byte_count(grp_st
560 iop_desc_set_dest_addr(grp_sta
561 iop_desc_set_memcpy_src_addr(g
562 sw_desc->unmap_src_cnt = 1;
563 sw_desc->unmap_len = len;
564 }
565 spin_unlock_bh(&iop_chan->lock);
566
567 return sw_desc ? &sw_desc->async_tx :
568 }
569
570 static struct dma_async_tx_descriptor *
571 iop_adma_prep_dma_memset(struct dma_chan *chan
572 int value, size_t len
573 {
574 struct iop_adma_chan *iop_chan = to_io
575 struct iop_adma_desc_slot *sw_desc, *g
576 int slot_cnt, slots_per_op;
577
578 if (unlikely(!len))
579 return NULL;
580 BUG_ON(unlikely(len > IOP_ADMA_MAX_BYT
581
582 dev_dbg(iop_chan->device->common.dev,
583 __func__, len);
584
585 spin_lock_bh(&iop_chan->lock);
586 slot_cnt = iop_chan_memset_slot_count(
587 sw_desc = iop_adma_alloc_slots(iop_cha
588 if (sw_desc) {
589 grp_start = sw_desc->group_hea
590 iop_desc_init_memset(grp_start
591 iop_desc_set_byte_count(grp_st
592 iop_desc_set_block_fill_val(gr
593 iop_desc_set_dest_addr(grp_sta
594 sw_desc->unmap_src_cnt = 1;
595 sw_desc->unmap_len = len;
596 }
597 spin_unlock_bh(&iop_chan->lock);
598
599 return sw_desc ? &sw_desc->async_tx :
600 }
601
602 static struct dma_async_tx_descriptor *
603 iop_adma_prep_dma_xor(struct dma_chan *chan, d
604 dma_addr_t *dma_src, uns
605 unsigned long flags)
606 {
607 struct iop_adma_chan *iop_chan = to_io
608 struct iop_adma_desc_slot *sw_desc, *g
609 int slot_cnt, slots_per_op;
610
611 if (unlikely(!len))
612 return NULL;
613 BUG_ON(unlikely(len > IOP_ADMA_XOR_MAX
614
615 dev_dbg(iop_chan->device->common.dev,
616 "%s src_cnt: %d len: %u flags:
617 __func__, src_cnt, len, flags)
618
619 spin_lock_bh(&iop_chan->lock);
620 slot_cnt = iop_chan_xor_slot_count(len
621 sw_desc = iop_adma_alloc_slots(iop_cha
622 if (sw_desc) {
623 grp_start = sw_desc->group_hea
624 iop_desc_init_xor(grp_start, s
625 iop_desc_set_byte_count(grp_st
626 iop_desc_set_dest_addr(grp_sta
627 sw_desc->unmap_src_cnt = src_c
628 sw_desc->unmap_len = len;
629 while (src_cnt--)
630 iop_desc_set_xor_src_a
631
632 }
633 spin_unlock_bh(&iop_chan->lock);
634
635 return sw_desc ? &sw_desc->async_tx :
636 }
637
638 static struct dma_async_tx_descriptor *
639 iop_adma_prep_dma_zero_sum(struct dma_chan *ch
640 unsigned int src_cn
641 unsigned long flags
642 {
643 struct iop_adma_chan *iop_chan = to_io
644 struct iop_adma_desc_slot *sw_desc, *g
645 int slot_cnt, slots_per_op;
646
647 if (unlikely(!len))
648 return NULL;
649
650 dev_dbg(iop_chan->device->common.dev,
651 __func__, src_cnt, len);
652
653 spin_lock_bh(&iop_chan->lock);
654 slot_cnt = iop_chan_zero_sum_slot_coun
655 sw_desc = iop_adma_alloc_slots(iop_cha
656 if (sw_desc) {
657 grp_start = sw_desc->group_hea
658 iop_desc_init_zero_sum(grp_sta
659 iop_desc_set_zero_sum_byte_cou
660 grp_start->xor_check_result =
661 pr_debug("\t%s: grp_start->xor
662 __func__, grp_start->x
663 sw_desc->unmap_src_cnt = src_c
664 sw_desc->unmap_len = len;
665 while (src_cnt--)
666 iop_desc_set_zero_sum_
667
668 }
669 spin_unlock_bh(&iop_chan->lock);
670
671 return sw_desc ? &sw_desc->async_tx :
672 }
673
674 static void iop_adma_dependency_added(struct d
675 {
676 struct iop_adma_chan *iop_chan = to_io
677 tasklet_schedule(&iop_chan->irq_taskle
678 }
679
680 static void iop_adma_free_chan_resources(struc
681 {
682 struct iop_adma_chan *iop_chan = to_io
683 struct iop_adma_desc_slot *iter, *_ite
684 int in_use_descs = 0;
685
686 iop_adma_slot_cleanup(iop_chan);
687
688 spin_lock_bh(&iop_chan->lock);
689 list_for_each_entry_safe(iter, _iter,
690 chain_
691 in_use_descs++;
692 list_del(&iter->chain_node);
693 }
694 list_for_each_entry_safe_reverse(
695 iter, _iter, &iop_chan->all_sl
696 list_del(&iter->slot_node);
697 kfree(iter);
698 iop_chan->slots_allocated--;
699 }
700 iop_chan->last_used = NULL;
701
702 dev_dbg(iop_chan->device->common.dev,
703 __func__, iop_chan->slots_allo
704 spin_unlock_bh(&iop_chan->lock);
705
706 /* one is ok since we left it on there
707 if (in_use_descs > 1)
708 printk(KERN_ERR "IOP: Freeing
709 in_use_descs - 1);
710 }
711
712 /**
713 * iop_adma_is_complete - poll the status of a
714 * @chan: ADMA channel handle
715 * @cookie: ADMA transaction identifier
716 */
717 static enum dma_status iop_adma_is_complete(st
718 dma_co
719 dma_co
720 dma_co
721 {
722 struct iop_adma_chan *iop_chan = to_io
723 dma_cookie_t last_used;
724 dma_cookie_t last_complete;
725 enum dma_status ret;
726
727 last_used = chan->cookie;
728 last_complete = iop_chan->completed_co
729
730 if (done)
731 *done = last_complete;
732 if (used)
733 *used = last_used;
734
735 ret = dma_async_is_complete(cookie, la
736 if (ret == DMA_SUCCESS)
737 return ret;
738
739 iop_adma_slot_cleanup(iop_chan);
740
741 last_used = chan->cookie;
742 last_complete = iop_chan->completed_co
743
744 if (done)
745 *done = last_complete;
746 if (used)
747 *used = last_used;
748
749 return dma_async_is_complete(cookie, l
750 }
751
752 static irqreturn_t iop_adma_eot_handler(int ir
753 {
754 struct iop_adma_chan *chan = data;
755
756 dev_dbg(chan->device->common.dev, "%s\
757
758 tasklet_schedule(&chan->irq_tasklet);
759
760 iop_adma_device_clear_eot_status(chan)
761
762 return IRQ_HANDLED;
763 }
764
765 static irqreturn_t iop_adma_eoc_handler(int ir
766 {
767 struct iop_adma_chan *chan = data;
768
769 dev_dbg(chan->device->common.dev, "%s\
770
771 tasklet_schedule(&chan->irq_tasklet);
772
773 iop_adma_device_clear_eoc_status(chan)
774
775 return IRQ_HANDLED;
776 }
777
778 static irqreturn_t iop_adma_err_handler(int ir
779 {
780 struct iop_adma_chan *chan = data;
781 unsigned long status = iop_chan_get_st
782
783 dev_printk(KERN_ERR, chan->device->com
784 "error ( %s%s%s%s%s%s%s)\n",
785 iop_is_err_int_parity(status,
786 iop_is_err_mcu_abort(status, c
787 iop_is_err_int_tabort(status,
788 iop_is_err_int_mabort(status,
789 iop_is_err_pci_tabort(status,
790 iop_is_err_pci_mabort(status,
791 iop_is_err_split_tx(status, ch
792
793 iop_adma_device_clear_err_status(chan)
794
795 BUG();
796
797 return IRQ_HANDLED;
798 }
799
800 static void iop_adma_issue_pending(struct dma_
801 {
802 struct iop_adma_chan *iop_chan = to_io
803
804 if (iop_chan->pending) {
805 iop_chan->pending = 0;
806 iop_chan_append(iop_chan);
807 }
808 }
809
810 /*
811 * Perform a transaction to verify the HW work
812 */
813 #define IOP_ADMA_TEST_SIZE 2000
814
815 static int __devinit iop_adma_memcpy_self_test
816 {
817 int i;
818 void *src, *dest;
819 dma_addr_t src_dma, dest_dma;
820 struct dma_chan *dma_chan;
821 dma_cookie_t cookie;
822 struct dma_async_tx_descriptor *tx;
823 int err = 0;
824 struct iop_adma_chan *iop_chan;
825
826 dev_dbg(device->common.dev, "%s\n", __
827
828 src = kzalloc(sizeof(u8) * IOP_ADMA_TE
829 if (!src)
830 return -ENOMEM;
831 dest = kzalloc(sizeof(u8) * IOP_ADMA_T
832 if (!dest) {
833 kfree(src);
834 return -ENOMEM;
835 }
836
837 /* Fill in src buffer */
838 for (i = 0; i < IOP_ADMA_TEST_SIZE; i+
839 ((u8 *) src)[i] = (u8)i;
840
841 memset(dest, 0, IOP_ADMA_TEST_SIZE);
842
843 /* Start copy, using first DMA channel
844 dma_chan = container_of(device->common
845 struct dma_cha
846 device_node);
847 if (iop_adma_alloc_chan_resources(dma_
848 err = -ENODEV;
849 goto out;
850 }
851
852 dest_dma = dma_map_single(dma_chan->de
853 IOP_ADMA_TEST_
854 src_dma = dma_map_single(dma_chan->dev
855 IOP_ADMA_TEST_
856 tx = iop_adma_prep_dma_memcpy(dma_chan
857 IOP_ADMA
858
859 cookie = iop_adma_tx_submit(tx);
860 iop_adma_issue_pending(dma_chan);
861 async_tx_ack(tx);
862 msleep(1);
863
864 if (iop_adma_is_complete(dma_chan, coo
865 DMA_SUCCESS) {
866 dev_printk(KERN_ERR, dma_chan-
867 "Self-test copy timed
868 err = -ENODEV;
869 goto free_resources;
870 }
871
872 iop_chan = to_iop_adma_chan(dma_chan);
873 dma_sync_single_for_cpu(&iop_chan->dev
874 IOP_ADMA_TEST_SIZE, DMA_FROM_D
875 if (memcmp(src, dest, IOP_ADMA_TEST_SI
876 dev_printk(KERN_ERR, dma_chan-
877 "Self-test copy failed
878 err = -ENODEV;
879 goto free_resources;
880 }
881
882 free_resources:
883 iop_adma_free_chan_resources(dma_chan)
884 out:
885 kfree(src);
886 kfree(dest);
887 return err;
888 }
889
890 #define IOP_ADMA_NUM_SRC_TEST 4 /* must be <=
891 static int __devinit
892 iop_adma_xor_zero_sum_self_test(struct iop_adm
893 {
894 int i, src_idx;
895 struct page *dest;
896 struct page *xor_srcs[IOP_ADMA_NUM_SRC
897 struct page *zero_sum_srcs[IOP_ADMA_NU
898 dma_addr_t dma_srcs[IOP_ADMA_NUM_SRC_T
899 dma_addr_t dma_addr, dest_dma;
900 struct dma_async_tx_descriptor *tx;
901 struct dma_chan *dma_chan;
902 dma_cookie_t cookie;
903 u8 cmp_byte = 0;
904 u32 cmp_word;
905 u32 zero_sum_result;
906 int err = 0;
907 struct iop_adma_chan *iop_chan;
908
909 dev_dbg(device->common.dev, "%s\n", __
910
911 for (src_idx = 0; src_idx < IOP_ADMA_N
912 xor_srcs[src_idx] = alloc_page
913 if (!xor_srcs[src_idx])
914 while (src_idx--) {
915 __free_page(xo
916 return -ENOMEM
917 }
918 }
919
920 dest = alloc_page(GFP_KERNEL);
921 if (!dest)
922 while (src_idx--) {
923 __free_page(xor_srcs[s
924 return -ENOMEM;
925 }
926
927 /* Fill in src buffers */
928 for (src_idx = 0; src_idx < IOP_ADMA_N
929 u8 *ptr = page_address(xor_src
930 for (i = 0; i < PAGE_SIZE; i++
931 ptr[i] = (1 << src_idx
932 }
933
934 for (src_idx = 0; src_idx < IOP_ADMA_N
935 cmp_byte ^= (u8) (1 << src_idx
936
937 cmp_word = (cmp_byte << 24) | (cmp_byt
938 (cmp_byte << 8) | cmp_
939
940 memset(page_address(dest), 0, PAGE_SIZ
941
942 dma_chan = container_of(device->common
943 struct dma_cha
944 device_node);
945 if (iop_adma_alloc_chan_resources(dma_
946 err = -ENODEV;
947 goto out;
948 }
949
950 /* test xor */
951 dest_dma = dma_map_page(dma_chan->devi
952 PAGE_SIZE, DMA
953 for (i = 0; i < IOP_ADMA_NUM_SRC_TEST;
954 dma_srcs[i] = dma_map_page(dma
955 0,
956 tx = iop_adma_prep_dma_xor(dma_chan, d
957 IOP_ADMA_NU
958
959 cookie = iop_adma_tx_submit(tx);
960 iop_adma_issue_pending(dma_chan);
961 async_tx_ack(tx);
962 msleep(8);
963
964 if (iop_adma_is_complete(dma_chan, coo
965 DMA_SUCCESS) {
966 dev_printk(KERN_ERR, dma_chan-
967 "Self-test xor timed o
968 err = -ENODEV;
969 goto free_resources;
970 }
971
972 iop_chan = to_iop_adma_chan(dma_chan);
973 dma_sync_single_for_cpu(&iop_chan->dev
974 PAGE_SIZE, DMA_FROM_DEVICE);
975 for (i = 0; i < (PAGE_SIZE / sizeof(u3
976 u32 *ptr = page_address(dest);
977 if (ptr[i] != cmp_word) {
978 dev_printk(KERN_ERR, d
979 "Self-test xor
980 err = -ENODEV;
981 goto free_resources;
982 }
983 }
984 dma_sync_single_for_device(&iop_chan->
985 PAGE_SIZE, DMA_TO_DEVICE);
986
987 /* skip zero sum if the capability is
988 if (!dma_has_cap(DMA_ZERO_SUM, dma_cha
989 goto free_resources;
990
991 /* zero sum the sources with the desti
992 for (i = 0; i < IOP_ADMA_NUM_SRC_TEST;
993 zero_sum_srcs[i] = xor_srcs[i]
994 zero_sum_srcs[i] = dest;
995
996 zero_sum_result = 1;
997
998 for (i = 0; i < IOP_ADMA_NUM_SRC_TEST
999 dma_srcs[i] = dma_map_page(dma
1000 ze
1001 DM
1002 tx = iop_adma_prep_dma_zero_sum(dma_c
1003 IOP_A
1004 &zero
1005
1006 cookie = iop_adma_tx_submit(tx);
1007 iop_adma_issue_pending(dma_chan);
1008 async_tx_ack(tx);
1009 msleep(8);
1010
1011 if (iop_adma_is_complete(dma_chan, co
1012 dev_printk(KERN_ERR, dma_chan
1013 "Self-test zero sum t
1014 err = -ENODEV;
1015 goto free_resources;
1016 }
1017
1018 if (zero_sum_result != 0) {
1019 dev_printk(KERN_ERR, dma_chan
1020 "Self-test zero sum f
1021 err = -ENODEV;
1022 goto free_resources;
1023 }
1024
1025 /* test memset */
1026 dma_addr = dma_map_page(dma_chan->dev
1027 PAGE_SIZE, DMA_FROM_D
1028 tx = iop_adma_prep_dma_memset(dma_cha
1029
1030 cookie = iop_adma_tx_submit(tx);
1031 iop_adma_issue_pending(dma_chan);
1032 async_tx_ack(tx);
1033 msleep(8);
1034
1035 if (iop_adma_is_complete(dma_chan, co
1036 dev_printk(KERN_ERR, dma_chan
1037 "Self-test memset tim
1038 err = -ENODEV;
1039 goto free_resources;
1040 }
1041
1042 for (i = 0; i < PAGE_SIZE/sizeof(u32)
1043 u32 *ptr = page_address(dest)
1044 if (ptr[i]) {
1045 dev_printk(KERN_ERR,
1046 "Self-test me
1047 err = -ENODEV;
1048 goto free_resources;
1049 }
1050 }
1051
1052 /* test for non-zero parity sum */
1053 zero_sum_result = 0;
1054 for (i = 0; i < IOP_ADMA_NUM_SRC_TEST
1055 dma_srcs[i] = dma_map_page(dm
1056 ze
1057 DM
1058 tx = iop_adma_prep_dma_zero_sum(dma_c
1059 IOP_A
1060 &zero
1061
1062 cookie = iop_adma_tx_submit(tx);
1063 iop_adma_issue_pending(dma_chan);
1064 async_tx_ack(tx);
1065 msleep(8);
1066
1067 if (iop_adma_is_complete(dma_chan, co
1068 dev_printk(KERN_ERR, dma_chan
1069 "Self-test non-zero s
1070 err = -ENODEV;
1071 goto free_resources;
1072 }
1073
1074 if (zero_sum_result != 1) {
1075 dev_printk(KERN_ERR, dma_chan
1076 "Self-test non-zero s
1077 err = -ENODEV;
1078 goto free_resources;
1079 }
1080
1081 free_resources:
1082 iop_adma_free_chan_resources(dma_chan
1083 out:
1084 src_idx = IOP_ADMA_NUM_SRC_TEST;
1085 while (src_idx--)
1086 __free_page(xor_srcs[src_idx]
1087 __free_page(dest);
1088 return err;
1089 }
1090
1091 static int __devexit iop_adma_remove(struct p
1092 {
1093 struct iop_adma_device *device = plat
1094 struct dma_chan *chan, *_chan;
1095 struct iop_adma_chan *iop_chan;
1096 int i;
1097 struct iop_adma_platform_data *plat_d
1098
1099 dma_async_device_unregister(&device->
1100
1101 for (i = 0; i < 3; i++) {
1102 unsigned int irq;
1103 irq = platform_get_irq(dev, i
1104 free_irq(irq, device);
1105 }
1106
1107 dma_free_coherent(&dev->dev, plat_dat
1108 device->dma_desc_pool
1109
1110 do {
1111 struct resource *res;
1112 res = platform_get_resource(d
1113 release_mem_region(res->start
1114 } while (0);
1115
1116 list_for_each_entry_safe(chan, _chan,
1117 device_node)
1118 iop_chan = to_iop_adma_chan(c
1119 list_del(&chan->device_node);
1120 kfree(iop_chan);
1121 }
1122 kfree(device);
1123
1124 return 0;
1125 }
1126
1127 static int __devinit iop_adma_probe(struct pl
1128 {
1129 struct resource *res;
1130 int ret = 0, i;
1131 struct iop_adma_device *adev;
1132 struct iop_adma_chan *iop_chan;
1133 struct dma_device *dma_dev;
1134 struct iop_adma_platform_data *plat_d
1135
1136 res = platform_get_resource(pdev, IOR
1137 if (!res)
1138 return -ENODEV;
1139
1140 if (!devm_request_mem_region(&pdev->d
1141 res->end - re
1142 return -EBUSY;
1143
1144 adev = kzalloc(sizeof(*adev), GFP_KER
1145 if (!adev)
1146 return -ENOMEM;
1147 dma_dev = &adev->common;
1148
1149 /* allocate coherent memory for hardw
1150 * note: writecombine gives slightly
1151 * requires that we explicitly flush
1152 */
1153 if ((adev->dma_desc_pool_virt = dma_a
1154 plat_
1155 &adev
1156 GFP_K
1157 ret = -ENOMEM;
1158 goto err_free_adev;
1159 }
1160
1161 dev_dbg(&pdev->dev, "%s: allocted des
1162 __func__, adev->dma_desc_pool
1163 (void *) adev->dma_desc_pool)
1164
1165 adev->id = plat_data->hw_id;
1166
1167 /* discover transaction capabilites f
1168 dma_dev->cap_mask = plat_data->cap_ma
1169
1170 adev->pdev = pdev;
1171 platform_set_drvdata(pdev, adev);
1172
1173 INIT_LIST_HEAD(&dma_dev->channels);
1174
1175 /* set base routines */
1176 dma_dev->device_alloc_chan_resources
1177 dma_dev->device_free_chan_resources =
1178 dma_dev->device_is_tx_complete = iop_
1179 dma_dev->device_issue_pending = iop_a
1180 dma_dev->device_dependency_added = io
1181 dma_dev->dev = &pdev->dev;
1182
1183 /* set prep routines based on capabil
1184 if (dma_has_cap(DMA_MEMCPY, dma_dev->
1185 dma_dev->device_prep_dma_memc
1186 if (dma_has_cap(DMA_MEMSET, dma_dev->
1187 dma_dev->device_prep_dma_mems
1188 if (dma_has_cap(DMA_XOR, dma_dev->cap
1189 dma_dev->max_xor = iop_adma_g
1190 dma_dev->device_prep_dma_xor
1191 }
1192 if (dma_has_cap(DMA_ZERO_SUM, dma_dev
1193 dma_dev->device_prep_dma_zero
1194 iop_adma_prep_dma_zer
1195 if (dma_has_cap(DMA_INTERRUPT, dma_de
1196 dma_dev->device_prep_dma_inte
1197 iop_adma_prep_dma_int
1198
1199 iop_chan = kzalloc(sizeof(*iop_chan),
1200 if (!iop_chan) {
1201 ret = -ENOMEM;
1202 goto err_free_dma;
1203 }
1204 iop_chan->device = adev;
1205
1206 iop_chan->mmr_base = devm_ioremap(&pd
1207 res->
1208 if (!iop_chan->mmr_base) {
1209 ret = -ENOMEM;
1210 goto err_free_iop_chan;
1211 }
1212 tasklet_init(&iop_chan->irq_tasklet,
1213 iop_chan);
1214
1215 /* clear errors before enabling inter
1216 iop_adma_device_clear_err_status(iop_
1217
1218 for (i = 0; i < 3; i++) {
1219 irq_handler_t handler[] = { i
1220 iop_a
1221 iop_a
1222 int irq = platform_get_irq(pd
1223 if (irq < 0) {
1224 ret = -ENXIO;
1225 goto err_free_iop_cha
1226 } else {
1227 ret = devm_request_ir
1228 handl
1229 if (ret)
1230 goto err_free
1231 }
1232 }
1233
1234 spin_lock_init(&iop_chan->lock);
1235 init_timer(&iop_chan->cleanup_watchdo
1236 iop_chan->cleanup_watchdog.data = (un
1237 iop_chan->cleanup_watchdog.function =
1238 INIT_LIST_HEAD(&iop_chan->chain);
1239 INIT_LIST_HEAD(&iop_chan->all_slots);
1240 INIT_RCU_HEAD(&iop_chan->common.rcu);
1241 iop_chan->common.device = dma_dev;
1242 list_add_tail(&iop_chan->common.devic
1243
1244 if (dma_has_cap(DMA_MEMCPY, dma_dev->
1245 ret = iop_adma_memcpy_self_te
1246 dev_dbg(&pdev->dev, "memcpy s
1247 if (ret)
1248 goto err_free_iop_cha
1249 }
1250
1251 if (dma_has_cap(DMA_XOR, dma_dev->cap
1252 dma_has_cap(DMA_MEMSET, dma_d
1253 ret = iop_adma_xor_zero_sum_s
1254 dev_dbg(&pdev->dev, "xor self
1255 if (ret)
1256 goto err_free_iop_cha
1257 }
1258
1259 dev_printk(KERN_INFO, &pdev->dev, "In
1260 "( %s%s%s%s%s%s%s%s%s%s)\n",
1261 dma_has_cap(DMA_PQ_XOR, dma_dev->ca
1262 dma_has_cap(DMA_PQ_UPDATE, dma_dev-
1263 dma_has_cap(DMA_PQ_ZERO_SUM, dma_de
1264 dma_has_cap(DMA_XOR, dma_dev->cap_m
1265 dma_has_cap(DMA_DUAL_XOR, dma_dev->
1266 dma_has_cap(DMA_ZERO_SUM, dma_dev->
1267 dma_has_cap(DMA_MEMSET, dma_dev->ca
1268 dma_has_cap(DMA_MEMCPY_CRC32C, dma_
1269 dma_has_cap(DMA_MEMCPY, dma_dev->ca
1270 dma_has_cap(DMA_INTERRUPT, dma_dev-
1271
1272 dma_async_device_register(dma_dev);
1273 goto out;
1274
1275 err_free_iop_chan:
1276 kfree(iop_chan);
1277 err_free_dma:
1278 dma_free_coherent(&adev->pdev->dev, p
1279 adev->dma_desc_pool_v
1280 err_free_adev:
1281 kfree(adev);
1282 out:
1283 return ret;
1284 }
1285
1286 static void iop_chan_start_null_memcpy(struct
1287 {
1288 struct iop_adma_desc_slot *sw_desc, *
1289 dma_cookie_t cookie;
1290 int slot_cnt, slots_per_op;
1291
1292 dev_dbg(iop_chan->device->common.dev,
1293
1294 spin_lock_bh(&iop_chan->lock);
1295 slot_cnt = iop_chan_memcpy_slot_count
1296 sw_desc = iop_adma_alloc_slots(iop_ch
1297 if (sw_desc) {
1298 grp_start = sw_desc->group_he
1299
1300 list_splice_init(&sw_desc->as
1301 sw_desc->async_tx.ack = 1;
1302 iop_desc_init_memcpy(grp_star
1303 iop_desc_set_byte_count(grp_s
1304 iop_desc_set_dest_addr(grp_st
1305 iop_desc_set_memcpy_src_addr(
1306
1307 cookie = iop_chan->common.coo
1308 cookie++;
1309 if (cookie <= 1)
1310 cookie = 2;
1311
1312 /* initialize the completed c
1313 * the most recently used coo
1314 */
1315 iop_chan->completed_cookie =
1316 iop_chan->common.cookie = sw_
1317
1318 /* channel should not be busy
1319 BUG_ON(iop_chan_is_busy(iop_c
1320
1321 /* clear any prior error-stat
1322 iop_adma_device_clear_err_sta
1323
1324 /* disable operation */
1325 iop_chan_disable(iop_chan);
1326
1327 /* set the descriptor address
1328 iop_chan_set_next_descriptor(
1329
1330 /* 1/ don't add pre-chained d
1331 * 2/ dummy read to flush nex
1332 */
1333 BUG_ON(iop_desc_get_next_desc
1334
1335 /* run the descriptor */
1336 iop_chan_enable(iop_chan);
1337 } else
1338 dev_printk(KERN_ERR, iop_chan
1339 "failed to allocate
1340 spin_unlock_bh(&iop_chan->lock);
1341 }
1342
1343 static void iop_chan_start_null_xor(struct io
1344 {
1345 struct iop_adma_desc_slot *sw_desc, *
1346 dma_cookie_t cookie;
1347 int slot_cnt, slots_per_op;
1348
1349 dev_dbg(iop_chan->device->common.dev,
1350
1351 spin_lock_bh(&iop_chan->lock);
1352 slot_cnt = iop_chan_xor_slot_count(0,
1353 sw_desc = iop_adma_alloc_slots(iop_ch
1354 if (sw_desc) {
1355 grp_start = sw_desc->group_he
1356 list_splice_init(&sw_desc->as
1357 sw_desc->async_tx.ack = 1;
1358 iop_desc_init_null_xor(grp_st
1359 iop_desc_set_byte_count(grp_s
1360 iop_desc_set_dest_addr(grp_st
1361 iop_desc_set_xor_src_addr(grp
1362 iop_desc_set_xor_src_addr(grp
1363
1364 cookie = iop_chan->common.coo
1365 cookie++;
1366 if (cookie <= 1)
1367 cookie = 2;
1368
1369 /* initialize the completed c
1370 * the most recently used coo
1371 */
1372 iop_chan->completed_cookie =
1373 iop_chan->common.cookie = sw_
1374
1375 /* channel should not be busy
1376 BUG_ON(iop_chan_is_busy(iop_c
1377
1378 /* clear any prior error-stat
1379 iop_adma_device_clear_err_sta
1380
1381 /* disable operation */
1382 iop_chan_disable(iop_chan);
1383
1384 /* set the descriptor address
1385 iop_chan_set_next_descriptor(
1386
1387 /* 1/ don't add pre-chained d
1388 * 2/ dummy read to flush nex
1389 */
1390 BUG_ON(iop_desc_get_next_desc
1391
1392 /* run the descriptor */
1393 iop_chan_enable(iop_chan);
1394 } else
1395 dev_printk(KERN_ERR, iop_chan
1396 "failed to allocate n
1397 spin_unlock_bh(&iop_chan->lock);
1398 }
1399
1400 static struct platform_driver iop_adma_driver
1401 .probe = iop_adma_probe,
1402 .remove = iop_adma_remove,
1403 .driver = {
1404 .owner = THIS_MODULE,
1405 .name = "iop-adma",
1406 },
1407 };
1408
1409 static int __init iop_adma_init (void)
1410 {
1411 return platform_driver_register(&iop_
1412 }
1413
1414 /* it's currently unsafe to unload this modul
1415 #if 0
1416 static void __exit iop_adma_exit (void)
1417 {
1418 platform_driver_unregister(&iop_adma_
1419 return;
1420 }
1421 module_exit(iop_adma_exit);
1422 #endif
1423
1424 module_init(iop_adma_init);
1425
1426 MODULE_AUTHOR("Intel Corporation");
1427 MODULE_DESCRIPTION("IOP ADMA Engine Driver");
1428 MODULE_LICENSE("GPL");
1429
| This page was automatically generated by the LXR engine. |