diff options
Diffstat (limited to 'drivers/pci/msi.c')
-rw-r--r-- | drivers/pci/msi.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 77b68eaf021e..69b7be33b3a2 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -196,6 +196,9 @@ void unmask_msi_irq(unsigned int irq) void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) { struct msi_desc *entry = get_irq_desc_msi(desc); + + BUG_ON(entry->dev->current_state != PCI_D0); + if (entry->msi_attrib.is_msix) { void __iomem *base = entry->mask_base + entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; @@ -229,10 +232,32 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg) read_msi_msg_desc(desc, msg); } +void get_cached_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) +{ + struct msi_desc *entry = get_irq_desc_msi(desc); + + /* Assert that the cache is valid, assuming that + * valid messages are not all-zeroes. */ + BUG_ON(!(entry->msg.address_hi | entry->msg.address_lo | + entry->msg.data)); + + *msg = entry->msg; +} + +void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg) +{ + struct irq_desc *desc = irq_to_desc(irq); + + get_cached_msi_msg_desc(desc, msg); +} + void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) { struct msi_desc *entry = get_irq_desc_msi(desc); - if (entry->msi_attrib.is_msix) { + + if (entry->dev->current_state != PCI_D0) { + /* Don't touch the hardware now */ + } else if (entry->msi_attrib.is_msix) { void __iomem *base; base = entry->mask_base + entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; @@ -435,7 +460,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec) static void __iomem *msix_map_region(struct pci_dev *dev, unsigned pos, unsigned nr_entries) { - unsigned long phys_addr; + resource_size_t phys_addr; u32 table_offset; u8 bir; |