bcma: don't map/unmap a subset of the PCI config space
For PCI config space access offsets < 256 for device '0', bcma_extpci_write_config performs an 'ioremap_nocache' on a 4 byte section of the PCI config space (an area that has already previously been mapped), and then subsequently unmaps that 4 byte section. This can't be a good thing for future read access from that now unmapped location. Modify the config space writes to use the existing access functions (similar to how it is done for the reads). Signed-off-by: Nathan Hintz <nlhintz@hotmail.com> Acked-by: Hauke Mehrtens <hauke@hauke-m.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
a35ab937cb
commit
447d7e25be
|
@ -149,7 +149,7 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
|
||||||
const void *buf, int len)
|
const void *buf, int len)
|
||||||
{
|
{
|
||||||
int err = -EINVAL;
|
int err = -EINVAL;
|
||||||
u32 addr = 0, val = 0;
|
u32 addr, val;
|
||||||
void __iomem *mmio = 0;
|
void __iomem *mmio = 0;
|
||||||
u16 chipid = pc->core->bus->chipinfo.id;
|
u16 chipid = pc->core->bus->chipinfo.id;
|
||||||
|
|
||||||
|
@ -165,12 +165,10 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
|
||||||
* requires indirect access.
|
* requires indirect access.
|
||||||
*/
|
*/
|
||||||
if (off < PCI_CONFIG_SPACE_SIZE) {
|
if (off < PCI_CONFIG_SPACE_SIZE) {
|
||||||
addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0;
|
addr = BCMA_CORE_PCI_PCICFG0;
|
||||||
addr |= (func << 8);
|
addr |= (func << 8);
|
||||||
addr |= (off & 0xfc);
|
addr |= (off & 0xfc);
|
||||||
mmio = ioremap_nocache(addr, sizeof(val));
|
val = pcicore_read32(pc, addr);
|
||||||
if (!mmio)
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
addr = bcma_get_cfgspace_addr(pc, dev, func, off);
|
addr = bcma_get_cfgspace_addr(pc, dev, func, off);
|
||||||
|
@ -189,12 +187,10 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
|
||||||
|
|
||||||
switch (len) {
|
switch (len) {
|
||||||
case 1:
|
case 1:
|
||||||
val = readl(mmio);
|
|
||||||
val &= ~(0xFF << (8 * (off & 3)));
|
val &= ~(0xFF << (8 * (off & 3)));
|
||||||
val |= *((const u8 *)buf) << (8 * (off & 3));
|
val |= *((const u8 *)buf) << (8 * (off & 3));
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
val = readl(mmio);
|
|
||||||
val &= ~(0xFFFF << (8 * (off & 3)));
|
val &= ~(0xFFFF << (8 * (off & 3)));
|
||||||
val |= *((const u16 *)buf) << (8 * (off & 3));
|
val |= *((const u16 *)buf) << (8 * (off & 3));
|
||||||
break;
|
break;
|
||||||
|
@ -202,13 +198,17 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
|
||||||
val = *((const u32 *)buf);
|
val = *((const u32 *)buf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (dev == 0 && !addr) {
|
if (dev == 0) {
|
||||||
/* accesses to config registers with offsets >= 256
|
/* accesses to config registers with offsets >= 256
|
||||||
* requires indirect access.
|
* requires indirect access.
|
||||||
*/
|
*/
|
||||||
addr = (func << 12);
|
if (off >= PCI_CONFIG_SPACE_SIZE) {
|
||||||
addr |= (off & 0x0FFF);
|
addr = (func << 12);
|
||||||
bcma_pcie_write_config(pc, addr, val);
|
addr |= (off & 0x0FFF);
|
||||||
|
bcma_pcie_write_config(pc, addr, val);
|
||||||
|
} else {
|
||||||
|
pcicore_write32(pc, addr, val);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
writel(val, mmio);
|
writel(val, mmio);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue