aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorThomas Petazzoni <thomas.petazzoni@bootlin.com>2019-02-20 04:48:41 -0500
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2019-02-22 05:51:14 -0500
commit33776d059630e5045ea9ccf756c74de8f9cc86de (patch)
tree72e9013567363a1e8473693b7573b1686951d7d8 /drivers/pci
parent59f81c35e0df840f7112cb296dde48df84a67c79 (diff)
PCI: pci-bridge-emul: Extend pci_bridge_emul_init() with flags
Depending on the capabilities of the PCI controller/platform, the PCI-to-PCI bridge emulation behavior might need to be different. For example, on platforms that use the pci-mvebu code, we currently don't support prefetchable memory BARs, so the corresponding fields in the PCI-to-PCI bridge configuration space should be read-only. To implement this, extend pci_bridge_emul_init() to take a "flags" argument, with currently one flag supported: PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR that will make the prefetchable memory base and limit registers read-only. The pci-mvebu and pci-aardvark drivers are updated accordingly. Fixes: 1f08673eef123 ("PCI: mvebu: Convert to PCI emulated bridge config space") Reported-by: Luís Mendes <luis.p.mendes@gmail.com> Reported-by: Leigh Brown <leigh@solinno.co.uk> Tested-by: Leigh Brown <leigh@solinno.co.uk> Tested-by: Luis Mendes <luis.p.mendes@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Cc: stable@vger.kernel.org Cc: Luís Mendes <luis.p.mendes@gmail.com> Cc: Leigh Brown <leigh@solinno.co.uk>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/controller/pci-aardvark.c2
-rw-r--r--drivers/pci/controller/pci-mvebu.c2
-rw-r--r--drivers/pci/pci-bridge-emul.c8
-rw-r--r--drivers/pci/pci-bridge-emul.h7
4 files changed, 15 insertions, 4 deletions
diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 750081c1cb48..6eecae447af3 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -499,7 +499,7 @@ static void advk_sw_pci_bridge_init(struct advk_pcie *pcie)
499 bridge->data = pcie; 499 bridge->data = pcie;
500 bridge->ops = &advk_pci_bridge_emul_ops; 500 bridge->ops = &advk_pci_bridge_emul_ops;
501 501
502 pci_bridge_emul_init(bridge); 502 pci_bridge_emul_init(bridge, 0);
503 503
504} 504}
505 505
diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index fa0fc46edb0c..d3a0419e42f2 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -583,7 +583,7 @@ static void mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
583 bridge->data = port; 583 bridge->data = port;
584 bridge->ops = &mvebu_pci_bridge_emul_ops; 584 bridge->ops = &mvebu_pci_bridge_emul_ops;
585 585
586 pci_bridge_emul_init(bridge); 586 pci_bridge_emul_init(bridge, PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR);
587} 587}
588 588
589static inline struct mvebu_pcie *sys_to_pcie(struct pci_sys_data *sys) 589static inline struct mvebu_pcie *sys_to_pcie(struct pci_sys_data *sys)
diff --git a/drivers/pci/pci-bridge-emul.c b/drivers/pci/pci-bridge-emul.c
index dd8d8060317e..83fb077d0b41 100644
--- a/drivers/pci/pci-bridge-emul.c
+++ b/drivers/pci/pci-bridge-emul.c
@@ -267,7 +267,8 @@ const static struct pci_bridge_reg_behavior pcie_cap_regs_behavior[] = {
267 * (typically at least vendor, device, revision), the ->ops pointer, 267 * (typically at least vendor, device, revision), the ->ops pointer,
268 * and optionally ->data and ->has_pcie. 268 * and optionally ->data and ->has_pcie.
269 */ 269 */
270int pci_bridge_emul_init(struct pci_bridge_emul *bridge) 270int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
271 unsigned int flags)
271{ 272{
272 bridge->conf.class_revision |= PCI_CLASS_BRIDGE_PCI << 16; 273 bridge->conf.class_revision |= PCI_CLASS_BRIDGE_PCI << 16;
273 bridge->conf.header_type = PCI_HEADER_TYPE_BRIDGE; 274 bridge->conf.header_type = PCI_HEADER_TYPE_BRIDGE;
@@ -295,6 +296,11 @@ int pci_bridge_emul_init(struct pci_bridge_emul *bridge)
295 } 296 }
296 } 297 }
297 298
299 if (flags & PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR) {
300 bridge->pci_regs_behavior[PCI_PREF_MEMORY_BASE / 4].ro = ~0;
301 bridge->pci_regs_behavior[PCI_PREF_MEMORY_BASE / 4].rw = 0;
302 }
303
298 return 0; 304 return 0;
299} 305}
300 306
diff --git a/drivers/pci/pci-bridge-emul.h b/drivers/pci/pci-bridge-emul.h
index f04637bb3222..e65b1b79899d 100644
--- a/drivers/pci/pci-bridge-emul.h
+++ b/drivers/pci/pci-bridge-emul.h
@@ -119,7 +119,12 @@ struct pci_bridge_emul {
119 bool has_pcie; 119 bool has_pcie;
120}; 120};
121 121
122int pci_bridge_emul_init(struct pci_bridge_emul *bridge); 122enum {
123 PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR = BIT(0),
124};
125
126int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
127 unsigned int flags);
123void pci_bridge_emul_cleanup(struct pci_bridge_emul *bridge); 128void pci_bridge_emul_cleanup(struct pci_bridge_emul *bridge);
124 129
125int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where, 130int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where,