[ARM] Kirkwood: add support for PCIe1
authorSaeed Bishara <saeed@marvell.com>
Tue, 8 Jun 2010 11:21:34 +0000 (14:21 +0300)
committerNicolas Pitre <nico@fluxnic.net>
Sat, 17 Jul 2010 02:01:59 +0000 (22:01 -0400)
This patch extends the kirkwood's PCIe support up to 2 controllers as in the 6282 devices.

Signed-off-by: Saeed Bishara <saeed@marvell.com>
Signed-off-by: Nicolas Pitre <nico@fluxnic.net>
15 files changed:
arch/arm/mach-kirkwood/addr-map.c
arch/arm/mach-kirkwood/common.c
arch/arm/mach-kirkwood/common.h
arch/arm/mach-kirkwood/db88f6281-bp-setup.c
arch/arm/mach-kirkwood/include/mach/bridge-regs.h
arch/arm/mach-kirkwood/include/mach/irqs.h
arch/arm/mach-kirkwood/include/mach/kirkwood.h
arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
arch/arm/mach-kirkwood/openrd-setup.c
arch/arm/mach-kirkwood/pcie.c
arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
arch/arm/mach-kirkwood/rd88f6281-setup.c
arch/arm/mach-kirkwood/t5325-setup.c
arch/arm/mach-kirkwood/ts219-setup.c
arch/arm/mach-kirkwood/ts41x-setup.c

index 2e69168..8d03bce 100644 (file)
@@ -31,6 +31,8 @@
 #define ATTR_DEV_CS0           0x3e
 #define ATTR_PCIE_IO           0xe0
 #define ATTR_PCIE_MEM          0xe8
+#define ATTR_PCIE1_IO          0xd0
+#define ATTR_PCIE1_MEM         0xd8
 #define ATTR_SRAM              0x01
 
 /*
@@ -106,17 +108,21 @@ void __init kirkwood_setup_cpu_mbus(void)
                      TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE);
        setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE,
                      TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE);
+       setup_cpu_win(2, KIRKWOOD_PCIE1_IO_PHYS_BASE, KIRKWOOD_PCIE1_IO_SIZE,
+                     TARGET_PCIE, ATTR_PCIE1_IO, KIRKWOOD_PCIE1_IO_BUS_BASE);
+       setup_cpu_win(3, KIRKWOOD_PCIE1_MEM_PHYS_BASE, KIRKWOOD_PCIE1_MEM_SIZE,
+                     TARGET_PCIE, ATTR_PCIE1_MEM, KIRKWOOD_PCIE1_MEM_BUS_BASE);
 
        /*
         * Setup window for NAND controller.
         */
-       setup_cpu_win(2, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE,
+       setup_cpu_win(4, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE,
                      TARGET_DEV_BUS, ATTR_DEV_NAND, -1);
 
        /*
         * Setup window for SRAM.
         */
-       setup_cpu_win(3, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE,
+       setup_cpu_win(5, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE,
                      TARGET_SRAM, ATTR_SRAM, -1);
 
        /*
index 4ccfdf9..9dd67c7 100644 (file)
@@ -43,6 +43,11 @@ static struct map_desc kirkwood_io_desc[] __initdata = {
                .pfn            = __phys_to_pfn(KIRKWOOD_PCIE_IO_PHYS_BASE),
                .length         = KIRKWOOD_PCIE_IO_SIZE,
                .type           = MT_DEVICE,
+       }, {
+               .virtual        = KIRKWOOD_PCIE1_IO_VIRT_BASE,
+               .pfn            = __phys_to_pfn(KIRKWOOD_PCIE1_IO_PHYS_BASE),
+               .length         = KIRKWOOD_PCIE1_IO_SIZE,
+               .type           = MT_DEVICE,
        }, {
                .virtual        = KIRKWOOD_REGS_VIRT_BASE,
                .pfn            = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE),
@@ -960,12 +965,14 @@ void __init kirkwood_init(void)
 static int __init kirkwood_clock_gate(void)
 {
        unsigned int curr = readl(CLOCK_GATING_CTRL);
+       u32 dev, rev;
 
+       kirkwood_pcie_id(&dev, &rev);
        printk(KERN_DEBUG "Gating clock of unused units\n");
        printk(KERN_DEBUG "before: 0x%08x\n", curr);
 
        /* Make sure those units are accessible */
-       writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0, CLOCK_GATING_CTRL);
+       writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0 | CGC_PEX1, CLOCK_GATING_CTRL);
 
        /* For SATA: first shutdown the phy */
        if (!(kirkwood_clk_ctrl & CGC_SATA0)) {
@@ -990,6 +997,18 @@ static int __init kirkwood_clock_gate(void)
                writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL);
        }
 
