aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Ellerman <michael@ellerman.id.au>2007-04-18 05:39:21 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-05-02 22:02:38 -0400
commit7fe3730de729b758e9f69b862b9255d998671b5f (patch)
tree2fc0cf3a003aaf6e8c257a32b748941e3eec93b2
parentf282b97021ddc95c6092b9016f667c0963858fb1 (diff)
MSI: arch must connect the irq and the msi_desc
set_irq_msi() currently connects an irq_desc to an msi_desc. The archs call it at some point in their setup routine, and then the generic code sets up the reverse mapping from the msi_desc back to the irq. set_irq_msi() should do both connections, making it the one and only call required to connect an irq with it's MSI desc and vice versa. The arch code MUST call set_irq_msi(), and it must do so only once it's sure it's not going to fail the irq allocation. Given that there's no need for the arch to return the irq anymore, the return value from the arch setup routine just becomes 0 for success and anything else for failure. Signed-off-by: Michael Ellerman <michael@ellerman.id.au> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--arch/i386/kernel/io_apic.c4
-rw-r--r--arch/ia64/sn/kernel/msi_sn.c4
-rw-r--r--arch/sparc64/kernel/pci.c4
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c4
-rw-r--r--arch/x86_64/kernel/io_apic.c4
-rw-r--r--drivers/pci/msi.c23
-rw-r--r--kernel/irq/chip.c3
7 files changed, 22 insertions, 24 deletions
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index b3ab8ffebd27..89d85d244926 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -2611,19 +2611,19 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
2611 if (irq < 0) 2611 if (irq < 0)
2612 return irq; 2612 return irq;
2613 2613
2614 set_irq_msi(irq, desc);
2615 ret = msi_compose_msg(dev, irq, &msg); 2614 ret = msi_compose_msg(dev, irq, &msg);
2616 if (ret < 0) { 2615 if (ret < 0) {
2617 destroy_irq(irq); 2616 destroy_irq(irq);
2618 return ret; 2617 return ret;
2619 } 2618 }
2620 2619
2620 set_irq_msi(irq, desc);
2621 write_msi_msg(irq, &msg); 2621 write_msi_msg(irq, &msg);
2622 2622
2623 set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, 2623 set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq,
2624 "edge"); 2624 "edge");
2625 2625
2626 return irq; 2626 return 0;
2627} 2627}
2628 2628
2629void arch_teardown_msi_irq(unsigned int irq) 2629void arch_teardown_msi_irq(unsigned int irq)
diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c
index 49873aa4a37d..83f190ffe350 100644
--- a/arch/ia64/sn/kernel/msi_sn.c
+++ b/arch/ia64/sn/kernel/msi_sn.c
@@ -87,7 +87,6 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry)
87 if (irq < 0) 87 if (irq < 0)
88 return irq; 88 return irq;
89 89
90 set_irq_msi(irq, entry);
91 /* 90 /*
92 * Set up the vector plumbing. Let the prom (via sn_intr_alloc) 91 * Set up the vector plumbing. Let the prom (via sn_intr_alloc)
93 * decide which cpu to direct this msi at by default. 92 * decide which cpu to direct this msi at by default.
@@ -144,10 +143,11 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry)
144 */ 143 */
145 msg.data = 0x100 + irq; 144 msg.data = 0x100 + irq;
146 145
146 set_irq_msi(irq, entry);
147 write_msi_msg(irq, &msg); 147 write_msi_msg(irq, &msg);
148 set_irq_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq); 148 set_irq_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq);
149 149
150 return irq; 150 return 0;
151} 151}
152 152
153#ifdef CONFIG_SMP 153#ifdef CONFIG_SMP
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 023af41ad68d..9a549547cb2b 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -1092,10 +1092,10 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
1092 return -EINVAL; 1092 return -EINVAL;
1093 1093
1094 err = p->setup_msi_irq(&virt_irq, pdev, desc); 1094 err = p->setup_msi_irq(&virt_irq, pdev, desc);
1095 if (err < 0) 1095 if (err)
1096 return err; 1096 return err;
1097 1097
1098 return virt_irq; 1098 return 0;
1099} 1099}
1100 1100
1101void arch_teardown_msi_irq(unsigned int virt_irq) 1101void arch_teardown_msi_irq(unsigned int virt_irq)
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index 94295c219329..1ccf4c9a9a43 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -1169,8 +1169,6 @@ static int pci_sun4v_setup_msi_irq(unsigned int *virt_irq_p,
1169 if (!devino) 1169 if (!devino)
1170 goto out_err; 1170 goto out_err;
1171 1171
1172 set_irq_msi(*virt_irq_p, entry);
1173
1174 msiqid = ((devino - pbm->msiq_first_devino) + 1172 msiqid = ((devino - pbm->msiq_first_devino) +
1175 pbm->msiq_first); 1173 pbm->msiq_first);
1176 1174
@@ -1204,6 +1202,8 @@ static int pci_sun4v_setup_msi_irq(unsigned int *virt_irq_p,
1204 msg.address_lo = pbm->msi32_start; 1202 msg.address_lo = pbm->msi32_start;
1205 } 1203 }
1206 msg.data = msi_num; 1204 msg.data = msi_num;
1205
1206 set_irq_msi(*virt_irq_p, entry);
1207 write_msi_msg(*virt_irq_p, &msg); 1207 write_msi_msg(*virt_irq_p, &msg);
1208 1208
1209 irq_install_pre_handler(*virt_irq_p, 1209 irq_install_pre_handler(*virt_irq_p,
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index c6a5bc7e8118..b7d2b76b92d4 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -1983,18 +1983,18 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
1983 if (irq < 0) 1983 if (irq < 0)
1984 return irq; 1984 return irq;
1985 1985
1986 set_irq_msi(irq, desc);
1987 ret = msi_compose_msg(dev, irq, &msg); 1986 ret = msi_compose_msg(dev, irq, &msg);
1988 if (ret < 0) { 1987 if (ret < 0) {
1989 destroy_irq(irq); 1988 destroy_irq(irq);
1990 return ret; 1989 return ret;
1991 } 1990 }
1992 1991
1992 set_irq_msi(irq, desc);
1993 write_msi_msg(irq, &msg); 1993 write_msi_msg(irq, &msg);
1994 1994
1995 set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); 1995 set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge");
1996 1996
1997 return irq; 1997 return 0;
1998} 1998}
1999 1999
2000void arch_teardown_msi_irq(unsigned int irq) 2000void arch_teardown_msi_irq(unsigned int irq)
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 7a44ba467481..88362f1bd9cf 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -297,7 +297,7 @@ void pci_restore_msi_state(struct pci_dev *dev)
297static int msi_capability_init(struct pci_dev *dev) 297static int msi_capability_init(struct pci_dev *dev)
298{ 298{
299 struct msi_desc *entry; 299 struct msi_desc *entry;
300 int pos, irq; 300 int pos, ret;
301 u16 control; 301 u16 control;
302 302
303 msi_set_enable(dev, 0); /* Ensure msi is disabled as I set it up */ 303 msi_set_enable(dev, 0); /* Ensure msi is disabled as I set it up */
@@ -335,21 +335,19 @@ static int msi_capability_init(struct pci_dev *dev)
335 maskbits); 335 maskbits);
336 } 336 }
337 /* Configure MSI capability structure */ 337 /* Configure MSI capability structure */
338 irq = arch_setup_msi_irq(dev, entry); 338 ret = arch_setup_msi_irq(dev, entry);
339 if (irq < 0) { 339 if (ret) {
340 kfree(entry); 340 kfree(entry);
341 return irq; 341 return ret;
342 } 342 }
343 entry->irq = irq;
344 list_add(&entry->list, &dev->msi_list); 343 list_add(&entry->list, &dev->msi_list);
345 set_irq_msi(irq, entry);
346 344
347 /* Set MSI enabled bits */ 345 /* Set MSI enabled bits */
348 pci_intx(dev, 0); /* disable intx */ 346 pci_intx(dev, 0); /* disable intx */
349 msi_set_enable(dev, 1); 347 msi_set_enable(dev, 1);
350 dev->msi_enabled = 1; 348 dev->msi_enabled = 1;
351 349
352 dev->irq = irq; 350 dev->irq = entry->irq;
353 return 0; 351 return 0;
354} 352}
355 353
@@ -367,7 +365,7 @@ static int msix_capability_init(struct pci_dev *dev,
367 struct msix_entry *entries, int nvec) 365 struct msix_entry *entries, int nvec)
368{ 366{
369 struct msi_desc *entry; 367 struct msi_desc *entry;
370 int irq, pos, i, j, nr_entries; 368 int irq, pos, i, j, nr_entries, ret;
371 unsigned long phys_addr; 369 unsigned long phys_addr;
372 u32 table_offset; 370 u32 table_offset;
373 u16 control; 371 u16 control;
@@ -407,16 +405,13 @@ static int msix_capability_init(struct pci_dev *dev,
407 entry->mask_base = base; 405 entry->mask_base = base;
408 406
409 /* Configure MSI-X capability structure */ 407 /* Configure MSI-X capability structure */
410 irq = arch_setup_msi_irq(dev, entry); 408 ret = arch_setup_msi_irq(dev, entry);
411 if (irq < 0) { 409 if (ret) {
412 kfree(entry); 410 kfree(entry);
413 break; 411 break;
414 } 412 }
415 entry->irq = irq; 413 entries[i].vector = entry->irq;
416 entries[i].vector = irq;
417 list_add(&entry->list, &dev->msi_list); 414 list_add(&entry->list, &dev->msi_list);
418
419 set_irq_msi(irq, entry);
420 } 415 }
421 if (i != nvec) { 416 if (i != nvec) {
422 int avail = i - 1; 417 int avail = i - 1;
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 0133f4f9e9f0..615ce97c6cfd 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/irq.h> 13#include <linux/irq.h>
14#include <linux/msi.h>
14#include <linux/module.h> 15#include <linux/module.h>
15#include <linux/interrupt.h> 16#include <linux/interrupt.h>
16#include <linux/kernel_stat.h> 17#include <linux/kernel_stat.h>
@@ -185,6 +186,8 @@ int set_irq_msi(unsigned int irq, struct msi_desc *entry)
185 desc = irq_desc + irq; 186 desc = irq_desc + irq;
186 spin_lock_irqsave(&desc->lock, flags); 187 spin_lock_irqsave(&desc->lock, flags);
187 desc->msi_desc = entry; 188 desc->msi_desc = entry;
189 if (entry)
190 entry->irq = irq;
188 spin_unlock_irqrestore(&desc->lock, flags); 191 spin_unlock_irqrestore(&desc->lock, flags);
189 return 0; 192 return 0;
190} 193}