diff options
Diffstat (limited to 'arch/arm/mach-davinci/dma.c')
-rw-r--r-- | arch/arm/mach-davinci/dma.c | 105 |
1 files changed, 57 insertions, 48 deletions
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c index f2e57d272958..648fbb760ae1 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/mach-davinci/dma.c | |||
@@ -18,22 +18,13 @@ | |||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 | */ | 19 | */ |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/sched.h> | ||
22 | #include <linux/init.h> | 21 | #include <linux/init.h> |
23 | #include <linux/module.h> | 22 | #include <linux/module.h> |
24 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
25 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
26 | #include <linux/spinlock.h> | ||
27 | #include <linux/compiler.h> | ||
28 | #include <linux/io.h> | 25 | #include <linux/io.h> |
29 | 26 | ||
30 | #include <mach/cputype.h> | ||
31 | #include <mach/memory.h> | ||
32 | #include <mach/hardware.h> | ||
33 | #include <mach/irqs.h> | ||
34 | #include <mach/edma.h> | 27 | #include <mach/edma.h> |
35 | #include <mach/mux.h> | ||
36 | |||
37 | 28 | ||
38 | /* Offsets matching "struct edmacc_param" */ | 29 | /* Offsets matching "struct edmacc_param" */ |
39 | #define PARM_OPT 0x00 | 30 | #define PARM_OPT 0x00 |
@@ -509,43 +500,59 @@ static irqreturn_t dma_tc1err_handler(int irq, void *data) | |||
509 | return IRQ_HANDLED; | 500 | return IRQ_HANDLED; |
510 | } | 501 | } |
511 | 502 | ||
512 | static int reserve_contiguous_params(int ctlr, unsigned int id, | 503 | static int reserve_contiguous_slots(int ctlr, unsigned int id, |
513 | unsigned int num_params, | 504 | unsigned int num_slots, |
514 | unsigned int start_param) | 505 | unsigned int start_slot) |
515 | { | 506 | { |
516 | int i, j; | 507 | int i, j; |
517 | unsigned int count = num_params; | 508 | unsigned int count = num_slots; |
509 | int stop_slot = start_slot; | ||
510 | DECLARE_BITMAP(tmp_inuse, EDMA_MAX_PARAMENTRY); | ||
518 | 511 | ||
519 | for (i = start_param; i < edma_info[ctlr]->num_slots; ++i) { | 512 | for (i = start_slot; i < edma_info[ctlr]->num_slots; ++i) { |
520 | j = EDMA_CHAN_SLOT(i); | 513 | j = EDMA_CHAN_SLOT(i); |
521 | if (!test_and_set_bit(j, edma_info[ctlr]->edma_inuse)) | 514 | if (!test_and_set_bit(j, edma_info[ctlr]->edma_inuse)) { |
515 | /* Record our current beginning slot */ | ||
516 | if (count == num_slots) | ||
517 | stop_slot = i; | ||
518 | |||
522 | count--; | 519 | count--; |
520 | set_bit(j, tmp_inuse); | ||
521 | |||
523 | if (count == 0) | 522 | if (count == 0) |
524 | break; | 523 | break; |
525 | else if (id == EDMA_CONT_PARAMS_FIXED_EXACT) | 524 | } else { |
526 | break; | 525 | clear_bit(j, tmp_inuse); |
527 | else | 526 | |
528 | count = num_params; | 527 | if (id == EDMA_CONT_PARAMS_FIXED_EXACT) { |
528 | stop_slot = i; | ||
529 | break; | ||
530 | } else | ||
531 | count = num_slots; | ||
532 | } | ||
529 | } | 533 | } |
530 | 534 | ||
531 | /* | 535 | /* |
532 | * We have to clear any bits that we set | 536 | * We have to clear any bits that we set |
533 | * if we run out parameter RAMs, i.e we do find a set | 537 | * if we run out parameter RAM slots, i.e we do find a set |
534 | * of contiguous parameter RAMs but do not find the exact number | 538 | * of contiguous parameter RAM slots but do not find the exact number |
535 | * requested as we may reach the total number of parameter RAMs | 539 | * requested as we may reach the total number of parameter RAM slots |
536 | */ | 540 | */ |
537 | if (count) { | 541 | if (i == edma_info[ctlr]->num_slots) |
538 | for (j = i - num_params + count + 1; j <= i ; ++j) | 542 | stop_slot = i; |
543 | |||
544 | for (j = start_slot; j < stop_slot; j++) | ||
545 | if (test_bit(j, tmp_inuse)) | ||
539 | clear_bit(j, edma_info[ctlr]->edma_inuse); | 546 | clear_bit(j, edma_info[ctlr]->edma_inuse); |
540 | 547 | ||
548 | if (count) | ||
541 | return -EBUSY; | 549 | return -EBUSY; |
542 | } | ||
543 | 550 | ||
544 | for (j = i - num_params + 1; j <= i; ++j) | 551 | for (j = i - num_slots + 1; j <= i; ++j) |
545 | memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(j), | 552 | memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(j), |
546 | &dummy_paramset, PARM_SIZE); | 553 | &dummy_paramset, PARM_SIZE); |
547 | 554 | ||
548 | return EDMA_CTLR_CHAN(ctlr, i - num_params + 1); | 555 | return EDMA_CTLR_CHAN(ctlr, i - num_slots + 1); |
549 | } | 556 | } |
550 | 557 | ||
551 | /*-----------------------------------------------------------------------*/ | 558 | /*-----------------------------------------------------------------------*/ |
@@ -743,26 +750,27 @@ EXPORT_SYMBOL(edma_free_slot); | |||
743 | /** | 750 | /** |
744 | * edma_alloc_cont_slots- alloc contiguous parameter RAM slots | 751 | * edma_alloc_cont_slots- alloc contiguous parameter RAM slots |
745 | * The API will return the starting point of a set of | 752 | * The API will return the starting point of a set of |
746 | * contiguous PARAM's that have been requested | 753 | * contiguous parameter RAM slots that have been requested |
747 | * | 754 | * |
748 | * @id: can only be EDMA_CONT_PARAMS_ANY or EDMA_CONT_PARAMS_FIXED_EXACT | 755 | * @id: can only be EDMA_CONT_PARAMS_ANY or EDMA_CONT_PARAMS_FIXED_EXACT |
749 | * or EDMA_CONT_PARAMS_FIXED_NOT_EXACT | 756 | * or EDMA_CONT_PARAMS_FIXED_NOT_EXACT |
750 | * @count: number of contiguous Paramter RAM's | 757 | * @count: number of contiguous Paramter RAM slots |
751 | * @param - the start value of Parameter RAM that should be passed if id | 758 | * @slot - the start value of Parameter RAM slot that should be passed if id |
752 | * is EDMA_CONT_PARAMS_FIXED_EXACT or EDMA_CONT_PARAMS_FIXED_NOT_EXACT | 759 | * is EDMA_CONT_PARAMS_FIXED_EXACT or EDMA_CONT_PARAMS_FIXED_NOT_EXACT |
753 | * | 760 | * |
754 | * If id is EDMA_CONT_PARAMS_ANY then the API starts looking for a set of | 761 | * If id is EDMA_CONT_PARAMS_ANY then the API starts looking for a set of |
755 | * contiguous Parameter RAMs from parameter RAM 64 in the case of DaVinci SOCs | 762 | * contiguous Parameter RAM slots from parameter RAM 64 in the case of |
756 | * and 32 in the case of Primus | 763 | * DaVinci SOCs and 32 in the case of DA8xx SOCs. |
757 | * | 764 | * |
758 | * If id is EDMA_CONT_PARAMS_FIXED_EXACT then the API starts looking for a | 765 | * If id is EDMA_CONT_PARAMS_FIXED_EXACT then the API starts looking for a |
759 | * set of contiguous parameter RAMs from the "param" that is passed as an | 766 | * set of contiguous parameter RAM slots from the "slot" that is passed as an |
760 | * argument to the API. | 767 | * argument to the API. |
761 | * | 768 | * |
762 | * If id is EDMA_CONT_PARAMS_FIXED_NOT_EXACT then the API initially tries | 769 | * If id is EDMA_CONT_PARAMS_FIXED_NOT_EXACT then the API initially tries |
763 | * starts looking for a set of contiguous parameter RAMs from the "param" | 770 | * starts looking for a set of contiguous parameter RAMs from the "slot" |
764 | * that is passed as an argument to the API. On failure the API will try to | 771 | * that is passed as an argument to the API. On failure the API will try to |
765 | * find a set of contiguous Parameter RAMs in the remaining Parameter RAMs | 772 | * find a set of contiguous Parameter RAM slots from the remaining Parameter |
773 | * RAM slots | ||
766 | */ | 774 | */ |
767 | int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count) | 775 | int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count) |
768 | { | 776 | { |
@@ -771,12 +779,13 @@ int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count) | |||
771 | * the number of channels and lesser than the total number | 779 | * the number of channels and lesser than the total number |
772 | * of slots | 780 | * of slots |
773 | */ | 781 | */ |
774 | if (slot < edma_info[ctlr]->num_channels || | 782 | if ((id != EDMA_CONT_PARAMS_ANY) && |
775 | slot >= edma_info[ctlr]->num_slots) | 783 | (slot < edma_info[ctlr]->num_channels || |
784 | slot >= edma_info[ctlr]->num_slots)) | ||
776 | return -EINVAL; | 785 | return -EINVAL; |
777 | 786 | ||
778 | /* | 787 | /* |
779 | * The number of parameter RAMs requested cannot be less than 1 | 788 | * The number of parameter RAM slots requested cannot be less than 1 |
780 | * and cannot be more than the number of slots minus the number of | 789 | * and cannot be more than the number of slots minus the number of |
781 | * channels | 790 | * channels |
782 | */ | 791 | */ |
@@ -786,11 +795,11 @@ int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count) | |||
786 | 795 | ||
787 | switch (id) { | 796 | switch (id) { |
788 | case EDMA_CONT_PARAMS_ANY: | 797 | case EDMA_CONT_PARAMS_ANY: |
789 | return reserve_contiguous_params(ctlr, id, count, | 798 | return reserve_contiguous_slots(ctlr, id, count, |
790 | edma_info[ctlr]->num_channels); | 799 | edma_info[ctlr]->num_channels); |
791 | case EDMA_CONT_PARAMS_FIXED_EXACT: | 800 | case EDMA_CONT_PARAMS_FIXED_EXACT: |
792 | case EDMA_CONT_PARAMS_FIXED_NOT_EXACT: | 801 | case EDMA_CONT_PARAMS_FIXED_NOT_EXACT: |
793 | return reserve_contiguous_params(ctlr, id, count, slot); | 802 | return reserve_contiguous_slots(ctlr, id, count, slot); |
794 | default: | 803 | default: |
795 | return -EINVAL; | 804 | return -EINVAL; |
796 | } | 805 | } |
@@ -799,21 +808,21 @@ int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count) | |||
799 | EXPORT_SYMBOL(edma_alloc_cont_slots); | 808 | EXPORT_SYMBOL(edma_alloc_cont_slots); |
800 | 809 | ||
801 | /** | 810 | /** |
802 | * edma_free_cont_slots - deallocate DMA parameter RAMs | 811 | * edma_free_cont_slots - deallocate DMA parameter RAM slots |
803 | * @slot: first parameter RAM of a set of parameter RAMs to be freed | 812 | * @slot: first parameter RAM of a set of parameter RAM slots to be freed |
804 | * @count: the number of contiguous parameter RAMs to be freed | 813 | * @count: the number of contiguous parameter RAM slots to be freed |
805 | * | 814 | * |
806 | * This deallocates the parameter RAM slots allocated by | 815 | * This deallocates the parameter RAM slots allocated by |
807 | * edma_alloc_cont_slots. | 816 | * edma_alloc_cont_slots. |
808 | * Callers/applications need to keep track of sets of contiguous | 817 | * Callers/applications need to keep track of sets of contiguous |
809 | * parameter RAMs that have been allocated using the edma_alloc_cont_slots | 818 | * parameter RAM slots that have been allocated using the edma_alloc_cont_slots |
810 | * API. | 819 | * API. |
811 | * Callers are responsible for ensuring the slots are inactive, and will | 820 | * Callers are responsible for ensuring the slots are inactive, and will |
812 | * not be activated. | 821 | * not be activated. |
813 | */ | 822 | */ |
814 | int edma_free_cont_slots(unsigned slot, int count) | 823 | int edma_free_cont_slots(unsigned slot, int count) |
815 | { | 824 | { |
816 | unsigned ctlr; | 825 | unsigned ctlr, slot_to_free; |
817 | int i; | 826 | int i; |
818 | 827 | ||
819 | ctlr = EDMA_CTLR(slot); | 828 | ctlr = EDMA_CTLR(slot); |
@@ -826,11 +835,11 @@ int edma_free_cont_slots(unsigned slot, int count) | |||
826 | 835 | ||
827 | for (i = slot; i < slot + count; ++i) { | 836 | for (i = slot; i < slot + count; ++i) { |
828 | ctlr = EDMA_CTLR(i); | 837 | ctlr = EDMA_CTLR(i); |
829 | slot = EDMA_CHAN_SLOT(i); | 838 | slot_to_free = EDMA_CHAN_SLOT(i); |
830 | 839 | ||
831 | memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), | 840 | memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot_to_free), |
832 | &dummy_paramset, PARM_SIZE); | 841 | &dummy_paramset, PARM_SIZE); |
833 | clear_bit(slot, edma_info[ctlr]->edma_inuse); | 842 | clear_bit(slot_to_free, edma_info[ctlr]->edma_inuse); |
834 | } | 843 | } |
835 | 844 | ||
836 | return 0; | 845 | return 0; |