From 9fc1ca5b73a82daedffa2d1d5daa48dd2093c39a Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Sat, 2 Feb 2013 11:44:24 +0000 Subject: MIPS: ath79: register platform devices for the PCI controllers The pci-ar71xx and pci-ar724x drivers were converted into platform drivers. Register the corresponding platform devices for the PCI controllers instead of using the ar7{1x,24}x_pcibios_init functions. Signed-off-by: Gabor Juhos Patchwork: http://patchwork.linux-mips.org/patch/4908/ Signed-off-by: John Crispin --- arch/mips/ath79/pci.c | 87 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 9 deletions(-) (limited to 'arch/mips/ath79/pci.c') diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c index ca83abd9d31e..81ef5797944a 100644 --- a/arch/mips/ath79/pci.c +++ b/arch/mips/ath79/pci.c @@ -14,6 +14,8 @@ #include #include +#include +#include #include #include #include @@ -110,21 +112,88 @@ void __init ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev)) ath79_pci_plat_dev_init = func; } -int __init ath79_register_pci(void) +static struct platform_device * +ath79_register_pci_ar71xx(void) +{ + struct platform_device *pdev; + struct resource res[2]; + + memset(res, 0, sizeof(res)); + + res[0].name = "cfg_base"; + res[0].flags = IORESOURCE_MEM; + res[0].start = AR71XX_PCI_CFG_BASE; + res[0].end = AR71XX_PCI_CFG_BASE + AR71XX_PCI_CFG_SIZE - 1; + + res[1].flags = IORESOURCE_IRQ; + res[1].start = ATH79_CPU_IRQ_IP2; + res[1].end = ATH79_CPU_IRQ_IP2; + + pdev = platform_device_register_simple("ar71xx-pci", -1, + res, ARRAY_SIZE(res)); + return pdev; +} + +static struct platform_device * +ath79_register_pci_ar724x(int id, + unsigned long cfg_base, + unsigned long ctrl_base, + int irq) { - if (soc_is_ar71xx()) - return ar71xx_pcibios_init(); + struct platform_device *pdev; + struct resource res[3]; - if (soc_is_ar724x()) - return ar724x_pcibios_init(ATH79_CPU_IRQ_IP2); + memset(res, 0, sizeof(res)); - if (soc_is_ar9342() || soc_is_ar9344()) { + res[0].name = "cfg_base"; + res[0].flags = IORESOURCE_MEM; + res[0].start = cfg_base; + res[0].end = cfg_base + AR724X_PCI_CFG_SIZE - 1; + + res[1].name = "ctrl_base"; + res[1].flags = IORESOURCE_MEM; + res[1].start = ctrl_base; + res[1].end = ctrl_base + AR724X_PCI_CTRL_SIZE - 1; + + res[2].flags = IORESOURCE_IRQ; + res[2].start = irq; + res[2].end = irq; + + pdev = platform_device_register_simple("ar724x-pci", id, + res, ARRAY_SIZE(res)); + return pdev; +} + +int __init ath79_register_pci(void) +{ + struct platform_device *pdev = NULL; + + if (soc_is_ar71xx()) { + pdev = ath79_register_pci_ar71xx(); + } else if (soc_is_ar724x()) { + pdev = ath79_register_pci_ar724x(-1, + AR724X_PCI_CFG_BASE, + AR724X_PCI_CTRL_BASE, + ATH79_CPU_IRQ_IP2); + } else if (soc_is_ar9342() || + soc_is_ar9344()) { u32 bootstrap; bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); - if (bootstrap & AR934X_BOOTSTRAP_PCIE_RC) - return ar724x_pcibios_init(ATH79_IP2_IRQ(0)); + if ((bootstrap & AR934X_BOOTSTRAP_PCIE_RC) == 0) + return -ENODEV; + + pdev = ath79_register_pci_ar724x(-1, + AR724X_PCI_CFG_BASE, + AR724X_PCI_CTRL_BASE, + ATH79_IP2_IRQ(0)); + } else { + /* No PCI support */ + return -ENODEV; } - return -ENODEV; + if (!pdev) + pr_err("unable to register PCI controller device\n"); + + return pdev ? 0 : -ENODEV; } -- cgit v1.2.3 From 6e783865b4e60f2ecf7708f8ea24db5c5ea07ced Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Mon, 4 Feb 2013 11:58:49 +0100 Subject: MIPS: ath79: remove unused ar7{1x,24}x_pcibios_init functions The functions are unused now, so remove them. Signed-off-by: Gabor Juhos Patchwork: http://patchwork.linux-mips.org/patch/4909/ Signed-off-by: John Crispin --- arch/mips/ath79/pci.c | 1 - arch/mips/include/asm/mach-ath79/pci.h | 28 ---------------------------- arch/mips/pci/pci-ar71xx.c | 26 -------------------------- arch/mips/pci/pci-ar724x.c | 32 -------------------------------- 4 files changed, 87 deletions(-) delete mode 100644 arch/mips/include/asm/mach-ath79/pci.h (limited to 'arch/mips/ath79/pci.c') diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c index 81ef5797944a..c94bcec169ab 100644 --- a/arch/mips/ath79/pci.c +++ b/arch/mips/ath79/pci.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "pci.h" static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev); diff --git a/arch/mips/include/asm/mach-ath79/pci.h b/arch/mips/include/asm/mach-ath79/pci.h deleted file mode 100644 index 7868f7fa028f..000000000000 --- a/arch/mips/include/asm/mach-ath79/pci.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Atheros AR71XX/AR724X PCI support - * - * Copyright (C) 2011 René Bolldorf - * Copyright (C) 2008-2011 Gabor Juhos - * Copyright (C) 2008 Imre Kaloz - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - */ - -#ifndef __ASM_MACH_ATH79_PCI_H -#define __ASM_MACH_ATH79_PCI_H - -#if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR71XX) -int ar71xx_pcibios_init(void); -#else -static inline int ar71xx_pcibios_init(void) { return 0; } -#endif - -#if defined(CONFIG_PCI_AR724X) -int ar724x_pcibios_init(int irq); -#else -static inline int ar724x_pcibios_init(int irq) { return 0; } -#endif - -#endif /* __ASM_MACH_ATH79_PCI_H */ diff --git a/arch/mips/pci/pci-ar71xx.c b/arch/mips/pci/pci-ar71xx.c index 35ee23450d87..69e0bb47de08 100644 --- a/arch/mips/pci/pci-ar71xx.c +++ b/arch/mips/pci/pci-ar71xx.c @@ -23,7 +23,6 @@ #include #include -#include #define AR71XX_PCI_REG_CRP_AD_CBE 0x00 #define AR71XX_PCI_REG_CRP_WRDATA 0x04 @@ -335,31 +334,6 @@ static void ar71xx_pci_reset(void) mdelay(100); } -__init int ar71xx_pcibios_init(void) -{ - u32 t; - - ar71xx_pcicfg_base = ioremap(AR71XX_PCI_CFG_BASE, AR71XX_PCI_CFG_SIZE); - if (ar71xx_pcicfg_base == NULL) - return -ENOMEM; - - ar71xx_pci_reset(); - - /* setup COMMAND register */ - t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE - | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK; - ar71xx_pci_local_write(PCI_COMMAND, 4, t); - - /* clear bus errors */ - ar71xx_pci_check_error(1); - - ar71xx_pci_irq_init(ATH79_CPU_IRQ_IP2); - - register_pci_controller(&ar71xx_pci_controller); - - return 0; -} - static int ar71xx_pci_probe(struct platform_device *pdev) { struct resource *res; diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c index b3f9d093c066..8f008d9a112c 100644 --- a/arch/mips/pci/pci-ar724x.c +++ b/arch/mips/pci/pci-ar724x.c @@ -15,7 +15,6 @@ #include #include #include -#include #define AR724X_PCI_REG_RESET 0x18 #define AR724X_PCI_REG_INT_STATUS 0x4c @@ -276,37 +275,6 @@ static void ar724x_pci_irq_init(int irq) irq_set_chained_handler(irq, ar724x_pci_irq_handler); } -int ar724x_pcibios_init(int irq) -{ - int ret; - - ret = -ENOMEM; - - ar724x_pci_devcfg_base = ioremap(AR724X_PCI_CFG_BASE, - AR724X_PCI_CFG_SIZE); - if (ar724x_pci_devcfg_base == NULL) - goto err; - - ar724x_pci_ctrl_base = ioremap(AR724X_PCI_CTRL_BASE, - AR724X_PCI_CTRL_SIZE); - if (ar724x_pci_ctrl_base == NULL) - goto err_unmap_devcfg; - - ar724x_pci_link_up = ar724x_pci_check_link(); - if (!ar724x_pci_link_up) - pr_warn("ar724x: PCIe link is down\n"); - - ar724x_pci_irq_init(irq); - register_pci_controller(&ar724x_pci_controller); - - return PCIBIOS_SUCCESSFUL; - -err_unmap_devcfg: - iounmap(ar724x_pci_devcfg_base); -err: - return ret; -} - static int ar724x_pci_probe(struct platform_device *pdev) { struct resource *res; -- cgit v1.2.3 From 617fed41e98417f3ea3e9974be251e125c8796f2 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Sun, 3 Feb 2013 09:58:37 +0000 Subject: MIPS: ath79: allow to specify bus number in PCI IRQ maps This is needed for multiple PCI bus support. Signed-off-by: Gabor Juhos Patchwork: http://patchwork.linux-mips.org/patch/4913/ Signed-off-by: John Crispin --- arch/mips/ath79/pci.c | 4 +++- arch/mips/ath79/pci.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'arch/mips/ath79/pci.c') diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c index c94bcec169ab..d90e07136383 100644 --- a/arch/mips/ath79/pci.c +++ b/arch/mips/ath79/pci.c @@ -75,7 +75,9 @@ int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) const struct ath79_pci_irq *entry; entry = &ath79_pci_irq_map[i]; - if (entry->slot == slot && entry->pin == pin) { + if (entry->bus == dev->bus->number && + entry->slot == slot && + entry->pin == pin) { irq = entry->irq; break; } diff --git a/arch/mips/ath79/pci.h b/arch/mips/ath79/pci.h index 51c6625dcc6d..1d00a3803c37 100644 --- a/arch/mips/ath79/pci.h +++ b/arch/mips/ath79/pci.h @@ -14,6 +14,7 @@ #define _ATH79_PCI_H struct ath79_pci_irq { + int bus; u8 slot; u8 pin; int irq; -- cgit v1.2.3 From 34b134aebda89888b6985b7a3139e9cbdf209236 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Sun, 3 Feb 2013 09:59:45 +0000 Subject: MIPS: pci-ar724x: remove static PCI IO/MEM resources Static resources become impractical when multiple PCI controllers are present. Move the resources into the platform device registration code and change the probe routine to get those from there platform device's resources. Signed-off-by: Gabor Juhos Patchwork: http://patchwork.linux-mips.org/patch/4914/ Signed-off-by: John Crispin --- arch/mips/ath79/pci.c | 21 ++++++++++++++++++++- arch/mips/pci/pci-ar724x.c | 40 ++++++++++++++++++++++++---------------- 2 files changed, 44 insertions(+), 17 deletions(-) (limited to 'arch/mips/ath79/pci.c') diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c index d90e07136383..45d1112de50d 100644 --- a/arch/mips/ath79/pci.c +++ b/arch/mips/ath79/pci.c @@ -139,10 +139,13 @@ static struct platform_device * ath79_register_pci_ar724x(int id, unsigned long cfg_base, unsigned long ctrl_base, + unsigned long mem_base, + unsigned long mem_size, + unsigned long io_base, int irq) { struct platform_device *pdev; - struct resource res[3]; + struct resource res[5]; memset(res, 0, sizeof(res)); @@ -160,6 +163,16 @@ ath79_register_pci_ar724x(int id, res[2].start = irq; res[2].end = irq; + res[3].name = "mem_base"; + res[3].flags = IORESOURCE_MEM; + res[3].start = mem_base; + res[3].end = mem_base + mem_size - 1; + + res[4].name = "io_base"; + res[4].flags = IORESOURCE_IO; + res[4].start = io_base; + res[4].end = io_base; + pdev = platform_device_register_simple("ar724x-pci", id, res, ARRAY_SIZE(res)); return pdev; @@ -175,6 +188,9 @@ int __init ath79_register_pci(void) pdev = ath79_register_pci_ar724x(-1, AR724X_PCI_CFG_BASE, AR724X_PCI_CTRL_BASE, + AR724X_PCI_MEM_BASE, + AR724X_PCI_MEM_SIZE, + 0, ATH79_CPU_IRQ_IP2); } else if (soc_is_ar9342() || soc_is_ar9344()) { @@ -187,6 +203,9 @@ int __init ath79_register_pci(void) pdev = ath79_register_pci_ar724x(-1, AR724X_PCI_CFG_BASE, AR724X_PCI_CTRL_BASE, + AR724X_PCI_MEM_BASE, + AR724X_PCI_MEM_SIZE, + 0, ATH79_IP2_IRQ(0)); } else { /* No PCI support */ diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c index 93ab8778ce10..d0d707de6c6c 100644 --- a/arch/mips/pci/pci-ar724x.c +++ b/arch/mips/pci/pci-ar724x.c @@ -42,6 +42,8 @@ struct ar724x_pci_controller { spinlock_t lock; struct pci_controller pci_controller; + struct resource io_res; + struct resource mem_res; }; static inline bool ar724x_pci_check_link(struct ar724x_pci_controller *apc) @@ -190,20 +192,6 @@ static struct pci_ops ar724x_pci_ops = { .write = ar724x_pci_write, }; -static struct resource ar724x_io_resource = { - .name = "PCI IO space", - .start = 0, - .end = 0, - .flags = IORESOURCE_IO, -}; - -static struct resource ar724x_mem_resource = { - .name = "PCI memory space", - .start = AR724X_PCI_MEM_BASE, - .end = AR724X_PCI_MEM_BASE + AR724X_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc) { struct ar724x_pci_controller *apc; @@ -331,9 +319,29 @@ static int ar724x_pci_probe(struct platform_device *pdev) spin_lock_init(&apc->lock); + res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base"); + if (!res) + return -EINVAL; + + apc->io_res.parent = res; + apc->io_res.name = "PCI IO space"; + apc->io_res.start = res->start; + apc->io_res.end = res->end; + apc->io_res.flags = IORESOURCE_IO; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem_base"); + if (!res) + return -EINVAL; + + apc->mem_res.parent = res; + apc->mem_res.name = "PCI memory space"; + apc->mem_res.start = res->start; + apc->mem_res.end = res->end; + apc->mem_res.flags = IORESOURCE_MEM; + apc->pci_controller.pci_ops = &ar724x_pci_ops; - apc->pci_controller.io_resource = &ar724x_io_resource; - apc->pci_controller.mem_resource = &ar724x_mem_resource; + apc->pci_controller.io_resource = &apc->io_res; + apc->pci_controller.mem_resource = &apc->mem_res; apc->link_up = ar724x_pci_check_link(apc); if (!apc->link_up) -- cgit v1.2.3 From 12401fc28d40aa5bf8bda6991a96b6d7a3dae3ac Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Sun, 3 Feb 2013 14:52:47 +0000 Subject: MIPS: pci-ar724x: setup command register of the PCI controller The command register of the PCI controller is not initialized correctly by the bootloader on some boards and this leads to non working PCI bus. Add code to initialize the command register from the Linux code to avoid this. Signed-off-by: Gabor Juhos Patchwork: http://patchwork.linux-mips.org/patch/4916/ Signed-off-by: John Crispin --- arch/mips/ath79/pci.c | 10 +++- arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 2 + arch/mips/pci/pci-ar724x.c | 63 ++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) (limited to 'arch/mips/ath79/pci.c') diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c index 45d1112de50d..942e3f9184f0 100644 --- a/arch/mips/ath79/pci.c +++ b/arch/mips/ath79/pci.c @@ -139,13 +139,14 @@ static struct platform_device * ath79_register_pci_ar724x(int id, unsigned long cfg_base, unsigned long ctrl_base, + unsigned long crp_base, unsigned long mem_base, unsigned long mem_size, unsigned long io_base, int irq) { struct platform_device *pdev; - struct resource res[5]; + struct resource res[6]; memset(res, 0, sizeof(res)); @@ -173,6 +174,11 @@ ath79_register_pci_ar724x(int id, res[4].start = io_base; res[4].end = io_base; + res[5].name = "crp_base"; + res[5].flags = IORESOURCE_MEM; + res[5].start = crp_base; + res[5].end = crp_base + AR724X_PCI_CRP_SIZE - 1; + pdev = platform_device_register_simple("ar724x-pci", id, res, ARRAY_SIZE(res)); return pdev; @@ -188,6 +194,7 @@ int __init ath79_register_pci(void) pdev = ath79_register_pci_ar724x(-1, AR724X_PCI_CFG_BASE, AR724X_PCI_CTRL_BASE, + AR724X_PCI_CRP_BASE, AR724X_PCI_MEM_BASE, AR724X_PCI_MEM_SIZE, 0, @@ -203,6 +210,7 @@ int __init ath79_register_pci(void) pdev = ath79_register_pci_ar724x(-1, AR724X_PCI_CFG_BASE, AR724X_PCI_CTRL_BASE, + AR724X_PCI_CRP_BASE, AR724X_PCI_MEM_BASE, AR724X_PCI_MEM_SIZE, 0, diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h index 7c87bfe6e4ff..a77f6ee70ec1 100644 --- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h @@ -67,6 +67,8 @@ #define AR724X_PCI_CFG_BASE 0x14000000 #define AR724X_PCI_CFG_SIZE 0x1000 +#define AR724X_PCI_CRP_BASE (AR71XX_APB_BASE + 0x000c0000) +#define AR724X_PCI_CRP_SIZE 0x1000 #define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000f0000) #define AR724X_PCI_CTRL_SIZE 0x100 diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c index 0440d8800f8a..8a0700d448fe 100644 --- a/arch/mips/pci/pci-ar724x.c +++ b/arch/mips/pci/pci-ar724x.c @@ -29,9 +29,17 @@ #define AR7240_BAR0_WAR_VALUE 0xffff +#define AR724X_PCI_CMD_INIT (PCI_COMMAND_MEMORY | \ + PCI_COMMAND_MASTER | \ + PCI_COMMAND_INVALIDATE | \ + PCI_COMMAND_PARITY | \ + PCI_COMMAND_SERR | \ + PCI_COMMAND_FAST_BACK) + struct ar724x_pci_controller { void __iomem *devcfg_base; void __iomem *ctrl_base; + void __iomem *crp_base; int irq; int irq_base; @@ -64,6 +72,51 @@ pci_bus_to_ar724x_controller(struct pci_bus *bus) return container_of(hose, struct ar724x_pci_controller, pci_controller); } +static int ar724x_pci_local_write(struct ar724x_pci_controller *apc, + int where, int size, u32 value) +{ + unsigned long flags; + void __iomem *base; + u32 data; + int s; + + WARN_ON(where & (size - 1)); + + if (!apc->link_up) + return PCIBIOS_DEVICE_NOT_FOUND; + + base = apc->crp_base; + + spin_lock_irqsave(&apc->lock, flags); + data = __raw_readl(base + (where & ~3)); + + switch (size) { + case 1: + s = ((where & 3) * 8); + data &= ~(0xff << s); + data |= ((value & 0xff) << s); + break; + case 2: + s = ((where & 2) * 8); + data &= ~(0xffff << s); + data |= ((value & 0xffff) << s); + break; + case 4: + data = value; + break; + default: + spin_unlock_irqrestore(&apc->lock, flags); + return PCIBIOS_BAD_REGISTER_NUMBER; + } + + __raw_writel(data, base + (where & ~3)); + /* flush write */ + __raw_readl(base + (where & ~3)); + spin_unlock_irqrestore(&apc->lock, flags); + + return PCIBIOS_SUCCESSFUL; +} + static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, uint32_t *value) { @@ -324,6 +377,14 @@ static int ar724x_pci_probe(struct platform_device *pdev) if (!apc->devcfg_base) return -EBUSY; + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "crp_base"); + if (!res) + return -EINVAL; + + apc->crp_base = devm_request_and_ioremap(&pdev->dev, res); + if (apc->crp_base == NULL) + return -EBUSY; + apc->irq = platform_get_irq(pdev, 0); if (apc->irq < 0) return -EINVAL; @@ -360,6 +421,8 @@ static int ar724x_pci_probe(struct platform_device *pdev) ar724x_pci_irq_init(apc, id); + ar724x_pci_local_write(apc, PCI_COMMAND, 4, AR724X_PCI_CMD_INIT); + register_pci_controller(&apc->pci_controller); return 0; -- cgit v1.2.3 From 42cb60d1fab4c81ef24876d985e08fc5bb899e41 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Thu, 7 Feb 2013 19:28:15 +0000 Subject: MIPS: pci-ar71xx: remove static PCI IO/MEM resources Signed-off-by: Gabor Juhos Patchwork: http://patchwork.linux-mips.org/patch/4927/ Signed-off-by: John Crispin --- arch/mips/ath79/pci.c | 12 +++++++++++- arch/mips/pci/pci-ar71xx.c | 40 ++++++++++++++++++++++++---------------- 2 files changed, 35 insertions(+), 17 deletions(-) (limited to 'arch/mips/ath79/pci.c') diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c index 942e3f9184f0..ea8aa10893d8 100644 --- a/arch/mips/ath79/pci.c +++ b/arch/mips/ath79/pci.c @@ -117,7 +117,7 @@ static struct platform_device * ath79_register_pci_ar71xx(void) { struct platform_device *pdev; - struct resource res[2]; + struct resource res[4]; memset(res, 0, sizeof(res)); @@ -130,6 +130,16 @@ ath79_register_pci_ar71xx(void) res[1].start = ATH79_CPU_IRQ_IP2; res[1].end = ATH79_CPU_IRQ_IP2; + res[2].name = "io_base"; + res[2].flags = IORESOURCE_IO; + res[2].start = 0; + res[2].end = 0; + + res[3].name = "mem_base"; + res[3].flags = IORESOURCE_MEM; + res[3].start = AR71XX_PCI_MEM_BASE; + res[3].end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1; + pdev = platform_device_register_simple("ar71xx-pci", -1, res, ARRAY_SIZE(res)); return pdev; diff --git a/arch/mips/pci/pci-ar71xx.c b/arch/mips/pci/pci-ar71xx.c index 44dc5bf720c0..e48dddbb4919 100644 --- a/arch/mips/pci/pci-ar71xx.c +++ b/arch/mips/pci/pci-ar71xx.c @@ -53,6 +53,8 @@ struct ar71xx_pci_controller { spinlock_t lock; int irq; struct pci_controller pci_ctrl; + struct resource io_res; + struct resource mem_res; }; /* Byte lane enable bits */ @@ -234,20 +236,6 @@ static struct pci_ops ar71xx_pci_ops = { .write = ar71xx_pci_write_config, }; -static struct resource ar71xx_pci_io_resource = { - .name = "PCI IO space", - .start = 0, - .end = 0, - .flags = IORESOURCE_IO, -}; - -static struct resource ar71xx_pci_mem_resource = { - .name = "PCI memory space", - .start = AR71XX_PCI_MEM_BASE, - .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; - static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc) { void __iomem *base = ath79_reset_base; @@ -370,6 +358,26 @@ static int ar71xx_pci_probe(struct platform_device *pdev) if (apc->irq < 0) return -EINVAL; + res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base"); + if (!res) + return -EINVAL; + + apc->io_res.parent = res; + apc->io_res.name = "PCI IO space"; + apc->io_res.start = res->start; + apc->io_res.end = res->end; + apc->io_res.flags = IORESOURCE_IO; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem_base"); + if (!res) + return -EINVAL; + + apc->mem_res.parent = res; + apc->mem_res.name = "PCI memory space"; + apc->mem_res.start = res->start; + apc->mem_res.end = res->end; + apc->mem_res.flags = IORESOURCE_MEM; + ar71xx_pci_reset(); /* setup COMMAND register */ @@ -383,8 +391,8 @@ static int ar71xx_pci_probe(struct platform_device *pdev) ar71xx_pci_irq_init(apc); apc->pci_ctrl.pci_ops = &ar71xx_pci_ops; - apc->pci_ctrl.mem_resource = &ar71xx_pci_mem_resource; - apc->pci_ctrl.io_resource = &ar71xx_pci_io_resource; + apc->pci_ctrl.mem_resource = &apc->mem_res; + apc->pci_ctrl.io_resource = &apc->io_res; register_pci_controller(&apc->pci_ctrl); -- cgit v1.2.3 From 7e69c10a8ee1f201c040997c6742c27e915730ad Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Thu, 7 Feb 2013 19:32:23 +0000 Subject: ath79: add ATH79_CPU_IRQ() macro Remove the individual ATH79_CPU_IRQ_* constants and use the new macro instead of those. Signed-off-by: Gabor Juhos Patchwork: http://patchwork.linux-mips.org/patch/4929/ Signed-off-by: John Crispin --- arch/mips/ath79/dev-usb.c | 12 ++++++------ arch/mips/ath79/dev-wmac.c | 8 ++++---- arch/mips/ath79/irq.c | 32 ++++++++++++++++---------------- arch/mips/ath79/pci.c | 6 +++--- arch/mips/include/asm/mach-ath79/irq.h | 9 ++------- 5 files changed, 31 insertions(+), 36 deletions(-) (limited to 'arch/mips/ath79/pci.c') diff --git a/arch/mips/ath79/dev-usb.c b/arch/mips/ath79/dev-usb.c index bd2bc108e1b5..2e041977c854 100644 --- a/arch/mips/ath79/dev-usb.c +++ b/arch/mips/ath79/dev-usb.c @@ -111,7 +111,7 @@ static void __init ath79_usb_setup(void) platform_device_register(&ath79_ohci_device); ath79_usb_init_resource(ath79_ehci_resources, AR71XX_EHCI_BASE, - AR71XX_EHCI_SIZE, ATH79_CPU_IRQ_USB); + AR71XX_EHCI_SIZE, ATH79_CPU_IRQ(3)); ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v1; platform_device_register(&ath79_ehci_device); } @@ -136,7 +136,7 @@ static void __init ar7240_usb_setup(void) iounmap(usb_ctrl_base); ath79_usb_init_resource(ath79_ohci_resources, AR7240_OHCI_BASE, - AR7240_OHCI_SIZE, ATH79_CPU_IRQ_USB); + AR7240_OHCI_SIZE, ATH79_CPU_IRQ(3)); platform_device_register(&ath79_ohci_device); } @@ -152,7 +152,7 @@ static void __init ar724x_usb_setup(void) mdelay(10); ath79_usb_init_resource(ath79_ehci_resources, AR724X_EHCI_BASE, - AR724X_EHCI_SIZE, ATH79_CPU_IRQ_USB); + AR724X_EHCI_SIZE, ATH79_CPU_IRQ(3)); ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; platform_device_register(&ath79_ehci_device); } @@ -169,7 +169,7 @@ static void __init ar913x_usb_setup(void) mdelay(10); ath79_usb_init_resource(ath79_ehci_resources, AR913X_EHCI_BASE, - AR913X_EHCI_SIZE, ATH79_CPU_IRQ_USB); + AR913X_EHCI_SIZE, ATH79_CPU_IRQ(3)); ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; platform_device_register(&ath79_ehci_device); } @@ -186,7 +186,7 @@ static void __init ar933x_usb_setup(void) mdelay(10); ath79_usb_init_resource(ath79_ehci_resources, AR933X_EHCI_BASE, - AR933X_EHCI_SIZE, ATH79_CPU_IRQ_USB); + AR933X_EHCI_SIZE, ATH79_CPU_IRQ(3)); ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; platform_device_register(&ath79_ehci_device); } @@ -212,7 +212,7 @@ static void __init ar934x_usb_setup(void) udelay(1000); ath79_usb_init_resource(ath79_ehci_resources, AR934X_EHCI_BASE, - AR934X_EHCI_SIZE, ATH79_CPU_IRQ_USB); + AR934X_EHCI_SIZE, ATH79_CPU_IRQ(3)); ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; platform_device_register(&ath79_ehci_device); } diff --git a/arch/mips/ath79/dev-wmac.c b/arch/mips/ath79/dev-wmac.c index d6d893c16ad4..4f6c4e389172 100644 --- a/arch/mips/ath79/dev-wmac.c +++ b/arch/mips/ath79/dev-wmac.c @@ -55,8 +55,8 @@ static void __init ar913x_wmac_setup(void) ath79_wmac_resources[0].start = AR913X_WMAC_BASE; ath79_wmac_resources[0].end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1; - ath79_wmac_resources[1].start = ATH79_CPU_IRQ_IP2; - ath79_wmac_resources[1].end = ATH79_CPU_IRQ_IP2; + ath79_wmac_resources[1].start = ATH79_CPU_IRQ(2); + ath79_wmac_resources[1].end = ATH79_CPU_IRQ(2); } @@ -83,8 +83,8 @@ static void __init ar933x_wmac_setup(void) ath79_wmac_resources[0].start = AR933X_WMAC_BASE; ath79_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1; - ath79_wmac_resources[1].start = ATH79_CPU_IRQ_IP2; - ath79_wmac_resources[1].end = ATH79_CPU_IRQ_IP2; + ath79_wmac_resources[1].start = ATH79_CPU_IRQ(2); + ath79_wmac_resources[1].end = ATH79_CPU_IRQ(2); t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); if (t & AR933X_BOOTSTRAP_REF_CLK_40) diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c index 219cfa1f5961..29348956d15d 100644 --- a/arch/mips/ath79/irq.c +++ b/arch/mips/ath79/irq.c @@ -114,7 +114,7 @@ static void __init ath79_misc_irq_init(void) handle_level_irq); } - irq_set_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler); + irq_set_chained_handler(ATH79_CPU_IRQ(6), ath79_misc_irq_handler); } static void ar934x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc) @@ -147,7 +147,7 @@ static void ar934x_ip2_irq_init(void) irq_set_chip_and_handler(i, &dummy_irq_chip, handle_level_irq); - irq_set_chained_handler(ATH79_CPU_IRQ_IP2, ar934x_ip2_irq_dispatch); + irq_set_chained_handler(ATH79_CPU_IRQ(2), ar934x_ip2_irq_dispatch); } asmlinkage void plat_irq_dispatch(void) @@ -157,22 +157,22 @@ asmlinkage void plat_irq_dispatch(void) pending = read_c0_status() & read_c0_cause() & ST0_IM; if (pending & STATUSF_IP7) - do_IRQ(ATH79_CPU_IRQ_TIMER); + do_IRQ(ATH79_CPU_IRQ(7)); else if (pending & STATUSF_IP2) ath79_ip2_handler(); else if (pending & STATUSF_IP4) - do_IRQ(ATH79_CPU_IRQ_GE0); + do_IRQ(ATH79_CPU_IRQ(4)); else if (pending & STATUSF_IP5) - do_IRQ(ATH79_CPU_IRQ_GE1); + do_IRQ(ATH79_CPU_IRQ(5)); else if (pending & STATUSF_IP3) ath79_ip3_handler(); else if (pending & STATUSF_IP6) - do_IRQ(ATH79_CPU_IRQ_MISC); + do_IRQ(ATH79_CPU_IRQ(6)); else spurious_interrupt(); @@ -188,60 +188,60 @@ asmlinkage void plat_irq_dispatch(void) static void ar71xx_ip2_handler(void) { ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_PCI); - do_IRQ(ATH79_CPU_IRQ_IP2); + do_IRQ(ATH79_CPU_IRQ(2)); } static void ar724x_ip2_handler(void) { ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_PCIE); - do_IRQ(ATH79_CPU_IRQ_IP2); + do_IRQ(ATH79_CPU_IRQ(2)); } static void ar913x_ip2_handler(void) { ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_WMAC); - do_IRQ(ATH79_CPU_IRQ_IP2); + do_IRQ(ATH79_CPU_IRQ(2)); } static void ar933x_ip2_handler(void) { ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_WMAC); - do_IRQ(ATH79_CPU_IRQ_IP2); + do_IRQ(ATH79_CPU_IRQ(2)); } static void ar934x_ip2_handler(void) { - do_IRQ(ATH79_CPU_IRQ_IP2); + do_IRQ(ATH79_CPU_IRQ(2)); } static void ar71xx_ip3_handler(void) { ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB); - do_IRQ(ATH79_CPU_IRQ_USB); + do_IRQ(ATH79_CPU_IRQ(3)); } static void ar724x_ip3_handler(void) { ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_USB); - do_IRQ(ATH79_CPU_IRQ_USB); + do_IRQ(ATH79_CPU_IRQ(3)); } static void ar913x_ip3_handler(void) { ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_USB); - do_IRQ(ATH79_CPU_IRQ_USB); + do_IRQ(ATH79_CPU_IRQ(3)); } static void ar933x_ip3_handler(void) { ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_USB); - do_IRQ(ATH79_CPU_IRQ_USB); + do_IRQ(ATH79_CPU_IRQ(3)); } static void ar934x_ip3_handler(void) { ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_USB); - do_IRQ(ATH79_CPU_IRQ_USB); + do_IRQ(ATH79_CPU_IRQ(3)); } void __init arch_init_irq(void) diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c index ea8aa10893d8..4350c252bce5 100644 --- a/arch/mips/ath79/pci.c +++ b/arch/mips/ath79/pci.c @@ -127,8 +127,8 @@ ath79_register_pci_ar71xx(void) res[0].end = AR71XX_PCI_CFG_BASE + AR71XX_PCI_CFG_SIZE - 1; res[1].flags = IORESOURCE_IRQ; - res[1].start = ATH79_CPU_IRQ_IP2; - res[1].end = ATH79_CPU_IRQ_IP2; + res[1].start = ATH79_CPU_IRQ(2); + res[1].end = ATH79_CPU_IRQ(2); res[2].name = "io_base"; res[2].flags = IORESOURCE_IO; @@ -208,7 +208,7 @@ int __init ath79_register_pci(void) AR724X_PCI_MEM_BASE, AR724X_PCI_MEM_SIZE, 0, - ATH79_CPU_IRQ_IP2); + ATH79_CPU_IRQ(2)); } else if (soc_is_ar9342() || soc_is_ar9344()) { u32 bootstrap; diff --git a/arch/mips/include/asm/mach-ath79/irq.h b/arch/mips/include/asm/mach-ath79/irq.h index 158ad7f41313..3dda4c24571d 100644 --- a/arch/mips/include/asm/mach-ath79/irq.h +++ b/arch/mips/include/asm/mach-ath79/irq.h @@ -12,6 +12,8 @@ #define MIPS_CPU_IRQ_BASE 0 #define NR_IRQS 48 +#define ATH79_CPU_IRQ(_x) (MIPS_CPU_IRQ_BASE + (_x)) + #define ATH79_MISC_IRQ_BASE 8 #define ATH79_MISC_IRQ_COUNT 32 #define ATH79_MISC_IRQ(_x) (ATH79_MISC_IRQ_BASE + (_x)) @@ -24,13 +26,6 @@ #define ATH79_IP2_IRQ_COUNT 2 #define ATH79_IP2_IRQ(_x) (ATH79_IP2_IRQ_BASE + (_x)) -#define ATH79_CPU_IRQ_IP2 (MIPS_CPU_IRQ_BASE + 2) -#define ATH79_CPU_IRQ_USB (MIPS_CPU_IRQ_BASE + 3) -#define ATH79_CPU_IRQ_GE0 (MIPS_CPU_IRQ_BASE + 4) -#define ATH79_CPU_IRQ_GE1 (MIPS_CPU_IRQ_BASE + 5) -#define ATH79_CPU_IRQ_MISC (MIPS_CPU_IRQ_BASE + 6) -#define ATH79_CPU_IRQ_TIMER (MIPS_CPU_IRQ_BASE + 7) - #define ATH79_MISC_IRQ_TIMER (ATH79_MISC_IRQ_BASE + 0) #define ATH79_MISC_IRQ_ERROR (ATH79_MISC_IRQ_BASE + 1) #define ATH79_MISC_IRQ_GPIO (ATH79_MISC_IRQ_BASE + 2) -- cgit v1.2.3 From 0a5f3b1c9f20eb44142e3b37662de15c944f759d Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Fri, 15 Feb 2013 13:38:23 +0000 Subject: MIPS: ath79: add PCI controller registration code for the QCA955X SoCs Add SoC specific PCI IRQ map, and register platform devices for the two built-in PCIe RCs. Cc: Rodriguez, Luis Cc: Giori, Kathy Cc: QCA Linux Team Signed-off-by: Gabor Juhos Patchwork: http://patchwork.linux-mips.org/patch/4951/ Signed-off-by: John Crispin --- arch/mips/ath79/Kconfig | 2 ++ arch/mips/ath79/pci.c | 36 ++++++++++++++++++++++++++ arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 13 ++++++++++ 3 files changed, 51 insertions(+) (limited to 'arch/mips/ath79/pci.c') diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index 77926e331b17..76a001e5fc26 100644 --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig @@ -90,6 +90,8 @@ config SOC_AR934X config SOC_QCA955X select USB_ARCH_HAS_EHCI + select HW_HAS_PCI + select PCI_AR724X if PCI def_bool n config PCI_AR724X diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c index 4350c252bce5..730c0b03060d 100644 --- a/arch/mips/ath79/pci.c +++ b/arch/mips/ath79/pci.c @@ -49,6 +49,21 @@ static const struct ath79_pci_irq ar724x_pci_irq_map[] __initconst = { } }; +static const struct ath79_pci_irq qca955x_pci_irq_map[] __initconst = { + { + .bus = 0, + .slot = 0, + .pin = 1, + .irq = ATH79_PCI_IRQ(0), + }, + { + .bus = 1, + .slot = 0, + .pin = 1, + .irq = ATH79_PCI_IRQ(1), + }, +}; + int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) { int irq = -1; @@ -64,6 +79,9 @@ int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) 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_qca955x()) { + ath79_pci_irq_map = qca955x_pci_irq_map; + ath79_pci_nr_irqs = ARRAY_SIZE(qca955x_pci_irq_map); } else { pr_crit("pci %s: invalid irq map\n", pci_name((struct pci_dev *) dev)); @@ -225,6 +243,24 @@ int __init ath79_register_pci(void) AR724X_PCI_MEM_SIZE, 0, ATH79_IP2_IRQ(0)); + } else if (soc_is_qca9558()) { + pdev = ath79_register_pci_ar724x(0, + QCA955X_PCI_CFG_BASE0, + QCA955X_PCI_CTRL_BASE0, + QCA955X_PCI_CRP_BASE0, + QCA955X_PCI_MEM_BASE0, + QCA955X_PCI_MEM_SIZE, + 0, + ATH79_IP2_IRQ(0)); + + pdev = ath79_register_pci_ar724x(1, + QCA955X_PCI_CFG_BASE1, + QCA955X_PCI_CTRL_BASE1, + QCA955X_PCI_CRP_BASE1, + QCA955X_PCI_MEM_BASE1, + QCA955X_PCI_MEM_SIZE, + 1, + ATH79_IP3_IRQ(2)); } else { /* No PCI support */ return -ENODEV; diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h index 47282120db1e..b7fa9d14d20f 100644 --- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h @@ -94,6 +94,19 @@ #define AR934X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000) #define AR934X_SRIF_SIZE 0x1000 +#define QCA955X_PCI_MEM_BASE0 0x10000000 +#define QCA955X_PCI_MEM_BASE1 0x12000000 +#define QCA955X_PCI_MEM_SIZE 0x02000000 +#define QCA955X_PCI_CFG_BASE0 0x14000000 +#define QCA955X_PCI_CFG_BASE1 0x16000000 +#define QCA955X_PCI_CFG_SIZE 0x1000 +#define QCA955X_PCI_CRP_BASE0 (AR71XX_APB_BASE + 0x000c0000) +#define QCA955X_PCI_CRP_BASE1 (AR71XX_APB_BASE + 0x00250000) +#define QCA955X_PCI_CRP_SIZE 0x1000 +#define QCA955X_PCI_CTRL_BASE0 (AR71XX_APB_BASE + 0x000f0000) +#define QCA955X_PCI_CTRL_BASE1 (AR71XX_APB_BASE + 0x00280000) +#define QCA955X_PCI_CTRL_SIZE 0x100 + #define QCA955X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) #define QCA955X_WMAC_SIZE 0x20000 -- cgit v1.2.3