Commit 5b4deb65 authored by Thomas Petazzoni's avatar Thomas Petazzoni Committed by Jason Cooper

PCI: mvebu: add support for MSI

This commit adds support for Message Signaled Interrupts in the
Marvell PCIe host controller. The work is very simple: it simply gets
a reference to the msi_chip associated to the PCIe controller thanks
to the msi-parent DT property, and stores this reference in the
pci_bus structure. This is enough to let the Linux PCI core use the
functions of msi_chip to setup and teardown MSIs.
Signed-off-by: default avatarThomas Petazzoni <thomas.petazzoni@free-electrons.com>
Reviewed-by: default avatarThierry Reding <thierry.reding@gmail.com>
Acked-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Signed-off-by: default avatarJason Cooper <jason@lakedaemon.net>
parent 31f614ed
...@@ -14,6 +14,8 @@ Mandatory properties: ...@@ -14,6 +14,8 @@ Mandatory properties:
- ranges: ranges describing the MMIO registers to control the PCIe - ranges: ranges describing the MMIO registers to control the PCIe
interfaces, and ranges describing the MBus windows needed to access interfaces, and ranges describing the MBus windows needed to access
the memory and I/O regions of each PCIe interface. the memory and I/O regions of each PCIe interface.
- msi-parent: Link to the hardware entity that serves as the Message
Signaled Interrupt controller for this PCI controller.
The ranges describing the MMIO registers have the following layout: The ranges describing the MMIO registers have the following layout:
...@@ -86,6 +88,7 @@ pcie-controller { ...@@ -86,6 +88,7 @@ pcie-controller {
#size-cells = <2>; #size-cells = <2>;
bus-range = <0x00 0xff>; bus-range = <0x00 0xff>;
msi-parent = <&mpic>;
ranges = ranges =
<0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 /* Port 0.0 registers */ <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 /* Port 0.0 registers */
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mbus.h> #include <linux/mbus.h>
#include <linux/msi.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/of_address.h> #include <linux/of_address.h>
...@@ -103,6 +104,7 @@ struct mvebu_pcie_port; ...@@ -103,6 +104,7 @@ struct mvebu_pcie_port;
struct mvebu_pcie { struct mvebu_pcie {
struct platform_device *pdev; struct platform_device *pdev;
struct mvebu_pcie_port *ports; struct mvebu_pcie_port *ports;
struct msi_chip *msi;
struct resource io; struct resource io;
struct resource realio; struct resource realio;
struct resource mem; struct resource mem;
...@@ -673,6 +675,12 @@ static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys) ...@@ -673,6 +675,12 @@ static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
return bus; return bus;
} }
void mvebu_pcie_add_bus(struct pci_bus *bus)
{
struct mvebu_pcie *pcie = sys_to_pcie(bus->sysdata);
bus->msi = pcie->msi;
}
resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev, resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
const struct resource *res, const struct resource *res,
resource_size_t start, resource_size_t start,
...@@ -709,6 +717,7 @@ static void __init mvebu_pcie_enable(struct mvebu_pcie *pcie) ...@@ -709,6 +717,7 @@ static void __init mvebu_pcie_enable(struct mvebu_pcie *pcie)
hw.map_irq = mvebu_pcie_map_irq; hw.map_irq = mvebu_pcie_map_irq;
hw.ops = &mvebu_pcie_ops; hw.ops = &mvebu_pcie_ops;
hw.align_resource = mvebu_pcie_align_resource; hw.align_resource = mvebu_pcie_align_resource;
hw.add_bus = mvebu_pcie_add_bus;
pci_common_init(&hw); pci_common_init(&hw);
} }
...@@ -777,6 +786,21 @@ static int mvebu_get_tgt_attr(struct device_node *np, int devfn, ...@@ -777,6 +786,21 @@ static int mvebu_get_tgt_attr(struct device_node *np, int devfn,
return -ENOENT; return -ENOENT;
} }
static void __init mvebu_pcie_msi_enable(struct mvebu_pcie *pcie)
{
struct device_node *msi_node;
msi_node = of_parse_phandle(pcie->pdev->dev.of_node,
"msi-parent", 0);
if (!msi_node)
return;
pcie->msi = of_pci_find_msi_chip_by_node(msi_node);
if (pcie->msi)
pcie->msi->dev = &pcie->pdev->dev;
}
static int __init mvebu_pcie_probe(struct platform_device *pdev) static int __init mvebu_pcie_probe(struct platform_device *pdev)
{ {
struct mvebu_pcie *pcie; struct mvebu_pcie *pcie;
...@@ -912,6 +936,8 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev) ...@@ -912,6 +936,8 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
i++; i++;
} }
mvebu_pcie_msi_enable(pcie);
mvebu_pcie_enable(pcie); mvebu_pcie_enable(pcie);
return 0; return 0;
......
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