+       /* For PCIe 1: first shutdown the phy */
+       if (dev == MV88F6282_DEV_ID) {
+               if (!(kirkwood_clk_ctrl & CGC_PEX1)) {
+                       writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL);
+                       while (1)
+                               if (readl(PCIE1_STATUS) & 0x1)
+                                       break;
+                       writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL);
+               }
+       } else  /* keep this bit set for devices that don't have PCIe1 */
+               kirkwood_clk_ctrl |= CGC_PEX1;
+
        /* Now gate clock the required units */
        writel(kirkwood_clk_ctrl, CLOCK_GATING_CTRL);
        printk(KERN_DEBUG " after: 0x%08x\n", readl(CLOCK_GATING_CTRL));
index 05e8a8a..5b2c1c1 100644 (file)
@@ -18,6 +18,9 @@ struct mvsdio_platform_data;
 struct mtd_partition;
 struct mtd_info;
 
+#define KW_PCIE0       (1 << 0)
+#define KW_PCIE1       (1 << 1)
+
 /*
  * Basic Kirkwood init functions used early by machine-setup.
  */
@@ -34,7 +37,7 @@ void kirkwood_ehci_init(void);
 void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data);
 void kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data);
 void kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq);
-void kirkwood_pcie_init(void);
+void kirkwood_pcie_init(unsigned int portmask);
 void kirkwood_sata_init(struct mv_sata_platform_data *sata_data);
 void kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data);
 void kirkwood_spi_init(void);
index db93504..16f6691 100644 (file)
@@ -82,9 +82,15 @@ static void __init db88f6281_init(void)
 
 static int __init db88f6281_pci_init(void)
 {
-       if (machine_is_db88f6281_bp())
-               kirkwood_pcie_init();
+       if (machine_is_db88f6281_bp()) {
+               u32 dev, rev;
 
+               kirkwood_pcie_id(&dev, &rev);
+               if (dev == MV88F6282_DEV_ID)
+                       kirkwood_pcie_init(KW_PCIE1 | KW_PCIE0);
+               else
+                       kirkwood_pcie_init(KW_PCIE0);
+       }
        return 0;
 }
 subsys_initcall(db88f6281_pci_init);
index 418f501..aff0e13 100644 (file)
@@ -59,8 +59,9 @@
 #define CGC_SATA1              (1 << 15)
 #define CGC_XOR1               (1 << 16)
 #define CGC_CRYPTO             (1 << 17)
+#define CGC_PEX1               (1 << 18)
 #define CGC_GE1                        (1 << 19)
 #define CGC_TDM                        (1 << 20)
-#define CGC_RESERVED           ((1 << 18) | (0x6 << 21))
+#define CGC_RESERVED           (0x6 << 21)
 
 #endif
index f00a0a4..9da2eb5 100644 (file)
@@ -23,6 +23,7 @@
 #define IRQ_KIRKWOOD_XOR_10    7
 #define IRQ_KIRKWOOD_XOR_11    8
 #define IRQ_KIRKWOOD_PCIE      9
+#define IRQ_KIRKWOOD_PCIE1     10
 #define IRQ_KIRKWOOD_GE00_SUM  11
 #define IRQ_KIRKWOOD_GE01_SUM  15
 #define IRQ_KIRKWOOD_USB       19
index dd7eddb..d141af4 100644 (file)
  * Marvell Kirkwood address maps.
  *
  * phys
- * e0000000    PCIe Memory space
+ * e0000000    PCIe #0 Memory space
+ * e8000000    PCIe #1 Memory space
  * f1000000    on-chip peripheral registers
- * f2000000    PCIe I/O space
- * f3000000    NAND controller address window
- * f4000000    Security Accelerator SRAM
+ * f2000000    PCIe #0 I/O space
+ * f3000000    PCIe #1 I/O space
+ * f4000000    NAND controller address window
+ * f5000000    Security Accelerator SRAM
  *
  * virt                phys            size
