/*
* GK20A Graphics channel
*
- * Copyright (c) 2011-2015, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2016, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
q->size = q->mem.size / sizeof (u32);
+ INIT_LIST_HEAD(&q->free);
+
return 0;
clean_up:
{
struct vm_gk20a *ch_vm = c->vm;
struct priv_cmd_queue *q = &c->priv_cmd_q;
+ struct priv_cmd_entry *e;
+ struct list_head *pos, *tmp, *head;
if (q->size == 0)
return;
gk20a_gmmu_unmap_free(ch_vm, &q->mem);
+ /* free free list */
+ head = &q->free;
+ list_for_each_safe(pos, tmp, head) {
+ e = container_of(pos, struct priv_cmd_entry, list);
+ kfree(e);
+ }
+
memset(q, 0, sizeof(struct priv_cmd_queue));
}
if (size > free_count)
return -EAGAIN;
- e = kzalloc(sizeof(struct priv_cmd_entry), GFP_KERNEL);
+ if (list_empty(&q->free))
+ e = kzalloc(sizeof(struct priv_cmd_entry), GFP_KERNEL);
+ else {
+ e = container_of((&q->free)->next,
+ struct priv_cmd_entry, list);
+ list_del(&e->list);
+ }
if (!e) {
gk20a_err(dev_from_gk20a(c->g),
"ch %d: fail to allocate priv cmd entry",
static void free_priv_cmdbuf(struct channel_gk20a *c,
struct priv_cmd_entry *e)
{
- kfree(e);
+ struct priv_cmd_queue *q = &c->priv_cmd_q;
+
+ list_add(&e->list, &q->free);
}
int gk20a_alloc_channel_gpfifo(struct channel_gk20a *c,
/*
* GK20A memory management
*
- * Copyright (c) 2011-2015, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2016, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
u32 size; /* num of entries in words */
u32 put; /* put for priv cmd queue */
u32 get; /* get for priv cmd queue */
+ struct list_head free; /* list of buffered entries */
};
struct priv_cmd_entry {