sh: add init member to pci_channel data
authorMagnus Damm <damm@igel.co.jp>
Wed, 11 Mar 2009 06:46:14 +0000 (15:46 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Thu, 16 Apr 2009 07:00:12 +0000 (16:00 +0900)
This patch adds an init callback to struct pci_channel and makes sure
it is initialized properly. Code is added to call this init function
from pcibios_init(). Return values are adjusted and a warning is is
printed if init fails.

Signed-off-by: Magnus Damm <damm@igel.co.jp>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
20 files changed:
arch/sh/boards/mach-dreamcast/setup.c
arch/sh/drivers/pci/ops-cayman.c
arch/sh/drivers/pci/ops-dreamcast.c
arch/sh/drivers/pci/ops-landisk.c
arch/sh/drivers/pci/ops-lboxre2.c
arch/sh/drivers/pci/ops-r7780rp.c
arch/sh/drivers/pci/ops-rts7751r2d.c
arch/sh/drivers/pci/ops-sdk7780.c
arch/sh/drivers/pci/ops-se7780.c
arch/sh/drivers/pci/ops-sh03.c
arch/sh/drivers/pci/ops-snapgear.c
arch/sh/drivers/pci/ops-titan.c
arch/sh/drivers/pci/pci-sh5.c
arch/sh/drivers/pci/pci-sh5.h
arch/sh/drivers/pci/pci-sh7751.c
arch/sh/drivers/pci/pci-sh7751.h
arch/sh/drivers/pci/pci-sh7780.c
arch/sh/drivers/pci/pci-sh7780.h
arch/sh/drivers/pci/pci.c
arch/sh/include/asm/pci.h

index d1bee4884cd667da313e0105e490cd2b5a5e6750..ebe99227d4e6674704b96e4c03c7e699401b6194 100644 (file)
@@ -30,7 +30,6 @@
 
 extern struct irq_chip systemasic_int;
 extern void aica_time_init(void);
-extern int gapspci_init(void);
 extern int systemasic_irq_demux(int);
 
 static void __init dreamcast_setup(char **cmdline_p)
@@ -51,11 +50,6 @@ static void __init dreamcast_setup(char **cmdline_p)
                                         handle_level_irq);
 
        board_time_init = aica_time_init;
-
-#ifdef CONFIG_PCI
-       if (gapspci_init() < 0)
-               printk(KERN_WARNING "GAPSPCI was not detected.\n");
-#endif
 }
 
 static struct sh_machine_vector mv_dreamcast __initmv = {
index 38ef76207af6c8ecaf43c53ccc0d98013396ad9d..f4a5e14f7e5aca16663b652d1afd63f2f0b4f0c9 100644 (file)
@@ -77,7 +77,7 @@ int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin)
 }
 
 struct pci_channel board_pci_channels[] = {
-       { &sh5_pci_ops, NULL, NULL, 0, 0xff },
+       { sh5_pci_init, &sh5_pci_ops, NULL, NULL, 0, 0xff },
        { NULL, NULL, NULL, 0, 0 },
 };
 EXPORT_SYMBOL(board_pci_channels);
index f5d2a2aa6f3f88b00ecb46700d245b98b182390f..f62063eb649082c4f4b36a713438ebbc54a731cd 100644 (file)
@@ -42,15 +42,6 @@ static struct resource gapspci_mem_resource = {
        .flags  = IORESOURCE_MEM,
 };
 
-static struct pci_ops gapspci_pci_ops;
-
-struct pci_channel board_pci_channels[] = {
-       { &gapspci_pci_ops, &gapspci_io_resource,
-         &gapspci_mem_resource, 0, 1 },
-       { 0, }
-};
-EXPORT_SYMBOL(board_pci_channels);
-
 /*
  * The !gapspci_config_access case really shouldn't happen, ever, unless
  * someone implicitly messes around with the last devfn value.. otherwise we
@@ -116,7 +107,7 @@ static struct pci_ops gapspci_pci_ops = {
  * gapspci init
  */
 
