diff options
Diffstat (limited to 'arch/powerpc/platforms/powernv/pci.c')
-rw-r--r-- | arch/powerpc/platforms/powernv/pci.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index a70bc1e385eb..be3cfc5ceabb 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <asm/iommu.h> | 31 | #include <asm/iommu.h> |
32 | #include <asm/tce.h> | 32 | #include <asm/tce.h> |
33 | #include <asm/abs_addr.h> | 33 | #include <asm/abs_addr.h> |
34 | #include <asm/firmware.h> | ||
34 | 35 | ||
35 | #include "powernv.h" | 36 | #include "powernv.h" |
36 | #include "pci.h" | 37 | #include "pci.h" |
@@ -52,32 +53,38 @@ static int pnv_msi_check_device(struct pci_dev* pdev, int nvec, int type) | |||
52 | 53 | ||
53 | static unsigned int pnv_get_one_msi(struct pnv_phb *phb) | 54 | static unsigned int pnv_get_one_msi(struct pnv_phb *phb) |
54 | { | 55 | { |
55 | unsigned int id; | 56 | unsigned long flags; |
57 | unsigned int id, rc; | ||
58 | |||
59 | spin_lock_irqsave(&phb->lock, flags); | ||
56 | 60 | ||
57 | spin_lock(&phb->lock); | ||
58 | id = find_next_zero_bit(phb->msi_map, phb->msi_count, phb->msi_next); | 61 | id = find_next_zero_bit(phb->msi_map, phb->msi_count, phb->msi_next); |
59 | if (id >= phb->msi_count && phb->msi_next) | 62 | if (id >= phb->msi_count && phb->msi_next) |
60 | id = find_next_zero_bit(phb->msi_map, phb->msi_count, 0); | 63 | id = find_next_zero_bit(phb->msi_map, phb->msi_count, 0); |
61 | if (id >= phb->msi_count) { | 64 | if (id >= phb->msi_count) { |
62 | spin_unlock(&phb->lock); | 65 | rc = 0; |
63 | return 0; | 66 | goto out; |
64 | } | 67 | } |
65 | __set_bit(id, phb->msi_map); | 68 | __set_bit(id, phb->msi_map); |
66 | spin_unlock(&phb->lock); | 69 | rc = id + phb->msi_base; |
67 | return id + phb->msi_base; | 70 | out: |
71 | spin_unlock_irqrestore(&phb->lock, flags); | ||
72 | return rc; | ||
68 | } | 73 | } |
69 | 74 | ||
70 | static void pnv_put_msi(struct pnv_phb *phb, unsigned int hwirq) | 75 | static void pnv_put_msi(struct pnv_phb *phb, unsigned int hwirq) |
71 | { | 76 | { |
77 | unsigned long flags; | ||
72 | unsigned int id; | 78 | unsigned int id; |
73 | 79 | ||
74 | if (WARN_ON(hwirq < phb->msi_base || | 80 | if (WARN_ON(hwirq < phb->msi_base || |
75 | hwirq >= (phb->msi_base + phb->msi_count))) | 81 | hwirq >= (phb->msi_base + phb->msi_count))) |
76 | return; | 82 | return; |
77 | id = hwirq - phb->msi_base; | 83 | id = hwirq - phb->msi_base; |
78 | spin_lock(&phb->lock); | 84 | |
85 | spin_lock_irqsave(&phb->lock, flags); | ||
79 | __clear_bit(id, phb->msi_map); | 86 | __clear_bit(id, phb->msi_map); |
80 | spin_unlock(&phb->lock); | 87 | spin_unlock_irqrestore(&phb->lock, flags); |
81 | } | 88 | } |
82 | 89 | ||
83 | static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | 90 | static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) |
@@ -555,10 +562,7 @@ void __init pnv_pci_init(void) | |||
555 | { | 562 | { |
556 | struct device_node *np; | 563 | struct device_node *np; |
557 | 564 | ||
558 | pci_set_flags(PCI_CAN_SKIP_ISA_ALIGN); | 565 | pci_add_flags(PCI_CAN_SKIP_ISA_ALIGN); |
559 | |||
560 | /* We do not want to just probe */ | ||
561 | pci_probe_only = 0; | ||
562 | 566 | ||
563 | /* OPAL absent, try POPAL first then RTAS detection of PHBs */ | 567 | /* OPAL absent, try POPAL first then RTAS detection of PHBs */ |
564 | if (!firmware_has_feature(FW_FEATURE_OPAL)) { | 568 | if (!firmware_has_feature(FW_FEATURE_OPAL)) { |