Commit d0e3db40 authored by Magnus Damm's avatar Magnus Damm Committed by Paul Mundt

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: default avatarMagnus Damm <damm@igel.co.jp>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent b8b47bfb
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
extern struct irq_chip systemasic_int; extern struct irq_chip systemasic_int;
extern void aica_time_init(void); extern void aica_time_init(void);
extern int gapspci_init(void);
extern int systemasic_irq_demux(int); extern int systemasic_irq_demux(int);
static void __init dreamcast_setup(char **cmdline_p) static void __init dreamcast_setup(char **cmdline_p)
...@@ -51,11 +50,6 @@ static void __init dreamcast_setup(char **cmdline_p) ...@@ -51,11 +50,6 @@ static void __init dreamcast_setup(char **cmdline_p)
handle_level_irq); handle_level_irq);
board_time_init = aica_time_init; 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 = { static struct sh_machine_vector mv_dreamcast __initmv = {
......
...@@ -77,7 +77,7 @@ int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) ...@@ -77,7 +77,7 @@ int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin)
} }
struct pci_channel board_pci_channels[] = { 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 }, { NULL, NULL, NULL, 0, 0 },
}; };
EXPORT_SYMBOL(board_pci_channels); EXPORT_SYMBOL(board_pci_channels);
......
...@@ -42,15 +42,6 @@ static struct resource gapspci_mem_resource = { ...@@ -42,15 +42,6 @@ static struct resource gapspci_mem_resource = {
.flags = IORESOURCE_MEM, .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 * The !gapspci_config_access case really shouldn't happen, ever, unless
* someone implicitly messes around with the last devfn value.. otherwise we * someone implicitly messes around with the last devfn value.. otherwise we
...@@ -116,7 +107,7 @@ static struct pci_ops gapspci_pci_ops = { ...@@ -116,7 +107,7 @@ static struct pci_ops gapspci_pci_ops = {
* gapspci init * gapspci init
*/ */
int __init gapspci_init(void) static int __init gapspci_init(struct pci_channel *chan)
{ {
char idbuf[16]; char idbuf[16];
int i; int i;
...@@ -168,3 +159,10 @@ char * __devinit pcibios_setup(char *str) ...@@ -168,3 +159,10 @@ char * __devinit pcibios_setup(char *str)
{ {
return 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);
...@@ -30,7 +30,7 @@ static struct resource sh7751_mem_resource = { ...@@ -30,7 +30,7 @@ static struct resource sh7751_mem_resource = {
}; };
struct pci_channel board_pci_channels[] = { 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}, {NULL, NULL, NULL, 0, 0},
}; };
......
...@@ -39,7 +39,7 @@ static struct resource sh7751_mem_resource = { ...@@ -39,7 +39,7 @@ static struct resource sh7751_mem_resource = {
extern struct pci_ops sh7751_pci_ops; extern struct pci_ops sh7751_pci_ops;
struct pci_channel board_pci_channels[] = { 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 }, { NULL, NULL, NULL, 0, 0 },
}; };
......
...@@ -43,7 +43,7 @@ static struct resource sh7780_mem_resource = { ...@@ -43,7 +43,7 @@ static struct resource sh7780_mem_resource = {
extern struct pci_ops sh7780_pci_ops; extern struct pci_ops sh7780_pci_ops;
struct pci_channel board_pci_channels[] = { 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 }, { NULL, NULL, NULL, 0, 0 },
}; };
EXPORT_SYMBOL(board_pci_channels); EXPORT_SYMBOL(board_pci_channels);
......
...@@ -47,7 +47,7 @@ static struct resource sh7751_mem_resource = { ...@@ -47,7 +47,7 @@ static struct resource sh7751_mem_resource = {
extern struct pci_ops sh7751_pci_ops; extern struct pci_ops sh7751_pci_ops;
struct pci_channel board_pci_channels[] = { 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 }, { NULL, NULL, NULL, 0, 0 },
}; };
EXPORT_SYMBOL(board_pci_channels); EXPORT_SYMBOL(board_pci_channels);
......
...@@ -49,7 +49,7 @@ static struct resource sdk7780_mem_resource = { ...@@ -49,7 +49,7 @@ static struct resource sdk7780_mem_resource = {
}; };
struct pci_channel board_pci_channels[] = { 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 }, { NULL, NULL, NULL, 0, 0 },
}; };
EXPORT_SYMBOL(board_pci_channels); EXPORT_SYMBOL(board_pci_channels);
......
...@@ -58,7 +58,7 @@ static struct resource se7780_mem_resource = { ...@@ -58,7 +58,7 @@ static struct resource se7780_mem_resource = {
extern struct pci_ops se7780_pci_ops; extern struct pci_ops se7780_pci_ops;
struct pci_channel board_pci_channels[] = { 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 }, { NULL, NULL, NULL, 0, 0 },
}; };
EXPORT_SYMBOL(board_pci_channels); EXPORT_SYMBOL(board_pci_channels);
......
...@@ -39,7 +39,7 @@ static struct resource sh7751_mem_resource = { ...@@ -39,7 +39,7 @@ static struct resource sh7751_mem_resource = {
extern struct pci_ops sh4_pci_ops; extern struct pci_ops sh4_pci_ops;
struct pci_channel board_pci_channels[] = { 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 }, { NULL, NULL, NULL, 0, 0 },
}; };
...@@ -40,7 +40,7 @@ static struct resource sh7751_mem_resource = { ...@@ -40,7 +40,7 @@ static struct resource sh7751_mem_resource = {
}; };
struct pci_channel board_pci_channels[] = { 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, } { 0, }
}; };
......
...@@ -52,7 +52,7 @@ static struct resource sh7751_mem_resource = { ...@@ -52,7 +52,7 @@ static struct resource sh7751_mem_resource = {
}; };
struct pci_channel board_pci_channels[] = { 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 }, { NULL, NULL, NULL, 0, 0 },
}; };
EXPORT_SYMBOL(board_pci_channels); EXPORT_SYMBOL(board_pci_channels);
......
...@@ -27,6 +27,12 @@ ...@@ -27,6 +27,12 @@
unsigned long pcicr_virt; unsigned long pcicr_virt;
unsigned long PCI_IO_AREA; 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 /* Rounds a number UP to the nearest power of two. Used for
* sizing the PCI window. * sizing the PCI window.
*/ */
......
...@@ -108,6 +108,7 @@ extern unsigned long pcicr_virt; ...@@ -108,6 +108,7 @@ extern unsigned long pcicr_virt;
extern struct pci_ops sh5_pci_ops; extern struct pci_ops sh5_pci_ops;
/* arch/sh/drivers/pci/pci-sh5.c */ /* arch/sh/drivers/pci/pci-sh5.c */
int sh5_pci_init(struct pci_channel *chan);
int sh5pci_init(unsigned long memStart, unsigned long memSize); int sh5pci_init(unsigned long memStart, unsigned long memSize);
#endif /* __PCI_SH5_H */ #endif /* __PCI_SH5_H */
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
* space mapping) will be called via the platform defined function * space mapping) will be called via the platform defined function
* pcibios_init_platform(). * pcibios_init_platform().
*/ */
static int __init sh7751_pci_init(void) int __init sh7751_pci_init(struct pci_channel *chan)
{ {
unsigned int id; unsigned int id;
int ret; int ret;
...@@ -40,19 +40,18 @@ static int __init sh7751_pci_init(void) ...@@ -40,19 +40,18 @@ static int __init sh7751_pci_init(void)
pr_debug("PCI: Starting intialization.\n"); pr_debug("PCI: Starting intialization.\n");
/* check for SH7751/SH7751R hardware */ /* 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) && if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) &&
id != ((SH7751R_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); pr_debug("PCI: This is not an SH7751(R) (%x)\n", id);
return -ENODEV; return -ENODEV;
} }
if ((ret = sh4_pci_check_direct(NULL)) != 0) if ((ret = sh4_pci_check_direct(chan)) != 0)
return ret; return ret;
return pcibios_init_platform(); return pcibios_init_platform();
} }
subsys_initcall(sh7751_pci_init);
static int __init __area_sdram_check(struct pci_channel *chan, static int __init __area_sdram_check(struct pci_channel *chan,
unsigned int area) unsigned int area)
...@@ -178,7 +177,7 @@ int __init sh7751_pcic_init(struct pci_channel *chan, ...@@ -178,7 +177,7 @@ int __init sh7751_pcic_init(struct pci_channel *chan,
} }
if (!word) if (!word)
return 0; return -1;
/* configure the wait control registers */ /* configure the wait control registers */
word = ctrl_inl(SH7751_WCR1); word = ctrl_inl(SH7751_WCR1);
...@@ -202,5 +201,5 @@ int __init sh7751_pcic_init(struct pci_channel *chan, ...@@ -202,5 +201,5 @@ int __init sh7751_pcic_init(struct pci_channel *chan,
word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM; word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM;
pci_write_reg(chan, word, SH4_PCICR); pci_write_reg(chan, word, SH4_PCICR);
return 1; return 0;
} }
...@@ -130,6 +130,7 @@ ...@@ -130,6 +130,7 @@
struct sh4_pci_address_map; struct sh4_pci_address_map;
/* arch/sh/drivers/pci/pci-sh7751.c */ /* arch/sh/drivers/pci/pci-sh7751.c */
int sh7751_pci_init(struct pci_channel *chan);
int sh7751_pcic_init(struct pci_channel *chan, int sh7751_pcic_init(struct pci_channel *chan,
struct sh4_pci_address_map *map); struct sh4_pci_address_map *map);
......
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
* space mapping) will be called via the platform defined function * space mapping) will be called via the platform defined function
* pcibios_init_platform(). * pcibios_init_platform().
*/ */
static int __init sh7780_pci_init(void) int __init sh7780_pci_init(struct pci_channel *chan)
{ {
unsigned int id; unsigned int id;
int ret, match = 0; int ret, match = 0;
...@@ -55,7 +55,7 @@ static int __init sh7780_pci_init(void) ...@@ -55,7 +55,7 @@ static int __init sh7780_pci_init(void)
ctrl_outl(0x00000001, SH7780_PCI_VCR2); /* Enable PCIC */ ctrl_outl(0x00000001, SH7780_PCI_VCR2); /* Enable PCIC */
/* check for SH7780/SH7780R hardware */ /* 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) { if ((id & 0xffff) == SH7780_VENDOR_ID) {
switch ((id >> 16) & 0xffff) { switch ((id >> 16) & 0xffff) {
case SH7763_DEVICE_ID: case SH7763_DEVICE_ID:
...@@ -82,12 +82,11 @@ static int __init sh7780_pci_init(void) ...@@ -82,12 +82,11 @@ static int __init sh7780_pci_init(void)
ctrl_outl(0x33333333, INTC_INTPRI); ctrl_outl(0x33333333, INTC_INTPRI);
} }
if ((ret = sh4_pci_check_direct(NULL)) != 0) if ((ret = sh4_pci_check_direct(chan)) != 0)
return ret; return ret;
return pcibios_init_platform(); return pcibios_init_platform();
} }
core_initcall(sh7780_pci_init);
int __init sh7780_pcic_init(struct pci_channel *chan, int __init sh7780_pcic_init(struct pci_channel *chan,
struct sh4_pci_address_map *map) struct sh4_pci_address_map *map)
...@@ -153,5 +152,5 @@ int __init sh7780_pcic_init(struct pci_channel *chan, ...@@ -153,5 +152,5 @@ int __init sh7780_pcic_init(struct pci_channel *chan,
word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO; word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO;
pci_write_reg(chan, word, SH4_PCICR); pci_write_reg(chan, word, SH4_PCICR);
return 1; return 0;
} }
...@@ -109,6 +109,7 @@ ...@@ -109,6 +109,7 @@
struct sh4_pci_address_map; struct sh4_pci_address_map;
/* arch/sh/drivers/pci/pci-sh7780.c */ /* arch/sh/drivers/pci/pci-sh7780.c */
int sh7780_pci_init(struct pci_channel *chan);
int sh7780_pcic_init(struct pci_channel *chan, int sh7780_pcic_init(struct pci_channel *chan,
struct sh4_pci_address_map *map); struct sh4_pci_address_map *map);
......
...@@ -28,19 +28,32 @@ static int __init pcibios_init(void) ...@@ -28,19 +28,32 @@ static int __init pcibios_init(void)
struct pci_bus *bus; struct pci_bus *bus;
int busno; 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 #ifdef CONFIG_PCI_AUTO
/* assign resources */ /* assign resources */
busno = 0; busno = 0;
for (p = board_pci_channels; p->pci_ops != NULL; p++) for (p = board_pci_channels; p->init; p++)
if (p->enabled)
busno = pciauto_assign_resources(busno, p) + 1; busno = pciauto_assign_resources(busno, p) + 1;
#endif #endif
/* scan the buses */ /* scan the buses */
busno = 0; busno = 0;
for (p = board_pci_channels; p->pci_ops != NULL; p++) { for (p = board_pci_channels; p->init; p++) {
if (p->enabled) {
bus = pci_scan_bus(busno, p->pci_ops, p); bus = pci_scan_bus(busno, p->pci_ops, p);
busno = bus->subordinate + 1; busno = bus->subordinate + 1;
} }
}
pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq); pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq);
......
...@@ -17,11 +17,13 @@ ...@@ -17,11 +17,13 @@
* external) PCI controllers. * external) PCI controllers.
*/ */
struct pci_channel { struct pci_channel {
int (*init)(struct pci_channel *chan);
struct pci_ops *pci_ops; struct pci_ops *pci_ops;
struct resource *io_resource; struct resource *io_resource;
struct resource *mem_resource; struct resource *mem_resource;
int first_devfn; int first_devfn;
int last_devfn; int last_devfn;
int enabled;
}; };
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment