Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
  1/*
  2 * Copyright (C) 2015 Broadcom Corporation
  3 *
  4 * This program is free software; you can redistribute it and/or
  5 * modify it under the terms of the GNU General Public License as
  6 * published by the Free Software Foundation version 2.
  7 *
  8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  9 * kind, whether express or implied; without even the implied warranty
 10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 11 * GNU General Public License for more details.
 12 */
 13
 14#include <linux/kernel.h>
 15#include <linux/pci.h>
 16#include <linux/clk.h>
 17#include <linux/module.h>
 18#include <linux/slab.h>
 19#include <linux/interrupt.h>
 20#include <linux/platform_device.h>
 21#include <linux/of_address.h>
 22#include <linux/of_pci.h>
 23#include <linux/of_irq.h>
 24#include <linux/of_platform.h>
 25#include <linux/phy/phy.h>
 26
 27#include "pcie-iproc.h"
 28
 29static const struct of_device_id iproc_pcie_of_match_table[] = {
 30	{
 31		.compatible = "brcm,iproc-pcie",
 32		.data = (int *)IPROC_PCIE_PAXB,
 33	}, {
 34		.compatible = "brcm,iproc-pcie-paxc",
 35		.data = (int *)IPROC_PCIE_PAXC,
 36	},
 37	{ /* sentinel */ }
 38};
 39MODULE_DEVICE_TABLE(of, iproc_pcie_of_match_table);
 40
 41static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
 42{
 43	const struct of_device_id *of_id;
 44	struct iproc_pcie *pcie;
 45	struct device_node *np = pdev->dev.of_node;
 46	struct resource reg;
 47	resource_size_t iobase = 0;
 48	LIST_HEAD(res);
 49	int ret;
 50
 51	of_id = of_match_device(iproc_pcie_of_match_table, &pdev->dev);
 52	if (!of_id)
 53		return -EINVAL;
 54
 55	pcie = devm_kzalloc(&pdev->dev, sizeof(struct iproc_pcie), GFP_KERNEL);
 56	if (!pcie)
 57		return -ENOMEM;
 58
 59	pcie->dev = &pdev->dev;
 60	pcie->type = (enum iproc_pcie_type)of_id->data;
 61	platform_set_drvdata(pdev, pcie);
 62
 63	ret = of_address_to_resource(np, 0, &reg);
 64	if (ret < 0) {
 65		dev_err(pcie->dev, "unable to obtain controller resources\n");
 66		return ret;
 67	}
 68
 69	pcie->base = devm_ioremap(pcie->dev, reg.start, resource_size(&reg));
 70	if (!pcie->base) {
 71		dev_err(pcie->dev, "unable to map controller registers\n");
 72		return -ENOMEM;
 73	}
 74	pcie->base_addr = reg.start;
 75
 76	if (of_property_read_bool(np, "brcm,pcie-ob")) {
 77		u32 val;
 78
 79		ret = of_property_read_u32(np, "brcm,pcie-ob-axi-offset",
 80					   &val);
 81		if (ret) {
 82			dev_err(pcie->dev,
 83				"missing brcm,pcie-ob-axi-offset property\n");
 84			return ret;
 85		}
 86		pcie->ob.axi_offset = val;
 87
 88		ret = of_property_read_u32(np, "brcm,pcie-ob-window-size",
 89					   &val);
 90		if (ret) {
 91			dev_err(pcie->dev,
 92				"missing brcm,pcie-ob-window-size property\n");
 93			return ret;
 94		}
 95		pcie->ob.window_size = (resource_size_t)val * SZ_1M;
 96
 97		if (of_property_read_bool(np, "brcm,pcie-ob-oarr-size"))
 98			pcie->ob.set_oarr_size = true;
 99
100		pcie->need_ob_cfg = true;
101	}
102
103	/* PHY use is optional */
104	pcie->phy = devm_phy_get(&pdev->dev, "pcie-phy");
105	if (IS_ERR(pcie->phy)) {
106		if (PTR_ERR(pcie->phy) == -EPROBE_DEFER)
107			return -EPROBE_DEFER;
108		pcie->phy = NULL;
109	}
110
111	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &iobase);
112	if (ret) {
113		dev_err(pcie->dev,
114			"unable to get PCI host bridge resources\n");
115		return ret;
116	}
117
118	pcie->map_irq = of_irq_parse_and_map_pci;
119
120	ret = iproc_pcie_setup(pcie, &res);
121	if (ret)
122		dev_err(pcie->dev, "PCIe controller setup failed\n");
123
124	pci_free_resource_list(&res);
125
126	return ret;
127}
128
129static int iproc_pcie_pltfm_remove(struct platform_device *pdev)
130{
131	struct iproc_pcie *pcie = platform_get_drvdata(pdev);
132
133	return iproc_pcie_remove(pcie);
134}
135
136static struct platform_driver iproc_pcie_pltfm_driver = {
137	.driver = {
138		.name = "iproc-pcie",
139		.of_match_table = of_match_ptr(iproc_pcie_of_match_table),
140	},
141	.probe = iproc_pcie_pltfm_probe,
142	.remove = iproc_pcie_pltfm_remove,
143};
144module_platform_driver(iproc_pcie_pltfm_driver);
145
146MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>");
147MODULE_DESCRIPTION("Broadcom iPROC PCIe platform driver");
148MODULE_LICENSE("GPL v2");