static int config_access(int devfn, int where, int size, u32 *ptr, bool write) { unsigned long flags; int func = PCI_FUNC(devfn); int dev = PCI_SLOT(devfn); u32 value = 0; int err = 0; u32 addr; if (((dev != 0) && (dev != 3)) || (func > 2)) return PCIBIOS_DEVICE_NOT_FOUND; /* Select Configuration access */ local_irq_save(flags); ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, 0, AR2315_PCIMISC_CFG_SEL); mb(); addr = (u32) configspace + (1 << (13 + dev)) + (func << 8) + where; if (size == 1) addr ^= 0x3; else if (size == 2) addr ^= 0x2; if (write) { value = *ptr; if (size == 1) err = put_dbe(value, (u8 *) addr); else if (size == 2) err = put_dbe(value, (u16 *) addr); else if (size == 4) err = put_dbe(value, (u32 *) addr); } else { if (size == 1) err = get_dbe(value, (u8 *) addr); else if (size == 2) err = get_dbe(value, (u16 *) addr); else if (size == 4) err = get_dbe(value, (u32 *) addr); if (err) *ptr = 0xffffffff; else *ptr = value; } /* Select Memory access */ ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, AR2315_PCIMISC_CFG_SEL, 0); local_irq_restore(flags); return (err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL); }
static int amazon_pci_config_access(unsigned char access_type, struct pci_bus *bus, unsigned int devfn, unsigned int where, u32 *data) { unsigned long flags; u32 pci_addr; u32 val; int ret; /* Amazon support slot from 0 to 15 */ /* devfn 0 & 0x20 is itself */ if ((bus->number != 0) || (devfn > 0x7f) || (devfn == 0) || (devfn == 0x20)) return 1; local_irq_save(flags); pci_addr = AMAZON_PCI_CFG_BASE | bus->number << AMAZON_PCI_CFG_BUSNUM_SHF | devfn << AMAZON_PCI_CFG_FUNNUM_SHF | (where & ~0x3); if (access_type == PCI_ACCESS_WRITE) { #ifdef CONFIG_SWAP_IO_SPACE val = swab32(*data); #endif ret = put_dbe(val, (u32 *)pci_addr); } else { ret = get_dbe(val, (u32 *)pci_addr); #ifdef CONFIG_SWAP_IO_SPACE *data = swab32(val); #else *data = val; #endif } amazon_writel(amazon_readl(PCI_MODE) & (~(1<<PCI_MODE_cfgok_bit)), PCI_MODE); amazon_writel(amazon_readl(STATUS_COMMAND_ADDR), STATUS_COMMAND_ADDR); amazon_writel(amazon_readl(PCI_MODE) | (~(1<<PCI_MODE_cfgok_bit)), PCI_MODE); mb(); local_irq_restore(flags); if (((*data) == 0xffffffff) && (access_type == PCI_ACCESS_READ)) return 1; return ret; }