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, |
