powerpc/iommu: Use bitmap library
[firefly-linux-kernel-4.4.55.git] / arch / powerpc / kernel / iommu.c
index ff5a6ce027b88e88df6dbf7aa32519f2d08e6d7c..c862fd716fe3ede17452e7bfe138b18292de31fb 100644 (file)
@@ -215,7 +215,8 @@ static unsigned long iommu_range_alloc(struct device *dev,
        spin_lock_irqsave(&(pool->lock), flags);
 
 again:
-       if ((pass == 0) && handle && *handle)
+       if ((pass == 0) && handle && *handle &&
+           (*handle >= pool->start) && (*handle < pool->end))
                start = *handle;
        else
                start = pool->hint;
@@ -236,7 +237,9 @@ again:
                 * but on second pass, start at 0 in pool 0.
                 */
                if ((start & mask) >= limit || pass > 0) {
+                       spin_unlock(&(pool->lock));
                        pool = &(tbl->pools[0]);
+                       spin_lock(&(pool->lock));
                        start = pool->start;
                } else {
                        start &= mask;
@@ -653,7 +656,7 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
        struct iommu_pool *p;
 
        /* number of bytes needed for the bitmap */
-       sz = (tbl->it_size + 7) >> 3;
+       sz = BITS_TO_LONGS(tbl->it_size) * sizeof(unsigned long);
 
        page = alloc_pages_node(nid, GFP_ATOMIC, get_order(sz));
        if (!page)
@@ -705,7 +708,7 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
 
 void iommu_free_table(struct iommu_table *tbl, const char *node_name)
 {
-       unsigned long bitmap_sz, i;
+       unsigned long bitmap_sz;
        unsigned int order;
 
        if (!tbl || !tbl->it_map) {
@@ -715,17 +718,11 @@ void iommu_free_table(struct iommu_table *tbl, const char *node_name)
        }
 
        /* verify that table contains no entries */
-       /* it_size is in entries, and we're examining 64 at a time */
-       for (i = 0; i < (tbl->it_size/64); i++) {
-               if (tbl->it_map[i] != 0) {
-                       printk(KERN_WARNING "%s: Unexpected TCEs for %s\n",
-                               __func__, node_name);
-                       break;
-               }
-       }
+       if (!bitmap_empty(tbl->it_map, tbl->it_size))
+               pr_warn("%s: Unexpected TCEs for %s\n", __func__, node_name);
 
        /* calculate bitmap size in bytes */
-       bitmap_sz = (tbl->it_size + 7) / 8;
+       bitmap_sz = BITS_TO_LONGS(tbl->it_size) * sizeof(unsigned long);
 
        /* free bitmap */
        order = get_order(bitmap_sz);