Linux Audio

Check our new training course

Loading...
v5.4
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright (C) 2015 Broadcom Corporation
  4 */
  5
  6#include <linux/kernel.h>
  7#include <linux/pci.h>
  8#include <linux/clk.h>
  9#include <linux/module.h>
 10#include <linux/slab.h>
 11#include <linux/interrupt.h>
 12#include <linux/platform_device.h>
 13#include <linux/of_address.h>
 14#include <linux/of_pci.h>
 15#include <linux/of_irq.h>
 16#include <linux/of_platform.h>
 17#include <linux/phy/phy.h>
 18
 19#include "../pci.h"
 20#include "pcie-iproc.h"
 21
 22static const struct of_device_id iproc_pcie_of_match_table[] = {
 23	{
 24		.compatible = "brcm,iproc-pcie",
 25		.data = (int *)IPROC_PCIE_PAXB,
 26	}, {
 27		.compatible = "brcm,iproc-pcie-paxb-v2",
 28		.data = (int *)IPROC_PCIE_PAXB_V2,
 29	}, {
 30		.compatible = "brcm,iproc-pcie-paxc",
 31		.data = (int *)IPROC_PCIE_PAXC,
 32	}, {
 33		.compatible = "brcm,iproc-pcie-paxc-v2",
 34		.data = (int *)IPROC_PCIE_PAXC_V2,
 35	},
 36	{ /* sentinel */ }
 37};
 38MODULE_DEVICE_TABLE(of, iproc_pcie_of_match_table);
 39
 40static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
 41{
 42	struct device *dev = &pdev->dev;
 43	struct iproc_pcie *pcie;
 44	struct device_node *np = dev->of_node;
 45	struct resource reg;
 46	resource_size_t iobase = 0;
 47	LIST_HEAD(resources);
 48	struct pci_host_bridge *bridge;
 49	int ret;
 50
 51	bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
 52	if (!bridge)
 53		return -ENOMEM;
 54
 55	pcie = pci_host_bridge_priv(bridge);
 56
 57	pcie->dev = dev;
 58	pcie->type = (enum iproc_pcie_type) of_device_get_match_data(dev);
 59
 60	ret = of_address_to_resource(np, 0, &reg);
 61	if (ret < 0) {
 62		dev_err(dev, "unable to obtain controller resources\n");
 63		return ret;
 64	}
 65
 66	pcie->base = devm_pci_remap_cfgspace(dev, reg.start,
 67					     resource_size(&reg));
 68	if (!pcie->base) {
 69		dev_err(dev, "unable to map controller registers\n");
 70		return -ENOMEM;
 71	}
 72	pcie->base_addr = reg.start;
 73
 74	if (of_property_read_bool(np, "brcm,pcie-ob")) {
 75		u32 val;
 76
 77		ret = of_property_read_u32(np, "brcm,pcie-ob-axi-offset",
 78					   &val);
 79		if (ret) {
 80			dev_err(dev,
 81				"missing brcm,pcie-ob-axi-offset property\n");
 82			return ret;
 83		}
 84		pcie->ob.axi_offset = val;
 85		pcie->need_ob_cfg = true;
 86	}
 87
 88	/*
 89	 * DT nodes are not used by all platforms that use the iProc PCIe
 90	 * core driver. For platforms that require explicit inbound mapping
 91	 * configuration, "dma-ranges" would have been present in DT
 92	 */
 93	pcie->need_ib_cfg = of_property_read_bool(np, "dma-ranges");
 94
 95	/* PHY use is optional */
 96	pcie->phy = devm_phy_optional_get(dev, "pcie-phy");
 97	if (IS_ERR(pcie->phy))
 98		return PTR_ERR(pcie->phy);
 99
100	ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &resources,
101						    &iobase);
102	if (ret) {
103		dev_err(dev, "unable to get PCI host bridge resources\n");
104		return ret;
105	}
106
107	/* PAXC doesn't support legacy IRQs, skip mapping */
108	switch (pcie->type) {
109	case IPROC_PCIE_PAXC:
110	case IPROC_PCIE_PAXC_V2:
 
111		break;
112	default:
113		pcie->map_irq = of_irq_parse_and_map_pci;
114	}
115
116	ret = iproc_pcie_setup(pcie, &resources);
117	if (ret) {
118		dev_err(dev, "PCIe controller setup failed\n");
119		pci_free_resource_list(&resources);
120		return ret;
121	}
122
123	platform_set_drvdata(pdev, pcie);
124	return 0;
125}
126
127static int iproc_pcie_pltfm_remove(struct platform_device *pdev)
128{
129	struct iproc_pcie *pcie = platform_get_drvdata(pdev);
130
131	return iproc_pcie_remove(pcie);
132}
133
134static void iproc_pcie_pltfm_shutdown(struct platform_device *pdev)
135{
136	struct iproc_pcie *pcie = platform_get_drvdata(pdev);
137
138	iproc_pcie_shutdown(pcie);
139}
140
141static struct platform_driver iproc_pcie_pltfm_driver = {
142	.driver = {
143		.name = "iproc-pcie",
144		.of_match_table = of_match_ptr(iproc_pcie_of_match_table),
145	},
146	.probe = iproc_pcie_pltfm_probe,
147	.remove = iproc_pcie_pltfm_remove,
148	.shutdown = iproc_pcie_pltfm_shutdown,
149};
150module_platform_driver(iproc_pcie_pltfm_driver);
151
152MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>");
153MODULE_DESCRIPTION("Broadcom iPROC PCIe platform driver");
154MODULE_LICENSE("GPL v2");
v5.14.15
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright (C) 2015 Broadcom Corporation
  4 */
  5
  6#include <linux/kernel.h>
  7#include <linux/pci.h>
  8#include <linux/clk.h>
  9#include <linux/module.h>
 10#include <linux/slab.h>
 11#include <linux/interrupt.h>
 12#include <linux/platform_device.h>
 13#include <linux/of_address.h>
 14#include <linux/of_pci.h>
 15#include <linux/of_irq.h>
 16#include <linux/of_platform.h>
 17#include <linux/phy/phy.h>
 18
 19#include "../pci.h"
 20#include "pcie-iproc.h"
 21
 22static const struct of_device_id iproc_pcie_of_match_table[] = {
 23	{
 24		.compatible = "brcm,iproc-pcie",
 25		.data = (int *)IPROC_PCIE_PAXB,
 26	}, {
 27		.compatible = "brcm,iproc-pcie-paxb-v2",
 28		.data = (int *)IPROC_PCIE_PAXB_V2,
 29	}, {
 30		.compatible = "brcm,iproc-pcie-paxc",
 31		.data = (int *)IPROC_PCIE_PAXC,
 32	}, {
 33		.compatible = "brcm,iproc-pcie-paxc-v2",
 34		.data = (int *)IPROC_PCIE_PAXC_V2,
 35	},
 36	{ /* sentinel */ }
 37};
 38MODULE_DEVICE_TABLE(of, iproc_pcie_of_match_table);
 39
 40static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
 41{
 42	struct device *dev = &pdev->dev;
 43	struct iproc_pcie *pcie;
 44	struct device_node *np = dev->of_node;
 45	struct resource reg;
 
 
 46	struct pci_host_bridge *bridge;
 47	int ret;
 48
 49	bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
 50	if (!bridge)
 51		return -ENOMEM;
 52
 53	pcie = pci_host_bridge_priv(bridge);
 54
 55	pcie->dev = dev;
 56	pcie->type = (enum iproc_pcie_type) of_device_get_match_data(dev);
 57
 58	ret = of_address_to_resource(np, 0, &reg);
 59	if (ret < 0) {
 60		dev_err(dev, "unable to obtain controller resources\n");
 61		return ret;
 62	}
 63
 64	pcie->base = devm_pci_remap_cfgspace(dev, reg.start,
 65					     resource_size(&reg));
 66	if (!pcie->base) {
 67		dev_err(dev, "unable to map controller registers\n");
 68		return -ENOMEM;
 69	}
 70	pcie->base_addr = reg.start;
 71
 72	if (of_property_read_bool(np, "brcm,pcie-ob")) {
 73		u32 val;
 74
 75		ret = of_property_read_u32(np, "brcm,pcie-ob-axi-offset",
 76					   &val);
 77		if (ret) {
 78			dev_err(dev,
 79				"missing brcm,pcie-ob-axi-offset property\n");
 80			return ret;
 81		}
 82		pcie->ob.axi_offset = val;
 83		pcie->need_ob_cfg = true;
 84	}
 85
 86	/*
 87	 * DT nodes are not used by all platforms that use the iProc PCIe
 88	 * core driver. For platforms that require explicit inbound mapping
 89	 * configuration, "dma-ranges" would have been present in DT
 90	 */
 91	pcie->need_ib_cfg = of_property_read_bool(np, "dma-ranges");
 92
 93	/* PHY use is optional */
 94	pcie->phy = devm_phy_optional_get(dev, "pcie-phy");
 95	if (IS_ERR(pcie->phy))
 96		return PTR_ERR(pcie->phy);
 97
 
 
 
 
 
 
 
 98	/* PAXC doesn't support legacy IRQs, skip mapping */
 99	switch (pcie->type) {
100	case IPROC_PCIE_PAXC:
101	case IPROC_PCIE_PAXC_V2:
102		pcie->map_irq = NULL;
103		break;
104	default:
105		break;
106	}
107
108	ret = iproc_pcie_setup(pcie, &bridge->windows);
109	if (ret) {
110		dev_err(dev, "PCIe controller setup failed\n");
 
111		return ret;
112	}
113
114	platform_set_drvdata(pdev, pcie);
115	return 0;
116}
117
118static int iproc_pcie_pltfm_remove(struct platform_device *pdev)
119{
120	struct iproc_pcie *pcie = platform_get_drvdata(pdev);
121
122	return iproc_pcie_remove(pcie);
123}
124
125static void iproc_pcie_pltfm_shutdown(struct platform_device *pdev)
126{
127	struct iproc_pcie *pcie = platform_get_drvdata(pdev);
128
129	iproc_pcie_shutdown(pcie);
130}
131
132static struct platform_driver iproc_pcie_pltfm_driver = {
133	.driver = {
134		.name = "iproc-pcie",
135		.of_match_table = of_match_ptr(iproc_pcie_of_match_table),
136	},
137	.probe = iproc_pcie_pltfm_probe,
138	.remove = iproc_pcie_pltfm_remove,
139	.shutdown = iproc_pcie_pltfm_shutdown,
140};
141module_platform_driver(iproc_pcie_pltfm_driver);
142
143MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>");
144MODULE_DESCRIPTION("Broadcom iPROC PCIe platform driver");
145MODULE_LICENSE("GPL v2");