Message ID | 20190220094841.11129-3-thomas.petazzoni@bootlin.com (mailing list archive) |
---|---|
State | New, archived |
Delegated to: | Bjorn Helgaas |
Headers | show |
Series | PCI: fix pci-mvebu after conversion to common bridge emul code | expand |
Tested patch against Vanilla kernels 4.20.11 and 5.0-rc7. It is working properly on both kernels. Tested-by: Luis Mendes <luis.p.mendes@gmail.com> On Wed, Feb 20, 2019 at 9:48 AM Thomas Petazzoni <thomas.petazzoni@bootlin.com> wrote: > > 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, this commit extends 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. > > Reported-by: Luís Mendes <luis.p.mendes@gmail.com> > Reported-by: Leigh Brown <leigh@solinno.co.uk> > Cc: Luís Mendes <luis.p.mendes@gmail.com> > Cc: Leigh Brown <leigh@solinno.co.uk> > Fixes: 1f08673eef123 ("PCI: mvebu: Convert to PCI emulated bridge config space") > Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com> > --- > drivers/pci/controller/pci-aardvark.c | 2 +- > drivers/pci/controller/pci-mvebu.c | 2 +- > drivers/pci/pci-bridge-emul.c | 8 +++++++- > drivers/pci/pci-bridge-emul.h | 7 ++++++- > 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) bridge->data = pcie; bridge->ops = &advk_pci_bridge_emul_ops; - pci_bridge_emul_init(bridge); + pci_bridge_emul_init(bridge, 0); } 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) bridge->data = port; bridge->ops = &mvebu_pci_bridge_emul_ops; - pci_bridge_emul_init(bridge); + pci_bridge_emul_init(bridge, PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR); } static 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[] = { * (typically at least vendor, device, revision), the ->ops pointer, * and optionally ->data and ->has_pcie. */ -int pci_bridge_emul_init(struct pci_bridge_emul *bridge) +int pci_bridge_emul_init(struct pci_bridge_emul *bridge, + unsigned int flags) { bridge->conf.class_revision |= PCI_CLASS_BRIDGE_PCI << 16; bridge->conf.header_type = PCI_HEADER_TYPE_BRIDGE; @@ -295,6 +296,11 @@ int pci_bridge_emul_init(struct pci_bridge_emul *bridge) } } + if (flags & PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR) { + bridge->pci_regs_behavior[PCI_PREF_MEMORY_BASE / 4].ro = ~0; + bridge->pci_regs_behavior[PCI_PREF_MEMORY_BASE / 4].rw = 0; + } + return 0; } 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 { bool has_pcie; }; -int pci_bridge_emul_init(struct pci_bridge_emul *bridge); +enum { + PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR = BIT(0), +}; + +int pci_bridge_emul_init(struct pci_bridge_emul *bridge, + unsigned int flags); void pci_bridge_emul_cleanup(struct pci_bridge_emul *bridge); int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where,
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, this commit extends 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. Reported-by: Luís Mendes <luis.p.mendes@gmail.com> Reported-by: Leigh Brown <leigh@solinno.co.uk> Cc: Luís Mendes <luis.p.mendes@gmail.com> Cc: Leigh Brown <leigh@solinno.co.uk> Fixes: 1f08673eef123 ("PCI: mvebu: Convert to PCI emulated bridge config space") Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com> --- drivers/pci/controller/pci-aardvark.c | 2 +- drivers/pci/controller/pci-mvebu.c | 2 +- drivers/pci/pci-bridge-emul.c | 8 +++++++- drivers/pci/pci-bridge-emul.h | 7 ++++++- 4 files changed, 15 insertions(+), 4 deletions(-)