diff options
-rw-r--r-- | drivers/pci/msi.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 435c1958a7b7..a4ef93ea4c54 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -68,6 +68,29 @@ static void msix_set_enable(struct pci_dev *dev, int enable) | |||
68 | } | 68 | } |
69 | } | 69 | } |
70 | 70 | ||
71 | static void msix_flush_writes(unsigned int irq) | ||
72 | { | ||
73 | struct msi_desc *entry; | ||
74 | |||
75 | entry = get_irq_msi(irq); | ||
76 | BUG_ON(!entry || !entry->dev); | ||
77 | switch (entry->msi_attrib.type) { | ||
78 | case PCI_CAP_ID_MSI: | ||
79 | /* nothing to do */ | ||
80 | break; | ||
81 | case PCI_CAP_ID_MSIX: | ||
82 | { | ||
83 | int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + | ||
84 | PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET; | ||
85 | readl(entry->mask_base + offset); | ||
86 | break; | ||
87 | } | ||
88 | default: | ||
89 | BUG(); | ||
90 | break; | ||
91 | } | ||
92 | } | ||
93 | |||
71 | static void msi_set_mask_bit(unsigned int irq, int flag) | 94 | static void msi_set_mask_bit(unsigned int irq, int flag) |
72 | { | 95 | { |
73 | struct msi_desc *entry; | 96 | struct msi_desc *entry; |
@@ -187,11 +210,13 @@ void write_msi_msg(unsigned int irq, struct msi_msg *msg) | |||
187 | void mask_msi_irq(unsigned int irq) | 210 | void mask_msi_irq(unsigned int irq) |
188 | { | 211 | { |
189 | msi_set_mask_bit(irq, 1); | 212 | msi_set_mask_bit(irq, 1); |
213 | msix_flush_writes(irq); | ||
190 | } | 214 | } |
191 | 215 | ||
192 | void unmask_msi_irq(unsigned int irq) | 216 | void unmask_msi_irq(unsigned int irq) |
193 | { | 217 | { |
194 | msi_set_mask_bit(irq, 0); | 218 | msi_set_mask_bit(irq, 0); |
219 | msix_flush_writes(irq); | ||
195 | } | 220 | } |
196 | 221 | ||
197 | static int msi_free_irq(struct pci_dev* dev, int irq); | 222 | static int msi_free_irq(struct pci_dev* dev, int irq); |