--- zzzz-none-000/linux-3.10.107/arch/mips/ath79/pci.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/arch/mips/ath79/pci.c 2021-02-04 17:41:59.000000000 +0000 @@ -13,6 +13,7 @@ */ #include +#include #include #include #include @@ -22,10 +23,13 @@ #include "pci.h" static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev); -static const struct ath79_pci_irq *ath79_pci_irq_map __initdata; -static unsigned ath79_pci_nr_irqs __initdata; +static const struct ath79_pci_irq *ath79_pci_irq_map; +static unsigned int ath79_pci_nr_irqs; -static const struct ath79_pci_irq ar71xx_pci_irq_map[] __initconst = { +static unsigned long (*__ath79_pci_swizzle_b)(unsigned long port); +static unsigned long (*__ath79_pci_swizzle_w)(unsigned long port); + +static const struct ath79_pci_irq ar71xx_pci_irq_map[] = { { .slot = 17, .pin = 1, @@ -41,7 +45,7 @@ } }; -static const struct ath79_pci_irq ar724x_pci_irq_map[] __initconst = { +static const struct ath79_pci_irq ar724x_pci_irq_map[] = { { .slot = 0, .pin = 1, @@ -49,7 +53,16 @@ } }; -static const struct ath79_pci_irq qca955x_pci_irq_map[] __initconst = { +static const struct ath79_pci_irq qca953x_pci_irq_map[] = { + { + .bus = 0, + .slot = 0, + .pin = 1, + .irq = ATH79_PCI_IRQ(0), + }, +}; + +static const struct ath79_pci_irq qca955x_pci_irq_map[] = { { .bus = 0, .slot = 0, @@ -64,7 +77,37 @@ }, }; -int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) +static const struct ath79_pci_irq qca956x_pci_irq_map[] = { + { + .bus = 0, + .slot = 0, + .pin = 1, + .irq = ATH79_PCI_IRQ(0), + }, + { + .bus = 1, + .slot = 0, + .pin = 1, + .irq = ATH79_PCI_IRQ(1), + }, +}; + +static const struct ath79_pci_irq qcn550x_pci_irq_map[] = { + { + .bus = 0, + .slot = 0, + .pin = 1, + .irq = ATH79_PCI_IRQ(0), + }, + { + .bus = 1, + .slot = 0, + .pin = 1, + .irq = ATH79_PCI_IRQ(1), + }, +}; + +int pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) { int irq = -1; int i; @@ -79,9 +122,18 @@ soc_is_ar9344()) { ath79_pci_irq_map = ar724x_pci_irq_map; ath79_pci_nr_irqs = ARRAY_SIZE(ar724x_pci_irq_map); + } else if (soc_is_qca953x()) { + ath79_pci_irq_map = qca953x_pci_irq_map; + ath79_pci_nr_irqs = ARRAY_SIZE(qca953x_pci_irq_map); } else if (soc_is_qca955x()) { ath79_pci_irq_map = qca955x_pci_irq_map; ath79_pci_nr_irqs = ARRAY_SIZE(qca955x_pci_irq_map); + } else if (soc_is_qca956x()) { + ath79_pci_irq_map = qca956x_pci_irq_map; + ath79_pci_nr_irqs = ARRAY_SIZE(qca956x_pci_irq_map); + } else if (soc_is_qcn550x()) { + ath79_pci_irq_map = qcn550x_pci_irq_map; + ath79_pci_nr_irqs = ARRAY_SIZE(qcn550x_pci_irq_map); } else { pr_crit("pci %s: invalid irq map\n", pci_name((struct pci_dev *) dev)); @@ -198,7 +250,7 @@ res[3].end = mem_base + mem_size - 1; res[4].name = "io_base"; - res[4].flags = IORESOURCE_IO; + res[4].flags = IORESOURCE_MEM; res[4].start = io_base; res[4].end = io_base; @@ -212,12 +264,50 @@ return pdev; } +static inline bool ar71xx_is_pci_addr(unsigned long port) +{ + unsigned long phys = CPHYSADDR(port); + + return (phys >= AR71XX_PCI_MEM_BASE && + phys < AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE); +} + +static unsigned long ar71xx_pci_swizzle_b(unsigned long port) +{ + return ar71xx_is_pci_addr(port) ? port ^ 3 : port; +} + +static unsigned long ar71xx_pci_swizzle_w(unsigned long port) +{ + return ar71xx_is_pci_addr(port) ? port ^ 2 : port; +} + +unsigned long ath79_pci_swizzle_b(unsigned long port) +{ + if (__ath79_pci_swizzle_b) + return __ath79_pci_swizzle_b(port); + + return port; +} +EXPORT_SYMBOL(ath79_pci_swizzle_b); + +unsigned long ath79_pci_swizzle_w(unsigned long port) +{ + if (__ath79_pci_swizzle_w) + return __ath79_pci_swizzle_w(port); + + return port; +} +EXPORT_SYMBOL(ath79_pci_swizzle_w); + int __init ath79_register_pci(void) { struct platform_device *pdev = NULL; if (soc_is_ar71xx()) { pdev = ath79_register_pci_ar71xx(); + __ath79_pci_swizzle_b = ar71xx_pci_swizzle_b; + __ath79_pci_swizzle_w = ar71xx_pci_swizzle_w; } else if (soc_is_ar724x()) { pdev = ath79_register_pci_ar724x(-1, AR724X_PCI_CFG_BASE, @@ -243,6 +333,15 @@ AR724X_PCI_MEM_SIZE, 0, ATH79_IP2_IRQ(0)); + } else if (soc_is_qca9533()) { + pdev = ath79_register_pci_ar724x(0, + QCA953X_PCI_CFG_BASE0, + QCA953X_PCI_CTRL_BASE0, + QCA953X_PCI_CRP_BASE0, + QCA953X_PCI_MEM_BASE0, + QCA953X_PCI_MEM_SIZE, + 0, + ATH79_IP2_IRQ(0)); } else if (soc_is_qca9558()) { pdev = ath79_register_pci_ar724x(0, QCA955X_PCI_CFG_BASE0, @@ -261,6 +360,24 @@ QCA955X_PCI_MEM_SIZE, 1, ATH79_IP3_IRQ(2)); + } else if (soc_is_qca956x()) { + pdev = ath79_register_pci_ar724x(0, + QCA956X_PCI_CFG_BASE1, + QCA956X_PCI_CTRL_BASE1, + QCA956X_PCI_CRP_BASE1, + QCA956X_PCI_MEM_BASE1, + QCA956X_PCI_MEM_SIZE, + 1, + ATH79_IP3_IRQ(2)); + } else if (soc_is_qcn550x()) { + pdev = ath79_register_pci_ar724x(0, + QCN550X_PCI_CFG_BASE1, + QCN550X_PCI_CTRL_BASE1, + QCN550X_PCI_CRP_BASE1, + QCN550X_PCI_MEM_BASE1, + QCN550X_PCI_MEM_SIZE, + 1, + ATH79_IP3_IRQ(2)); } else { /* No PCI support */ return -ENODEV;