pci-v4.11-fixes-3
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJY3X6QAAoJEFmIoMA60/r8GXwP/iCy0zUQu6xunEdDJQPIo1vJ JVZFl6e3DiuT5w5SUd0jNzcK6nv4oAM3bS8cLAmhYx0f/7vRAFnW2QhUQO5wQB2i iA4ZIRV/TenSXeCesIUpBeQ6I7cxQPFBY3568Bjb1eueTuvTjvKyB2CgxQiSO7sq 7ZTPTrAjg3LZPPCwfEIMU/XQD8vwMziIx48P+YkMiP5oOGt+8LPvVBNcGyxdDaoG lXDdxPtSB96h0fDGmPtyCs0bRZrbjPSH6Krlmw3UKcGFdYWrxQc5UMNIMF0g7otX u5ZQ5athDumLBhLLXxpPUsmcdKbc+HWhTgERsxfVLQWTPM0oYSQkzrxZBwOt7cfJ LadD4Zmw3/kw28WYrFvb5ZTcZK63UZN+EkTozJT8euus0PW0ySFoWanLQq9G6wM9 hnnRBT5zgKm5wo4XiEkBDJo9Mn6cVWMa/209Rn+tSocGw430oY6RQsATXuujNAjB oVQDGEbHo0/7E/qQO2He+azv2W+Mgpz3Vwma9zfvqd2VqctNxPKHyCsX26mR+NYh E6z90WSF9zpFbxLBJfeFxfKXinX9oE4FneGpGz6LDdr33bESsaEjQiwEYrPd7u8x fBuLw/u/SuLXKcRoyRQwgDoordxc2MVjxwElq41o8RbP2++7oVg+gzIWBIhKn6NP XRr5XC0Mv3HJj+RJy87O =vi64 -----END PGP SIGNATURE----- Merge tag 'pci-v4.11-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci Pull PCI fixes from Bjorn Helgaas: - fix iProc memory corruption - fix ThunderX usage of unregistered PNP/ACPI ID - fix ThunderX resource reservation on early firmware * tag 'pci-v4.11-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: PCI: thunder-pem: Add legacy firmware support for Cavium ThunderX host controller PCI: thunder-pem: Use Cavium assigned hardware ID for ThunderX host controller PCI: iproc: Save host bridge window resource in struct iproc_pcie
This commit is contained in:
commit
d4562267b9
|
@ -14,6 +14,7 @@
|
|||
* Copyright (C) 2015 - 2016 Cavium, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/of_address.h>
|
||||
|
@ -334,6 +335,50 @@ static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg,
|
|||
|
||||
#if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
|
||||
|
||||
#define PEM_RES_BASE 0x87e0c0000000UL
|
||||
#define PEM_NODE_MASK GENMASK(45, 44)
|
||||
#define PEM_INDX_MASK GENMASK(26, 24)
|
||||
#define PEM_MIN_DOM_IN_NODE 4
|
||||
#define PEM_MAX_DOM_IN_NODE 10
|
||||
|
||||
static void thunder_pem_reserve_range(struct device *dev, int seg,
|
||||
struct resource *r)
|
||||
{
|
||||
resource_size_t start = r->start, end = r->end;
|
||||
struct resource *res;
|
||||
const char *regionid;
|
||||
|
||||
regionid = kasprintf(GFP_KERNEL, "PEM RC:%d", seg);
|
||||
if (!regionid)
|
||||
return;
|
||||
|
||||
res = request_mem_region(start, end - start + 1, regionid);
|
||||
if (res)
|
||||
res->flags &= ~IORESOURCE_BUSY;
|
||||
else
|
||||
kfree(regionid);
|
||||
|
||||
dev_info(dev, "%pR %s reserved\n", r,
|
||||
res ? "has been" : "could not be");
|
||||
}
|
||||
|
||||
static void thunder_pem_legacy_fw(struct acpi_pci_root *root,
|
||||
struct resource *res_pem)
|
||||
{
|
||||
int node = acpi_get_node(root->device->handle);
|
||||
int index;
|
||||
|
||||
if (node == NUMA_NO_NODE)
|
||||
node = 0;
|
||||
|
||||
index = root->segment - PEM_MIN_DOM_IN_NODE;
|
||||
index -= node * PEM_MAX_DOM_IN_NODE;
|
||||
res_pem->start = PEM_RES_BASE | FIELD_PREP(PEM_NODE_MASK, node) |
|
||||
FIELD_PREP(PEM_INDX_MASK, index);
|
||||
res_pem->end = res_pem->start + SZ_16M - 1;
|
||||
res_pem->flags = IORESOURCE_MEM;
|
||||
}
|
||||
|
||||
static int thunder_pem_acpi_init(struct pci_config_window *cfg)
|
||||
{
|
||||
struct device *dev = cfg->parent;
|
||||
|
@ -346,10 +391,17 @@ static int thunder_pem_acpi_init(struct pci_config_window *cfg)
|
|||
if (!res_pem)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = acpi_get_rc_resources(dev, "THRX0002", root->segment, res_pem);
|
||||
ret = acpi_get_rc_resources(dev, "CAVA02B", root->segment, res_pem);
|
||||
|
||||
/*
|
||||
* If we fail to gather resources it means that we run with old
|
||||
* FW where we need to calculate PEM-specific resources manually.
|
||||
*/
|
||||
if (ret) {
|
||||
dev_err(dev, "can't get rc base address\n");
|
||||
return ret;
|
||||
thunder_pem_legacy_fw(root, res_pem);
|
||||
/* Reserve PEM-specific resources and PCI configuration space */
|
||||
thunder_pem_reserve_range(dev, root->segment, res_pem);
|
||||
thunder_pem_reserve_range(dev, root->segment, &cfg->res);
|
||||
}
|
||||
|
||||
return thunder_pem_init(dev, cfg, res_pem);
|
||||
|
|
|
@ -44,8 +44,7 @@ static int iproc_pcie_bcma_probe(struct bcma_device *bdev)
|
|||
{
|
||||
struct device *dev = &bdev->dev;
|
||||
struct iproc_pcie *pcie;
|
||||
LIST_HEAD(res);
|
||||
struct resource res_mem;
|
||||
LIST_HEAD(resources);
|
||||
int ret;
|
||||
|
||||
pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
|
||||
|
@ -63,22 +62,23 @@ static int iproc_pcie_bcma_probe(struct bcma_device *bdev)
|
|||
|
||||
pcie->base_addr = bdev->addr;
|
||||
|
||||
res_mem.start = bdev->addr_s[0];
|
||||
res_mem.end = bdev->addr_s[0] + SZ_128M - 1;
|
||||
res_mem.name = "PCIe MEM space";
|
||||
res_mem.flags = IORESOURCE_MEM;
|
||||
pci_add_resource(&res, &res_mem);
|
||||
pcie->mem.start = bdev->addr_s[0];
|
||||
pcie->mem.end = bdev->addr_s[0] + SZ_128M - 1;
|
||||
pcie->mem.name = "PCIe MEM space";
|
||||
pcie->mem.flags = IORESOURCE_MEM;
|
||||
pci_add_resource(&resources, &pcie->mem);
|
||||
|
||||
pcie->map_irq = iproc_pcie_bcma_map_irq;
|
||||
|
||||
ret = iproc_pcie_setup(pcie, &res);
|
||||
if (ret)
|
||||
ret = iproc_pcie_setup(pcie, &resources);
|
||||
if (ret) {
|
||||
dev_err(dev, "PCIe controller setup failed\n");
|
||||
|
||||
pci_free_resource_list(&res);
|
||||
pci_free_resource_list(&resources);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bcma_set_drvdata(bdev, pcie);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void iproc_pcie_bcma_remove(struct bcma_device *bdev)
|
||||
|
|
|
@ -51,7 +51,7 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
|
|||
struct device_node *np = dev->of_node;
|
||||
struct resource reg;
|
||||
resource_size_t iobase = 0;
|
||||
LIST_HEAD(res);
|
||||
LIST_HEAD(resources);
|
||||
int ret;
|
||||
|
||||
pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
|
||||
|
@ -96,10 +96,10 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
|
|||
pcie->phy = NULL;
|
||||
}
|
||||
|
||||
ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &iobase);
|
||||
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");
|
||||
dev_err(dev, "unable to get PCI host bridge resources\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -112,14 +112,15 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
|
|||
pcie->map_irq = of_irq_parse_and_map_pci;
|
||||
}
|
||||
|
||||
ret = iproc_pcie_setup(pcie, &res);
|
||||
if (ret)
|
||||
ret = iproc_pcie_setup(pcie, &resources);
|
||||
if (ret) {
|
||||
dev_err(dev, "PCIe controller setup failed\n");
|
||||
|
||||
pci_free_resource_list(&res);
|
||||
pci_free_resource_list(&resources);
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, pcie);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iproc_pcie_pltfm_remove(struct platform_device *pdev)
|
||||
|
|
|
@ -90,6 +90,7 @@ struct iproc_pcie {
|
|||
#ifdef CONFIG_ARM
|
||||
struct pci_sys_data sysdata;
|
||||
#endif
|
||||
struct resource mem;
|
||||
struct pci_bus *root_bus;
|
||||
struct phy *phy;
|
||||
int (*map_irq)(const struct pci_dev *, u8, u8);
|
||||
|
|
Loading…
Reference in New Issue