Skip to content

Commit d456226

Browse files
committed
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
2 parents 89970a0 + 9abb27c commit d456226

File tree

4 files changed

+78
-24
lines changed

4 files changed

+78
-24
lines changed

drivers/pci/host/pci-thunder-pem.c

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* Copyright (C) 2015 - 2016 Cavium, Inc.
1515
*/
1616

17+
#include <linux/bitfield.h>
1718
#include <linux/kernel.h>
1819
#include <linux/init.h>
1920
#include <linux/of_address.h>
@@ -334,6 +335,50 @@ static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg,
334335

335336
#if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
336337

338+
#define PEM_RES_BASE 0x87e0c0000000UL
339+
#define PEM_NODE_MASK GENMASK(45, 44)
340+
#define PEM_INDX_MASK GENMASK(26, 24)
341+
#define PEM_MIN_DOM_IN_NODE 4
342+
#define PEM_MAX_DOM_IN_NODE 10
343+
344+
static void thunder_pem_reserve_range(struct device *dev, int seg,
345+
struct resource *r)
346+
{
347+
resource_size_t start = r->start, end = r->end;
348+
struct resource *res;
349+
const char *regionid;
350+
351+
regionid = kasprintf(GFP_KERNEL, "PEM RC:%d", seg);
352+
if (!regionid)
353+
return;
354+
355+
res = request_mem_region(start, end - start + 1, regionid);
356+
if (res)
357+
res->flags &= ~IORESOURCE_BUSY;
358+
else
359+
kfree(regionid);
360+
361+
dev_info(dev, "%pR %s reserved\n", r,
362+
res ? "has been" : "could not be");
363+
}
364+
365+
static void thunder_pem_legacy_fw(struct acpi_pci_root *root,
366+
struct resource *res_pem)
367+
{
368+
int node = acpi_get_node(root->device->handle);
369+
int index;
370+
371+
if (node == NUMA_NO_NODE)
372+
node = 0;
373+
374+
index = root->segment - PEM_MIN_DOM_IN_NODE;
375+
index -= node * PEM_MAX_DOM_IN_NODE;
376+
res_pem->start = PEM_RES_BASE | FIELD_PREP(PEM_NODE_MASK, node) |
377+
FIELD_PREP(PEM_INDX_MASK, index);
378+
res_pem->end = res_pem->start + SZ_16M - 1;
379+
res_pem->flags = IORESOURCE_MEM;
380+
}
381+
337382
static int thunder_pem_acpi_init(struct pci_config_window *cfg)
338383
{
339384
struct device *dev = cfg->parent;
@@ -346,10 +391,17 @@ static int thunder_pem_acpi_init(struct pci_config_window *cfg)
346391
if (!res_pem)
347392
return -ENOMEM;
348393

349-
ret = acpi_get_rc_resources(dev, "THRX0002", root->segment, res_pem);
394+
ret = acpi_get_rc_resources(dev, "CAVA02B", root->segment, res_pem);
395+
396+
/*
397+
* If we fail to gather resources it means that we run with old
398+
* FW where we need to calculate PEM-specific resources manually.
399+
*/
350400
if (ret) {
351-
dev_err(dev, "can't get rc base address\n");
352-
return ret;
401+
thunder_pem_legacy_fw(root, res_pem);
402+
/* Reserve PEM-specific resources and PCI configuration space */
403+
thunder_pem_reserve_range(dev, root->segment, res_pem);
404+
thunder_pem_reserve_range(dev, root->segment, &cfg->res);
353405
}
354406

355407
return thunder_pem_init(dev, cfg, res_pem);

drivers/pci/host/pcie-iproc-bcma.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ static int iproc_pcie_bcma_probe(struct bcma_device *bdev)
4444
{
4545
struct device *dev = &bdev->dev;
4646
struct iproc_pcie *pcie;
47-
LIST_HEAD(res);
48-
struct resource res_mem;
47+
LIST_HEAD(resources);
4948
int ret;
5049

5150
pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
@@ -63,22 +62,23 @@ static int iproc_pcie_bcma_probe(struct bcma_device *bdev)
6362

6463
pcie->base_addr = bdev->addr;
6564

66-
res_mem.start = bdev->addr_s[0];
67-
res_mem.end = bdev->addr_s[0] + SZ_128M - 1;
68-
res_mem.name = "PCIe MEM space";
69-
res_mem.flags = IORESOURCE_MEM;
70-
pci_add_resource(&res, &res_mem);
65+
pcie->mem.start = bdev->addr_s[0];
66+
pcie->mem.end = bdev->addr_s[0] + SZ_128M - 1;
67+
pcie->mem.name = "PCIe MEM space";
68+
pcie->mem.flags = IORESOURCE_MEM;
69+
pci_add_resource(&resources, &pcie->mem);
7170

7271
pcie->map_irq = iproc_pcie_bcma_map_irq;
7372

74-
ret = iproc_pcie_setup(pcie, &res);
75-
if (ret)
73+
ret = iproc_pcie_setup(pcie, &resources);
74+
if (ret) {
7675
dev_err(dev, "PCIe controller setup failed\n");
77-
78-
pci_free_resource_list(&res);
76+
pci_free_resource_list(&resources);
77+
return ret;
78+
}
7979

8080
bcma_set_drvdata(bdev, pcie);
81-
return ret;
81+
return 0;
8282
}
8383

8484
static void iproc_pcie_bcma_remove(struct bcma_device *bdev)

drivers/pci/host/pcie-iproc-platform.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
5151
struct device_node *np = dev->of_node;
5252
struct resource reg;
5353
resource_size_t iobase = 0;
54-
LIST_HEAD(res);
54+
LIST_HEAD(resources);
5555
int ret;
5656

5757
pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
@@ -96,10 +96,10 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
9696
pcie->phy = NULL;
9797
}
9898

99-
ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &iobase);
99+
ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &resources,
100+
&iobase);
100101
if (ret) {
101-
dev_err(dev,
102-
"unable to get PCI host bridge resources\n");
102+
dev_err(dev, "unable to get PCI host bridge resources\n");
103103
return ret;
104104
}
105105

@@ -112,14 +112,15 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
112112
pcie->map_irq = of_irq_parse_and_map_pci;
113113
}
114114

115-
ret = iproc_pcie_setup(pcie, &res);
116-
if (ret)
115+
ret = iproc_pcie_setup(pcie, &resources);
116+
if (ret) {
117117
dev_err(dev, "PCIe controller setup failed\n");
118-
119-
pci_free_resource_list(&res);
118+
pci_free_resource_list(&resources);
119+
return ret;
120+
}
120121

121122
platform_set_drvdata(pdev, pcie);
122-
return ret;
123+
return 0;
123124
}
124125

125126
static int iproc_pcie_pltfm_remove(struct platform_device *pdev)

drivers/pci/host/pcie-iproc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ struct iproc_pcie {
9090
#ifdef CONFIG_ARM
9191
struct pci_sys_data sysdata;
9292
#endif
93+
struct resource mem;
9394
struct pci_bus *root_bus;
9495
struct phy *phy;
9596
int (*map_irq)(const struct pci_dev *, u8, u8);

0 commit comments

Comments
 (0)