- * fee00000    f1000000        1M      on-chip peripheral registers
- * fef00000    f2000000        1M      PCIe I/O space
+ * fed00000    f1000000        1M      on-chip peripheral registers
+ * fee00000    f2000000        1M      PCIe #0 I/O space
+ * fef00000    f3000000        1M      PCIe #1 I/O space
  */
 
-#define KIRKWOOD_SRAM_PHYS_BASE                0xf4000000
+#define KIRKWOOD_SRAM_PHYS_BASE                0xf5000000
 #define KIRKWOOD_SRAM_SIZE             SZ_2K
 
-#define KIRKWOOD_NAND_MEM_PHYS_BASE    0xf3000000
+#define KIRKWOOD_NAND_MEM_PHYS_BASE    0xf4000000
 #define KIRKWOOD_NAND_MEM_SIZE         SZ_1K
 
+#define KIRKWOOD_PCIE1_IO_PHYS_BASE    0xf3000000
+#define KIRKWOOD_PCIE1_IO_VIRT_BASE    0xfef00000
+#define KIRKWOOD_PCIE1_IO_BUS_BASE     0x00000000
+#define KIRKWOOD_PCIE1_IO_SIZE         SZ_1M
+
 #define KIRKWOOD_PCIE_IO_PHYS_BASE     0xf2000000
-#define KIRKWOOD_PCIE_IO_VIRT_BASE     0xfef00000
+#define KIRKWOOD_PCIE_IO_VIRT_BASE     0xfee00000
 #define KIRKWOOD_PCIE_IO_BUS_BASE      0x00000000
 #define KIRKWOOD_PCIE_IO_SIZE          SZ_1M
 
 #define KIRKWOOD_REGS_PHYS_BASE                0xf1000000
-#define KIRKWOOD_REGS_VIRT_BASE                0xfee00000
+#define KIRKWOOD_REGS_VIRT_BASE                0xfed00000
 #define KIRKWOOD_REGS_SIZE             SZ_1M
 
 #define KIRKWOOD_PCIE_MEM_PHYS_BASE    0xe0000000
 #define KIRKWOOD_PCIE_MEM_BUS_BASE     0xe0000000
 #define KIRKWOOD_PCIE_MEM_SIZE         SZ_128M
 
+#define KIRKWOOD_PCIE1_MEM_PHYS_BASE   0xe8000000
+#define KIRKWOOD_PCIE1_MEM_BUS_BASE    0xe8000000
+#define KIRKWOOD_PCIE1_MEM_SIZE                SZ_128M
+
 /*
  * Register Map
  */
@@ -72,6 +84,9 @@
 #define PCIE_VIRT_BASE         (KIRKWOOD_REGS_VIRT_BASE | 0x40000)
 #define PCIE_LINK_CTRL         (PCIE_VIRT_BASE | 0x70)
 #define PCIE_STATUS            (PCIE_VIRT_BASE | 0x1a04)
+#define PCIE1_VIRT_BASE                (KIRKWOOD_REGS_VIRT_BASE | 0x44000)
+#define PCIE1_LINK_CTRL                (PCIE1_VIRT_BASE | 0x70)
+#define PCIE1_STATUS           (PCIE1_VIRT_BASE | 0x1a04)
 
 #define USB_PHYS_BASE          (KIRKWOOD_REGS_PHYS_BASE | 0x50000)
 
index 5e6f711..c6b92b4 100644 (file)
@@ -155,7 +155,7 @@ static void __init mv88f6281gtw_ge_init(void)
 static int __init mv88f6281gtw_ge_pci_init(void)
 {
        if (machine_is_mv88f6281gtw_ge())
-               kirkwood_pcie_init();
+               kirkwood_pcie_init(KW_PCIE0);
 
        return 0;
 }
index a481036..fd64cd2 100644 (file)
@@ -93,7 +93,7 @@ static int __init openrd_pci_init(void)
        if (machine_is_openrd_base() ||
            machine_is_openrd_client() ||
            machine_is_openrd_ultimate())
-               kirkwood_pcie_init();
+               kirkwood_pcie_init(KW_PCIE0);
 
        return 0;
 }
