aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris
diff options
context:
space:
mode:
authorJesper Nilsson <jesper.nilsson@axis.com>2008-01-25 12:03:00 -0500
committerJesper Nilsson <jesper.nilsson@axis.com>2008-02-08 05:06:36 -0500
commit108ecfbc3110574fe929e9dd1f622580f95359c0 (patch)
tree94e312110337993f7b2ff10a3d756020536f41b3 /arch/cris
parent0836c6d26f3512db5fa9698376846c5cec4fae13 (diff)
CRIS v32: Fix bug in internal memory allocator mm/intmem.c
- Fix bug where allocated memory didn't account for alignment. - Add support for ARTPEC-3 - Add module_init for crisv32_intmem_init.
Diffstat (limited to 'arch/cris')
-rw-r--r--arch/cris/arch-v32/mm/intmem.c48
1 files changed, 31 insertions, 17 deletions
diff --git a/arch/cris/arch-v32/mm/intmem.c b/arch/cris/arch-v32/mm/intmem.c
index 41ee7f7997fd..9e8b69cdf19e 100644
--- a/arch/cris/arch-v32/mm/intmem.c
+++ b/arch/cris/arch-v32/mm/intmem.c
@@ -7,11 +7,17 @@
7#include <linux/list.h> 7#include <linux/list.h>
8#include <linux/slab.h> 8#include <linux/slab.h>
9#include <asm/io.h> 9#include <asm/io.h>
10#include <asm/arch/memmap.h> 10#include <memmap.h>
11 11
12#define STATUS_FREE 0 12#define STATUS_FREE 0
13#define STATUS_ALLOCATED 1 13#define STATUS_ALLOCATED 1
14 14
15#ifdef CONFIG_ETRAX_L2CACHE
16#define RESERVED_SIZE 66*1024
17#else
18#define RESERVED_SIZE 0
19#endif
20
15struct intmem_allocation { 21struct intmem_allocation {
16 struct list_head entry; 22 struct list_head entry;
17 unsigned int size; 23 unsigned int size;
@@ -30,9 +36,10 @@ static void crisv32_intmem_init(void)
30 struct intmem_allocation* alloc = 36 struct intmem_allocation* alloc =
31 (struct intmem_allocation*)kmalloc(sizeof *alloc, GFP_KERNEL); 37 (struct intmem_allocation*)kmalloc(sizeof *alloc, GFP_KERNEL);
32 INIT_LIST_HEAD(&intmem_allocations); 38 INIT_LIST_HEAD(&intmem_allocations);
33 intmem_virtual = ioremap(MEM_INTMEM_START, MEM_INTMEM_SIZE); 39 intmem_virtual = ioremap(MEM_INTMEM_START + RESERVED_SIZE,
40 MEM_INTMEM_SIZE - RESERVED_SIZE);
34 initiated = 1; 41 initiated = 1;
35 alloc->size = MEM_INTMEM_SIZE; 42 alloc->size = MEM_INTMEM_SIZE - RESERVED_SIZE;
36 alloc->offset = 0; 43 alloc->offset = 0;
37 alloc->status = STATUS_FREE; 44 alloc->status = STATUS_FREE;
38 list_add_tail(&alloc->entry, &intmem_allocations); 45 list_add_tail(&alloc->entry, &intmem_allocations);
@@ -59,19 +66,23 @@ void* crisv32_intmem_alloc(unsigned size, unsigned align)
59 (struct intmem_allocation*) 66 (struct intmem_allocation*)
60 kmalloc(sizeof *alloc, GFP_ATOMIC); 67 kmalloc(sizeof *alloc, GFP_ATOMIC);
61 alloc->status = STATUS_FREE; 68 alloc->status = STATUS_FREE;
62 alloc->size = allocation->size - size - alignment; 69 alloc->size = allocation->size - size -
63 alloc->offset = allocation->offset + size; 70 alignment;
71 alloc->offset = allocation->offset + size +
72 alignment;
64 list_add(&alloc->entry, &allocation->entry); 73 list_add(&alloc->entry, &allocation->entry);
65 74
66 if (alignment) { 75 if (alignment) {
67 struct intmem_allocation* tmp; 76 struct intmem_allocation *tmp;
68 tmp = (struct intmem_allocation*) 77 tmp = (struct intmem_allocation *)
69 kmalloc(sizeof *tmp, GFP_ATOMIC); 78 kmalloc(sizeof *tmp,
79 GFP_ATOMIC);
70 tmp->offset = allocation->offset; 80 tmp->offset = allocation->offset;
71 tmp->size = alignment; 81 tmp->size = alignment;
72 tmp->status = STATUS_FREE; 82 tmp->status = STATUS_FREE;
73 allocation->offset += alignment; 83 allocation->offset += alignment;
74 list_add_tail(&tmp->entry, &allocation->entry); 84 list_add_tail(&tmp->entry,
85 &allocation->entry);
75 } 86 }
76 } 87 }
77 allocation->status = STATUS_ALLOCATED; 88 allocation->status = STATUS_ALLOCATED;
@@ -96,22 +107,24 @@ void crisv32_intmem_free(void* addr)
96 107
97 list_for_each_entry_safe(allocation, tmp, &intmem_allocations, entry) { 108 list_for_each_entry_safe(allocation, tmp, &intmem_allocations, entry) {
98 if (allocation->offset == (int)(addr - intmem_virtual)) { 109 if (allocation->offset == (int)(addr - intmem_virtual)) {
99 struct intmem_allocation* prev = 110 struct intmem_allocation *prev =
100 list_entry(allocation->entry.prev, 111 list_entry(allocation->entry.prev,
101 struct intmem_allocation, entry); 112 struct intmem_allocation, entry);
102 struct intmem_allocation* next = 113 struct intmem_allocation *next =
103 list_entry(allocation->entry.next, 114 list_entry(allocation->entry.next,
104 struct intmem_allocation, entry); 115 struct intmem_allocation, entry);
105 116
106 allocation->status = STATUS_FREE; 117 allocation->status = STATUS_FREE;
107 /* Join with prev and/or next if also free */ 118 /* Join with prev and/or next if also free */
108 if (prev->status == STATUS_FREE) { 119 if ((prev != &intmem_allocations) &&
120 (prev->status == STATUS_FREE)) {
109 prev->size += allocation->size; 121 prev->size += allocation->size;
110 list_del(&allocation->entry); 122 list_del(&allocation->entry);
111 kfree(allocation); 123 kfree(allocation);
112 allocation = prev; 124 allocation = prev;
113 } 125 }
114 if (next->status == STATUS_FREE) { 126 if ((next != &intmem_allocations) &&
127 (next->status == STATUS_FREE)) {
115 allocation->size += next->size; 128 allocation->size += next->size;
116 list_del(&next->entry); 129 list_del(&next->entry);
117 kfree(next); 130 kfree(next);
@@ -125,15 +138,16 @@ void crisv32_intmem_free(void* addr)
125 138
126void* crisv32_intmem_phys_to_virt(unsigned long addr) 139void* crisv32_intmem_phys_to_virt(unsigned long addr)
127{ 140{
128 return (void*)(addr - MEM_INTMEM_START+ 141 return (void *)(addr - (MEM_INTMEM_START + RESERVED_SIZE) +
129 (unsigned long)intmem_virtual); 142 (unsigned long)intmem_virtual);
130} 143}
131 144
132unsigned long crisv32_intmem_virt_to_phys(void* addr) 145unsigned long crisv32_intmem_virt_to_phys(void* addr)
133{ 146{
134 return (unsigned long)((unsigned long )addr - 147 return (unsigned long)((unsigned long )addr -
135 (unsigned long)intmem_virtual + MEM_INTMEM_START); 148 (unsigned long)intmem_virtual + MEM_INTMEM_START +
149 RESERVED_SIZE);
136} 150}
137 151
138 152module_init(crisv32_intmem_init);
139 153