Commit 6b290397 authored by Bjorn Helgaas's avatar Bjorn Helgaas Committed by Bjorn Helgaas

Merge branch 'pci/dt-resources' into next

* pci/dt-resources:
  PCI: Make of_irq_parse_pci() static
  powerpc/pci: Use of_irq_parse_and_map_pci() helper
  PCI: Move OF-related PCI functions into PCI core
parents 3972b0e2 7e297843
...@@ -10,7 +10,6 @@ menuconfig ARCH_MVEBU ...@@ -10,7 +10,6 @@ menuconfig ARCH_MVEBU
select ZONE_DMA if ARM_LPAE select ZONE_DMA if ARM_LPAE
select GPIOLIB select GPIOLIB
select PCI_QUIRKS if PCI select PCI_QUIRKS if PCI
select OF_ADDRESS_PCI
if ARCH_MVEBU if ARCH_MVEBU
......
...@@ -339,8 +339,7 @@ struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node) ...@@ -339,8 +339,7 @@ struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
*/ */
static int pci_read_irq_line(struct pci_dev *pci_dev) static int pci_read_irq_line(struct pci_dev *pci_dev)
{ {
struct of_phandle_args oirq; unsigned int virq = 0;
unsigned int virq;
pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev)); pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev));
...@@ -348,7 +347,7 @@ static int pci_read_irq_line(struct pci_dev *pci_dev) ...@@ -348,7 +347,7 @@ static int pci_read_irq_line(struct pci_dev *pci_dev)
memset(&oirq, 0xff, sizeof(oirq)); memset(&oirq, 0xff, sizeof(oirq));
#endif #endif
/* Try to get a mapping from the device-tree */ /* Try to get a mapping from the device-tree */
if (of_irq_parse_pci(pci_dev, &oirq)) { if (!of_irq_parse_and_map_pci(pci_dev, 0, 0)) {
u8 line, pin; u8 line, pin;
/* If that fails, lets fallback to what is in the config /* If that fails, lets fallback to what is in the config
...@@ -372,11 +371,6 @@ static int pci_read_irq_line(struct pci_dev *pci_dev) ...@@ -372,11 +371,6 @@ static int pci_read_irq_line(struct pci_dev *pci_dev)
virq = irq_create_mapping(NULL, line); virq = irq_create_mapping(NULL, line);
if (virq) if (virq)
irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
} else {
pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %pOF\n",
oirq.args_count, oirq.args[0], oirq.args[1], oirq.np);
virq = irq_create_of_mapping(&oirq);
} }
if (!virq) { if (!virq) {
......
...@@ -62,10 +62,6 @@ config OF_DYNAMIC ...@@ -62,10 +62,6 @@ config OF_DYNAMIC
config OF_ADDRESS config OF_ADDRESS
def_bool y def_bool y
depends on !SPARC && HAS_IOMEM depends on !SPARC && HAS_IOMEM
select OF_ADDRESS_PCI if PCI
config OF_ADDRESS_PCI
bool
config OF_IRQ config OF_IRQ
def_bool y def_bool y
...@@ -82,18 +78,6 @@ config OF_MDIO ...@@ -82,18 +78,6 @@ config OF_MDIO
help help
OpenFirmware MDIO bus (Ethernet PHY) accessors OpenFirmware MDIO bus (Ethernet PHY) accessors
config OF_PCI
def_tristate PCI
depends on PCI
help
OpenFirmware PCI bus accessors
config OF_PCI_IRQ
def_tristate PCI
depends on OF_PCI && OF_IRQ
help
OpenFirmware PCI IRQ routing helpers
config OF_RESERVED_MEM config OF_RESERVED_MEM
depends on OF_EARLY_FLATTREE depends on OF_EARLY_FLATTREE
bool bool
......
...@@ -10,8 +10,6 @@ obj-$(CONFIG_OF_IRQ) += irq.o ...@@ -10,8 +10,6 @@ obj-$(CONFIG_OF_IRQ) += irq.o
obj-$(CONFIG_OF_NET) += of_net.o obj-$(CONFIG_OF_NET) += of_net.o
obj-$(CONFIG_OF_UNITTEST) += unittest.o obj-$(CONFIG_OF_UNITTEST) += unittest.o
obj-$(CONFIG_OF_MDIO) += of_mdio.o obj-$(CONFIG_OF_MDIO) += of_mdio.o
obj-$(CONFIG_OF_PCI) += of_pci.o
obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o
obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
obj-$(CONFIG_OF_RESOLVE) += resolver.o obj-$(CONFIG_OF_RESOLVE) += resolver.o
obj-$(CONFIG_OF_OVERLAY) += overlay.o obj-$(CONFIG_OF_OVERLAY) += overlay.o
......
...@@ -96,7 +96,7 @@ static unsigned int of_bus_default_get_flags(const __be32 *addr) ...@@ -96,7 +96,7 @@ static unsigned int of_bus_default_get_flags(const __be32 *addr)
return IORESOURCE_MEM; return IORESOURCE_MEM;
} }
#ifdef CONFIG_OF_ADDRESS_PCI #ifdef CONFIG_PCI
/* /*
* PCI bus specific translator * PCI bus specific translator
*/ */
...@@ -171,9 +171,7 @@ static int of_bus_pci_translate(__be32 *addr, u64 offset, int na) ...@@ -171,9 +171,7 @@ static int of_bus_pci_translate(__be32 *addr, u64 offset, int na)
{ {
return of_bus_default_translate(addr + 1, offset, na - 1); return of_bus_default_translate(addr + 1, offset, na - 1);
} }
#endif /* CONFIG_OF_ADDRESS_PCI */
#ifdef CONFIG_PCI
const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
unsigned int *flags) unsigned int *flags)
{ {
...@@ -426,7 +424,7 @@ static unsigned int of_bus_isa_get_flags(const __be32 *addr) ...@@ -426,7 +424,7 @@ static unsigned int of_bus_isa_get_flags(const __be32 *addr)
*/ */
static struct of_bus of_busses[] = { static struct of_bus of_busses[] = {
#ifdef CONFIG_OF_ADDRESS_PCI #ifdef CONFIG_PCI
/* PCI */ /* PCI */
{ {
.name = "pci", .name = "pci",
...@@ -437,7 +435,7 @@ static struct of_bus of_busses[] = { ...@@ -437,7 +435,7 @@ static struct of_bus of_busses[] = {
.translate = of_bus_pci_translate, .translate = of_bus_pci_translate,
.get_flags = of_bus_pci_get_flags, .get_flags = of_bus_pci_get_flags,
}, },
#endif /* CONFIG_OF_ADDRESS_PCI */ #endif /* CONFIG_PCI */
/* ISA */ /* ISA */
{ {
.name = "isa", .name = "isa",
......
This diff is collapsed.
#include <linux/kernel.h>
#include <linux/of_pci.h>
#include <linux/of_irq.h>
#include <linux/export.h>
/**
* of_irq_parse_pci - Resolve the interrupt for a PCI device
* @pdev: the device whose interrupt is to be resolved
* @out_irq: structure of_irq filled by this function
*
* This function resolves the PCI interrupt for a given PCI device. If a
* device-node exists for a given pci_dev, it will use normal OF tree
* walking. If not, it will implement standard swizzling and walk up the
* PCI tree until an device-node is found, at which point it will finish
* resolving using the OF tree walking.
*/
int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
{
struct device_node *dn, *ppnode;
struct pci_dev *ppdev;
__be32 laddr[3];
u8 pin;
int rc;
/* Check if we have a device node, if yes, fallback to standard
* device tree parsing
*/
dn = pci_device_to_OF_node(pdev);
if (dn) {
rc = of_irq_parse_one(dn, 0, out_irq);
if (!rc)
return rc;
}
/* Ok, we don't, time to have fun. Let's start by building up an
* interrupt spec. we assume #interrupt-cells is 1, which is standard
* for PCI. If you do different, then don't use that routine.
*/
rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
if (rc != 0)
goto err;
/* No pin, exit with no error message. */
if (pin == 0)
return -ENODEV;
/* Now we walk up the PCI tree */
for (;;) {
/* Get the pci_dev of our parent */
ppdev = pdev->bus->self;
/* Ouch, it's a host bridge... */
if (ppdev == NULL) {
ppnode = pci_bus_to_OF_node(pdev->bus);
/* No node for host bridge ? give up */
if (ppnode == NULL) {
rc = -EINVAL;
goto err;
}
} else {
/* We found a P2P bridge, check if it has a node */
ppnode = pci_device_to_OF_node(ppdev);
}
/* Ok, we have found a parent with a device-node, hand over to
* the OF parsing code.
* We build a unit address from the linux device to be used for
* resolution. Note that we use the linux bus number which may
* not match your firmware bus numbering.
* Fortunately, in most cases, interrupt-map-mask doesn't
* include the bus number as part of the matching.
* You should still be careful about that though if you intend
* to rely on this function (you ship a firmware that doesn't
* create device nodes for all PCI devices).
*/
if (ppnode)
break;
/* We can only get here if we hit a P2P bridge with no node,
* let's do standard swizzling and try again
*/
pin = pci_swizzle_interrupt_pin(pdev, pin);
pdev = ppdev;
}
out_irq->np = ppnode;
out_irq->args_count = 1;
out_irq->args[0] = pin;
laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8));
laddr[1] = laddr[2] = cpu_to_be32(0);
rc = of_irq_parse_raw(laddr, out_irq);
if (rc)
goto err;
return 0;
err:
if (rc == -ENOENT) {
dev_warn(&pdev->dev,
"%s: no interrupt-map found, INTx interrupts not available\n",
__func__);
pr_warn_once("%s: possibly some PCI slots don't have level triggered interrupts capability\n",
__func__);
} else {
dev_err(&pdev->dev, "%s: failed with rc=%d\n", __func__, rc);
}
return rc;
}
EXPORT_SYMBOL_GPL(of_irq_parse_pci);
/**
* of_irq_parse_and_map_pci() - Decode a PCI irq from the device tree and map to a virq
* @dev: The pci device needing an irq
* @slot: PCI slot number; passed when used as map_irq callback. Unused
* @pin: PCI irq pin number; passed when used as map_irq callback. Unused
*
* @slot and @pin are unused, but included in the function so that this
* function can be used directly as the map_irq callback to
* pci_assign_irq() and struct pci_host_bridge.map_irq pointer
*/
int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin)
{
struct of_phandle_args oirq;
int ret;
ret = of_irq_parse_pci(dev, &oirq);
if (ret)
return 0; /* Proper return code 0 == NO_IRQ */
return irq_create_of_mapping(&oirq);
}
EXPORT_SYMBOL_GPL(of_irq_parse_and_map_pci);
This diff is collapsed.
...@@ -9,8 +9,7 @@ struct pci_dev; ...@@ -9,8 +9,7 @@ struct pci_dev;
struct of_phandle_args; struct of_phandle_args;
struct device_node; struct device_node;
#ifdef CONFIG_OF_PCI #if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_PCI)
int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq);
struct device_node *of_pci_find_child_device(struct device_node *parent, struct device_node *of_pci_find_child_device(struct device_node *parent,
unsigned int devfn); unsigned int devfn);
int of_pci_get_devfn(struct device_node *np); int of_pci_get_devfn(struct device_node *np);
...@@ -23,11 +22,6 @@ int of_pci_map_rid(struct device_node *np, u32 rid, ...@@ -23,11 +22,6 @@ int of_pci_map_rid(struct device_node *np, u32 rid,
const char *map_name, const char *map_mask_name, const char *map_name, const char *map_mask_name,
struct device_node **target, u32 *id_out); struct device_node **target, u32 *id_out);
#else #else
static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
{
return 0;
}
static inline struct device_node *of_pci_find_child_device(struct device_node *parent, static inline struct device_node *of_pci_find_child_device(struct device_node *parent,
unsigned int devfn) unsigned int devfn)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment