--- zzzz-none-000/linux-3.10.107/arch/powerpc/platforms/powermac/pci.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/arch/powerpc/platforms/powermac/pci.c 2021-02-04 17:41:59.000000000 +0000 @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -28,6 +27,8 @@ #include #include +#include "pmac.h" + #undef DEBUG #ifdef DEBUG @@ -134,17 +135,23 @@ |(((unsigned int)(off)) & 0xFCUL) \ |1UL) -static volatile void __iomem *macrisc_cfg_access(struct pci_controller* hose, - u8 bus, u8 dev_fn, u8 offset) +static void __iomem *macrisc_cfg_map_bus(struct pci_bus *bus, + unsigned int dev_fn, + int offset) { unsigned int caddr; + struct pci_controller *hose; - if (bus == hose->first_busno) { + hose = pci_bus_to_host(bus); + if (hose == NULL) + return NULL; + + if (bus->number == hose->first_busno) { if (dev_fn < (11 << 3)) return NULL; caddr = MACRISC_CFA0(dev_fn, offset); } else - caddr = MACRISC_CFA1(bus, dev_fn, offset); + caddr = MACRISC_CFA1(bus->number, dev_fn, offset); /* Uninorth will return garbage if we don't read back the value ! */ do { @@ -155,129 +162,46 @@ return hose->cfg_data + offset; } -static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 *val) -{ - struct pci_controller *hose; - volatile void __iomem *addr; - - hose = pci_bus_to_host(bus); - if (hose == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset >= 0x100) - return PCIBIOS_BAD_REGISTER_NUMBER; - addr = macrisc_cfg_access(hose, bus->number, devfn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - switch (len) { - case 1: - *val = in_8(addr); - break; - case 2: - *val = in_le16(addr); - break; - default: - *val = in_le32(addr); - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 val) -{ - struct pci_controller *hose; - volatile void __iomem *addr; - - hose = pci_bus_to_host(bus); - if (hose == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset >= 0x100) - return PCIBIOS_BAD_REGISTER_NUMBER; - addr = macrisc_cfg_access(hose, bus->number, devfn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - switch (len) { - case 1: - out_8(addr, val); - break; - case 2: - out_le16(addr, val); - break; - default: - out_le32(addr, val); - break; - } - return PCIBIOS_SUCCESSFUL; -} - static struct pci_ops macrisc_pci_ops = { - .read = macrisc_read_config, - .write = macrisc_write_config, + .map_bus = macrisc_cfg_map_bus, + .read = pci_generic_config_read, + .write = pci_generic_config_write, }; #ifdef CONFIG_PPC32 /* * Verify that a specific (bus, dev_fn) exists on chaos */ -static int chaos_validate_dev(struct pci_bus *bus, int devfn, int offset) +static void __iomem *chaos_map_bus(struct pci_bus *bus, unsigned int devfn, + int offset) { struct device_node *np; const u32 *vendor, *device; if (offset >= 0x100) - return PCIBIOS_BAD_REGISTER_NUMBER; + return NULL; np = of_pci_find_child_device(bus->dev.of_node, devfn); if (np == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; + return NULL; vendor = of_get_property(np, "vendor-id", NULL); device = of_get_property(np, "device-id", NULL); if (vendor == NULL || device == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; + return NULL; if ((*vendor == 0x106b) && (*device == 3) && (offset >= 0x10) && (offset != 0x14) && (offset != 0x18) && (offset <= 0x24)) - return PCIBIOS_BAD_REGISTER_NUMBER; + return NULL; - return PCIBIOS_SUCCESSFUL; -} - -static int -chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset, - int len, u32 *val) -{ - int result = chaos_validate_dev(bus, devfn, offset); - if (result == PCIBIOS_BAD_REGISTER_NUMBER) - *val = ~0U; - if (result != PCIBIOS_SUCCESSFUL) - return result; - return macrisc_read_config(bus, devfn, offset, len, val); -} - -static int -chaos_write_config(struct pci_bus *bus, unsigned int devfn, int offset, - int len, u32 val) -{ - int result = chaos_validate_dev(bus, devfn, offset); - if (result != PCIBIOS_SUCCESSFUL) - return result; - return macrisc_write_config(bus, devfn, offset, len, val); + return macrisc_cfg_map_bus(bus, devfn, offset); } static struct pci_ops chaos_pci_ops = { - .read = chaos_read_config, - .write = chaos_write_config, + .map_bus = chaos_map_bus, + .read = pci_generic_config_read, + .write = pci_generic_config_write, }; static void __init setup_chaos(struct pci_controller *hose, @@ -472,15 +396,24 @@ |(((unsigned int)(off)) & 0xfcU) \ |1UL) -static volatile void __iomem *u4_pcie_cfg_access(struct pci_controller* hose, - u8 bus, u8 dev_fn, int offset) +static void __iomem *u4_pcie_cfg_map_bus(struct pci_bus *bus, + unsigned int dev_fn, + int offset) { + struct pci_controller *hose; unsigned int caddr; - if (bus == hose->first_busno) { + if (offset >= 0x1000) + return NULL; + + hose = pci_bus_to_host(bus); + if (!hose) + return NULL; + + if (bus->number == hose->first_busno) { caddr = U4_PCIE_CFA0(dev_fn, offset); } else - caddr = U4_PCIE_CFA1(bus, dev_fn, offset); + caddr = U4_PCIE_CFA1(bus->number, dev_fn, offset); /* Uninorth will return garbage if we don't read back the value ! */ do { @@ -491,74 +424,11 @@ return hose->cfg_data + offset; } -static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 *val) -{ - struct pci_controller *hose; - volatile void __iomem *addr; - - hose = pci_bus_to_host(bus); - if (hose == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset >= 0x1000) - return PCIBIOS_BAD_REGISTER_NUMBER; - addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - switch (len) { - case 1: - *val = in_8(addr); - break; - case 2: - *val = in_le16(addr); - break; - default: - *val = in_le32(addr); - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static int u4_pcie_write_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 val) -{ - struct pci_controller *hose; - volatile void __iomem *addr; - - hose = pci_bus_to_host(bus); - if (hose == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset >= 0x1000) - return PCIBIOS_BAD_REGISTER_NUMBER; - addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - switch (len) { - case 1: - out_8(addr, val); - break; - case 2: - out_le16(addr, val); - break; - default: - out_le32(addr, val); - break; - } - return PCIBIOS_SUCCESSFUL; -} - static struct pci_ops u4_pcie_pci_ops = { - .read = u4_pcie_read_config, - .write = u4_pcie_write_config, + .map_bus = u4_pcie_cfg_map_bus, + .read = pci_generic_config_read, + .write = pci_generic_config_write, }; static void pmac_pci_fixup_u4_of_node(struct pci_dev *dev) @@ -698,7 +568,7 @@ { struct device_node *nec; - for (nec = NULL; (nec = of_find_node_by_name(nec, "usb")) != NULL;) { + for_each_node_by_name(nec, "usb") { struct pci_controller *hose; u32 data; const u32 *prop; @@ -930,6 +800,7 @@ return -ENOMEM; hose->first_busno = bus_range ? bus_range[0] : 0; hose->last_busno = bus_range ? bus_range[1] : 0xff; + hose->controller_ops = pmac_pci_controller_ops; disp_name = NULL; @@ -1074,7 +945,7 @@ } #ifdef CONFIG_PPC32 -int pmac_pci_enable_device_hook(struct pci_dev *dev) +static bool pmac_pci_enable_device_hook(struct pci_dev *dev) { struct device_node* node; int updatecfg = 0; @@ -1090,11 +961,11 @@ && !node) { printk(KERN_INFO "Apple USB OHCI %s disabled by firmware\n", pci_name(dev)); - return -EINVAL; + return false; } if (!node) - return 0; + return true; uninorth_child = node->parent && of_device_is_compatible(node->parent, "uni-north"); @@ -1135,7 +1006,7 @@ L1_CACHE_BYTES >> 2); } - return 0; + return true; } void pmac_pci_fixup_ohci(struct pci_dev *dev) @@ -1355,3 +1226,30 @@ pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0); } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_U4_PCIE, fixup_u4_pcie); + +#ifdef CONFIG_PPC64 +static int pmac_pci_probe_mode(struct pci_bus *bus) +{ + struct device_node *node = pci_bus_to_OF_node(bus); + + /* We need to use normal PCI probing for the AGP bus, + * since the device for the AGP bridge isn't in the tree. + * Same for the PCIe host on U4 and the HT host bridge. + */ + if (bus->self == NULL && (of_device_is_compatible(node, "u3-agp") || + of_device_is_compatible(node, "u4-pcie") || + of_device_is_compatible(node, "u3-ht"))) + return PCI_PROBE_NORMAL; + return PCI_PROBE_DEVTREE; +} +#endif /* CONFIG_PPC64 */ + +struct pci_controller_ops pmac_pci_controller_ops = { +#ifdef CONFIG_PPC64 + .probe_mode = pmac_pci_probe_mode, +#endif +#ifdef CONFIG_PPC32 + .enable_device_hook = pmac_pci_enable_device_hook, +#endif +}; +