aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/msi_bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev/msi_bitmap.c')
-rw-r--r--arch/powerpc/sysdev/msi_bitmap.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/arch/powerpc/sysdev/msi_bitmap.c b/arch/powerpc/sysdev/msi_bitmap.c
index 2ff630267e9e..0c75214b6f92 100644
--- a/arch/powerpc/sysdev/msi_bitmap.c
+++ b/arch/powerpc/sysdev/msi_bitmap.c
@@ -20,32 +20,37 @@ int msi_bitmap_alloc_hwirqs(struct msi_bitmap *bmp, int num)
20 int offset, order = get_count_order(num); 20 int offset, order = get_count_order(num);
21 21
22 spin_lock_irqsave(&bmp->lock, flags); 22 spin_lock_irqsave(&bmp->lock, flags);
23 /* 23
24 * This is fast, but stricter than we need. We might want to add 24 offset = bitmap_find_next_zero_area(bmp->bitmap, bmp->irq_count, 0,
25 * a fallback routine which does a linear search with no alignment. 25 num, (1 << order) - 1);
26 */ 26 if (offset > bmp->irq_count)
27 offset = bitmap_find_free_region(bmp->bitmap, bmp->irq_count, order); 27 goto err;
28
29 bitmap_set(bmp->bitmap, offset, num);
28 spin_unlock_irqrestore(&bmp->lock, flags); 30 spin_unlock_irqrestore(&bmp->lock, flags);
29 31
30 pr_debug("msi_bitmap: allocated 0x%x (2^%d) at offset 0x%x\n", 32 pr_debug("msi_bitmap: allocated 0x%x at offset 0x%x\n", num, offset);
31 num, order, offset);
32 33
33 return offset; 34 return offset;
35err:
36 spin_unlock_irqrestore(&bmp->lock, flags);
37 return -ENOMEM;
34} 38}
39EXPORT_SYMBOL(msi_bitmap_alloc_hwirqs);
35 40
36void msi_bitmap_free_hwirqs(struct msi_bitmap *bmp, unsigned int offset, 41void msi_bitmap_free_hwirqs(struct msi_bitmap *bmp, unsigned int offset,
37 unsigned int num) 42 unsigned int num)
38{ 43{
39 unsigned long flags; 44 unsigned long flags;
40 int order = get_count_order(num);
41 45
42 pr_debug("msi_bitmap: freeing 0x%x (2^%d) at offset 0x%x\n", 46 pr_debug("msi_bitmap: freeing 0x%x at offset 0x%x\n",
43 num, order, offset); 47 num, offset);
44 48
45 spin_lock_irqsave(&bmp->lock, flags); 49 spin_lock_irqsave(&bmp->lock, flags);
46 bitmap_release_region(bmp->bitmap, offset, order); 50 bitmap_clear(bmp->bitmap, offset, num);
47 spin_unlock_irqrestore(&bmp->lock, flags); 51 spin_unlock_irqrestore(&bmp->lock, flags);
48} 52}
53EXPORT_SYMBOL(msi_bitmap_free_hwirqs);
49 54
50void msi_bitmap_reserve_hwirq(struct msi_bitmap *bmp, unsigned int hwirq) 55void msi_bitmap_reserve_hwirq(struct msi_bitmap *bmp, unsigned int hwirq)
51{ 56{
@@ -143,7 +148,7 @@ void msi_bitmap_free(struct msi_bitmap *bmp)
143#define check(x) \ 148#define check(x) \
144 if (!(x)) printk("msi_bitmap: test failed at line %d\n", __LINE__); 149 if (!(x)) printk("msi_bitmap: test failed at line %d\n", __LINE__);
145 150
146void __init test_basics(void) 151static void __init test_basics(void)
147{ 152{
148 struct msi_bitmap bmp; 153 struct msi_bitmap bmp;
149 int i, size = 512; 154 int i, size = 512;
@@ -180,6 +185,15 @@ void __init test_basics(void)
180 msi_bitmap_free_hwirqs(&bmp, size / 2, 1); 185 msi_bitmap_free_hwirqs(&bmp, size / 2, 1);
181 check(msi_bitmap_alloc_hwirqs(&bmp, 1) == size / 2); 186 check(msi_bitmap_alloc_hwirqs(&bmp, 1) == size / 2);
182 187
188 /* Check we get a naturally aligned offset */
189 check(msi_bitmap_alloc_hwirqs(&bmp, 2) % 2 == 0);
190 check(msi_bitmap_alloc_hwirqs(&bmp, 4) % 4 == 0);
191 check(msi_bitmap_alloc_hwirqs(&bmp, 8) % 8 == 0);
192 check(msi_bitmap_alloc_hwirqs(&bmp, 9) % 16 == 0);
193 check(msi_bitmap_alloc_hwirqs(&bmp, 3) % 4 == 0);
194 check(msi_bitmap_alloc_hwirqs(&bmp, 7) % 8 == 0);
195 check(msi_bitmap_alloc_hwirqs(&bmp, 121) % 128 == 0);
196
183 msi_bitmap_free(&bmp); 197 msi_bitmap_free(&bmp);
184 198
185 /* Clients may check bitmap == NULL for "not-allocated" */ 199 /* Clients may check bitmap == NULL for "not-allocated" */
@@ -188,7 +202,7 @@ void __init test_basics(void)
188 kfree(bmp.bitmap); 202 kfree(bmp.bitmap);
189} 203}
190 204
191void __init test_of_node(void) 205static void __init test_of_node(void)
192{ 206{
193 u32 prop_data[] = { 10, 10, 25, 3, 40, 1, 100, 100, 200, 20 }; 207 u32 prop_data[] = { 10, 10, 25, 3, 40, 1, 100, 100, 200, 20 };
194 const char *expected_str = "0-9,20-24,28-39,41-99,220-255"; 208 const char *expected_str = "0-9,20-24,28-39,41-99,220-255";
@@ -236,7 +250,7 @@ void __init test_of_node(void)
236 kfree(bmp.bitmap); 250 kfree(bmp.bitmap);
237} 251}
238 252
239int __init msi_bitmap_selftest(void) 253static int __init msi_bitmap_selftest(void)
240{ 254{
241 printk(KERN_DEBUG "Running MSI bitmap self-tests ...\n"); 255 printk(KERN_DEBUG "Running MSI bitmap self-tests ...\n");
242 256