diff options
author | Jonas Aaberg <jonas.aberg@stericsson.com> | 2010-06-20 17:25:08 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2010-06-22 21:01:53 -0400 |
commit | c675b1b424446b52de00cad84ca3d823d29a3d0e (patch) | |
tree | f829269f5967575481405b0cafdd6ef1c4efeb28 /drivers/dma | |
parent | a8be8627a3a00859367d219848f2cd771d6aa925 (diff) |
DMAENGINE: ste_dma40: use kmem cache
Use kmem cache instead of own cache, reducing code duplication
and bug sources.
Signed-off-by: Jonas Aaberg <jonas.aberg@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.c | 52 |
1 files changed, 18 insertions, 34 deletions
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index d72eff6cfaef..b60a6dbf1e09 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c | |||
@@ -34,10 +34,6 @@ | |||
34 | #define D40_ALLOC_PHY (1 << 30) | 34 | #define D40_ALLOC_PHY (1 << 30) |
35 | #define D40_ALLOC_LOG_FREE 0 | 35 | #define D40_ALLOC_LOG_FREE 0 |
36 | 36 | ||
37 | /* The number of free d40_desc to keep in memory before starting | ||
38 | * to kfree() them */ | ||
39 | #define D40_DESC_CACHE_SIZE 50 | ||
40 | |||
41 | /* Hardware designer of the block */ | 37 | /* Hardware designer of the block */ |
42 | #define D40_PERIPHID2_DESIGNER 0x8 | 38 | #define D40_PERIPHID2_DESIGNER 0x8 |
43 | 39 | ||
@@ -172,8 +168,6 @@ struct d40_base; | |||
172 | * @client: Cliented owned descriptor list. | 168 | * @client: Cliented owned descriptor list. |
173 | * @active: Active descriptor. | 169 | * @active: Active descriptor. |
174 | * @queue: Queued jobs. | 170 | * @queue: Queued jobs. |
175 | * @free: List of free descripts, ready to be reused. | ||
176 | * @free_len: Number of descriptors in the free list. | ||
177 | * @dma_cfg: The client configuration of this dma channel. | 171 | * @dma_cfg: The client configuration of this dma channel. |
178 | * @base: Pointer to the device instance struct. | 172 | * @base: Pointer to the device instance struct. |
179 | * @src_def_cfg: Default cfg register setting for src. | 173 | * @src_def_cfg: Default cfg register setting for src. |
@@ -197,8 +191,6 @@ struct d40_chan { | |||
197 | struct list_head client; | 191 | struct list_head client; |
198 | struct list_head active; | 192 | struct list_head active; |
199 | struct list_head queue; | 193 | struct list_head queue; |
200 | struct list_head free; | ||
201 | int free_len; | ||
202 | struct stedma40_chan_cfg dma_cfg; | 194 | struct stedma40_chan_cfg dma_cfg; |
203 | struct d40_base *base; | 195 | struct d40_base *base; |
204 | /* Default register configurations */ | 196 | /* Default register configurations */ |
@@ -242,6 +234,7 @@ struct d40_chan { | |||
242 | * @lcpa_base: The virtual mapped address of LCPA. | 234 | * @lcpa_base: The virtual mapped address of LCPA. |
243 | * @phy_lcpa: The physical address of the LCPA. | 235 | * @phy_lcpa: The physical address of the LCPA. |
244 | * @lcpa_size: The size of the LCPA area. | 236 | * @lcpa_size: The size of the LCPA area. |
237 | * @desc_slab: cache for descriptors. | ||
245 | */ | 238 | */ |
246 | struct d40_base { | 239 | struct d40_base { |
247 | spinlock_t interrupt_lock; | 240 | spinlock_t interrupt_lock; |
@@ -268,6 +261,7 @@ struct d40_base { | |||
268 | void *lcpa_base; | 261 | void *lcpa_base; |
269 | dma_addr_t phy_lcpa; | 262 | dma_addr_t phy_lcpa; |
270 | resource_size_t lcpa_size; | 263 | resource_size_t lcpa_size; |
264 | struct kmem_cache *desc_slab; | ||
271 | }; | 265 | }; |
272 | 266 | ||
273 | /** | 267 | /** |
@@ -382,36 +376,21 @@ static struct d40_desc *d40_desc_get(struct d40_chan *d40c) | |||
382 | if (async_tx_test_ack(&d->txd)) { | 376 | if (async_tx_test_ack(&d->txd)) { |
383 | d40_pool_lli_free(d); | 377 | d40_pool_lli_free(d); |
384 | d40_desc_remove(d); | 378 | d40_desc_remove(d); |
385 | desc = d; | 379 | break; |
386 | goto out; | ||
387 | } | 380 | } |
388 | } | ||
389 | |||
390 | if (list_empty(&d40c->free)) { | ||
391 | /* Alloc new desc because we're out of used ones */ | ||
392 | desc = kzalloc(sizeof(struct d40_desc), GFP_NOWAIT); | ||
393 | if (desc == NULL) | ||
394 | goto out; | ||
395 | INIT_LIST_HEAD(&desc->node); | ||
396 | } else { | 381 | } else { |
397 | /* Reuse an old desc. */ | 382 | d = kmem_cache_alloc(d40c->base->desc_slab, GFP_NOWAIT); |
398 | desc = list_first_entry(&d40c->free, | 383 | if (d != NULL) { |
399 | struct d40_desc, | 384 | memset(d, 0, sizeof(struct d40_desc)); |
400 | node); | 385 | INIT_LIST_HEAD(&d->node); |
401 | list_del(&desc->node); | 386 | } |
402 | d40c->free_len--; | ||
403 | } | 387 | } |
404 | out: | 388 | return d; |
405 | return desc; | ||
406 | } | 389 | } |
407 | 390 | ||
408 | static void d40_desc_free(struct d40_chan *d40c, struct d40_desc *d40d) | 391 | static void d40_desc_free(struct d40_chan *d40c, struct d40_desc *d40d) |
409 | { | 392 | { |
410 | if (d40c->free_len < D40_DESC_CACHE_SIZE) { | 393 | kmem_cache_free(d40c->base->desc_slab, d40d); |
411 | list_add_tail(&d40d->node, &d40c->free); | ||
412 | d40c->free_len++; | ||
413 | } else | ||
414 | kfree(d40d); | ||
415 | } | 394 | } |
416 | 395 | ||
417 | static void d40_desc_submit(struct d40_chan *d40c, struct d40_desc *desc) | 396 | static void d40_desc_submit(struct d40_chan *d40c, struct d40_desc *desc) |
@@ -2107,13 +2086,10 @@ static void __init d40_chan_init(struct d40_base *base, struct dma_device *dma, | |||
2107 | 2086 | ||
2108 | d40c->log_num = D40_PHY_CHAN; | 2087 | d40c->log_num = D40_PHY_CHAN; |
2109 | 2088 | ||
2110 | INIT_LIST_HEAD(&d40c->free); | ||
2111 | INIT_LIST_HEAD(&d40c->active); | 2089 | INIT_LIST_HEAD(&d40c->active); |
2112 | INIT_LIST_HEAD(&d40c->queue); | 2090 | INIT_LIST_HEAD(&d40c->queue); |
2113 | INIT_LIST_HEAD(&d40c->client); | 2091 | INIT_LIST_HEAD(&d40c->client); |
2114 | 2092 | ||
2115 | d40c->free_len = 0; | ||
2116 | |||
2117 | tasklet_init(&d40c->tasklet, dma_tasklet, | 2093 | tasklet_init(&d40c->tasklet, dma_tasklet, |
2118 | (unsigned long) d40c); | 2094 | (unsigned long) d40c); |
2119 | 2095 | ||
@@ -2398,6 +2374,12 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) | |||
2398 | if (!base->lcla_pool.alloc_map) | 2374 | if (!base->lcla_pool.alloc_map) |
2399 | goto failure; | 2375 | goto failure; |
2400 | 2376 | ||
2377 | base->desc_slab = kmem_cache_create(D40_NAME, sizeof(struct d40_desc), | ||
2378 | 0, SLAB_HWCACHE_ALIGN, | ||
2379 | NULL); | ||
2380 | if (base->desc_slab == NULL) | ||
2381 | goto failure; | ||
2382 | |||
2401 | return base; | 2383 | return base; |
2402 | 2384 | ||
2403 | failure: | 2385 | failure: |
@@ -2612,6 +2594,8 @@ static int __init d40_probe(struct platform_device *pdev) | |||
2612 | 2594 | ||
2613 | failure: | 2595 | failure: |
2614 | if (base) { | 2596 | if (base) { |
2597 | if (base->desc_slab) | ||
2598 | kmem_cache_destroy(base->desc_slab); | ||
2615 | if (base->virtbase) | 2599 | if (base->virtbase) |
2616 | iounmap(base->virtbase); | 2600 | iounmap(base->virtbase); |
2617 | if (base->lcla_pool.phy) | 2601 | if (base->lcla_pool.phy) |