diff options
| author | Linus Walleij <linus.walleij@stericsson.com> | 2010-03-02 16:17:20 -0500 |
|---|---|---|
| committer | Dan Williams <dan.j.williams@intel.com> | 2010-03-02 16:17:20 -0500 |
| commit | b87108a772e001af3fa79f9cfd87b190375f47a2 (patch) | |
| tree | 003099acce3eb98244bbef317b4db52fe9cbe933 | |
| parent | 848ad121240f539e14a59eddd69e164aea9560b2 (diff) | |
DMAENGINE: COH 901 318 descriptor pool refactoring
This centralize some spread-out initialization of descriptors into
one function and cleans up the error paths.
Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
| -rw-r--r-- | arch/arm/mach-u300/include/mach/coh901318.h | 2 | ||||
| -rw-r--r-- | drivers/dma/coh901318.c | 54 |
2 files changed, 26 insertions, 30 deletions
diff --git a/arch/arm/mach-u300/include/mach/coh901318.h b/arch/arm/mach-u300/include/mach/coh901318.h index f4cfee9c7d2..b8155b4e5ff 100644 --- a/arch/arm/mach-u300/include/mach/coh901318.h +++ b/arch/arm/mach-u300/include/mach/coh901318.h | |||
| @@ -53,7 +53,7 @@ struct coh901318_params { | |||
| 53 | * struct coh_dma_channel - dma channel base | 53 | * struct coh_dma_channel - dma channel base |
| 54 | * @name: ascii name of dma channel | 54 | * @name: ascii name of dma channel |
| 55 | * @number: channel id number | 55 | * @number: channel id number |
| 56 | * @desc_nbr_max: number of preallocated descriptortors | 56 | * @desc_nbr_max: number of preallocated descriptors |
| 57 | * @priority_high: prio of channel, 0 low otherwise high. | 57 | * @priority_high: prio of channel, 0 low otherwise high. |
| 58 | * @param: configuration parameters | 58 | * @param: configuration parameters |
| 59 | * @dev_addr: physical address of periphal connected to channel | 59 | * @dev_addr: physical address of periphal connected to channel |
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index f1bf4f74ad8..12a7a151be6 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c | |||
| @@ -335,16 +335,22 @@ coh901318_desc_get(struct coh901318_chan *cohc) | |||
| 335 | * TODO: alloc a pile of descs instead of just one, | 335 | * TODO: alloc a pile of descs instead of just one, |
| 336 | * avoid many small allocations. | 336 | * avoid many small allocations. |
| 337 | */ | 337 | */ |
| 338 | desc = kmalloc(sizeof(struct coh901318_desc), GFP_NOWAIT); | 338 | desc = kzalloc(sizeof(struct coh901318_desc), GFP_NOWAIT); |
| 339 | if (desc == NULL) | 339 | if (desc == NULL) |
| 340 | goto out; | 340 | goto out; |
| 341 | INIT_LIST_HEAD(&desc->node); | 341 | INIT_LIST_HEAD(&desc->node); |
| 342 | dma_async_tx_descriptor_init(&desc->desc, &cohc->chan); | ||
| 342 | } else { | 343 | } else { |
| 343 | /* Reuse an old desc. */ | 344 | /* Reuse an old desc. */ |
| 344 | desc = list_first_entry(&cohc->free, | 345 | desc = list_first_entry(&cohc->free, |
| 345 | struct coh901318_desc, | 346 | struct coh901318_desc, |
| 346 | node); | 347 | node); |
| 347 | list_del(&desc->node); | 348 | list_del(&desc->node); |
| 349 | /* Initialize it a bit so it's not insane */ | ||
| 350 | desc->sg = NULL; | ||
| 351 | desc->sg_len = 0; | ||
| 352 | desc->desc.callback = NULL; | ||
| 353 | desc->desc.callback_param = NULL; | ||
| 348 | } | 354 | } |
| 349 | 355 | ||
| 350 | out: | 356 | out: |
| @@ -885,6 +891,7 @@ coh901318_prep_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, | |||
| 885 | struct coh901318_chan *cohc = to_coh901318_chan(chan); | 891 | struct coh901318_chan *cohc = to_coh901318_chan(chan); |
| 886 | int lli_len; | 892 | int lli_len; |
| 887 | u32 ctrl_last = cohc_chan_param(cohc)->ctrl_lli_last; | 893 | u32 ctrl_last = cohc_chan_param(cohc)->ctrl_lli_last; |
| 894 | int ret; | ||
| 888 | 895 | ||
| 889 | spin_lock_irqsave(&cohc->lock, flg); | 896 | spin_lock_irqsave(&cohc->lock, flg); |
| 890 | 897 | ||
| @@ -905,22 +912,19 @@ coh901318_prep_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, | |||
| 905 | if (data == NULL) | 912 | if (data == NULL) |
| 906 | goto err; | 913 | goto err; |
| 907 | 914 | ||
| 908 | cohd = coh901318_desc_get(cohc); | 915 | ret = coh901318_lli_fill_memcpy( |
| 909 | cohd->sg = NULL; | 916 | &cohc->base->pool, data, src, size, dest, |
| 910 | cohd->sg_len = 0; | 917 | cohc_chan_param(cohc)->ctrl_lli_chained, |
| 911 | cohd->data = data; | 918 | ctrl_last); |
| 912 | 919 | if (ret) | |
| 913 | cohd->pending_irqs = | 920 | goto err; |
| 914 | coh901318_lli_fill_memcpy( | ||
| 915 | &cohc->base->pool, data, src, size, dest, | ||
| 916 | cohc_chan_param(cohc)->ctrl_lli_chained, | ||
| 917 | ctrl_last); | ||
| 918 | cohd->flags = flags; | ||
| 919 | 921 | ||
| 920 | COH_DBG(coh901318_list_print(cohc, data)); | 922 | COH_DBG(coh901318_list_print(cohc, data)); |
| 921 | 923 | ||
| 922 | dma_async_tx_descriptor_init(&cohd->desc, chan); | 924 | /* Pick a descriptor to handle this transfer */ |
| 923 | 925 | cohd = coh901318_desc_get(cohc); | |
| 926 | cohd->data = data; | ||
| 927 | cohd->flags = flags; | ||
| 924 | cohd->desc.tx_submit = coh901318_tx_submit; | 928 | cohd->desc.tx_submit = coh901318_tx_submit; |
| 925 | 929 | ||
| 926 | spin_unlock_irqrestore(&cohc->lock, flg); | 930 | spin_unlock_irqrestore(&cohc->lock, flg); |
| @@ -962,11 +966,6 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
| 962 | /* Trigger interrupt after last lli */ | 966 | /* Trigger interrupt after last lli */ |
| 963 | ctrl_last |= COH901318_CX_CTRL_TC_IRQ_ENABLE; | 967 | ctrl_last |= COH901318_CX_CTRL_TC_IRQ_ENABLE; |
| 964 | 968 | ||
| 965 | cohd = coh901318_desc_get(cohc); | ||
| 966 | cohd->sg = NULL; | ||
| 967 | cohd->sg_len = 0; | ||
| 968 | cohd->dir = direction; | ||
| 969 | |||
| 970 | if (direction == DMA_TO_DEVICE) { | 969 | if (direction == DMA_TO_DEVICE) { |
| 971 | u32 tx_flags = COH901318_CX_CTRL_PRDD_SOURCE | | 970 | u32 tx_flags = COH901318_CX_CTRL_PRDD_SOURCE | |
| 972 | COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE; | 971 | COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE; |
| @@ -984,11 +983,6 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
| 984 | } else | 983 | } else |
| 985 | goto err_direction; | 984 | goto err_direction; |
| 986 | 985 | ||
| 987 | dma_async_tx_descriptor_init(&cohd->desc, chan); | ||
| 988 | |||
| 989 | cohd->desc.tx_submit = coh901318_tx_submit; | ||
| 990 | |||
| 991 | |||
| 992 | /* The dma only supports transmitting packages up to | 986 | /* The dma only supports transmitting packages up to |
| 993 | * MAX_DMA_PACKET_SIZE. Calculate to total number of | 987 | * MAX_DMA_PACKET_SIZE. Calculate to total number of |
| 994 | * dma elemts required to send the entire sg list | 988 | * dma elemts required to send the entire sg list |
| @@ -1023,19 +1017,21 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
| 1023 | ctrl, | 1017 | ctrl, |
| 1024 | ctrl_last, | 1018 | ctrl_last, |
| 1025 | direction, COH901318_CX_CTRL_TC_IRQ_ENABLE); | 1019 | direction, COH901318_CX_CTRL_TC_IRQ_ENABLE); |
| 1026 | cohd->data = data; | ||
| 1027 | |||
| 1028 | cohd->flags = flags; | ||
| 1029 | 1020 | ||
| 1030 | COH_DBG(coh901318_list_print(cohc, data)); | 1021 | COH_DBG(coh901318_list_print(cohc, data)); |
| 1031 | 1022 | ||
| 1023 | /* Pick a descriptor to handle this transfer */ | ||
| 1024 | cohd = coh901318_desc_get(cohc); | ||
| 1025 | cohd->dir = direction; | ||
| 1026 | cohd->flags = flags; | ||
| 1027 | cohd->desc.tx_submit = coh901318_tx_submit; | ||
| 1028 | cohd->data = data; | ||
| 1029 | |||
| 1032 | spin_unlock_irqrestore(&cohc->lock, flg); | 1030 | spin_unlock_irqrestore(&cohc->lock, flg); |
| 1033 | 1031 | ||
| 1034 | return &cohd->desc; | 1032 | return &cohd->desc; |
| 1035 | err_dma_alloc: | 1033 | err_dma_alloc: |
| 1036 | err_direction: | 1034 | err_direction: |
| 1037 | coh901318_desc_remove(cohd); | ||
| 1038 | coh901318_desc_free(cohc, cohd); | ||
| 1039 | spin_unlock_irqrestore(&cohc->lock, flg); | 1035 | spin_unlock_irqrestore(&cohc->lock, flg); |
| 1040 | out: | 1036 | out: |
| 1041 | return NULL; | 1037 | return NULL; |
