diff options
Diffstat (limited to 'drivers/pci/msi.c')
-rw-r--r-- | drivers/pci/msi.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 26938da8f438..e3a05cc9a595 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -123,7 +123,7 @@ static void msix_flush_writes(unsigned int irq) | |||
123 | } | 123 | } |
124 | } | 124 | } |
125 | 125 | ||
126 | static void msi_set_mask_bit(unsigned int irq, int flag) | 126 | static void msi_set_mask_bits(unsigned int irq, u32 mask, u32 flag) |
127 | { | 127 | { |
128 | struct msi_desc *entry; | 128 | struct msi_desc *entry; |
129 | 129 | ||
@@ -137,8 +137,8 @@ static void msi_set_mask_bit(unsigned int irq, int flag) | |||
137 | 137 | ||
138 | pos = (long)entry->mask_base; | 138 | pos = (long)entry->mask_base; |
139 | pci_read_config_dword(entry->dev, pos, &mask_bits); | 139 | pci_read_config_dword(entry->dev, pos, &mask_bits); |
140 | mask_bits &= ~(1); | 140 | mask_bits &= ~(mask); |
141 | mask_bits |= flag; | 141 | mask_bits |= flag & mask; |
142 | pci_write_config_dword(entry->dev, pos, mask_bits); | 142 | pci_write_config_dword(entry->dev, pos, mask_bits); |
143 | } else { | 143 | } else { |
144 | msi_set_enable(entry->dev, !flag); | 144 | msi_set_enable(entry->dev, !flag); |
@@ -241,13 +241,13 @@ void write_msi_msg(unsigned int irq, struct msi_msg *msg) | |||
241 | 241 | ||
242 | void mask_msi_irq(unsigned int irq) | 242 | void mask_msi_irq(unsigned int irq) |
243 | { | 243 | { |
244 | msi_set_mask_bit(irq, 1); | 244 | msi_set_mask_bits(irq, 1, 1); |
245 | msix_flush_writes(irq); | 245 | msix_flush_writes(irq); |
246 | } | 246 | } |
247 | 247 | ||
248 | void unmask_msi_irq(unsigned int irq) | 248 | void unmask_msi_irq(unsigned int irq) |
249 | { | 249 | { |
250 | msi_set_mask_bit(irq, 0); | 250 | msi_set_mask_bits(irq, 1, 0); |
251 | msix_flush_writes(irq); | 251 | msix_flush_writes(irq); |
252 | } | 252 | } |
253 | 253 | ||
@@ -291,7 +291,8 @@ static void __pci_restore_msi_state(struct pci_dev *dev) | |||
291 | msi_set_enable(dev, 0); | 291 | msi_set_enable(dev, 0); |
292 | write_msi_msg(dev->irq, &entry->msg); | 292 | write_msi_msg(dev->irq, &entry->msg); |
293 | if (entry->msi_attrib.maskbit) | 293 | if (entry->msi_attrib.maskbit) |
294 | msi_set_mask_bit(dev->irq, entry->msi_attrib.masked); | 294 | msi_set_mask_bits(dev->irq, entry->msi_attrib.maskbits_mask, |
295 | entry->msi_attrib.masked); | ||
295 | 296 | ||
296 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); | 297 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); |
297 | control &= ~(PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE); | 298 | control &= ~(PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE); |
@@ -315,7 +316,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev) | |||
315 | 316 | ||
316 | list_for_each_entry(entry, &dev->msi_list, list) { | 317 | list_for_each_entry(entry, &dev->msi_list, list) { |
317 | write_msi_msg(entry->irq, &entry->msg); | 318 | write_msi_msg(entry->irq, &entry->msg); |
318 | msi_set_mask_bit(entry->irq, entry->msi_attrib.masked); | 319 | msi_set_mask_bits(entry->irq, 1, entry->msi_attrib.masked); |
319 | } | 320 | } |
320 | 321 | ||
321 | BUG_ON(list_empty(&dev->msi_list)); | 322 | BUG_ON(list_empty(&dev->msi_list)); |
@@ -382,6 +383,7 @@ static int msi_capability_init(struct pci_dev *dev) | |||
382 | pci_write_config_dword(dev, | 383 | pci_write_config_dword(dev, |
383 | msi_mask_bits_reg(pos, is_64bit_address(control)), | 384 | msi_mask_bits_reg(pos, is_64bit_address(control)), |
384 | maskbits); | 385 | maskbits); |
386 | entry->msi_attrib.maskbits_mask = temp; | ||
385 | } | 387 | } |
386 | list_add_tail(&entry->list, &dev->msi_list); | 388 | list_add_tail(&entry->list, &dev->msi_list); |
387 | 389 | ||
@@ -583,6 +585,11 @@ void pci_disable_msi(struct pci_dev* dev) | |||
583 | 585 | ||
584 | BUG_ON(list_empty(&dev->msi_list)); | 586 | BUG_ON(list_empty(&dev->msi_list)); |
585 | entry = list_entry(dev->msi_list.next, struct msi_desc, list); | 587 | entry = list_entry(dev->msi_list.next, struct msi_desc, list); |
588 | /* Return the the pci reset with msi irqs unmasked */ | ||
589 | if (entry->msi_attrib.maskbit) { | ||
590 | u32 mask = entry->msi_attrib.maskbits_mask; | ||
591 | msi_set_mask_bits(dev->irq, mask, ~mask); | ||
592 | } | ||
586 | if (!entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) { | 593 | if (!entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) { |
587 | return; | 594 | return; |
588 | } | 595 | } |