On Mon, Apr 11, 2016 at 04:29:32PM -0700, David Daney wrote: > From: David Daney <david.daney@xxxxxxxxxx> > > The 32-bit addressing modes in the I/O and Prefetchable Memory > registers are required to be read-only. Since the underlying access > method allows them to be set, we must emulate their read-only nature > and always set them. > > Signed-off-by: David Daney <david.daney@xxxxxxxxxx> Applied to pci/host-thunder for v4.7, thanks, David! > --- > drivers/pci/host/pci-thunder-pem.c | 42 ++++++++++++++++++++++++++++++-------- > 1 file changed, 34 insertions(+), 8 deletions(-) > > diff --git a/drivers/pci/host/pci-thunder-pem.c b/drivers/pci/host/pci-thunder-pem.c > index cabb92a..196adf6 100644 > --- a/drivers/pci/host/pci-thunder-pem.c > +++ b/drivers/pci/host/pci-thunder-pem.c > @@ -153,11 +153,11 @@ static int thunder_pem_config_read(struct pci_bus *bus, unsigned int devfn, > * reserved bits, this makes the code simpler and is OK as the bits > * are not affected by writing zeros to them. > */ > -static u32 thunder_pem_bridge_w1c_bits(int where) > +static u32 thunder_pem_bridge_w1c_bits(u64 where_aligned) > { > u32 w1c_bits = 0; > > - switch (where & ~3) { > + switch (where_aligned) { > case 0x04: /* Command/Status */ > case 0x1c: /* Base and I/O Limit/Secondary Status */ > w1c_bits = 0xff000000; > @@ -184,12 +184,34 @@ static u32 thunder_pem_bridge_w1c_bits(int where) > return w1c_bits; > } > > +/* Some bits must be written to one so they appear to be read-only. */ > +static u32 thunder_pem_bridge_w1_bits(u64 where_aligned) > +{ > + u32 w1_bits; > + > + switch (where_aligned) { > + case 0x1c: /* I/O Base / I/O Limit, Secondary Status*/ > + /* Force 32-bit I/O addressing. */ > + w1_bits = 0x0101; > + break; > + case 0x24: /* Prefetchable Memory Base / Prefetchable Memory Limit */ > + /* Force 64-bit addressing */ > + w1_bits = 0x00010001; > + break; > + default: > + w1_bits = 0; > + break; > + } > + return w1_bits; > +} > + > static int thunder_pem_bridge_write(struct pci_bus *bus, unsigned int devfn, > int where, int size, u32 val) > { > struct gen_pci *pci = bus->sysdata; > struct thunder_pem_pci *pem_pci; > u64 write_val, read_val; > + u64 where_aligned = where & ~3ull; > u32 mask = 0; > > pem_pci = container_of(pci, struct thunder_pem_pci, gen_pci); > @@ -205,8 +227,7 @@ static int thunder_pem_bridge_write(struct pci_bus *bus, unsigned int devfn, > */ > switch (size) { > case 1: > - read_val = where & ~3ull; > - writeq(read_val, pem_pci->pem_reg_base + PEM_CFG_RD); > + writeq(where_aligned, pem_pci->pem_reg_base + PEM_CFG_RD); > read_val = readq(pem_pci->pem_reg_base + PEM_CFG_RD); > read_val >>= 32; > mask = ~(0xff << (8 * (where & 3))); > @@ -215,8 +236,7 @@ static int thunder_pem_bridge_write(struct pci_bus *bus, unsigned int devfn, > val |= (u32)read_val; > break; > case 2: > - read_val = where & ~3ull; > - writeq(read_val, pem_pci->pem_reg_base + PEM_CFG_RD); > + writeq(where_aligned, pem_pci->pem_reg_base + PEM_CFG_RD); > read_val = readq(pem_pci->pem_reg_base + PEM_CFG_RD); > read_val >>= 32; > mask = ~(0xffff << (8 * (where & 3))); > @@ -244,11 +264,17 @@ static int thunder_pem_bridge_write(struct pci_bus *bus, unsigned int devfn, > } > > /* > + * Some bits must be read-only with value of one. Since the > + * access method allows these to be cleared if a zero is > + * written, force them to one before writing. > + */ > + val |= thunder_pem_bridge_w1_bits(where_aligned); > + > + /* > * Low order bits are the config address, the high order 32 > * bits are the data to be written. > */ > - write_val = where & ~3ull; > - write_val |= (((u64)val) << 32); > + write_val = (((u64)val) << 32) | where_aligned; > writeq(write_val, pem_pci->pem_reg_base + PEM_CFG_WR); > return PCIBIOS_SUCCESSFUL; > } > -- > 1.8.3.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-pci" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html