Merge branch 'staging/for_v3.7' into v4l_for_linus
[pandora-kernel.git] / lib / swiotlb.c
index 45bc1f8..f114bf6 100644 (file)
@@ -170,7 +170,7 @@ void __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose)
  * Statically reserve bounce buffer space and initialize bounce buffer data
  * structures for the software IO TLB used to implement the DMA API.
  */
-void __init
+static void __init
 swiotlb_init_with_default_size(size_t default_size, int verbose)
 {
        unsigned long bytes;
@@ -206,8 +206,9 @@ swiotlb_init(int verbose)
 int
 swiotlb_late_init_with_default_size(size_t default_size)
 {
-       unsigned long i, bytes, req_nslabs = io_tlb_nslabs;
+       unsigned long bytes, req_nslabs = io_tlb_nslabs;
        unsigned int order;
+       int rc = 0;
 
        if (!io_tlb_nslabs) {
                io_tlb_nslabs = (default_size >> IO_TLB_SHIFT);
@@ -229,16 +230,32 @@ swiotlb_late_init_with_default_size(size_t default_size)
                order--;
        }
 
-       if (!io_tlb_start)
-               goto cleanup1;
-
+       if (!io_tlb_start) {
+               io_tlb_nslabs = req_nslabs;
+               return -ENOMEM;
+       }
        if (order != get_order(bytes)) {
                printk(KERN_WARNING "Warning: only able to allocate %ld MB "
                       "for software IO TLB\n", (PAGE_SIZE << order) >> 20);
                io_tlb_nslabs = SLABS_PER_PAGE << order;
-               bytes = io_tlb_nslabs << IO_TLB_SHIFT;
        }
+       rc = swiotlb_late_init_with_tbl(io_tlb_start, io_tlb_nslabs);
+       if (rc)
+               free_pages((unsigned long)io_tlb_start, order);
+       return rc;
+}
+
+int
+swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs)
+{
+       unsigned long i, bytes;
+
+       bytes = nslabs << IO_TLB_SHIFT;
+
+       io_tlb_nslabs = nslabs;
+       io_tlb_start = tlb;
        io_tlb_end = io_tlb_start + bytes;
+
        memset(io_tlb_start, 0, bytes);
 
        /*
@@ -288,10 +305,8 @@ cleanup3:
        io_tlb_list = NULL;
 cleanup2:
        io_tlb_end = NULL;
-       free_pages((unsigned long)io_tlb_start, order);
        io_tlb_start = NULL;
-cleanup1:
-       io_tlb_nslabs = req_nslabs;
+       io_tlb_nslabs = 0;
        return -ENOMEM;
 }