diff options
author | Michael Ellerman <michael@ellerman.id.au> | 2008-08-06 09:10:02 +1000 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-08-20 16:34:58 +1000 |
commit | 7e7ab3677502a0f798f38bfa1a7d53dd22faa0bc (patch) | |
tree | 7bb1d6b2f7f45907033d2db517d1c804a1e5e1ed /arch/powerpc/sysdev/fsl_msi.c | |
parent | 7e302869e0c5261aba779e059cddcd2fbf7aedbe (diff) | |
download | blackbird-op-linux-7e7ab3677502a0f798f38bfa1a7d53dd22faa0bc.tar.gz blackbird-op-linux-7e7ab3677502a0f798f38bfa1a7d53dd22faa0bc.zip |
powerpc: Convert the FSL MSI code to use msi_bitmap
This is 90% straight forward, although we have to change a few
printk format strings as well because of the change in type of hwirq.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/sysdev/fsl_msi.c')
-rw-r--r-- | arch/powerpc/sysdev/fsl_msi.c | 103 |
1 files changed, 14 insertions, 89 deletions
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index d49fa9904d53..f25ce818d40a 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -14,7 +14,6 @@ */ #include <linux/irq.h> #include <linux/bootmem.h> -#include <linux/bitmap.h> #include <linux/msi.h> #include <linux/pci.h> #include <linux/of_platform.h> @@ -67,96 +66,22 @@ static struct irq_host_ops fsl_msi_host_ops = { .map = fsl_msi_host_map, }; -static irq_hw_number_t fsl_msi_alloc_hwirqs(struct fsl_msi *msi, int num) -{ - unsigned long flags; - int order = get_count_order(num); - int offset; - - spin_lock_irqsave(&msi->bitmap_lock, flags); - - offset = bitmap_find_free_region(msi->fsl_msi_bitmap, - NR_MSI_IRQS, order); - - spin_unlock_irqrestore(&msi->bitmap_lock, flags); - - pr_debug("%s: allocated 0x%x (2^%d) at offset 0x%x\n", - __func__, num, order, offset); - - return offset; -} - -static void fsl_msi_free_hwirqs(struct fsl_msi *msi, int offset, int num) -{ - unsigned long flags; - int order = get_count_order(num); - - pr_debug("%s: freeing 0x%x (2^%d) at offset 0x%x\n", - __func__, num, order, offset); - - spin_lock_irqsave(&msi->bitmap_lock, flags); - bitmap_release_region(msi->fsl_msi_bitmap, offset, order); - spin_unlock_irqrestore(&msi->bitmap_lock, flags); -} - -static int fsl_msi_free_dt_hwirqs(struct fsl_msi *msi) -{ - int i; - int len; - const u32 *p; - - bitmap_allocate_region(msi->fsl_msi_bitmap, 0, - get_count_order(NR_MSI_IRQS)); - - p = of_get_property(msi->irqhost->of_node, "msi-available-ranges", - &len); - - if (!p) { - /* No msi-available-ranges property, - * All the 256 MSI interrupts can be used - */ - fsl_msi_free_hwirqs(msi, 0, 0x100); - return 0; - } - - if ((len % (2 * sizeof(u32))) != 0) { - printk(KERN_WARNING "fsl_msi: Malformed msi-available-ranges " - "property on %s\n", msi->irqhost->of_node->full_name); - return -EINVAL; - } - - /* Format is: (<u32 start> <u32 count>)+ */ - len /= 2 * sizeof(u32); - for (i = 0; i < len; i++, p += 2) - fsl_msi_free_hwirqs(msi, *p, *(p + 1)); - - return 0; -} - static int fsl_msi_init_allocator(struct fsl_msi *msi_data) { int rc; - int size = BITS_TO_LONGS(NR_MSI_IRQS) * sizeof(u32); - msi_data->fsl_msi_bitmap = kzalloc(size, GFP_KERNEL); + rc = msi_bitmap_alloc(&msi_data->bitmap, NR_MSI_IRQS, + msi_data->irqhost->of_node); + if (rc) + return rc; - if (msi_data->fsl_msi_bitmap == NULL) { - pr_debug("%s: ENOMEM allocating allocator bitmap!\n", - __func__); - return -ENOMEM; + rc = msi_bitmap_reserve_dt_hwirqs(&msi_data->bitmap); + if (rc < 0) { + msi_bitmap_free(&msi_data->bitmap); + return rc; } - rc = fsl_msi_free_dt_hwirqs(msi_data); - if (rc) - goto out_free; - return 0; -out_free: - kfree(msi_data->fsl_msi_bitmap); - - msi_data->fsl_msi_bitmap = NULL; - return rc; - } static int fsl_msi_check_device(struct pci_dev *pdev, int nvec, int type) @@ -176,7 +101,8 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev) if (entry->irq == NO_IRQ) continue; set_irq_msi(entry->irq, NULL); - fsl_msi_free_hwirqs(msi_data, virq_to_hw(entry->irq), 1); + msi_bitmap_free_hwirqs(&msi_data->bitmap, + virq_to_hw(entry->irq), 1); irq_dispose_mapping(entry->irq); } @@ -198,15 +124,14 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq, static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) { - irq_hw_number_t hwirq; - int rc; + int rc, hwirq; unsigned int virq; struct msi_desc *entry; struct msi_msg msg; struct fsl_msi *msi_data = fsl_msi; list_for_each_entry(entry, &pdev->msi_list, list) { - hwirq = fsl_msi_alloc_hwirqs(msi_data, 1); + hwirq = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1); if (hwirq < 0) { rc = hwirq; pr_debug("%s: fail allocating msi interrupt\n", @@ -217,9 +142,9 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) virq = irq_create_mapping(msi_data->irqhost, hwirq); if (virq == NO_IRQ) { - pr_debug("%s: fail mapping hwirq 0x%lx\n", + pr_debug("%s: fail mapping hwirq 0x%x\n", __func__, hwirq); - fsl_msi_free_hwirqs(msi_data, hwirq, 1); + msi_bitmap_free_hwirqs(&msi_data->bitmap, hwirq, 1); rc = -ENOSPC; goto out_free; } |