index dee1eff..49c4fc6 100644 (file)
 #include <mach/bridge-regs.h>
 #include "common.h"
 
+void __init kirkwood_pcie_id(u32 *dev, u32 *rev)
+{
+       *dev = orion_pcie_dev_id((void __iomem *)PCIE_VIRT_BASE);
+       *rev = orion_pcie_rev((void __iomem *)PCIE_VIRT_BASE);
+}
 
-#define PCIE_BASE      ((void __iomem *)PCIE_VIRT_BASE)
+struct pcie_port {
+       u8                      root_bus_nr;
+       void __iomem            *base;
+       spinlock_t              conf_lock;
+       int                     irq;
+       struct resource         res[2];
+};
 
-void __init kirkwood_pcie_id(u32 *dev, u32 *rev)
+static int pcie_port_map[2];
+static int num_pcie_ports;
+
+static inline struct pcie_port *bus_to_port(struct pci_bus *bus)
 {
-       *dev = orion_pcie_dev_id(PCIE_BASE);
-       *rev = orion_pcie_rev(PCIE_BASE);
+       struct pci_sys_data *sys = bus->sysdata;
+       return sys->private_data;
 }
 
-static int pcie_valid_config(int bus, int dev)
+static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
 {
        /*
         * Don't go out when trying to access --
         * 1. nonexisting device on local bus
         * 2. where there's no device connected (no link)
         */
-       if (bus == 0 && dev == 0)
+       if (bus == pp->root_bus_nr && dev == 0)
                return 1;
 
-       if (!orion_pcie_link_up(PCIE_BASE))
+       if (!orion_pcie_link_up(pp->base))
                return 0;
 
-       if (bus == 0 && dev != 1)
+       if (bus == pp->root_bus_nr && dev != 1)
                return 0;
 
        return 1;
@@ -52,22 +66,22 @@ static int pcie_valid_config(int bus, int dev)
  * and then reading the PCIE_CONF_DATA register. Need to make sure these
  * transactions are atomic.
  */
-static DEFINE_SPINLOCK(kirkwood_pcie_lock);
 
 static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
                        int size, u32 *val)
 {
+       struct pcie_port *pp = bus_to_port(bus);
        unsigned long flags;
        int ret;
 
-       if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) {
+       if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) {
                *val = 0xffffffff;
                return PCIBIOS_DEVICE_NOT_FOUND;
        }
 
-       spin_lock_irqsave(&kirkwood_pcie_lock, flags);
-       ret = orion_pcie_rd_conf(PCIE_BASE, bus, devfn, where, size, val);
-       spin_unlock_irqrestore(&kirkwood_pcie_lock, flags);
+       spin_lock_irqsave(&pp->conf_lock, flags);
+       ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
+       spin_unlock_irqrestore(&pp->conf_lock, flags);
 
        return ret;
 }
@@ -75,15 +89,16 @@ static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
 static int pcie_wr_conf(struct pci_bus *bus, u32 devfn,
                        int where, int size, u32 val)
 {
+       struct pcie_port *pp = bus_to_port(bus);
        unsigned long flags;
        int ret;
 
-       if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0)
+       if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
-       spin_lock_irqsave(&kirkwood_pcie_lock, flags);
-       ret = orion_pcie_wr_conf(PCIE_BASE, bus, devfn, where, size, val);
-       spin_unlock_irqrestore(&kirkwood_pcie_lock, flags);
+       spin_lock_irqsave(&pp->conf_lock, flags);
+       ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
+       spin_unlock_irqrestore(&pp->conf_lock, flags);
 
        return ret;
 }
@@ -93,50 +108,112 @@ static struct pci_ops pcie_ops = {
        .write = pcie_wr_conf,
 };
 
