Skip to content

Commit

Permalink
PCI: designware: Add driver for prototyping kits based on ARC SDP
Browse files Browse the repository at this point in the history
Add a reference platform driver for PCI RC IP Protoyping Kits based on the
ARC SDP.

[bhelgaas: changelog, split patch up, MAINTAINERS update]
Signed-off-by: Joao Pinto <jpinto@synopsys.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Pratyush Anand <pratyush.anand@gmail.com>
  • Loading branch information
Joao Pinto authored and bjorn-helgaas committed Mar 15, 2016
1 parent dac29e6 commit 5a3aa2a
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 0 deletions.
17 changes: 17 additions & 0 deletions Documentation/devicetree/bindings/pci/designware-pcie.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,20 @@ Optional properties:
- clock-names: Must include the following entries:
- "pcie"
- "pcie_bus"

Example configuration:

pcie: pcie@0xdffff000 {
compatible = "snps,dw-pcie";
reg = <0xdffff000 0x1000>, /* Controller registers */
<0xd0000000 0x2000>; /* PCI config space */
reg-names = "ctrlreg", "config";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
ranges = <0x81000000 0 0x00000000 0xde000000 0 0x00010000
0x82000000 0 0xd0400000 0xd0400000 0 0x0d000000>;
interrupts = <25>, <24>;
#interrupt-cells = <1>;
num-lanes = <1>;
};
7 changes: 7 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -8367,6 +8367,13 @@ L: linux-pci@vger.kernel.org
S: Maintained
F: drivers/pci/host/*designware*

PCI DRIVER FOR SYNOPSYS PROTOTYPING DEVICE
M: Joao Pinto <jpinto@synopsys.com>
L: linux-pci@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/pci/designware-pcie.txt
F: drivers/pci/host/pcie-designware-plat.c

PCI DRIVER FOR GENERIC OF HOSTS
M: Will Deacon <will.deacon@arm.com>
L: linux-pci@vger.kernel.org
Expand Down
11 changes: 11 additions & 0 deletions drivers/pci/host/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@ config PCI_MVEBU
depends on ARCH_MVEBU || ARCH_DOVE
depends on OF

config PCIE_DW_PLAT
bool "Platform bus based DesignWare PCIe Controller"
select PCIE_DW
---help---
This selects the DesignWare PCIe controller support. Select this if
you have a PCIe controller on Platform bus.

If you have a controller with this interface, say Y or M here.

If unsure, say N.

config PCIE_DW
bool

Expand Down
1 change: 1 addition & 0 deletions drivers/pci/host/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
obj-$(CONFIG_PCIE_DW) += pcie-designware.o
obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
Expand Down
138 changes: 138 additions & 0 deletions drivers/pci/host/pcie-designware-plat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*
* PCIe RC driver for Synopsys DesignWare Core
*
* Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
*
* Authors: Joao Pinto <jpinto@synopsys.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/resource.h>
#include <linux/signal.h>
#include <linux/types.h>

#include "pcie-designware.h"

struct dw_plat_pcie {
void __iomem *mem_base;
struct pcie_port pp;
};

static irqreturn_t dw_plat_pcie_msi_irq_handler(int irq, void *arg)
{
struct pcie_port *pp = arg;

return dw_handle_msi_irq(pp);
}

static void dw_plat_pcie_host_init(struct pcie_port *pp)
{
dw_pcie_setup_rc(pp);
dw_pcie_wait_for_link(pp);

if (IS_ENABLED(CONFIG_PCI_MSI))
dw_pcie_msi_init(pp);
}

static struct pcie_host_ops dw_plat_pcie_host_ops = {
.host_init = dw_plat_pcie_host_init,
};

static int dw_plat_add_pcie_port(struct pcie_port *pp,
struct platform_device *pdev)
{
int ret;

pp->irq = platform_get_irq(pdev, 1);
if (pp->irq < 0)
return pp->irq;

if (IS_ENABLED(CONFIG_PCI_MSI)) {
pp->msi_irq = platform_get_irq(pdev, 0);
if (pp->msi_irq < 0)
return pp->msi_irq;

ret = devm_request_irq(&pdev->dev, pp->msi_irq,
dw_plat_pcie_msi_irq_handler,
IRQF_SHARED, "dw-plat-pcie-msi", pp);
if (ret) {
dev_err(&pdev->dev, "failed to request MSI IRQ\n");
return ret;
}
}

pp->root_bus_nr = -1;
pp->ops = &dw_plat_pcie_host_ops;

ret = dw_pcie_host_init(pp);
if (ret) {
dev_err(&pdev->dev, "failed to initialize host\n");
return ret;
}

return 0;
}

static int dw_plat_pcie_probe(struct platform_device *pdev)
{
struct dw_plat_pcie *dw_plat_pcie;
struct pcie_port *pp;
struct resource *res; /* Resource from DT */
int ret;

dw_plat_pcie = devm_kzalloc(&pdev->dev, sizeof(*dw_plat_pcie),
GFP_KERNEL);
if (!dw_plat_pcie)
return -ENOMEM;

pp = &dw_plat_pcie->pp;
pp->dev = &pdev->dev;

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENODEV;

dw_plat_pcie->mem_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(dw_plat_pcie->mem_base))
return PTR_ERR(dw_plat_pcie->mem_base);

pp->dbi_base = dw_plat_pcie->mem_base;

ret = dw_plat_add_pcie_port(pp, pdev);
if (ret < 0)
return ret;

platform_set_drvdata(pdev, dw_plat_pcie);
return 0;
}

static const struct of_device_id dw_plat_pcie_of_match[] = {
{ .compatible = "snps,dw-pcie", },
{},
};
MODULE_DEVICE_TABLE(of, dw_plat_pcie_of_match);

static struct platform_driver dw_plat_pcie_driver = {
.driver = {
.name = "dw-pcie",
.of_match_table = dw_plat_pcie_of_match,
},
.probe = dw_plat_pcie_probe,
};

module_platform_driver(dw_plat_pcie_driver);

MODULE_AUTHOR("Joao Pinto <Joao.Pinto@synopsys.com>");
MODULE_DESCRIPTION("Synopsys PCIe host controller glue platform driver");
MODULE_LICENSE("GPL v2");

0 comments on commit 5a3aa2a

Please sign in to comment.