aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorJonas Aaberg <jonas.aberg@stericsson.com>2010-06-20 17:25:08 -0400
committerDan Williams <dan.j.williams@intel.com>2010-06-22 21:01:53 -0400
commitc675b1b424446b52de00cad84ca3d823d29a3d0e (patch)
treef829269f5967575481405b0cafdd6ef1c4efeb28 /drivers/dma
parenta8be8627a3a00859367d219848f2cd771d6aa925 (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.c52
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 */
246struct d40_base { 239struct 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 }
404out: 388 return d;
405 return desc;
406} 389}
407 390
408static void d40_desc_free(struct d40_chan *d40c, struct d40_desc *d40d) 391static 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
417static void d40_desc_submit(struct d40_chan *d40c, struct d40_desc *desc) 396static 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
2403failure: 2385failure:
@@ -2612,6 +2594,8 @@ static int __init d40_probe(struct platform_device *pdev)
2612 2594
2613failure: 2595failure:
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)