-
-static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
+static int __init pcie0_ioresources_setup(struct pci_sys_data *sys)
 {
-       struct resource *res;
-       extern unsigned int kirkwood_clk_ctrl;
+       struct pcie_port *pp = (struct pcie_port *)sys->private_data;
 
        /*
-        * Generic PCIe unit setup.
+        * IORESOURCE_IO
         */
-       orion_pcie_setup(PCIE_BASE, &kirkwood_mbus_dram_info);
+       pp->res[0].name = "PCIe 0 I/O Space";
+       pp->res[0].start = KIRKWOOD_PCIE_IO_PHYS_BASE;
+       pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
+       pp->res[0].flags = IORESOURCE_IO;
+       if (request_resource(&ioport_resource, &pp->res[0]))
+               panic("Request PCIe 0 IO resource failed\n");
+       sys->resource[0] = &pp->res[0];
 
        /*
-        * Request resources.
+        * IORESOURCE_MEM
         */
-       res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
-       if (!res)
-               panic("pcie_setup unable to alloc resources");
+       pp->res[1].name = "PCIe 0 MEM";
+       pp->res[1].start = KIRKWOOD_PCIE_MEM_PHYS_BASE;
+       pp->res[1].end = pp->res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1;
+       pp->res[1].flags = IORESOURCE_MEM;
+       if (request_resource(&iomem_resource, &pp->res[1]))
+               panic("Request PCIe 0 Memory resource failed\n");
+       sys->resource[1] = &pp->res[1];
+
+       sys->resource[2] = NULL;
+       sys->io_offset = 0;
+
+       return 1;
+}
+
+static int __init pcie1_ioresources_setup(struct pci_sys_data *sys)
+{
+       struct pcie_port *pp = (struct pcie_port *)sys->private_data;
 
        /*
         * IORESOURCE_IO
         */
-       res[0].name = "PCIe I/O Space";
-       res[0].flags = IORESOURCE_IO;
-       res[0].start = KIRKWOOD_PCIE_IO_BUS_BASE;
-       res[0].end = res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
-       if (request_resource(&ioport_resource, &res[0]))
-               panic("Request PCIe IO resource failed\n");
-       sys->resource[0] = &res[0];
+       pp->res[0].name = "PCIe 1 I/O Space";
+       pp->res[0].start = KIRKWOOD_PCIE1_IO_PHYS_BASE;
+       pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE1_IO_SIZE - 1;
+       pp->res[0].flags = IORESOURCE_IO;
+       if (request_resource(&ioport_resource, &pp->res[0]))
+               panic("Request PCIe IO resource failed\n");
+       sys->resource[0] = &pp->res[0];
 
        /*
         * IORESOURCE_MEM
         */
-       res[1].name = "PCIe Memory Space";
-       res[1].flags = IORESOURCE_MEM;
-       res[1].start = KIRKWOOD_PCIE_MEM_BUS_BASE;
-       res[1].end = res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1;
-       if (request_resource(&iomem_resource, &res[1]))
-               panic("Request PCIe Memory resource failed\n");
-       sys->resource[1] = &res[1];
+       pp->res[1].name = "PCIe 1 MEM";
+       pp->res[1].start = KIRKWOOD_PCIE1_MEM_PHYS_BASE;
+       pp->res[1].end = pp->res[1].start + KIRKWOOD_PCIE1_MEM_SIZE - 1;
+       pp->res[1].flags = IORESOURCE_MEM;
+       if (request_resource(&iomem_resource, &pp->res[1]))
+               panic("Request PCIe Memory resource failed\n");
+       sys->resource[1] = &pp->res[1];
 
        sys->resource[2] = NULL;
        sys->io_offset = 0;
 
-       kirkwood_clk_ctrl |= CGC_PEX0;
+       return 1;
+}
+
+static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
+{
+       extern unsigned int kirkwood_clk_ctrl;
+       struct pcie_port *pp;
+       int index;
+
+       if (nr >= num_pcie_ports)
+               return 0;
+
+       index = pcie_port_map[nr];
+       printk(KERN_INFO "PCI: bus%d uses PCIe port %d\n", sys->busnr, index);
+
+       pp = kzalloc(sizeof(*pp), GFP_KERNEL);
+       if (!pp)
+               panic("PCIe: failed to allocate pcie_port data");
+       sys->private_data = pp;
+       pp->root_bus_nr = sys->busnr;
+       spin_lock_init(&pp->conf_lock);
+
+       switch (index) {
+       case 0:
+               pp->base = (void __iomem *)PCIE_VIRT_BASE;
+               pp->irq = IRQ_KIRKWOOD_PCIE;
+               kirkwood_clk_ctrl |= CGC_PEX0;
+               pcie0_ioresources_setup(sys);
+               break;
+       case 1:
+               pp->base = (void __iomem *)PCIE1_VIRT_BASE;
+               pp->irq = IRQ_KIRKWOOD_PCIE1;
+               kirkwood_clk_ctrl |= CGC_PEX1;
+               pcie1_ioresources_setup(sys);
+               break;
+       default:
+               panic("PCIe setup: invalid controller");
+       }
+
+       /*
+        * Generic PCIe unit setup.
+        */
+       orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
+
+       orion_pcie_setup(pp->base, &kirkwood_mbus_dram_info);
 
        return 1;
 }
