Skip to content
Snippets Groups Projects
Select Git revision
  • 9e2aee80c78d5084e0c58745e9762c29da6bd53f
  • seco_lf-6.6.52-2.2.1 default protected
  • MODV-209-e-39-add-gpio-line-names-in-kernel-device-tree
  • niccolor/e88-lt9611uxc-dsi-complete-support
  • seco_lf-6.6.52-2.2.1_e88-lt9611uxc-i2s
  • seco_lf-6.6.52-2.2.1_e39-nxpbtuart
  • chka-modv-206-poc
  • seco_lf-6.6.52-2.2.1-rtl8211f_led
  • seco_lf-5.10.y protected
  • seco_lf_v2024.04_6.6.52_2.2.x_e39_spidev-overlay
  • seco_lf_v2024.04_6.6.52_2.2.x_e39_sdcard-card-detect-gpio-mode
  • integrate/gitlab-ci/cleaos-833-add-cnfluence-labels-into-config/into/seco_lf-5.10.y
  • integrate/gitlab-ci/cleaos-448-bitbake-logs-in-failed-job/into/seco_lf-6.6.52-2.2.1
  • integrate/gitlab-ci/cleaos-448-bitbake-logs-in-failed-job/into/seco_lf-5.10.y
  • chka-seco_lf-6.6.52-2.2.1-fix-eth-led-modv-198
  • didi/spi-cs
  • seco_lf-6.6.23-2.0.0_e39-e83-temperature-sensor
  • seco_lf-6.6.23-2.0.0_e39-e83-status-led
  • seco_lf-6.6.23-2.0.0_e39-e83-lvds-7inch-powersequence
  • chka-fix-eth-led-modv-198
  • seco_lf-6.6.52-2.2.1_e88-e83-dev
  • lf-6.6.52-2.2.1
  • lf-6.1.55-2.2.1
  • lf-6.6.3-1.0.0
  • lf-6.6.3-imx95-er2
  • lf-6.1.55-2.2.0
  • lf-6.6.y-imx95-er1
  • lf-5.15.71-2.2.2
  • lf-6.1.36-2.1.0
  • lf-5.15.71-2.2.1
  • lf-6.1.22-2.0.0
  • lf-6.1.1-1.0.1
  • rel_imx_5.4.24_2.1.4
  • rel_imx_4.9.88_2.0.13
  • rel_imx_4.14.98_2.3.5
  • lf-6.1.1-1.0.0
  • rel_imx_5.4.3_2.0.2
  • lf-5.15.71-2.2.0
  • lf-5.10.72-2.2.3
  • lf-5.15.52-2.1.0
  • imx_5.15.52_imx8ulp_er1
41 results

