aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/fsl_msi.c
diff options
context:
space:
mode:
authorLi Yang <leoli@freescale.com>2010-04-22 04:31:36 -0400
committerKumar Gala <galak@kernel.crashing.org>2010-05-24 22:26:32 -0400
commit694a7a3611a1c0e28d99b4955151c6ce68e89752 (patch)
treeb8a41e9a07b9407e14c9ece25bbbb289e16228bd /arch/powerpc/sysdev/fsl_msi.c
parent02adac6051b0ff8df3877ae3d94e0e68063c6a30 (diff)
powerpc/fsl_msi: enable msi allocation in all banks
Put all fsl_msi banks in a linked list. The list of banks then can be traversed when allocating new msi interrupts. Also fix failing path of fsl_setup_msi_irqs(). Signed-off-by: Zhao Chenhui <b26998@freescale.com> Signed-off-by: Li Yang <leoli@freescale.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/sysdev/fsl_msi.c')
-rw-r--r--arch/powerpc/sysdev/fsl_msi.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index b769982612a0..efffcbd190a1 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -25,6 +25,8 @@
25#include <asm/mpic.h> 25#include <asm/mpic.h>
26#include "fsl_msi.h" 26#include "fsl_msi.h"
27 27
28LIST_HEAD(msi_head);
29
28struct fsl_msi_feature { 30struct fsl_msi_feature {
29 u32 fsl_pic_ip; 31 u32 fsl_pic_ip;
30 u32 msiir_offset; 32 u32 msiir_offset;
@@ -138,16 +140,19 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
138 140
139static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) 141static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
140{ 142{
141 int rc, hwirq = NO_IRQ; 143 int rc, hwirq = -ENOMEM;
142 unsigned int virq; 144 unsigned int virq;
143 struct msi_desc *entry; 145 struct msi_desc *entry;
144 struct msi_msg msg; 146 struct msi_msg msg;
145 struct fsl_msi *msi_data; 147 struct fsl_msi *msi_data;
146 148
147 list_for_each_entry(entry, &pdev->msi_list, list) { 149 list_for_each_entry(entry, &pdev->msi_list, list) {
148 msi_data = get_irq_chip_data(entry->irq); 150 list_for_each_entry(msi_data, &msi_head, list) {
151 hwirq = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1);
152 if (hwirq >= 0)
153 break;
154 }
149 155
150 hwirq = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1);
151 if (hwirq < 0) { 156 if (hwirq < 0) {
152 rc = hwirq; 157 rc = hwirq;
153 pr_debug("%s: fail allocating msi interrupt\n", 158 pr_debug("%s: fail allocating msi interrupt\n",
@@ -173,6 +178,7 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
173 return 0; 178 return 0;
174 179
175out_free: 180out_free:
181 /* free by the caller of this function */
176 return rc; 182 return rc;
177} 183}
178 184
@@ -337,6 +343,8 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev,
337 } 343 }
338 } 344 }
339 345
346 list_add_tail(&msi->list, &msi_head);
347
340 /* The multiple setting ppc_md.setup_msi_irqs will not harm things */ 348 /* The multiple setting ppc_md.setup_msi_irqs will not harm things */
341 if (!ppc_md.setup_msi_irqs) { 349 if (!ppc_md.setup_msi_irqs) {
342 ppc_md.setup_msi_irqs = fsl_setup_msi_irqs; 350 ppc_md.setup_msi_irqs = fsl_setup_msi_irqs;