@@ -163,7 +240,7 @@ kirkwood_pcie_scan_bus(int nr, struct pci_sys_data *sys)
 {
        struct pci_bus *bus;
 
-       if (nr == 0) {
+       if (nr < num_pcie_ports) {
                bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
        } else {
                bus = NULL;
@@ -175,18 +252,37 @@ kirkwood_pcie_scan_bus(int nr, struct pci_sys_data *sys)
 
 static int __init kirkwood_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
-       return IRQ_KIRKWOOD_PCIE;
+       struct pcie_port *pp = bus_to_port(dev->bus);
+
+       return pp->irq;
 }
 
 static struct hw_pci kirkwood_pci __initdata = {
-       .nr_controllers = 1,
        .swizzle        = pci_std_swizzle,
        .setup          = kirkwood_pcie_setup,
        .scan           = kirkwood_pcie_scan_bus,
        .map_irq        = kirkwood_pcie_map_irq,
 };
 
-void __init kirkwood_pcie_init(void)
+static void __init add_pcie_port(int index, unsigned long base)
+{
+       printk(KERN_INFO "Kirkwood PCIe port %d: ", index);
+
+       if (orion_pcie_link_up((void __iomem *)base)) {
+               printk(KERN_INFO "link up\n");
+               pcie_port_map[num_pcie_ports++] = index;
+       } else
+               printk(KERN_INFO "link down, ignoring\n");
+}
+
+void __init kirkwood_pcie_init(unsigned int portmask)
 {
+       if (portmask & KW_PCIE0)
+               add_pcie_port(0, PCIE_VIRT_BASE);
+
+       if (portmask & KW_PCIE1)
+               add_pcie_port(1, PCIE1_VIRT_BASE);
+
+       kirkwood_pci.nr_controllers = num_pcie_ports;
        pci_common_init(&kirkwood_pci);
 }
index 3bf6304..c34718c 100644 (file)
@@ -71,7 +71,7 @@ static void __init rd88f6192_init(void)
 static int __init rd88f6192_pci_init(void)
 {
        if (machine_is_rd88f6192_nas())
-               kirkwood_pcie_init();
+               kirkwood_pcie_init(KW_PCIE0);
 
        return 0;
 }
index 31708dd..3d14771 100644 (file)
@@ -107,7 +107,7 @@ static void __init rd88f6281_init(void)
 static int __init rd88f6281_pci_init(void)
 {
        if (machine_is_rd88f6281())
-               kirkwood_pcie_init();
+               kirkwood_pcie_init(KW_PCIE0);
 
        return 0;
 }
index 6a94daa..d01bf89 100644 (file)
@@ -176,7 +176,7 @@ static void __init hp_t5325_init(void)
 static int __init hp_t5325_pci_init(void)
 {
        if (machine_is_t5325())
-               kirkwood_pcie_init();
+               kirkwood_pcie_init(KW_PCIE0);
 
        return 0;
 }
index 063979d..a5bd7fd 100644 (file)
@@ -111,10 +111,10 @@ static void __init qnap_ts219_init(void)
 
 static int __init ts219_pci_init(void)
 {
-   if (machine_is_ts219())
-           kirkwood_pcie_init();
+       if (machine_is_ts219())
+               kirkwood_pcie_init(KW_PCIE0);
 
-   return 0;
+       return 0;
 }
 subsys_initcall(ts219_pci_init);
 
index e9d85d7..2e14afe 100644 (file)
@@ -141,7 +141,7 @@ static void __init qnap_ts41x_init(void)
 static int __init ts41x_pci_init(void)
 {
        if (machine_is_ts41x())
-               kirkwood_pcie_init();
+               kirkwood_pcie_init(KW_PCIE0);
 
    return 0;
 }