diff options
author | Jesper Nilsson <jesper.nilsson@axis.com> | 2008-01-25 12:03:00 -0500 |
---|---|---|
committer | Jesper Nilsson <jesper.nilsson@axis.com> | 2008-02-08 05:06:36 -0500 |
commit | 108ecfbc3110574fe929e9dd1f622580f95359c0 (patch) | |
tree | 94e312110337993f7b2ff10a3d756020536f41b3 /arch/cris | |
parent | 0836c6d26f3512db5fa9698376846c5cec4fae13 (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.c | 48 |
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 | |||
15 | struct intmem_allocation { | 21 | struct 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 | ||
126 | void* crisv32_intmem_phys_to_virt(unsigned long addr) | 139 | void* 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 | ||
132 | unsigned long crisv32_intmem_virt_to_phys(void* addr) | 145 | unsigned 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 | 152 | module_init(crisv32_intmem_init); | |
139 | 153 | ||