Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * PCIe RC driver for Synopsys DesignWare Core
  4 *
  5 * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
  6 *
  7 * Authors: Joao Pinto <Joao.Pinto@synopsys.com>
  8 */
  9#include <linux/clk.h>
 10#include <linux/delay.h>
 11#include <linux/gpio.h>
 12#include <linux/interrupt.h>
 13#include <linux/kernel.h>
 14#include <linux/init.h>
 15#include <linux/of_gpio.h>
 16#include <linux/pci.h>
 17#include <linux/platform_device.h>
 18#include <linux/resource.h>
 19#include <linux/signal.h>
 20#include <linux/types.h>
 21
 22#include "pcie-designware.h"
 23
 24struct dw_plat_pcie {
 25	struct dw_pcie		*pci;
 26};
 27
 28static int dw_plat_pcie_host_init(struct pcie_port *pp)
 29{
 30	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 31
 32	dw_pcie_setup_rc(pp);
 33	dw_pcie_wait_for_link(pci);
 34
 35	if (IS_ENABLED(CONFIG_PCI_MSI))
 36		dw_pcie_msi_init(pp);
 37
 38	return 0;
 39}
 40
 41static const struct dw_pcie_host_ops dw_plat_pcie_host_ops = {
 42	.host_init = dw_plat_pcie_host_init,
 43};
 44
 45static int dw_plat_add_pcie_port(struct pcie_port *pp,
 46				 struct platform_device *pdev)
 47{
 48	struct device *dev = &pdev->dev;
 49	int ret;
 50
 51	pp->irq = platform_get_irq(pdev, 1);
 52	if (pp->irq < 0)
 53		return pp->irq;
 54
 55	if (IS_ENABLED(CONFIG_PCI_MSI)) {
 56		pp->msi_irq = platform_get_irq(pdev, 0);
 57		if (pp->msi_irq < 0)
 58			return pp->msi_irq;
 59	}
 60
 61	pp->root_bus_nr = -1;
 62	pp->ops = &dw_plat_pcie_host_ops;
 63
 64	ret = dw_pcie_host_init(pp);
 65	if (ret) {
 66		dev_err(dev, "failed to initialize host\n");
 67		return ret;
 68	}
 69
 70	return 0;
 71}
 72
 73static const struct dw_pcie_ops dw_pcie_ops = {
 74};
 75
 76static int dw_plat_pcie_probe(struct platform_device *pdev)
 77{
 78	struct device *dev = &pdev->dev;
 79	struct dw_plat_pcie *dw_plat_pcie;
 80	struct dw_pcie *pci;
 81	struct resource *res;  /* Resource from DT */
 82	int ret;
 83
 84	dw_plat_pcie = devm_kzalloc(dev, sizeof(*dw_plat_pcie), GFP_KERNEL);
 85	if (!dw_plat_pcie)
 86		return -ENOMEM;
 87
 88	pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
 89	if (!pci)
 90		return -ENOMEM;
 91
 92	pci->dev = dev;
 93	pci->ops = &dw_pcie_ops;
 94
 95	dw_plat_pcie->pci = pci;
 96
 97	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 98	pci->dbi_base = devm_ioremap_resource(dev, res);
 99	if (IS_ERR(pci->dbi_base))
100		return PTR_ERR(pci->dbi_base);
101
102	platform_set_drvdata(pdev, dw_plat_pcie);
103
104	ret = dw_plat_add_pcie_port(&pci->pp, pdev);
105	if (ret < 0)
106		return ret;
107
108	return 0;
109}
110
111static const struct of_device_id dw_plat_pcie_of_match[] = {
112	{ .compatible = "snps,dw-pcie", },
113	{},
114};
115
116static struct platform_driver dw_plat_pcie_driver = {
117	.driver = {
118		.name	= "dw-pcie",
119		.of_match_table = dw_plat_pcie_of_match,
120		.suppress_bind_attrs = true,
121	},
122	.probe = dw_plat_pcie_probe,
123};
124builtin_platform_driver(dw_plat_pcie_driver);