of: pci: add registry of MSI chips
This commit adds a very basic registry of msi_chip structures, so that an IRQ controller driver can register an msi_chip, and a PCIe host controller can find it, based on a 'struct device_node'. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Acked-by: Rob Herring <rob.herring@calxeda.com> Signed-off-by: Jason Cooper <jason@lakedaemon.net>
This commit is contained in:
parent
0cbdcfcf42
commit
0d5a6db3aa
|
@ -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 */
|
||||
|
|
|
@ -68,6 +68,8 @@ 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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue