Skip to content

Commit

Permalink
Merge branches 'pci/host-aardvark', 'pci/host-altera', 'pci/host-dra7…
Browse files Browse the repository at this point in the history
…xx', 'pci/host-hv', 'pci/host-vmd' and 'pci/host-xilinx' into next

* pci/host-aardvark:
  arm64: dts: marvell: Add Aardvark PCIe support for Armada 3700
  PCI: aardvark: Add Aardvark PCI host controller driver
  dt-bindings: add DT binding for the Aardvark PCIe controller

* pci/host-altera:
  PCI: altera: Poll for link up status after retraining the link
  PCI: altera: Check link status before retrain link
  PCI: altera: Reorder read/write functions

* pci/host-dra7xx:
  PCI: dra7xx: Fix return value in case of error

* pci/host-hv:
  PCI: hv: Fix interrupt cleanup path
  PCI: hv: Handle all pending messages in hv_pci_onchannelcallback()
  PCI: hv: Don't leak buffer in hv_pci_onchannelcallback()

* pci/host-vmd:
  x86/PCI: VMD: Separate MSI and MSI-X vector sharing
  x86/PCI: VMD: Use x86_vector_domain as parent domain
  x86/PCI: VMD: Use lock save/restore in interrupt enable path
  x86/PCI: VMD: Initialize list item in IRQ disable
  x86/PCI: VMD: Select device dma ops to override

* pci/host-xilinx:
  PCI: xilinx: Fix return value in case of error

Manually apply changes from pci/demodularize-hosts and
pci/host-request-windows to drivers/pci/host/pci-aardvark.c
  • Loading branch information
Bjorn Helgaas committed Aug 1, 2016
7 parents ea1f4e9 + 76f6386 + 3a928e9 + 991bfef + 0c6e617 + 9c20530 + cec6dba commit a04bee8
Show file tree
Hide file tree
Showing 12 changed files with 1,182 additions and 51 deletions.
56 changes: 56 additions & 0 deletions Documentation/devicetree/bindings/pci/aardvark-pci.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
Aardvark PCIe controller

This PCIe controller is used on the Marvell Armada 3700 ARM64 SoC.

The Device Tree node describing an Aardvark PCIe controller must
contain the following properties:

- compatible: Should be "marvell,armada-3700-pcie"
- reg: range of registers for the PCIe controller
- interrupts: the interrupt line of the PCIe controller
- #address-cells: set to <3>
- #size-cells: set to <2>
- device_type: set to "pci"
- ranges: ranges for the PCI memory and I/O regions
- #interrupt-cells: set to <1>
- msi-controller: indicates that the PCIe controller can itself
handle MSI interrupts
- msi-parent: pointer to the MSI controller to be used
- interrupt-map-mask and interrupt-map: standard PCI properties to
define the mapping of the PCIe interface to interrupt numbers.
- bus-range: PCI bus numbers covered

In addition, the Device Tree describing an Aardvark PCIe controller
must include a sub-node that describes the legacy interrupt controller
built into the PCIe controller. This sub-node must have the following
properties:

- interrupt-controller
- #interrupt-cells: set to <1>

Example:

pcie0: pcie@d0070000 {
compatible = "marvell,armada-3700-pcie";
device_type = "pci";
status = "disabled";
reg = <0 0xd0070000 0 0x20000>;
#address-cells = <3>;
#size-cells = <2>;
bus-range = <0x00 0xff>;
interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
#interrupt-cells = <1>;
msi-controller;
msi-parent = <&pcie0>;
ranges = <0x82000000 0 0xe8000000 0 0xe8000000 0 0x1000000 /* Port 0 MEM */
0x81000000 0 0xe9000000 0 0xe9000000 0 0x10000>; /* Port 0 IO*/
interrupt-map-mask = <0 0 0 7>;
interrupt-map = <0 0 0 1 &pcie_intc 0>,
<0 0 0 2 &pcie_intc 1>,
<0 0 0 3 &pcie_intc 2>,
<0 0 0 4 &pcie_intc 3>;
pcie_intc: interrupt-controller {
interrupt-controller;
#interrupt-cells = <1>;
};
};
7 changes: 7 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -8742,6 +8742,13 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: drivers/pci/host/*mvebu*

PCI DRIVER FOR AARDVARK (Marvell Armada 3700)
M: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
L: linux-pci@vger.kernel.org
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: drivers/pci/host/pci-aardvark.c

PCI DRIVER FOR NVIDIA TEGRA
M: Thierry Reding <thierry.reding@gmail.com>
L: linux-tegra@vger.kernel.org
Expand Down
5 changes: 5 additions & 0 deletions arch/arm64/boot/dts/marvell/armada-3720-db.dts
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,8 @@
&usb3 {
status = "okay";
};

/* CON17 (PCIe) / CON12 (mini-PCIe) */
&pcie0 {
status = "okay";
};
25 changes: 25 additions & 0 deletions arch/arm64/boot/dts/marvell/armada-37xx.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -141,5 +141,30 @@
<0x1d40000 0x40000>; /* GICR */
};
};

pcie0: pcie@d0070000 {
compatible = "marvell,armada-3700-pcie";
device_type = "pci";
status = "disabled";
reg = <0 0xd0070000 0 0x20000>;
#address-cells = <3>;
#size-cells = <2>;
bus-range = <0x00 0xff>;
interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
#interrupt-cells = <1>;
msi-parent = <&pcie0>;
msi-controller;
ranges = <0x82000000 0 0xe8000000 0 0xe8000000 0 0x1000000 /* Port 0 MEM */
0x81000000 0 0xe9000000 0 0xe9000000 0 0x10000>; /* Port 0 IO*/
interrupt-map-mask = <0 0 0 7>;
interrupt-map = <0 0 0 1 &pcie_intc 0>,
<0 0 0 2 &pcie_intc 1>,
<0 0 0 3 &pcie_intc 2>,
<0 0 0 4 &pcie_intc 3>;
pcie_intc: interrupt-controller {
interrupt-controller;
#interrupt-cells = <1>;
};
};
};
};
41 changes: 25 additions & 16 deletions arch/x86/pci/vmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,23 +119,26 @@ static void vmd_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
static void vmd_irq_enable(struct irq_data *data)
{
struct vmd_irq *vmdirq = data->chip_data;
unsigned long flags;

raw_spin_lock(&list_lock);
raw_spin_lock_irqsave(&list_lock, flags);
list_add_tail_rcu(&vmdirq->node, &vmdirq->irq->irq_list);
raw_spin_unlock(&list_lock);
raw_spin_unlock_irqrestore(&list_lock, flags);

data->chip->irq_unmask(data);
}

static void vmd_irq_disable(struct irq_data *data)
{
struct vmd_irq *vmdirq = data->chip_data;
unsigned long flags;

data->chip->irq_mask(data);

raw_spin_lock(&list_lock);
raw_spin_lock_irqsave(&list_lock, flags);
list_del_rcu(&vmdirq->node);
raw_spin_unlock(&list_lock);
INIT_LIST_HEAD_RCU(&vmdirq->node);
raw_spin_unlock_irqrestore(&list_lock, flags);
}

