diff options
author | Michael Ellerman <michael@ellerman.id.au> | 2007-04-18 05:39:21 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-05-02 22:02:38 -0400 |
commit | 7fe3730de729b758e9f69b862b9255d998671b5f (patch) | |
tree | 2fc0cf3a003aaf6e8c257a32b748941e3eec93b2 /drivers/pci | |
parent | f282b97021ddc95c6092b9016f667c0963858fb1 (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>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/msi.c | 23 |
1 files changed, 9 insertions, 14 deletions
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) | |||
297 | static int msi_capability_init(struct pci_dev *dev) | 297 | static 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; |