diff options
Diffstat (limited to 'drivers/pci/msi.c')
-rw-r--r-- | drivers/pci/msi.c | 85 |
1 files changed, 62 insertions, 23 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index aca7578b05e5..b35f93c232cf 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -30,20 +30,60 @@ static int pci_msi_enable = 1; /* Arch hooks */ -#ifndef arch_msi_check_device -int arch_msi_check_device(struct pci_dev *dev, int nvec, int type) +#if defined(CONFIG_GENERIC_HARDIRQS) +int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) { + struct msi_chip *chip = dev->bus->msi; + int err; + + if (!chip || !chip->setup_irq) + return -EINVAL; + + err = chip->setup_irq(chip, dev, desc); + if (err < 0) + return err; + + irq_set_chip_data(desc->irq, chip); + return 0; } -#endif -#ifndef arch_setup_msi_irqs -# define arch_setup_msi_irqs default_setup_msi_irqs -# define HAVE_DEFAULT_MSI_SETUP_IRQS -#endif +void __weak arch_teardown_msi_irq(unsigned int irq) +{ + struct msi_chip *chip = irq_get_chip_data(irq); -#ifdef HAVE_DEFAULT_MSI_SETUP_IRQS -int default_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) + if (!chip || !chip->teardown_irq) + return; + + chip->teardown_irq(chip, irq); +} + +int __weak arch_msi_check_device(struct pci_dev *dev, int nvec, int type) +{ + struct msi_chip *chip = dev->bus->msi; + + if (!chip || !chip->check_device) + return 0; + + return chip->check_device(chip, dev, nvec, type); +} +#else +int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) +{ + return -ENOSYS; +} + +void __weak arch_teardown_msi_irq(unsigned int irq) +{ +} + +int __weak arch_msi_check_device(struct pci_dev *dev, int nvec, int type) +{ + return 0; +} +#endif /* CONFIG_GENERIC_HARDIRQS */ + +int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) { struct msi_desc *entry; int ret; @@ -65,14 +105,11 @@ int default_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) return 0; } -#endif - -#ifndef arch_teardown_msi_irqs -# define arch_teardown_msi_irqs default_teardown_msi_irqs -# define HAVE_DEFAULT_MSI_TEARDOWN_IRQS -#endif -#ifdef HAVE_DEFAULT_MSI_TEARDOWN_IRQS +/* + * We have a default implementation available as a separate non-weak + * function, as it is used by the Xen x86 PCI code + */ void default_teardown_msi_irqs(struct pci_dev *dev) { struct msi_desc *entry; @@ -89,14 +126,12 @@ void default_teardown_msi_irqs(struct pci_dev *dev) arch_teardown_msi_irq(entry->irq + i); } } -#endif -#ifndef arch_restore_msi_irqs -# define arch_restore_msi_irqs default_restore_msi_irqs -# define HAVE_DEFAULT_MSI_RESTORE_IRQS -#endif +void __weak arch_teardown_msi_irqs(struct pci_dev *dev) +{ + return default_teardown_msi_irqs(dev); +} -#ifdef HAVE_DEFAULT_MSI_RESTORE_IRQS void default_restore_msi_irqs(struct pci_dev *dev, int irq) { struct msi_desc *entry; @@ -114,7 +149,11 @@ void default_restore_msi_irqs(struct pci_dev *dev, int irq) if (entry) write_msi_msg(irq, &entry->msg); } -#endif + +void __weak arch_restore_msi_irqs(struct pci_dev *dev, int irq) +{ + return default_restore_msi_irqs(dev, irq); +} static void msi_set_enable(struct pci_dev *dev, int enable) { |