Commit f46c7a6f authored by Russell King's avatar Russell King

[ARM] 2.5.15 PCI cleanups/fixups

2.5.15 removes the pcibios_init() call from the generic PCI layer to
the architecture layers.  This allows us to clean up the ARM PCI
layer by moving the machine specific PCI initialisation from
arch/arm/kernel/bios32.c to the machine specific files.

We also fix a bug in the resource flags in the iop310 initialisation.
parent 47a00fe0
......@@ -545,73 +545,8 @@ static void __init pcibios_init_hw(struct hw_pci *hw)
}
}
extern struct hw_pci ebsa285_pci;
extern struct hw_pci cats_pci;
extern struct hw_pci netwinder_pci;
extern struct hw_pci personal_server_pci;
extern struct hw_pci ftv_pci;
extern struct hw_pci shark_pci;
extern struct hw_pci integrator_pci;
extern struct hw_pci iq80310_pci;
void __init pcibios_init(void)
void __init pci_common_init(struct hw_pci *hw)
{
struct hw_pci *hw = NULL;
do {
#ifdef CONFIG_ARCH_EBSA285
if (machine_is_ebsa285()) {
hw = &ebsa285_pci;
break;
}
#endif
#ifdef CONFIG_ARCH_SHARK
if (machine_is_shark()) {
hw = &shark_pci;
break;
}
#endif
#ifdef CONFIG_ARCH_CATS
if (machine_is_cats()) {
hw = &cats_pci;
break;
}
#endif
#ifdef CONFIG_ARCH_NETWINDER
if (machine_is_netwinder()) {
hw = &netwinder_pci;
break;
}
#endif
#ifdef CONFIG_ARCH_PERSONAL_SERVER
if (machine_is_personal_server()) {
hw = &personal_server_pci;
break;
}
#endif
#ifdef CONFIG_ARCH_FTVPCI
if (machine_is_ftvpci()) {
hw = &ftv_pci;
break;
}
#endif
#ifdef CONFIG_ARCH_INTEGRATOR
if (machine_is_integrator()) {
hw = &integrator_pci;
break;
}
#endif
#ifdef CONFIG_ARCH_IQ80310
if (machine_is_iq80310()) {
hw = &iq80310_pci;
break;
}
#endif
} while (0);
if (hw == NULL)
return;
if (hw->preinit)
hw->preinit();
pcibios_init_hw(hw);
......
......@@ -11,6 +11,7 @@
#include <asm/irq.h>
#include <asm/mach/pci.h>
#include <asm/mach-types.h>
/* cats host-specific stuff */
static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 };
......@@ -34,7 +35,7 @@ static int __init cats_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
* why not the standard PCI swizzle? does this prevent 4-port tulip
* cards being used (ie, pci-pci bridge based cards)?
*/
struct hw_pci cats_pci __initdata = {
static struct hw_pci cats_pci __initdata = {
swizzle: NULL,
map_irq: cats_map_irq,
nr_controllers: 1,
......@@ -43,3 +44,12 @@ struct hw_pci cats_pci __initdata = {
preinit: dc21285_preinit,
postinit: dc21285_postinit,
};
static int cats_pci_init(void)
{
if (machine_is_cats())
pci_common_init(&cats_pci);
return 0;
}
subsys_initcall(cats_pci_init);
/*
* linux/arch/arm/kernel/dec21285.c: PCI functions for DC21285
*
* Copyright (C) 1998-2000 Russell King, Phil Blundell
* Copyright (C) 1998-2001 Russell King
* Copyright (C) 1998-2000 Phil Blundell
*
* 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
......@@ -261,31 +262,45 @@ static void dc21285_parity_irq(int irq, void *dev_id, struct pt_regs *regs)
add_timer(timer);
}
void __init dc21285_setup_resources(struct resource **resource)
int __init dc21285_setup(int nr, struct pci_sys_data *sys)
{
struct resource *busmem, *busmempf;
struct resource *res;
busmem = kmalloc(sizeof(*busmem), GFP_KERNEL);
busmempf = kmalloc(sizeof(*busmempf), GFP_KERNEL);
memset(busmem, 0, sizeof(*busmem));
memset(busmempf, 0, sizeof(*busmempf));
if (nr || !footbridge_cfn_mode())
return 0;
busmem->flags = IORESOURCE_MEM;
busmem->name = "Footbridge non-prefetch";
busmempf->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
busmempf->name = "Footbridge prefetch";
res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL);
if (!res) {
printk("out of memory for root bus resources");
return 0;
}
memset(res, 0, sizeof(struct resource) * 2);
allocate_resource(&iomem_resource, busmempf, 0x20000000,
0x80000000, 0xffffffff, 0x20000000, NULL, NULL);
allocate_resource(&iomem_resource, busmem, 0x40000000,
res[0].flags = IORESOURCE_MEM;
res[0].name = "Footbridge non-prefetch";
res[1].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
res[1].name = "Footbridge prefetch";
allocate_resource(&iomem_resource, &res[1], 0x20000000,
0xa0000000, 0xffffffff, 0x20000000, NULL, NULL);
allocate_resource(&iomem_resource, &res[0], 0x40000000,
0x80000000, 0xffffffff, 0x40000000, NULL, NULL);
resource[0] = &ioport_resource;
resource[1] = busmem;
resource[2] = busmempf;
sys->resource[0] = &ioport_resource;
sys->resource[1] = &res[0];
sys->resource[2] = &res[1];
sys->mem_offset = DC21285_PCI_MEM;
return 1;
}
struct pci_bus * __init dc21285_scan_bus(int nr, struct pci_sys_data *sys)
{
return pci_scan_bus(0, &dc21285_ops, sys);
}
void __init dc21285_init(void *sysdata)
void __init dc21285_preinit(void)
{
unsigned int mem_size, mem_mask;
int cfn_mode;
......@@ -313,17 +328,13 @@ void __init dc21285_init(void *sysdata)
"central function" : "addin");
if (cfn_mode) {
static struct resource csrmem, csrio;
static struct resource csrio;
csrio.flags = IORESOURCE_IO;
csrio.name = "Footbridge";
csrmem.flags = IORESOURCE_MEM;
csrmem.name = "Footbridge";
allocate_resource(&ioport_resource, &csrio, 128,
0xff00, 0xffff, 128, NULL, NULL);
allocate_resource(&iomem_resource, &csrmem, 128,
0xf4000000, 0xf8000000, 128, NULL, NULL);
/*
* Map our SDRAM at a known address in PCI space, just in case
......@@ -331,22 +342,12 @@ void __init dc21285_init(void *sysdata)
* necessary, since some VGA cards forcefully use PCI addresses
* in the range 0x000a0000 to 0x000c0000. (eg, S3 cards).
*/
*CSR_PCICSRBASE = csrmem.start;
*CSR_PCICSRBASE = 0xf4000000;
*CSR_PCICSRIOBASE = csrio.start;
*CSR_PCISDRAMBASE = __virt_to_bus(PAGE_OFFSET);
*CSR_PCIROMBASE = 0;
*CSR_PCICMD = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
PCI_COMMAND_INVALIDATE | PCICMD_ERROR_BITS;
pci_scan_bus(0, &dc21285_ops, sysdata);
/*
* Clear any existing errors - we aren't
* interested in historical data...
*/
*CSR_SA110_CNTL = (*CSR_SA110_CNTL & 0xffffde07) |
SA110_CNTL_RXSERR;
*CSR_PCICMD = (*CSR_PCICMD & 0xffff) | PCICMD_ERROR_BITS;
} else if (footbridge_cfn_mode() != 0) {
/*
* If we are not compiled to accept "add-in" mode, then
......@@ -357,6 +358,19 @@ void __init dc21285_init(void *sysdata)
panic("PCI: this kernel is compiled for central "
"function mode only");
}
}
void __init dc21285_postinit(void)
{
if (footbridge_cfn_mode()) {
/*
* Clear any existing errors - we aren't
* interested in historical data...
*/
*CSR_SA110_CNTL = (*CSR_SA110_CNTL & 0xffffde07) |
SA110_CNTL_RXSERR;
*CSR_PCICMD = (*CSR_PCICMD & 0xffff) | PCICMD_ERROR_BITS;
}
/*
* Initialise PCI error IRQ after we've finished probing
......
......@@ -11,6 +11,7 @@
#include <asm/irq.h>
#include <asm/mach/pci.h>
#include <asm/mach-types.h>
static int irqmap_ebsa285[] __initdata = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI };
......@@ -27,7 +28,7 @@ static int __init ebsa285_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
return irqmap_ebsa285[(slot + pin) & 3];
}
struct hw_pci ebsa285_pci __initdata = {
static struct hw_pci ebsa285_pci __initdata = {
swizzle: pci_std_swizzle,
map_irq: ebsa285_map_irq,
nr_controllers: 1,
......@@ -36,3 +37,12 @@ struct hw_pci ebsa285_pci __initdata = {
preinit: dc21285_preinit,
postinit: dc21285_postinit,
};
static int __init ebsa285_init_pci(void)
{
if (machine_is_ebsa285())
pci_common_init(&ebsa285_pci);
return 0;
}
subsys_initcall(ebsa285_init_pci);
......@@ -11,6 +11,7 @@
#include <asm/irq.h>
#include <asm/mach/pci.h>
#include <asm/mach-types.h>
/*
* We now use the slot ID instead of the device identifiers to select
......@@ -41,7 +42,7 @@ static int __init netwinder_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
}
}
struct hw_pci netwinder_pci __initdata = {
static struct hw_pci netwinder_pci __initdata = {
swizzle: pci_std_swizzle,
map_irq: netwinder_map_irq,
nr_controllers: 1,
......@@ -50,3 +51,12 @@ struct hw_pci netwinder_pci __initdata = {
preinit: dc21285_preinit,
postinit: dc21285_postinit,
};
static int __init netwinder_pci_init(void)
{
if (machine_is_netwinder())
pci_common_init(&netwinder_pci);
return 0;
}
subsys_initcall(netwinder_pci_init);
......@@ -11,6 +11,7 @@
#include <asm/irq.h>
#include <asm/mach/pci.h>
#include <asm/mach-types.h>
static int irqmap_personal_server[] __initdata = {
IRQ_IN0, IRQ_IN1, IRQ_IN2, IRQ_IN3, 0, 0, 0,
......@@ -36,7 +37,7 @@ static int __init personal_server_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
return irqmap_personal_server[(line - 1) & 3];
}
struct hw_pci personal_server_pci __initdata = {
static struct hw_pci personal_server_pci __initdata = {
map_irq: personal_server_map_irq,
nr_controllers: 1,
setup: dc21285_setup,
......@@ -44,3 +45,12 @@ struct hw_pci personal_server_pci __initdata = {
preinit: dc21285_preinit,
postinit: dc21285_postinit,
};
static int __init personal_pci_init(void)
{
if (machine_is_personal_server())
pci_common_init(&personal_server_pci);
return 0;
}
subsys_initcall(&personal_pci_init);
......@@ -11,6 +11,7 @@
#include <asm/irq.h>
#include <asm/mach/pci.h>
#include <asm/mach-types.h>
/*
* Owing to a PCB cockup, issue A backplanes are wired thus:
......@@ -43,9 +44,17 @@ static u8 __init ftv_swizzle(struct pci_dev *dev, u8 *pin)
}
/* ftv host-specific stuff */
struct hw_pci ftv_pci __initdata = {
static struct hw_pci ftv_pci __initdata = {
init: plx90x0_init,
swizzle: ftv_swizzle,
map_irq: ftv_map_irq,
};
static int __init ftv_pci_init(void)
{
if (machine_is_ftvpci())
pci_common_init(&ftv_pci);
return 0;
}
subsys_initcall(ftv_pci_init);
......@@ -31,6 +31,7 @@
#include <asm/irq.h>
#include <asm/system.h>
#include <asm/mach/pci.h>
#include <asm/mach-types.h>
/*
* A small note about bridges and interrupts. The DECchip 21050 (and
......@@ -112,7 +113,7 @@ static int __init integrator_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
extern void pci_v3_init(void *);
struct hw_pci integrator_pci __initdata = {
static struct hw_pci integrator_pci __initdata = {
swizzle: integrator_swizzle,
map_irq: integrator_map_irq,
setup: pci_v3_setup,
......@@ -121,3 +122,12 @@ struct hw_pci integrator_pci __initdata = {
preinit: pci_v3_preinit,
postinit: pci_v3_postinit,
};
static int __init integrator_pci_init(void)
{
if (machine_is_integrator())
pci_common_init(&integrator_pci);
return 0;
}
subsys_initcall(integrator_pci_init);
......@@ -452,20 +452,24 @@ int iop310_setup(int nr, struct pci_sys_data *sys)
res[0].start = IOP310_PCIPRI_LOWER_IO + 0x6e000000;
res[0].end = IOP310_PCIPRI_LOWER_IO + 0x6e00ffff;
res[0].name = "PCI IO Primary";
res[0].flags = IORESOURCE_IO;
res[1].start = IOP310_PCIPRI_LOWER_MEM;
res[1].end = IOP310_PCIPRI_LOWER_MEM + IOP310_PCI_WINDOW_SIZE;
res[1].name = "PCI Memory Primary";
res[1].flags = IORESOURCE_MEM;
break;
case 1:
res[0].start = IOP310_PCISEC_LOWER_IO + 0x6e000000;
res[0].end = IOP310_PCISEC_LOWER_IO + 0x6e00ffff;
res[0].name = "PCI IO Secondary";
res[0].flags = IORESOURCE_IO;
res[1].start = IOP310_PCISEC_LOWER_MEM;
res[1].end = IOP310_PCISEC_LOWER_MEM + IOP310_PCI_WINDOW_SIZE;
res[1].name = "PCI Memory Secondary";
res[1].flags = IORESOURCE_MEM;
break;
}
......
......@@ -18,6 +18,7 @@
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/mach/pci.h>
#include <asm/mach-types.h>
/*
* The following macro is used to lookup irqs in a standard table
......@@ -140,10 +141,19 @@ static void iq80310_preinit(void)
iop310_init();
}
struct hw_pci iq80310_pci __initdata = {
static struct hw_pci iq80310_pci __initdata = {
swizzle: pci_std_swizzle,
nr_controllers: 2,
setup: iq80310_setup,
scan: iop310_scan_bus,
preinit: iq80310_preinit,
};
static int __init iq80310_pci_init(void)
{
if (machine_is_iq80310())
pci_common_init(&iq80310_pci);
return 0;
}
subsys_initcall(iq80310_pci_init);
......@@ -11,6 +11,7 @@
#include <asm/irq.h>
#include <asm/mach/pci.h>
#include <asm/mach-types.h>
static int __init shark_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
......@@ -22,7 +23,7 @@ static int __init shark_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
extern void __init via82c505_preinit(void *sysdata);
struct hw_pci shark_pci __initdata = {
static struct hw_pci shark_pci __initdata = {
setup: via82c505_setup,
swizzle: pci_std_swizzle,
map_irq: shark_map_irq,
......@@ -30,3 +31,12 @@ struct hw_pci shark_pci __initdata = {
scan: via82c505_scan_bus,
preinit: via82c505_preinit
};
static int __init shark_pci_init(void)
{
if (machine_is_shark())
pci_common_init(&shark_pci);
return 0;
}
subsys_initcall(shark_pci_init);
......@@ -12,27 +12,13 @@ struct pci_sys_data;
struct pci_bus;
struct hw_pci {
/* START OF OLD STUFF */
/* Initialise the hardware */
void (*init)(void *);
/* Setup bus resources */
void (*setup_resources)(struct resource **);
/* IRQ swizzle */
u8 (*swizzle)(struct pci_dev *dev, u8 *pin);
/* IRQ mapping */
int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin);
/* END OF OLD STUFF */
/* NEW STUFF */
int nr_controllers;
int (*setup)(int nr, struct pci_sys_data *);
struct pci_bus *(*scan)(int nr, struct pci_sys_data *);
void (*preinit)(void);
void (*postinit)(void);
u8 (*swizzle)(struct pci_dev *dev, u8 *pin);
int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin);
};
/*
......@@ -56,6 +42,11 @@ struct pci_sys_data {
*/
u8 pci_std_swizzle(struct pci_dev *dev, u8 *pinp);
/*
* Call this with your hw_pci struct to initialise the PCI system.
*/
void pci_common_init(struct hw_pci *);
/*
* PCI controllers
*/
......@@ -70,7 +61,7 @@ extern void dc21285_postinit(void);
extern int via82c505_setup(int nr, struct pci_sys_data *);
extern struct pci_bus *via82c505_scan_bus(int nr, struct pci_sys_data *);
extern void __init via82c505_init(void *sysdata);
extern void via82c505_init(void *sysdata);
extern int pci_v3_setup(int nr, struct pci_sys_data *);
extern struct pci_bus *pci_v3_scan_bus(int nr, struct pci_sys_data *);
......
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