pcie-iproc-platform.c

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    pcie-iproc-platform.c 3.79 KiB
    // SPDX-License-Identifier: GPL-2.0
    /*
     * Copyright (C) 2015 Broadcom Corporation
     */
    
    #include <linux/kernel.h>
    #include <linux/pci.h>
    #include <linux/clk.h>
    #include <linux/module.h>
    #include <linux/slab.h>
    #include <linux/interrupt.h>
    #include <linux/platform_device.h>
    #include <linux/of_address.h>
    #include <linux/of_pci.h>
    #include <linux/of_irq.h>
    #include <linux/of_platform.h>
    #include <linux/phy/phy.h>
    
    #include "../pci.h"
    #include "pcie-iproc.h"
    
    static const struct of_device_id iproc_pcie_of_match_table[] = {
    	{
    		.compatible = "brcm,iproc-pcie",
    		.data = (int *)IPROC_PCIE_PAXB,
    	}, {
    		.compatible = "brcm,iproc-pcie-paxb-v2",
    		.data = (int *)IPROC_PCIE_PAXB_V2,
    	}, {
    		.compatible = "brcm,iproc-pcie-paxc",
    		.data = (int *)IPROC_PCIE_PAXC,
    	}, {
    		.compatible = "brcm,iproc-pcie-paxc-v2",
    		.data = (int *)IPROC_PCIE_PAXC_V2,
    	},
    	{ /* sentinel */ }
    };
    MODULE_DEVICE_TABLE(of, iproc_pcie_of_match_table);
    
    static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
    {
    	struct device *dev = &pdev->dev;
    	struct iproc_pcie *pcie;
    	struct device_node *np = dev->of_node;
    	struct resource reg;
    	resource_size_t iobase = 0;
    	LIST_HEAD(resources);
    	struct pci_host_bridge *bridge;
    	int ret;
    
    	bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
    	if (!bridge)
    		return -ENOMEM;
    
    	pcie = pci_host_bridge_priv(bridge);
    
    	pcie->dev = dev;
    	pcie->type = (enum iproc_pcie_type) of_device_get_match_data(dev);
    
    	ret = of_address_to_resource(np, 0, &reg);
    	if (ret < 0) {
    		dev_err(dev, "unable to obtain controller resources\n");
    		return ret;
    	}
    
    	pcie->base = devm_pci_remap_cfgspace(dev, reg.start,
    					     resource_size(&reg));
    	if (!pcie->base) {
    		dev_err(dev, "unable to map controller registers\n");
    		return -ENOMEM;
    	}
    	pcie->base_addr = reg.start;
    
    	if (of_property_read_bool(np, "brcm,pcie-ob")) {
    		u32 val;
    
    		ret = of_property_read_u32(np, "brcm,pcie-ob-axi-offset",
    					   &val);
    		if (ret) {
    			dev_err(dev,
    				"missing brcm,pcie-ob-axi-offset property\n");
    			return ret;
    		}
    		pcie->ob.axi_offset = val;
    		pcie->need_ob_cfg = true;
    	}
    
    	/*
    	 * DT nodes are not used by all platforms that use the iProc PCIe
    	 * core driver. For platforms that require explict inbound mapping
    	 * configuration, "dma-ranges" would have been present in DT
    	 */
    	pcie->need_ib_cfg = of_property_read_bool(np, "dma-ranges");
    
    	/* PHY use is optional */
    	pcie->phy = devm_phy_get(dev, "pcie-phy");
    	if (IS_ERR(pcie->phy)) {
    		if (PTR_ERR(pcie->phy) == -EPROBE_DEFER)
    			return -EPROBE_DEFER;
    		pcie->phy = NULL;
    	}
    
    	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &resources,
    					       &iobase);
    	if (ret) {
    		dev_err(dev, "unable to get PCI host bridge resources\n");
    		return ret;
    	}
    
    	/* PAXC doesn't support legacy IRQs, skip mapping */
    	switch (pcie->type) {
    	case IPROC_PCIE_PAXC:
    	case IPROC_PCIE_PAXC_V2:
    		break;
    	default:
    		pcie->map_irq = of_irq_parse_and_map_pci;
    	}
    
    	ret = iproc_pcie_setup(pcie, &resources);
    	if (ret) {
    		dev_err(dev, "PCIe controller setup failed\n");
    		pci_free_resource_list(&resources);
    		return ret;
    	}
    
    	platform_set_drvdata(pdev, pcie);
    	return 0;
    }
    
    static int iproc_pcie_pltfm_remove(struct platform_device *pdev)
    {
    	struct iproc_pcie *pcie = platform_get_drvdata(pdev);
    
    	return iproc_pcie_remove(pcie);
    }
    
    static void iproc_pcie_pltfm_shutdown(struct platform_device *pdev)
    {
    	struct iproc_pcie *pcie = platform_get_drvdata(pdev);
    
    	iproc_pcie_shutdown(pcie);
    }
    
    static struct platform_driver iproc_pcie_pltfm_driver = {
    	.driver = {
    		.name = "iproc-pcie",
    		.of_match_table = of_match_ptr(iproc_pcie_of_match_table),
    	},
    	.probe = iproc_pcie_pltfm_probe,
    	.remove = iproc_pcie_pltfm_remove,
    	.shutdown = iproc_pcie_pltfm_shutdown,
    };
    module_platform_driver(iproc_pcie_pltfm_driver);
    
    MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>");
    MODULE_DESCRIPTION("Broadcom iPROC PCIe platform driver");
    MODULE_LICENSE("GPL v2");