-int __init gapspci_init(void)
+static int __init gapspci_init(struct pci_channel *chan)
 {
        char idbuf[16];
        int i;
@@ -168,3 +159,10 @@ char * __devinit pcibios_setup(char *str)
 {
        return str;
 }
+
+struct pci_channel board_pci_channels[] = {
+       { gapspci_init, &gapspci_pci_ops, &gapspci_io_resource,
+         &gapspci_mem_resource, 0, 1 },
+       { 0, }
+};
+EXPORT_SYMBOL(board_pci_channels);
index 343c072a5a7960408b9d56520b271a30a255c007..c46911d95eca53ac4f3051d6b61848fba3ebd5e8 100644 (file)
@@ -30,7 +30,7 @@ static struct resource sh7751_mem_resource = {
 };
 
 struct pci_channel board_pci_channels[] = {
-       {&sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0x3ff},
+       { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0x3ff},
        {NULL, NULL, NULL, 0, 0},
 };
 
index 8bff32a22101e5e39e75ff39f87c8d9d31172d25..f606df2195c1f2617089454ba69934dfb8b17dea 100644 (file)
@@ -39,7 +39,7 @@ static struct resource sh7751_mem_resource = {
 extern struct pci_ops sh7751_pci_ops;
 
 struct pci_channel board_pci_channels[] = {
-       { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
+       { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
        { NULL, NULL, NULL, 0, 0 },
 };
 
index bf32ee8b1321b45c2ed346296651e4b467d83ded..b51b7e4078d0b54df8b1453eb899b502491bb4e7 100644 (file)
@@ -43,7 +43,7 @@ static struct resource sh7780_mem_resource = {
 extern struct pci_ops sh7780_pci_ops;
 
 struct pci_channel board_pci_channels[] = {
-       { &sh4_pci_ops, &sh7780_io_resource, &sh7780_mem_resource, 0, 0xff },
+       { sh7780_pci_init, &sh4_pci_ops, &sh7780_io_resource, &sh7780_mem_resource, 0, 0xff },
        { NULL, NULL, NULL, 0, 0 },
 };
 EXPORT_SYMBOL(board_pci_channels);
index e4208a697321d26d04881a992617587dc5994196..fe5a231b866983228deb651c648b7ecc56f98dd7 100644 (file)
@@ -47,7 +47,7 @@ static struct resource sh7751_mem_resource = {
 extern struct pci_ops sh7751_pci_ops;
 
 struct pci_channel board_pci_channels[] = {
-       { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
+       { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
        { NULL, NULL, NULL, 0, 0 },
 };
 EXPORT_SYMBOL(board_pci_channels);
index 21d59d4a2150ddb3fca09dfa64c6a5af0b466598..7277cd15ae6aef3daefcd584cc38962e64c0b0fc 100644 (file)
@@ -49,7 +49,7 @@ static struct resource sdk7780_mem_resource = {
 };
 
 struct pci_channel board_pci_channels[] = {
-       { &sh4_pci_ops, &sdk7780_io_resource, &sdk7780_mem_resource, 0, 0xff },
+       { sh7780_pci_init, &sh4_pci_ops, &sdk7780_io_resource, &sdk7780_mem_resource, 0, 0xff },
        { NULL, NULL, NULL, 0, 0 },
 };
 EXPORT_SYMBOL(board_pci_channels);
index 78a6f2bc4f12b93f4c41dcdfcc35cd9433fbce18..76a74fb42fb01e56baeaf72876be263e57235ae7 100644 (file)
@@ -58,7 +58,7 @@ static struct resource se7780_mem_resource = {
 extern struct pci_ops se7780_pci_ops;
 
 struct pci_channel board_pci_channels[] = {
-       { &sh4_pci_ops, &se7780_io_resource, &se7780_mem_resource, 0, 0xff },
+       { sh7780_pci_init, &sh4_pci_ops, &se7780_io_resource, &se7780_mem_resource, 0, 0xff },
        { NULL, NULL, NULL, 0, 0 },
 };
 EXPORT_SYMBOL(board_pci_channels);
index e1703ff5a4d237339264e9e4c699dcb8dc4c2073..0218135f0bb8e488b27904a425569edea257069b 100644 (file)
@@ -39,7 +39,7 @@ static struct resource sh7751_mem_resource = {
 extern struct pci_ops sh4_pci_ops;
 
 struct pci_channel board_pci_channels[] = {
-       { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
+       { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
        { NULL, NULL, NULL, 0, 0 },
 };
 
index cba80153dde983b0920248a3fa99dc54f42500a5..2e254c6cf6c1aa51f9a8813a83f4b9cd47eca77e 100644 (file)
@@ -40,7 +40,7 @@ static struct resource sh7751_mem_resource = {
 };
 
 struct pci_channel board_pci_channels[] = {
-       { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
+       { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
        { 0, }
 };
 
index 69fcc5c5d5204947fb150b76bf33af0b8b038be1..ffa79bdf475570bea85d92a045c2166178f047ec 100644 (file)
@@ -52,7 +52,7 @@ static struct resource sh7751_mem_resource = {
 };
 
 struct pci_channel board_pci_channels[] = {
-       { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
+       { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
        { NULL, NULL, NULL, 0, 0 },
 };
 EXPORT_SYMBOL(board_pci_channels);
index 7a97438762c836f5860e3854e95ea243ae0b9ac1..008a02ec0d9f8b53cdacd775d88f0a897ec88b74 100644 (file)
 unsigned long pcicr_virt;
 unsigned long PCI_IO_AREA;
 
+int __init sh5_pci_init(struct pci_channel *chan)
+{
+       pr_debug("PCI: Starting intialization.\n");
+       return pcibios_init_platform();
+}
+
 /* Rounds a number UP to the nearest power of two. Used for
  * sizing the PCI window.
  */
index 7cff3fc04d30a2fb29d2079dfbc6062723abb1eb..af09f384c7d276bb258ab75ff8f295f45ffff8f4 100644 (file)
@@ -108,6 +108,7 @@ extern unsigned long pcicr_virt;
 extern struct pci_ops sh5_pci_ops;
 
 /* arch/sh/drivers/pci/pci-sh5.c */
+int sh5_pci_init(struct pci_channel *chan);
 int sh5pci_init(unsigned long memStart, unsigned long memSize);
 
 #endif /* __PCI_SH5_H */
index 9c2c01490d626c86decbe76d58409edaeca7316a..230db8bd97443a8a38c2f9a0bceb7e7689fa90dc 100644 (file)
@@ -32,7 +32,7 @@
  * space mapping) will be called via the platform defined function
  * pcibios_init_platform().
  */
-static int __init sh7751_pci_init(void)
+int __init sh7751_pci_init(struct pci_channel *chan)
 {
        unsigned int id;
        int ret;
@@ -40,19 +40,18 @@ static int __init sh7751_pci_init(void)
        pr_debug("PCI: Starting intialization.\n");
 
        /* check for SH7751/SH7751R hardware */
-       id = pci_read_reg(NULL, SH7751_PCICONF0);
+       id = pci_read_reg(chan, SH7751_PCICONF0);
        if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) &&
            id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) {
                pr_debug("PCI: This is not an SH7751(R) (%x)\n", id);
                return -ENODEV;
        }
 
-       if ((ret = sh4_pci_check_direct(NULL)) != 0)
+       if ((ret = sh4_pci_check_direct(chan)) != 0)
                return ret;
 
        return pcibios_init_platform();
 }
-subsys_initcall(sh7751_pci_init);
 
 static int __init __area_sdram_check(struct pci_channel *chan,
                                     unsigned int area)
@@ -178,7 +177,7 @@ int __init sh7751_pcic_init(struct pci_channel *chan,
        }
 
        if (!word)
-               return 0;
+               return -1;
 
        /* configure the wait control registers */
        word = ctrl_inl(SH7751_WCR1);
@@ -202,5 +201,5 @@ int __init sh7751_pcic_init(struct pci_channel *chan,
        word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM;
        pci_write_reg(chan, word, SH4_PCICR);
 
-       return 1;
+       return 0;
 }
index 6f101e5a6c834b969a2f8d31036f103ddfa9014f..0ea4387df13612a17613fcb0735f0e919c3a51b2 100644 (file)
 struct sh4_pci_address_map;
 
 /* arch/sh/drivers/pci/pci-sh7751.c */
+int sh7751_pci_init(struct pci_channel *chan);
 int sh7751_pcic_init(struct pci_channel *chan,
                     struct sh4_pci_address_map *map);
 
index 56f673f66cb5bea1d2aa1929d06ebf906610e015..4706e880b0874c8a20b301f409f5cc32010390a0 100644 (file)
@@ -45,7 +45,7 @@
  * space mapping) will be called via the platform defined function
  * pcibios_init_platform().
  */
-static int __init sh7780_pci_init(void)
+int __init sh7780_pci_init(struct pci_channel *chan)
 {
        unsigned int id;
        int ret, match = 0;
@@ -55,7 +55,7 @@ static int __init sh7780_pci_init(void)
        ctrl_outl(0x00000001, SH7780_PCI_VCR2); /* Enable PCIC */
 
        /* check for SH7780/SH7780R hardware */
-       id = pci_read_reg(NULL, SH7780_PCIVID);
+       id = pci_read_reg(chan, SH7780_PCIVID);
        if ((id & 0xffff) == SH7780_VENDOR_ID) {
                switch ((id >> 16) & 0xffff) {
                case SH7763_DEVICE_ID:
@@ -82,12 +82,11 @@ static int __init sh7780_pci_init(void)
                ctrl_outl(0x33333333, INTC_INTPRI);
        }
 
-       if ((ret = sh4_pci_check_direct(NULL)) != 0)
+       if ((ret = sh4_pci_check_direct(chan)) != 0)
                return ret;
 
        return pcibios_init_platform();
 }
-core_initcall(sh7780_pci_init);
 
 int __init sh7780_pcic_init(struct pci_channel *chan,
                            struct sh4_pci_address_map *map)
@@ -153,5 +152,5 @@ int __init sh7780_pcic_init(struct pci_channel *chan,
        word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO;
        pci_write_reg(chan, word, SH4_PCICR);
 
-       return 1;
+       return 0;
 }
index d34961153d5834040bf3a4487b6891d2d3daf597..2f3c92065ec34dbed740ab277e7669cd56241cfd 100644 (file)
 struct sh4_pci_address_map;
 
 /* arch/sh/drivers/pci/pci-sh7780.c */
+int sh7780_pci_init(struct pci_channel *chan);
 int sh7780_pcic_init(struct pci_channel *chan,
                     struct sh4_pci_address_map *map);
 
index 0d6ac7a1db4987f55bbd874bae48fb96359fe314..29ec16e69afa2dda7da5a99014095d2fb8ea3c6d 100644 (file)
@@ -28,18 +28,31 @@ static int __init pcibios_init(void)
        struct pci_bus *bus;
        int busno;
 
+       /* init channels */
+       busno = 0;
+       for (p = board_pci_channels; p->init; p++) {
+               if (p->init(p) == 0)
+                       p->enabled = 1;
+               else
+                       pr_err("Unable to init pci channel %d\n", busno);
+               busno++;
+       }
+
 #ifdef CONFIG_PCI_AUTO
        /* assign resources */
        busno = 0;
-       for (p = board_pci_channels; p->pci_ops != NULL; p++)
-               busno = pciauto_assign_resources(busno, p) + 1;
+       for (p = board_pci_channels; p->init; p++)
+               if (p->enabled)
+                       busno = pciauto_assign_resources(busno, p) + 1;
 #endif
 
        /* scan the buses */
        busno = 0;
-       for (p = board_pci_channels; p->pci_ops != NULL; p++) {
-               bus = pci_scan_bus(busno, p->pci_ops, p);
-               busno = bus->subordinate + 1;
+       for (p = board_pci_channels; p->init; p++) {
+               if (p->enabled) {
+                       bus = pci_scan_bus(busno, p->pci_ops, p);
+                       busno = bus->subordinate + 1;
+               }
        }
 
        pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq);
index df1d383e18a51e0283b00510f496bec3c7f2aa3b..5c7a8f1d2d546c13a8f81a3ebe9391549bb23fb8 100644 (file)
  * external) PCI controllers.
  */
 struct pci_channel {
+       int (*init)(struct pci_channel *chan);
        struct pci_ops *pci_ops;
        struct resource *io_resource;
        struct resource *mem_resource;
        int first_devfn;
        int last_devfn;
+       int enabled;
 };
 
 /*