Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.2-rc3 93 lines 2.3 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * PCIe host controller driver for Amazon's Annapurna Labs IP (used in chips 4 * such as Graviton and Alpine) 5 * 6 * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 7 * 8 * Author: Jonathan Chocron <jonnyc@amazon.com> 9 */ 10 11#include <linux/pci.h> 12#include <linux/pci-ecam.h> 13#include <linux/pci-acpi.h> 14#include "../../pci.h" 15 16#if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) 17 18struct al_pcie_acpi { 19 void __iomem *dbi_base; 20}; 21 22static void __iomem *al_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, 23 int where) 24{ 25 struct pci_config_window *cfg = bus->sysdata; 26 struct al_pcie_acpi *pcie = cfg->priv; 27 void __iomem *dbi_base = pcie->dbi_base; 28 29 if (bus->number == cfg->busr.start) { 30 /* 31 * The DW PCIe core doesn't filter out transactions to other 32 * devices/functions on the root bus num, so we do this here. 33 */ 34 if (PCI_SLOT(devfn) > 0) 35 return NULL; 36 else 37 return dbi_base + where; 38 } 39 40 return pci_ecam_map_bus(bus, devfn, where); 41} 42 43static int al_pcie_init(struct pci_config_window *cfg) 44{ 45 struct device *dev = cfg->parent; 46 struct acpi_device *adev = to_acpi_device(dev); 47 struct acpi_pci_root *root = acpi_driver_data(adev); 48 struct al_pcie_acpi *al_pcie; 49 struct resource *res; 50 int ret; 51 52 al_pcie = devm_kzalloc(dev, sizeof(*al_pcie), GFP_KERNEL); 53 if (!al_pcie) 54 return -ENOMEM; 55 56 res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL); 57 if (!res) 58 return -ENOMEM; 59 60 ret = acpi_get_rc_resources(dev, "AMZN0001", root->segment, res); 61 if (ret) { 62 dev_err(dev, "can't get rc dbi base address for SEG %d\n", 63 root->segment); 64 return ret; 65 } 66 67 dev_dbg(dev, "Root port dbi res: %pR\n", res); 68 69 al_pcie->dbi_base = devm_pci_remap_cfg_resource(dev, res); 70 if (IS_ERR(al_pcie->dbi_base)) { 71 long err = PTR_ERR(al_pcie->dbi_base); 72 73 dev_err(dev, "couldn't remap dbi base %pR (err:%ld)\n", 74 res, err); 75 return err; 76 } 77 78 cfg->priv = al_pcie; 79 80 return 0; 81} 82 83struct pci_ecam_ops al_pcie_ops = { 84 .bus_shift = 20, 85 .init = al_pcie_init, 86 .pci_ops = { 87 .map_bus = al_pcie_map_bus, 88 .read = pci_generic_config_read, 89 .write = pci_generic_config_write, 90 } 91}; 92 93#endif /* defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) */