The existing code uses bunch of hardcoded values from the PCI Bus Binding to IEEE Std 1275 spec; and it does so in quite non-obvious way.
This defines fields from the cell#0 of the "reg" property of a PCI device and uses them for parsing. This should cause no behavioral change. Signed-off-by: Alexey Kardashevskiy <a...@ozlabs.ru> --- arch/powerpc/kernel/pci_of_scan.c | 53 ++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 8078bce89bec..fc55ee710eb3 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -42,13 +42,50 @@ unsigned int pci_parse_of_flags(u32 addr0, int bridge) { unsigned int flags = 0; - if (addr0 & 0x02000000) { +/* + * PCI Bus Binding to IEEE Std 1275-1994 + * + * Bit# 33222222 22221111 11111100 00000000 + * 10987654 32109876 54321098 76543210 + * phys.hi cell: npt000ss bbbbbbbb dddddfff rrrrrrrr + * phys.mid cell: hhhhhhhh hhhhhhhh hhhhhhhh hhhhhhhh + * phys.lo cell: llllllll llllllll llllllll llllllll + * + * where: + * n is 0 if the address is relocatable, 1 otherwise + * p is 1 if the addressable region is "prefetchable", 0 otherwise + * t is 1 if the address is aliased (for non-relocatable I/O), + * below 1 MB (for Memory),or below 64 KB (for relocatable I/O). + * ss is the space code, denoting the address space + * bbbbbbbb is the 8-bit Bus Number + * ddddd is the 5-bit Device Number + * fff is the 3-bit Function Number + * rrrrrrrr is the 8-bit Register Number + */ +#define OF_PCI_ADDR0_SPACE_CODE(ss) (((ss)&0x3UL)<<24) +#define OF_PCI_ADDR0_SPACE_CFG OF_PCI_ADDR0_SPACE_CODE(0) +#define OF_PCI_ADDR0_SPACE_IO OF_PCI_ADDR0_SPACE_CODE(1) +#define OF_PCI_ADDR0_SPACE_MMIO32 OF_PCI_ADDR0_SPACE_CODE(2) +#define OF_PCI_ADDR0_SPACE_MMIO64 OF_PCI_ADDR0_SPACE_CODE(3) +#define OF_PCI_ADDR0_SPACE_MMIO (OF_PCI_ADDR0_SPACE_MMIO32 | \ + OF_PCI_ADDR0_SPACE_MMIO64) +#define OF_PCI_ADDR0_RELOC (1UL<<31) +#define OF_PCI_ADDR0_PREFETCH (1UL<<30) +#define OF_PCI_ADDR0_ALIAS (1UL<<29) +#define OF_PCI_ADDR0_BUS 0x00FF0000UL +#define OF_PCI_ADDR0_DEV 0x0000F800UL +#define OF_PCI_ADDR0_FN 0x00000700UL +#define OF_PCI_ADDR0_BARREG 0x000000FFUL + + if (addr0 & OF_PCI_ADDR0_SPACE_MMIO) { flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY; - flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64; - if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64) - flags |= IORESOURCE_MEM_64; - flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M; - if (addr0 & 0x40000000) + if ((addr0 & OF_PCI_ADDR0_SPACE_MMIO) == + OF_PCI_ADDR0_SPACE_MMIO64) + flags |= PCI_BASE_ADDRESS_MEM_TYPE_64 | + IORESOURCE_MEM_64; + if (addr0 & OF_PCI_ADDR0_ALIAS) + flags |= PCI_BASE_ADDRESS_MEM_TYPE_1M; + if (addr0 & OF_PCI_ADDR0_PREFETCH) flags |= IORESOURCE_PREFETCH | PCI_BASE_ADDRESS_MEM_PREFETCH; /* Note: We don't know whether the ROM has been left enabled @@ -56,9 +93,9 @@ unsigned int pci_parse_of_flags(u32 addr0, int bridge) * not set the IORESOURCE_ROM_ENABLE flag) for now rather than * do a config space read, it will be force-enabled if needed */ - if (!bridge && (addr0 & 0xff) == 0x30) + if (!bridge && (addr0 & OF_PCI_ADDR0_BARREG) == PCI_ROM_ADDRESS) flags |= IORESOURCE_READONLY; - } else if (addr0 & 0x01000000) + } else if (addr0 & OF_PCI_ADDR0_SPACE_IO) flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO; if (flags) flags |= IORESOURCE_SIZEALIGN; -- 2.17.1