mvebu msi pci changes for v3.12
- introduce support for MSI on PCI - fix s390 build breakage when !HAVE_GENERIC_HARDIRQS NOTE: This branch is a dependency for changes going though arm-soc from both Thomas Petazzoni and Thierry Reding. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.20 (GNU/Linux) iQEcBAABAgAGBQJSC9XJAAoJEAi3KVZQDZAebeUIAJCZtJ9cth52Hhbw5hZCpuwy 9F7C8FVrOA66xw9ryFBhcKMFZN9G1YAciaBmIXSXL6Zxj/p4ZTDdzfyiWHM67Hvj Bq+fD6GgtARB3zmi10dWhIqKOEXC7wmG68u3k4xengLxB8d4VlGHRXnrAzz+XAyo y6mtCgzfALXkjNTTHmZW3ecuxiyXo2T7IP2e5feK8qgmFRvBR0vWdv59Kk/qurSd E/9MjdtMJjLIXy/+h0vbAQbujA7g3e+P0JaNsxNDPxDIrWG3a61gzOqlbkgNZKIu HCaSxg37d2cPG9PVTdoWq88nZ1+aVBfWQdaL59jmui2lZ6LNZtrnwnsSg6SOzEA= =/x8J -----END PGP SIGNATURE----- Merge tag 'msi-3.12' of git://git.infradead.org/linux-mvebu into next/drivers From Jason Cooper: mvebu msi pci changes for v3.12 - introduce support for MSI on PCI - fix s390 build breakage when !HAVE_GENERIC_HARDIRQS NOTE: This branch is a dependency for changes going though arm-soc from both Thomas Petazzoni and Thierry Reding. * tag 'msi-3.12' of git://git.infradead.org/linux-mvebu: PCI: msi: add default MSI operations for !HAVE_GENERIC_HARDIRQS platforms ARM: pci: add ->add_bus() and ->remove_bus() hooks to hw_pci of: pci: add registry of MSI chips PCI: Introduce new MSI chip infrastructure PCI: remove ARCH_SUPPORTS_MSI kconfig option PCI: use weak functions for MSI arch-specific functions Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
commit
158a71f838
|
@ -441,7 +441,6 @@ config ARCH_NETX
|
|||
config ARCH_IOP13XX
|
||||
bool "IOP13xx-based"
|
||||
depends on MMU
|
||||
select ARCH_SUPPORTS_MSI
|
||||
select CPU_XSC3
|
||||
select NEED_MACH_MEMORY_H
|
||||
select NEED_RET_TO_USER
|
||||
|
|
|
@ -36,6 +36,8 @@ struct hw_pci {
|
|||
resource_size_t start,
|
||||
resource_size_t size,
|
||||
resource_size_t align);
|
||||
void (*add_bus)(struct pci_bus *bus);
|
||||
void (*remove_bus)(struct pci_bus *bus);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -63,6 +65,8 @@ struct pci_sys_data {
|
|||
resource_size_t start,
|
||||
resource_size_t size,
|
||||
resource_size_t align);
|
||||
void (*add_bus)(struct pci_bus *bus);
|
||||
void (*remove_bus)(struct pci_bus *bus);
|
||||
void *private_data; /* platform controller private data */
|
||||
};
|
||||
|
||||
|
|
|
@ -363,6 +363,20 @@ void pcibios_fixup_bus(struct pci_bus *bus)
|
|||
}
|
||||
EXPORT_SYMBOL(pcibios_fixup_bus);
|
||||
|
||||
void pcibios_add_bus(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_sys_data *sys = bus->sysdata;
|
||||
if (sys->add_bus)
|
||||
sys->add_bus(bus);
|
||||
}
|
||||
|
||||
void pcibios_remove_bus(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_sys_data *sys = bus->sysdata;
|
||||
if (sys->remove_bus)
|
||||
sys->remove_bus(bus);
|
||||
}
|
||||
|
||||
/*
|
||||
* Swizzle the device pin each time we cross a bridge. If a platform does
|
||||
* not provide a swizzle function, we perform the standard PCI swizzling.
|
||||
|
@ -464,6 +478,8 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
|
|||
sys->swizzle = hw->swizzle;
|
||||
sys->map_irq = hw->map_irq;
|
||||
sys->align_resource = hw->align_resource;
|
||||
sys->add_bus = hw->add_bus;
|
||||
sys->remove_bus = hw->remove_bus;
|
||||
INIT_LIST_HEAD(&sys->resources);
|
||||
|
||||
if (hw->private_data)
|
||||
|
|
|
@ -9,7 +9,6 @@ config IA64
|
|||
select PCI if (!IA64_HP_SIM)
|
||||
select ACPI if (!IA64_HP_SIM)
|
||||
select PM if (!IA64_HP_SIM)
|
||||
select ARCH_SUPPORTS_MSI
|
||||
select HAVE_UNSTABLE_SCHED_CLOCK
|
||||
select HAVE_IDE
|
||||
select HAVE_OPROFILE
|
||||
|
|
|
@ -727,7 +727,6 @@ config CAVIUM_OCTEON_SOC
|
|||
select SYS_HAS_CPU_CAVIUM_OCTEON
|
||||
select SWAP_IO_SPACE
|
||||
select HW_HAS_PCI
|
||||
select ARCH_SUPPORTS_MSI
|
||||
select ZONE_DMA32
|
||||
select USB_ARCH_HAS_OHCI
|
||||
select USB_ARCH_HAS_EHCI
|
||||
|
@ -763,7 +762,6 @@ config NLM_XLR_BOARD
|
|||
select CEVT_R4K
|
||||
select CSRC_R4K
|
||||
select IRQ_CPU
|
||||
select ARCH_SUPPORTS_MSI
|
||||
select ZONE_DMA32 if 64BIT
|
||||
select SYNC_R4K
|
||||
select SYS_HAS_EARLY_PRINTK
|
||||
|
|
|
@ -136,11 +136,6 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
|
|||
return channel ? 15 : 14;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_CAVIUM_OCTEON
|
||||
/* MSI arch hook for OCTEON */
|
||||
#define arch_setup_msi_irqs arch_setup_msi_irqs
|
||||
#endif
|
||||
|
||||
extern char * (*pcibios_plat_setup)(char *str);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
|
|
|
@ -727,7 +727,6 @@ config PCI
|
|||
default y if !40x && !CPM2 && !8xx && !PPC_83xx \
|
||||
&& !PPC_85xx && !PPC_86xx && !GAMECUBE_COMMON
|
||||
default PCI_QSPAN if !4xx && !CPM2 && 8xx
|
||||
select ARCH_SUPPORTS_MSI
|
||||
select GENERIC_PCI_IOMAP
|
||||
help
|
||||
Find out whether your system includes a PCI bus. PCI is the name of
|
||||
|
|
|
@ -113,11 +113,6 @@ extern int pci_domain_nr(struct pci_bus *bus);
|
|||
/* Decide whether to display the domain number in /proc */
|
||||
extern int pci_proc_domain(struct pci_bus *bus);
|
||||
|
||||
/* MSI arch hooks */
|
||||
#define arch_setup_msi_irqs arch_setup_msi_irqs
|
||||
#define arch_teardown_msi_irqs arch_teardown_msi_irqs
|
||||
#define arch_msi_check_device arch_msi_check_device
|
||||
|
||||
struct vm_area_struct;
|
||||
/* Map a range of PCI memory or I/O space for a device into user space */
|
||||
int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
|
||||
|
|
|
@ -430,7 +430,6 @@ menuconfig PCI
|
|||
bool "PCI support"
|
||||
default n
|
||||
depends on 64BIT
|
||||
select ARCH_SUPPORTS_MSI
|
||||
select PCI_MSI
|
||||
help
|
||||
Enable PCI support.
|
||||
|
|
|
@ -21,10 +21,6 @@ void pci_iounmap(struct pci_dev *, void __iomem *);
|
|||
int pci_domain_nr(struct pci_bus *);
|
||||
int pci_proc_domain(struct pci_bus *);
|
||||
|
||||
/* MSI arch hooks */
|
||||
#define arch_setup_msi_irqs arch_setup_msi_irqs
|
||||
#define arch_teardown_msi_irqs arch_teardown_msi_irqs
|
||||
|
||||
#define ZPCI_BUS_NR 0 /* default bus number */
|
||||
#define ZPCI_DEVFN 0 /* default device number */
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@ config SPARC32
|
|||
|
||||
config SPARC64
|
||||
def_bool 64BIT
|
||||
select ARCH_SUPPORTS_MSI
|
||||
select HAVE_FUNCTION_TRACER
|
||||
select HAVE_FUNCTION_GRAPH_TRACER
|
||||
select HAVE_FUNCTION_GRAPH_FP_TEST
|
||||
|
|
|
@ -380,7 +380,6 @@ config PCI
|
|||
select PCI_DOMAINS
|
||||
select GENERIC_PCI_IOMAP
|
||||
select TILE_GXIO_TRIO if TILEGX
|
||||
select ARCH_SUPPORTS_MSI if TILEGX
|
||||
select PCI_MSI if TILEGX
|
||||
---help---
|
||||
Enable PCI root complex support, so PCIe endpoint devices can
|
||||
|
|
|
@ -2014,7 +2014,6 @@ menu "Bus options (PCI etc.)"
|
|||
config PCI
|
||||
bool "PCI support"
|
||||
default y
|
||||
select ARCH_SUPPORTS_MSI if (X86_LOCAL_APIC && X86_IO_APIC)
|
||||
---help---
|
||||
Find out whether you have a PCI motherboard. PCI is the name of a
|
||||
bus system, i.e. the way the CPU talks to the other stuff inside
|
||||
|
|
|
@ -100,29 +100,6 @@ static inline void early_quirks(void) { }
|
|||
extern void pci_iommu_alloc(void);
|
||||
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
/* MSI arch specific hooks */
|
||||
static inline int x86_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
|
||||
{
|
||||
return x86_msi.setup_msi_irqs(dev, nvec, type);
|
||||
}
|
||||
|
||||
static inline void x86_teardown_msi_irqs(struct pci_dev *dev)
|
||||
{
|
||||
x86_msi.teardown_msi_irqs(dev);
|
||||
}
|
||||
|
||||
static inline void x86_teardown_msi_irq(unsigned int irq)
|
||||
{
|
||||
x86_msi.teardown_msi_irq(irq);
|
||||
}
|
||||
static inline void x86_restore_msi_irqs(struct pci_dev *dev, int irq)
|
||||
{
|
||||
x86_msi.restore_msi_irqs(dev, irq);
|
||||
}
|
||||
#define arch_setup_msi_irqs x86_setup_msi_irqs
|
||||
#define arch_teardown_msi_irqs x86_teardown_msi_irqs
|
||||
#define arch_teardown_msi_irq x86_teardown_msi_irq
|
||||
#define arch_restore_msi_irqs x86_restore_msi_irqs
|
||||
/* implemented in arch/x86/kernel/apic/io_apic. */
|
||||
struct msi_desc;
|
||||
int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
|
||||
|
@ -130,16 +107,9 @@ void native_teardown_msi_irq(unsigned int irq);
|
|||
void native_restore_msi_irqs(struct pci_dev *dev, int irq);
|
||||
int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc,
|
||||
unsigned int irq_base, unsigned int irq_offset);
|
||||
/* default to the implementation in drivers/lib/msi.c */
|
||||
#define HAVE_DEFAULT_MSI_TEARDOWN_IRQS
|
||||
#define HAVE_DEFAULT_MSI_RESTORE_IRQS
|
||||
void default_teardown_msi_irqs(struct pci_dev *dev);
|
||||
void default_restore_msi_irqs(struct pci_dev *dev, int irq);
|
||||
#else
|
||||
#define native_setup_msi_irqs NULL
|
||||
#define native_teardown_msi_irq NULL
|
||||
#define default_teardown_msi_irqs NULL
|
||||
#define default_restore_msi_irqs NULL
|
||||
#endif
|
||||
|
||||
#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
|
||||
|
|
|
@ -107,6 +107,8 @@ struct x86_platform_ops x86_platform = {
|
|||
};
|
||||
|
||||
EXPORT_SYMBOL_GPL(x86_platform);
|
||||
|
||||
#if defined(CONFIG_PCI_MSI)
|
||||
struct x86_msi_ops x86_msi = {
|
||||
.setup_msi_irqs = native_setup_msi_irqs,
|
||||
.compose_msi_msg = native_compose_msi_msg,
|
||||
|
@ -116,6 +118,28 @@ struct x86_msi_ops x86_msi = {
|
|||
.setup_hpet_msi = default_setup_hpet_msi,
|
||||
};
|
||||
|
||||
/* MSI arch specific hooks */
|
||||
int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
|
||||
{
|
||||
return x86_msi.setup_msi_irqs(dev, nvec, type);
|
||||
}
|
||||
|
||||
void arch_teardown_msi_irqs(struct pci_dev *dev)
|
||||
{
|
||||
x86_msi.teardown_msi_irqs(dev);
|
||||
}
|
||||
|
||||
void arch_teardown_msi_irq(unsigned int irq)
|
||||
{
|
||||
x86_msi.teardown_msi_irq(irq);
|
||||
}
|
||||
|
||||
void arch_restore_msi_irqs(struct pci_dev *dev, int irq)
|
||||
{
|
||||
x86_msi.restore_msi_irqs(dev, irq);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct x86_io_apic_ops x86_io_apic_ops = {
|
||||
.init = native_io_apic_init_mappings,
|
||||
.read = native_io_apic_read,
|
||||
|
|
|
@ -89,3 +89,48 @@ int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
|
|||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
|
||||
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
|
||||
static LIST_HEAD(of_pci_msi_chip_list);
|
||||
static DEFINE_MUTEX(of_pci_msi_chip_mutex);
|
||||
|
||||
int of_pci_msi_chip_add(struct msi_chip *chip)
|
||||
{
|
||||
if (!of_property_read_bool(chip->of_node, "msi-controller"))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&of_pci_msi_chip_mutex);
|
||||
list_add(&chip->list, &of_pci_msi_chip_list);
|
||||
mutex_unlock(&of_pci_msi_chip_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_pci_msi_chip_add);
|
||||
|
||||
void of_pci_msi_chip_remove(struct msi_chip *chip)
|
||||
{
|
||||
mutex_lock(&of_pci_msi_chip_mutex);
|
||||
list_del(&chip->list);
|
||||
mutex_unlock(&of_pci_msi_chip_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_pci_msi_chip_remove);
|
||||
|
||||
struct msi_chip *of_pci_find_msi_chip_by_node(struct device_node *of_node)
|
||||
{
|
||||
struct msi_chip *c;
|
||||
|
||||
mutex_lock(&of_pci_msi_chip_mutex);
|
||||
list_for_each_entry(c, &of_pci_msi_chip_list, list) {
|
||||
if (c->of_node == of_node) {
|
||||
mutex_unlock(&of_pci_msi_chip_mutex);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&of_pci_msi_chip_mutex);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_pci_find_msi_chip_by_node);
|
||||
|
||||
#endif /* CONFIG_PCI_MSI */
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
#
|
||||
# PCI configuration
|
||||
#
|
||||
config ARCH_SUPPORTS_MSI
|
||||
bool
|
||||
|
||||
config PCI_MSI
|
||||
bool "Message Signaled Interrupts (MSI and MSI-X)"
|
||||
depends on PCI
|
||||
depends on ARCH_SUPPORTS_MSI
|
||||
help
|
||||
This allows device drivers to enable MSI (Message Signaled
|
||||
Interrupts). Message Signaled Interrupts enable a device to
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
void __weak arch_teardown_msi_irq(unsigned int irq)
|
||||
{
|
||||
struct msi_chip *chip = irq_get_chip_data(irq);
|
||||
|
||||
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
|
||||
#endif /* CONFIG_GENERIC_HARDIRQS */
|
||||
|
||||
#ifndef arch_setup_msi_irqs
|
||||
# define arch_setup_msi_irqs default_setup_msi_irqs
|
||||
# define HAVE_DEFAULT_MSI_SETUP_IRQS
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DEFAULT_MSI_SETUP_IRQS
|
||||
int default_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -666,6 +666,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
|
|||
|
||||
child->parent = parent;
|
||||
child->ops = parent->ops;
|
||||
child->msi = parent->msi;
|
||||
child->sysdata = parent->sysdata;
|
||||
child->bus_flags = parent->bus_flags;
|
||||
|
||||
|
|
|
@ -51,12 +51,31 @@ struct msi_desc {
|
|||
};
|
||||
|
||||
/*
|
||||
* The arch hook for setup up msi irqs
|
||||
* The arch hooks to setup up msi irqs. Those functions are
|
||||
* implemented as weak symbols so that they /can/ be overriden by
|
||||
* architecture specific code if needed.
|
||||
*/
|
||||
int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc);
|
||||
void arch_teardown_msi_irq(unsigned int irq);
|
||||
int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
|
||||
void arch_teardown_msi_irqs(struct pci_dev *dev);
|
||||
int arch_msi_check_device(struct pci_dev* dev, int nvec, int type);
|
||||
void arch_restore_msi_irqs(struct pci_dev *dev, int irq);
|
||||
|
||||
void default_teardown_msi_irqs(struct pci_dev *dev);
|
||||
void default_restore_msi_irqs(struct pci_dev *dev, int irq);
|
||||
|
||||
struct msi_chip {
|
||||
struct module *owner;
|
||||
struct device *dev;
|
||||
struct device_node *of_node;
|
||||
struct list_head list;
|
||||
|
||||
int (*setup_irq)(struct msi_chip *chip, struct pci_dev *dev,
|
||||
struct msi_desc *desc);
|
||||
void (*teardown_irq)(struct msi_chip *chip, unsigned int irq);
|
||||
int (*check_device)(struct msi_chip *chip, struct pci_dev *dev,
|
||||
int nvec, int type);
|
||||
};
|
||||
|
||||
#endif /* LINUX_MSI_H */
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define __OF_PCI_H
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/msi.h>
|
||||
|
||||
struct pci_dev;
|
||||
struct of_irq;
|
||||
|
@ -13,4 +14,15 @@ struct device_node *of_pci_find_child_device(struct device_node *parent,
|
|||
int of_pci_get_devfn(struct device_node *np);
|
||||
int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
|
||||
|
||||
#if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI)
|
||||
int of_pci_msi_chip_add(struct msi_chip *chip);
|
||||
void of_pci_msi_chip_remove(struct msi_chip *chip);
|
||||
struct msi_chip *of_pci_find_msi_chip_by_node(struct device_node *of_node);
|
||||
#else
|
||||
static inline int of_pci_msi_chip_add(struct msi_chip *chip) { return -EINVAL; }
|
||||
static inline void of_pci_msi_chip_remove(struct msi_chip *chip) { }
|
||||
static inline struct msi_chip *
|
||||
of_pci_find_msi_chip_by_node(struct device_node *of_node) { return NULL; }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -433,6 +433,7 @@ struct pci_bus {
|
|||
struct resource busn_res; /* bus numbers routed to this bus */
|
||||
|
||||
struct pci_ops *ops; /* configuration access functions */
|
||||
struct msi_chip *msi; /* MSI controller */
|
||||
void *sysdata; /* hook for sys-specific extension */
|
||||
struct proc_dir_entry *procdir; /* directory entry in /proc/bus/pci */
|
||||
|
||||
|
|
Loading…
Reference in New Issue