/*
Expand Down Expand Up @@ -166,16 +169,20 @@ static irq_hw_number_t vmd_get_hwirq(struct msi_domain_info *info,
* XXX: We can be even smarter selecting the best IRQ once we solve the
* affinity problem.
*/
static struct vmd_irq_list *vmd_next_irq(struct vmd_dev *vmd)
static struct vmd_irq_list *vmd_next_irq(struct vmd_dev *vmd, struct msi_desc *desc)
{
int i, best = 0;
int i, best = 1;
unsigned long flags;

raw_spin_lock(&list_lock);
if (!desc->msi_attrib.is_msix || vmd->msix_count == 1)
return &vmd->irqs[0];

raw_spin_lock_irqsave(&list_lock, flags);
for (i = 1; i < vmd->msix_count; i++)
if (vmd->irqs[i].count < vmd->irqs[best].count)
best = i;
vmd->irqs[best].count++;
raw_spin_unlock(&list_lock);
raw_spin_unlock_irqrestore(&list_lock, flags);

return &vmd->irqs[best];
}
Expand All @@ -184,14 +191,15 @@ static int vmd_msi_init(struct irq_domain *domain, struct msi_domain_info *info,
unsigned int virq, irq_hw_number_t hwirq,
msi_alloc_info_t *arg)
{
struct vmd_dev *vmd = vmd_from_bus(msi_desc_to_pci_dev(arg->desc)->bus);
struct msi_desc *desc = arg->desc;
struct vmd_dev *vmd = vmd_from_bus(msi_desc_to_pci_dev(desc)->bus);
struct vmd_irq *vmdirq = kzalloc(sizeof(*vmdirq), GFP_KERNEL);

if (!vmdirq)
return -ENOMEM;

INIT_LIST_HEAD(&vmdirq->node);
vmdirq->irq = vmd_next_irq(vmd);
vmdirq->irq = vmd_next_irq(vmd, desc);
vmdirq->virq = virq;

irq_domain_set_info(domain, virq, vmdirq->irq->vmd_vector, info->chip,
Expand All @@ -203,11 +211,12 @@ static void vmd_msi_free(struct irq_domain *domain,
struct msi_domain_info *info, unsigned int virq)
{
struct vmd_irq *vmdirq = irq_get_chip_data(virq);
unsigned long flags;

/* XXX: Potential optimization to rebalance */
raw_spin_lock(&list_lock);
raw_spin_lock_irqsave(&list_lock, flags);
vmdirq->irq->count--;
raw_spin_unlock(&list_lock);
raw_spin_unlock_irqrestore(&list_lock, flags);

kfree_rcu(vmdirq, rcu);
}
Expand Down Expand Up @@ -261,7 +270,7 @@ static struct device *to_vmd_dev(struct device *dev)

static struct dma_map_ops *vmd_dma_ops(struct device *dev)
{
return to_vmd_dev(dev)->archdata.dma_ops;
return get_dma_ops(to_vmd_dev(dev));
}

static void *vmd_alloc(struct device *dev, size_t size, dma_addr_t *addr,
Expand Down Expand Up @@ -367,7 +376,7 @@ static void vmd_teardown_dma_ops(struct vmd_dev *vmd)
{
struct dma_domain *domain = &vmd->dma_domain;

if (vmd->dev->dev.archdata.dma_ops)
if (get_dma_ops(&vmd->dev->dev))
del_dma_domain(domain);
}

Expand All @@ -379,7 +388,7 @@ static void vmd_teardown_dma_ops(struct vmd_dev *vmd)

static void vmd_setup_dma_ops(struct vmd_dev *vmd)
{
const struct dma_map_ops *source = vmd->dev->dev.archdata.dma_ops;
const struct dma_map_ops *source = get_dma_ops(&vmd->dev->dev);
struct dma_map_ops *dest = &vmd->dma_ops;
struct dma_domain *domain = &vmd->dma_domain;

Expand Down Expand Up @@ -594,7 +603,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd)
sd->node = pcibus_to_node(vmd->dev->bus);

vmd->irq_domain = pci_msi_create_irq_domain(NULL, &vmd_msi_domain_info,
NULL);
x86_vector_domain);
if (!vmd->irq_domain)
return -ENODEV;

Expand Down
9 changes: 9 additions & 0 deletions drivers/pci/host/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ config PCI_MVEBU
depends on ARM
depends on OF

config PCI_AARDVARK
bool "Aardvark PCIe controller"
depends on ARCH_MVEBU && ARM64
depends on OF
depends on PCI_MSI_IRQ_DOMAIN
help
Add support for Aardvark 64bit PCIe Host Controller. This
controller is part of the South Bridge of the Marvel Armada
3700 SoC.

config PCIE_XILINX_NWL
bool "NWL PCIe Core"
Expand Down
1 change: 1 addition & 0 deletions drivers/pci/host/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o
obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o
obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
obj-$(CONFIG_PCIE_RCAR) += pcie-rcar.o
Expand Down
Loading

0 comments on commit a04bee8

Please sign in to comment.