aboutsummaryrefslogtreecommitdiffstats
path: root/lib/swiotlb.c
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2009-11-10 05:46:18 -0500
committerIngo Molnar <mingo@elte.hu>2009-11-10 06:31:52 -0500
commit5740afdb68abadc473fd5392df733558a58c1254 (patch)
tree82f87512446607118d48b0e6db9f011abd5e1124 /lib/swiotlb.c
parent9f993ac3f708b661207ed7de521f245586217a68 (diff)
swiotlb: Add swiotlb_free() function
swiotlb_free() function frees all allocated memory for swiotlb. We need to initialize swiotlb before IOMMU initialization (x86 and powerpc needs to allocate memory from bootmem allocator). If IOMMU initialization is successful, we need to free swiotlb resource (don't want to waste 64MB). Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Cc: chrisw@sous-sol.org Cc: dwmw2@infradead.org Cc: joerg.roedel@amd.com Cc: muli@il.ibm.com LKML-Reference: <1257849980-22640-8-git-send-email-fujita.tomonori@lab.ntt.co.jp> [ -v2: build fix for the !CONFIG_SWIOTLB case ] Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'lib/swiotlb.c')
-rw-r--r--lib/swiotlb.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index ac25cd28e80..eee512b63f1 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -97,6 +97,8 @@ static phys_addr_t *io_tlb_orig_addr;
97 */ 97 */
98static DEFINE_SPINLOCK(io_tlb_lock); 98static DEFINE_SPINLOCK(io_tlb_lock);
99 99
100static int late_alloc;
101
100static int __init 102static int __init
101setup_io_tlb_npages(char *str) 103setup_io_tlb_npages(char *str)
102{ 104{
@@ -262,6 +264,8 @@ swiotlb_late_init_with_default_size(size_t default_size)
262 264
263 swiotlb_print_info(bytes); 265 swiotlb_print_info(bytes);
264 266
267 late_alloc = 1;
268
265 return 0; 269 return 0;
266 270
267cleanup4: 271cleanup4:
@@ -281,6 +285,32 @@ cleanup1:
281 return -ENOMEM; 285 return -ENOMEM;
282} 286}
283 287
288void __init swiotlb_free(void)
289{
290 if (!io_tlb_overflow_buffer)
291 return;
292
293 if (late_alloc) {
294 free_pages((unsigned long)io_tlb_overflow_buffer,
295 get_order(io_tlb_overflow));
296 free_pages((unsigned long)io_tlb_orig_addr,
297 get_order(io_tlb_nslabs * sizeof(phys_addr_t)));
298 free_pages((unsigned long)io_tlb_list, get_order(io_tlb_nslabs *
299 sizeof(int)));
300 free_pages((unsigned long)io_tlb_start,
301 get_order(io_tlb_nslabs << IO_TLB_SHIFT));
302 } else {
303 free_bootmem_late(__pa(io_tlb_overflow_buffer),
304 io_tlb_overflow);
305 free_bootmem_late(__pa(io_tlb_orig_addr),
306 io_tlb_nslabs * sizeof(phys_addr_t));
307 free_bootmem_late(__pa(io_tlb_list),
308 io_tlb_nslabs * sizeof(int));
309 free_bootmem_late(__pa(io_tlb_start),
310 io_tlb_nslabs << IO_TLB_SHIFT);
311 }
312}
313
284static int is_swiotlb_buffer(phys_addr_t paddr) 314static int is_swiotlb_buffer(phys_addr_t paddr)
285{ 315{
286 return paddr >= virt_to_phys(io_tlb_start) && 316 return paddr >= virt_to_phys(io_tlb_start) &&