Linux Audio

Check our new training course

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