Skip to content

Commit

Permalink
PCI: mvebu: add support for MSI
Browse files Browse the repository at this point in the history
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: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Reviewed-by: Thierry Reding <thierry.reding@gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
  • Loading branch information
Thomas Petazzoni authored and Jason Cooper committed Sep 30, 2013
1 parent 31f614e commit 5b4deb6
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Documentation/devicetree/bindings/pci/mvebu-pci.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Mandatory properties:
- ranges: ranges describing the MMIO registers to control the PCIe
interfaces, and ranges describing the MBus windows needed to access
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:

Expand Down Expand Up @@ -86,6 +88,7 @@ pcie-controller {
#size-cells = <2>;

bus-range = <0x00 0xff>;
msi-parent = <&mpic>;

ranges =
<0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 /* Port 0.0 registers */
Expand Down
26 changes: 26 additions & 0 deletions drivers/pci/host/pci-mvebu.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/mbus.h>
#include <linux/msi.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/of_address.h>
Expand Down Expand Up @@ -103,6 +104,7 @@ struct mvebu_pcie_port;
struct mvebu_pcie {
struct platform_device *pdev;
struct mvebu_pcie_port *ports;
struct msi_chip *msi;
struct resource io;
struct resource realio;
struct resource mem;
Expand Down Expand Up @@ -673,6 +675,12 @@ static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
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,
const struct resource *res,
resource_size_t start,
Expand Down Expand Up @@ -709,6 +717,7 @@ static void __init mvebu_pcie_enable(struct mvebu_pcie *pcie)
hw.map_irq = mvebu_pcie_map_irq;
hw.ops = &mvebu_pcie_ops;
hw.align_resource = mvebu_pcie_align_resource;
hw.add_bus = mvebu_pcie_add_bus;

pci_common_init(&hw);
}
Expand Down Expand Up @@ -777,6 +786,21 @@ static int mvebu_get_tgt_attr(struct device_node *np, int devfn,
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)
{
struct mvebu_pcie *pcie;
Expand Down Expand Up @@ -912,6 +936,8 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
i++;
}

mvebu_pcie_msi_enable(pcie);

mvebu_pcie_enable(pcie);

return 0;
Expand Down

0 comments on commit 5b4deb6

Please sign in to comment.