diff options
| -rw-r--r-- | arch/powerpc/platforms/powernv/pci.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index a70bc1e385eb..f92b9ef7340e 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
| @@ -52,32 +52,38 @@ static int pnv_msi_check_device(struct pci_dev* pdev, int nvec, int type) | |||
| 52 | 52 | ||
| 53 | static unsigned int pnv_get_one_msi(struct pnv_phb *phb) | 53 | static unsigned int pnv_get_one_msi(struct pnv_phb *phb) |
| 54 | { | 54 | { |
| 55 | unsigned int id; | 55 | unsigned long flags; |
| 56 | unsigned int id, rc; | ||
| 57 | |||
| 58 | spin_lock_irqsave(&phb->lock, flags); | ||
| 56 | 59 | ||
| 57 | spin_lock(&phb->lock); | ||
| 58 | id = find_next_zero_bit(phb->msi_map, phb->msi_count, phb->msi_next); | 60 | id = find_next_zero_bit(phb->msi_map, phb->msi_count, phb->msi_next); |
| 59 | if (id >= phb->msi_count && phb->msi_next) | 61 | if (id >= phb->msi_count && phb->msi_next) |
| 60 | id = find_next_zero_bit(phb->msi_map, phb->msi_count, 0); | 62 | id = find_next_zero_bit(phb->msi_map, phb->msi_count, 0); |
| 61 | if (id >= phb->msi_count) { | 63 | if (id >= phb->msi_count) { |
| 62 | spin_unlock(&phb->lock); | 64 | rc = 0; |
| 63 | return 0; | 65 | goto out; |
| 64 | } | 66 | } |
| 65 | __set_bit(id, phb->msi_map); | 67 | __set_bit(id, phb->msi_map); |
| 66 | spin_unlock(&phb->lock); | 68 | rc = id + phb->msi_base; |
| 67 | return id + phb->msi_base; | 69 | out: |
| 70 | spin_unlock_irqrestore(&phb->lock, flags); | ||
| 71 | return rc; | ||
| 68 | } | 72 | } |
| 69 | 73 | ||
| 70 | static void pnv_put_msi(struct pnv_phb *phb, unsigned int hwirq) | 74 | static void pnv_put_msi(struct pnv_phb *phb, unsigned int hwirq) |
| 71 | { | 75 | { |
| 76 | unsigned long flags; | ||
| 72 | unsigned int id; | 77 | unsigned int id; |
| 73 | 78 | ||
| 74 | if (WARN_ON(hwirq < phb->msi_base || | 79 | if (WARN_ON(hwirq < phb->msi_base || |
| 75 | hwirq >= (phb->msi_base + phb->msi_count))) | 80 | hwirq >= (phb->msi_base + phb->msi_count))) |
| 76 | return; | 81 | return; |
| 77 | id = hwirq - phb->msi_base; | 82 | id = hwirq - phb->msi_base; |
| 78 | spin_lock(&phb->lock); | 83 | |
| 84 | spin_lock_irqsave(&phb->lock, flags); | ||
| 79 | __clear_bit(id, phb->msi_map); | 85 | __clear_bit(id, phb->msi_map); |
| 80 | spin_unlock(&phb->lock); | 86 | spin_unlock_irqrestore(&phb->lock, flags); |
| 81 | } | 87 | } |
| 82 | 88 | ||
| 83 | static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | 89 | static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) |
