aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorMagnus Damm <damm@igel.co.jp>2009-03-11 15:46:14 +0900
committerPaul Mundt <lethal@linux-sh.org>2009-04-16 16:00:12 +0900
commitd0e3db40e2a1352aa2a2f425a7d4631bddc03d51 (patch)
tree275392db569a7f3808d8f86cfcb4874bfe81f997 /arch
parentb8b47bfbe4eb1ae0e6891e49c86a5f4fb00413be (diff)
sh: add init member to pci_channel data
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/sh/boards/mach-dreamcast/setup.c6
-rw-r--r--arch/sh/drivers/pci/ops-cayman.c2
-rw-r--r--arch/sh/drivers/pci/ops-dreamcast.c18
-rw-r--r--arch/sh/drivers/pci/ops-landisk.c2
-rw-r--r--arch/sh/drivers/pci/ops-lboxre2.c2
-rw-r--r--arch/sh/drivers/pci/ops-r7780rp.c2
-rw-r--r--arch/sh/drivers/pci/ops-rts7751r2d.c2
-rw-r--r--arch/sh/drivers/pci/ops-sdk7780.c2
-rw-r--r--arch/sh/drivers/pci/ops-se7780.c2
-rw-r--r--arch/sh/drivers/pci/ops-sh03.c2
-rw-r--r--arch/sh/drivers/pci/ops-snapgear.c2
-rw-r--r--arch/sh/drivers/pci/ops-titan.c2
-rw-r--r--arch/sh/drivers/pci/pci-sh5.c6
-rw-r--r--arch/sh/drivers/pci/pci-sh5.h1
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.c11
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.h1
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c9
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.h1
-rw-r--r--arch/sh/drivers/pci/pci.c23
-rw-r--r--arch/sh/include/asm/pci.h2
20 files changed, 56 insertions, 42 deletions
diff --git a/arch/sh/boards/mach-dreamcast/setup.c b/arch/sh/boards/mach-dreamcast/setup.c
index d1bee4884cd..ebe99227d4e 100644
--- a/arch/sh/boards/mach-dreamcast/setup.c
+++ b/arch/sh/boards/mach-dreamcast/setup.c
@@ -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 = {
diff --git a/arch/sh/drivers/pci/ops-cayman.c b/arch/sh/drivers/pci/ops-cayman.c
index 38ef76207af..f4a5e14f7e5 100644
--- a/arch/sh/drivers/pci/ops-cayman.c
+++ b/arch/sh/drivers/pci/ops-cayman.c
@@ -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);
diff --git a/arch/sh/drivers/pci/ops-dreamcast.c b/arch/sh/drivers/pci/ops-dreamcast.c
index f5d2a2aa6f3..f62063eb649 100644
--- a/arch/sh/drivers/pci/ops-dreamcast.c
+++ b/arch/sh/drivers/pci/ops-dreamcast.c
@@ -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);
diff --git a/arch/sh/drivers/pci/ops-landisk.c b/arch/sh/drivers/pci/ops-landisk.c
index 343c072a5a7..c46911d95ec 100644
--- a/arch/sh/drivers/pci/ops-landisk.c
+++ b/arch/sh/drivers/pci/ops-landisk.c
@@ -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},
};
diff --git a/arch/sh/drivers/pci/ops-lboxre2.c b/arch/sh/drivers/pci/ops-lboxre2.c
index 8bff32a2210..f606df2195c 100644
--- a/arch/sh/drivers/pci/ops-lboxre2.c
+++ b/arch/sh/drivers/pci/ops-lboxre2.c
@@ -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 },
};
diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c
index bf32ee8b132..b51b7e4078d 100644
--- a/arch/sh/drivers/pci/ops-r7780rp.c
+++ b/arch/sh/drivers/pci/ops-r7780rp.c
@@ -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);
diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c
index e4208a69732..fe5a231b866 100644
--- a/arch/sh/drivers/pci/ops-rts7751r2d.c
+++ b/arch/sh/drivers/pci/ops-rts7751r2d.c
@@ -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);
diff --git a/arch/sh/drivers/pci/ops-sdk7780.c b/arch/sh/drivers/pci/ops-sdk7780.c
index 21d59d4a215..7277cd15ae6 100644
--- a/arch/sh/drivers/pci/ops-sdk7780.c
+++ b/arch/sh/drivers/pci/ops-sdk7780.c
@@ -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);
diff --git a/arch/sh/drivers/pci/ops-se7780.c b/arch/sh/drivers/pci/ops-se7780.c
index 78a6f2bc4f1..76a74fb42fb 100644
--- a/arch/sh/drivers/pci/ops-se7780.c
+++ b/arch/sh/drivers/pci/ops-se7780.c
@@ -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);
diff --git a/arch/sh/drivers/pci/ops-sh03.c b/arch/sh/drivers/pci/ops-sh03.c
index e1703ff5a4d..0218135f0bb 100644
--- a/arch/sh/drivers/pci/ops-sh03.c
+++ b/arch/sh/drivers/pci/ops-sh03.c
@@ -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 },
};
diff --git a/arch/sh/drivers/pci/ops-snapgear.c b/arch/sh/drivers/pci/ops-snapgear.c
index cba80153dde..2e254c6cf6c 100644
--- a/arch/sh/drivers/pci/ops-snapgear.c
+++ b/arch/sh/drivers/pci/ops-snapgear.c
@@ -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, }
};
diff --git a/arch/sh/drivers/pci/ops-titan.c b/arch/sh/drivers/pci/ops-titan.c
index 69fcc5c5d52..ffa79bdf475 100644
--- a/arch/sh/drivers/pci/ops-titan.c
+++ b/arch/sh/drivers/pci/ops-titan.c
@@ -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);
diff --git a/arch/sh/drivers/pci/pci-sh5.c b/arch/sh/drivers/pci/pci-sh5.c
index 7a97438762c..008a02ec0d9 100644
--- a/arch/sh/drivers/pci/pci-sh5.c
+++ b/arch/sh/drivers/pci/pci-sh5.c
@@ -27,6 +27,12 @@
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.
*/
diff --git a/arch/sh/drivers/pci/pci-sh5.h b/arch/sh/drivers/pci/pci-sh5.h
index 7cff3fc04d3..af09f384c7d 100644
--- a/arch/sh/drivers/pci/pci-sh5.h
+++ b/arch/sh/drivers/pci/pci-sh5.h
@@ -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 */
diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c
index 9c2c01490d6..230db8bd974 100644
--- a/arch/sh/drivers/pci/pci-sh7751.c
+++ b/arch/sh/drivers/pci/pci-sh7751.c
@@ -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;
}
diff --git a/arch/sh/drivers/pci/pci-sh7751.h b/arch/sh/drivers/pci/pci-sh7751.h
index 6f101e5a6c8..0ea4387df13 100644
--- a/arch/sh/drivers/pci/pci-sh7751.h
+++ b/arch/sh/drivers/pci/pci-sh7751.h
@@ -130,6 +130,7 @@
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);
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index 56f673f66cb..4706e880b08 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -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;
}
diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h
index d34961153d5..2f3c92065ec 100644
--- a/arch/sh/drivers/pci/pci-sh7780.h
+++ b/arch/sh/drivers/pci/pci-sh7780.h
@@ -109,6 +109,7 @@
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);
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index 0d6ac7a1db4..29ec16e69af 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -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);
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h
index df1d383e18a..5c7a8f1d2d5 100644
--- a/arch/sh/include/asm/pci.h
+++ b/arch/sh/include/asm/pci.h
@@ -17,11 +17,13 @@
* 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;
};
/*