diff options
author | Rabin Vincent <rabin.vincent@stericsson.com> | 2011-01-25 05:18:30 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-01-31 01:27:20 -0500 |
commit | 7f933bed96e9872131014ea2bdd5b012e43fc316 (patch) | |
tree | 32e54ca912ab509ba5b66f45e0d276bad51a9ae5 /drivers/dma | |
parent | 1f7622ca55b1f5875e32140b4781759f800aded3 (diff) |
dma40: use flags to reduce parameter count
Acked-by: Per Forlin <per.forlin@stericsson.com>
Acked-by: Jonas Aaberg <jonas.aberg@stericsson.com>
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r-- | drivers/dma/ste_dma40_ll.c | 84 | ||||
-rw-r--r-- | drivers/dma/ste_dma40_ll.h | 5 |
2 files changed, 52 insertions, 37 deletions
diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c index 876aad2c838a..88b9e371be2f 100644 --- a/drivers/dma/ste_dma40_ll.c +++ b/drivers/dma/ste_dma40_ll.c | |||
@@ -127,10 +127,11 @@ static int d40_phy_fill_lli(struct d40_phy_lli *lli, | |||
127 | u32 data_size, | 127 | u32 data_size, |
128 | dma_addr_t next_lli, | 128 | dma_addr_t next_lli, |
129 | u32 reg_cfg, | 129 | u32 reg_cfg, |
130 | bool term_int, | 130 | struct stedma40_half_channel_info *info, |
131 | bool is_device, | 131 | unsigned int flags) |
132 | struct stedma40_half_channel_info *info) | ||
133 | { | 132 | { |
133 | bool addr_inc = flags & LLI_ADDR_INC; | ||
134 | bool term_int = flags & LLI_TERM_INT; | ||
134 | unsigned int data_width = info->data_width; | 135 | unsigned int data_width = info->data_width; |
135 | int psize = info->psize; | 136 | int psize = info->psize; |
136 | int num_elems; | 137 | int num_elems; |
@@ -155,7 +156,7 @@ static int d40_phy_fill_lli(struct d40_phy_lli *lli, | |||
155 | * Distance to next element sized entry. | 156 | * Distance to next element sized entry. |
156 | * Usually the size of the element unless you want gaps. | 157 | * Usually the size of the element unless you want gaps. |
157 | */ | 158 | */ |
158 | if (!is_device) | 159 | if (addr_inc) |
159 | lli->reg_elt |= (0x1 << data_width) << | 160 | lli->reg_elt |= (0x1 << data_width) << |
160 | D40_SREG_ELEM_PHY_EIDX_POS; | 161 | D40_SREG_ELEM_PHY_EIDX_POS; |
161 | 162 | ||
@@ -201,40 +202,45 @@ static int d40_seg_size(int size, int data_width1, int data_width2) | |||
201 | 202 | ||
202 | static struct d40_phy_lli * | 203 | static struct d40_phy_lli * |
203 | d40_phy_buf_to_lli(struct d40_phy_lli *lli, dma_addr_t addr, u32 size, | 204 | d40_phy_buf_to_lli(struct d40_phy_lli *lli, dma_addr_t addr, u32 size, |
204 | dma_addr_t lli_phys, u32 reg_cfg, bool term_int, | 205 | dma_addr_t lli_phys, u32 reg_cfg, |
205 | bool is_device, struct stedma40_half_channel_info *info, | 206 | struct stedma40_half_channel_info *info, |
206 | struct stedma40_half_channel_info *otherinfo) | 207 | struct stedma40_half_channel_info *otherinfo, |
208 | unsigned long flags) | ||
207 | { | 209 | { |
210 | bool addr_inc = flags & LLI_ADDR_INC; | ||
211 | bool term_int = flags & LLI_TERM_INT; | ||
208 | int err; | 212 | int err; |
209 | dma_addr_t next = lli_phys; | 213 | dma_addr_t next = lli_phys; |
210 | int size_rest = size; | 214 | int size_rest = size; |
211 | int size_seg = 0; | 215 | int size_seg = 0; |
212 | 216 | ||
217 | /* | ||
218 | * This piece may be split up based on d40_seg_size(); we only want the | ||
219 | * term int on the last part. | ||
220 | */ | ||
221 | if (term_int) | ||
222 | flags &= ~LLI_TERM_INT; | ||
223 | |||
213 | do { | 224 | do { |
214 | size_seg = d40_seg_size(size_rest, info->data_width, | 225 | size_seg = d40_seg_size(size_rest, info->data_width, |
215 | otherinfo->data_width); | 226 | otherinfo->data_width); |
216 | size_rest -= size_seg; | 227 | size_rest -= size_seg; |
217 | 228 | ||
218 | if (term_int && size_rest == 0) | 229 | if (term_int && size_rest == 0) { |
219 | next = 0; | 230 | next = 0; |
220 | else | 231 | flags |= LLI_TERM_INT; |
232 | } else | ||
221 | next = ALIGN(next + sizeof(struct d40_phy_lli), | 233 | next = ALIGN(next + sizeof(struct d40_phy_lli), |
222 | D40_LLI_ALIGN); | 234 | D40_LLI_ALIGN); |
223 | 235 | ||
224 | err = d40_phy_fill_lli(lli, | 236 | err = d40_phy_fill_lli(lli, addr, size_seg, next, |
225 | addr, | 237 | reg_cfg, info, flags); |
226 | size_seg, | ||
227 | next, | ||
228 | reg_cfg, | ||
229 | !next, | ||
230 | is_device, | ||
231 | info); | ||
232 | 238 | ||
233 | if (err) | 239 | if (err) |
234 | goto err; | 240 | goto err; |
235 | 241 | ||
236 | lli++; | 242 | lli++; |
237 | if (!is_device) | 243 | if (addr_inc) |
238 | addr += size_seg; | 244 | addr += size_seg; |
239 | } while (size_rest); | 245 | } while (size_rest); |
240 | 246 | ||
@@ -256,31 +262,29 @@ int d40_phy_sg_to_lli(struct scatterlist *sg, | |||
256 | int total_size = 0; | 262 | int total_size = 0; |
257 | int i; | 263 | int i; |
258 | struct scatterlist *current_sg = sg; | 264 | struct scatterlist *current_sg = sg; |
259 | dma_addr_t dst; | ||
260 | struct d40_phy_lli *lli = lli_sg; | 265 | struct d40_phy_lli *lli = lli_sg; |
261 | dma_addr_t l_phys = lli_phys; | 266 | dma_addr_t l_phys = lli_phys; |
267 | unsigned long flags = 0; | ||
268 | |||
269 | if (!target) | ||
270 | flags |= LLI_ADDR_INC; | ||
262 | 271 | ||
263 | for_each_sg(sg, current_sg, sg_len, i) { | 272 | for_each_sg(sg, current_sg, sg_len, i) { |
273 | dma_addr_t sg_addr = sg_dma_address(current_sg); | ||
274 | unsigned int len = sg_dma_len(current_sg); | ||
275 | dma_addr_t dst = target ?: sg_addr; | ||
264 | 276 | ||
265 | total_size += sg_dma_len(current_sg); | 277 | total_size += sg_dma_len(current_sg); |
266 | 278 | ||
267 | if (target) | 279 | if (i == sg_len - 1) |
268 | dst = target; | 280 | flags |= LLI_TERM_INT; |
269 | else | ||
270 | dst = sg_dma_address(current_sg); | ||
271 | 281 | ||
272 | l_phys = ALIGN(lli_phys + (lli - lli_sg) * | 282 | l_phys = ALIGN(lli_phys + (lli - lli_sg) * |
273 | sizeof(struct d40_phy_lli), D40_LLI_ALIGN); | 283 | sizeof(struct d40_phy_lli), D40_LLI_ALIGN); |
274 | 284 | ||
275 | lli = d40_phy_buf_to_lli(lli, | 285 | lli = d40_phy_buf_to_lli(lli, dst, len, l_phys, |
276 | dst, | 286 | reg_cfg, info, otherinfo, flags); |
277 | sg_dma_len(current_sg), | 287 | |
278 | l_phys, | ||
279 | reg_cfg, | ||
280 | sg_len - 1 == i, | ||
281 | target == dst, | ||
282 | info, | ||
283 | otherinfo); | ||
284 | if (lli == NULL) | 288 | if (lli == NULL) |
285 | return -EINVAL; | 289 | return -EINVAL; |
286 | } | 290 | } |
@@ -343,8 +347,10 @@ static void d40_log_fill_lli(struct d40_log_lli *lli, | |||
343 | dma_addr_t data, u32 data_size, | 347 | dma_addr_t data, u32 data_size, |
344 | u32 reg_cfg, | 348 | u32 reg_cfg, |
345 | u32 data_width, | 349 | u32 data_width, |
346 | bool addr_inc) | 350 | unsigned int flags) |
347 | { | 351 | { |
352 | bool addr_inc = flags & LLI_ADDR_INC; | ||
353 | |||
348 | lli->lcsp13 = reg_cfg; | 354 | lli->lcsp13 = reg_cfg; |
349 | 355 | ||
350 | /* The number of elements to transfer */ | 356 | /* The number of elements to transfer */ |
@@ -369,8 +375,9 @@ static struct d40_log_lli *d40_log_buf_to_lli(struct d40_log_lli *lli_sg, | |||
369 | u32 lcsp13, /* src or dst*/ | 375 | u32 lcsp13, /* src or dst*/ |
370 | u32 data_width1, | 376 | u32 data_width1, |
371 | u32 data_width2, | 377 | u32 data_width2, |
372 | bool addr_inc) | 378 | unsigned int flags) |
373 | { | 379 | { |
380 | bool addr_inc = flags & LLI_ADDR_INC; | ||
374 | struct d40_log_lli *lli = lli_sg; | 381 | struct d40_log_lli *lli = lli_sg; |
375 | int size_rest = size; | 382 | int size_rest = size; |
376 | int size_seg = 0; | 383 | int size_seg = 0; |
@@ -383,7 +390,7 @@ static struct d40_log_lli *d40_log_buf_to_lli(struct d40_log_lli *lli_sg, | |||
383 | addr, | 390 | addr, |
384 | size_seg, | 391 | size_seg, |
385 | lcsp13, data_width1, | 392 | lcsp13, data_width1, |
386 | addr_inc); | 393 | flags); |
387 | if (addr_inc) | 394 | if (addr_inc) |
388 | addr += size_seg; | 395 | addr += size_seg; |
389 | lli++; | 396 | lli++; |
@@ -403,7 +410,10 @@ int d40_log_sg_to_lli(struct scatterlist *sg, | |||
403 | struct scatterlist *current_sg = sg; | 410 | struct scatterlist *current_sg = sg; |
404 | int i; | 411 | int i; |
405 | struct d40_log_lli *lli = lli_sg; | 412 | struct d40_log_lli *lli = lli_sg; |
406 | bool autoinc = !dev_addr; | 413 | unsigned long flags = 0; |
414 | |||
415 | if (!dev_addr) | ||
416 | flags |= LLI_ADDR_INC; | ||
407 | 417 | ||
408 | for_each_sg(sg, current_sg, sg_len, i) { | 418 | for_each_sg(sg, current_sg, sg_len, i) { |
409 | dma_addr_t sg_addr = sg_dma_address(current_sg); | 419 | dma_addr_t sg_addr = sg_dma_address(current_sg); |
@@ -416,7 +426,7 @@ int d40_log_sg_to_lli(struct scatterlist *sg, | |||
416 | lcsp13, | 426 | lcsp13, |
417 | data_width1, | 427 | data_width1, |
418 | data_width2, | 428 | data_width2, |
419 | autoinc); | 429 | flags); |
420 | } | 430 | } |
421 | 431 | ||
422 | return total_size; | 432 | return total_size; |
diff --git a/drivers/dma/ste_dma40_ll.h b/drivers/dma/ste_dma40_ll.h index 4626c8874374..59e72f0cc901 100644 --- a/drivers/dma/ste_dma40_ll.h +++ b/drivers/dma/ste_dma40_ll.h | |||
@@ -293,6 +293,11 @@ struct d40_def_lcsp { | |||
293 | 293 | ||
294 | /* Physical channels */ | 294 | /* Physical channels */ |
295 | 295 | ||
296 | enum d40_lli_flags { | ||
297 | LLI_ADDR_INC = 1 << 0, | ||
298 | LLI_TERM_INT = 1 << 1, | ||
299 | }; | ||
300 | |||
296 | void d40_phy_cfg(struct stedma40_chan_cfg *cfg, | 301 | void d40_phy_cfg(struct stedma40_chan_cfg *cfg, |
297 | u32 *src_cfg, | 302 | u32 *src_cfg, |
298 | u32 *dst_cfg, | 303 | u32 *dst_cfg, |