X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Farm%2Fmach-ixp4xx%2Fcommon-pci.c;h=9562177b5fe1454c680a2ed0dc151cd25dbbc503;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=c20dc322695323452fd5dc4a2d221a7296098002;hpb=e812ccbe0c915857ebea6a632bfadc631f7504a9;p=linux-2.6.git diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index c20dc3226..9562177b5 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -33,7 +33,6 @@ #include #include #include -#include /* @@ -54,7 +53,7 @@ unsigned long ixp4xx_pci_reg_base = 0; * these transactions are atomic or we will end up * with corrupt data on the bus or in a driver. */ -static spinlock_t ixp4xx_pci_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(ixp4xx_pci_lock); /* * Read from PCI config space @@ -239,9 +238,10 @@ static u32 byte_lane_enable_bits(u32 n, int size) return 0xffffffff; } -static int read_config(u8 bus_num, u16 devfn, int where, int size, u32 *value) +static int ixp4xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) { u32 n, byte_enables, addr, data; + u8 bus_num = bus->number; pr_debug("read_config from %d size %d dev %d:%d:%d\n", where, size, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn)); @@ -261,9 +261,10 @@ static int read_config(u8 bus_num, u16 devfn, int where, int size, u32 *value) return PCIBIOS_SUCCESSFUL; } -static int write_config(u8 bus_num, u16 devfn, int where, int size, u32 value) +static int ixp4xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) { u32 n, byte_enables, addr, data; + u8 bus_num = bus->number; pr_debug("write_config_byte %#x to %d size %d dev %d:%d:%d\n", value, where, size, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn)); @@ -281,31 +282,11 @@ static int write_config(u8 bus_num, u16 devfn, int where, int size, u32 value) return PCIBIOS_SUCCESSFUL; } -/* - * Generalized PCI config access functions. - */ -static int ixp4xx_read_config(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 *value) -{ - if (bus->number && !PCI_SLOT(devfn)) - return local_read_config(where, size, value); - return read_config(bus->number, devfn, where, size, value); -} - -static int ixp4xx_write_config(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 value) -{ - if (bus->number && !PCI_SLOT(devfn)) - return local_write_config(where, size, value); - return write_config(bus->number, devfn, where, size, value); -} - struct pci_ops ixp4xx_ops = { - .read = ixp4xx_read_config, - .write = ixp4xx_write_config, + .read = ixp4xx_pci_read_config, + .write = ixp4xx_pci_write_config, }; - /* * PCI abort handler */ @@ -360,6 +341,29 @@ int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) return (dev->bus == &pci_bus_type ) && ((dma_addr + size) >= SZ_64M); } +/* + * Only first 64MB of memory can be accessed via PCI. + * We use GFP_DMA to allocate safe buffers to do map/unmap. + * This is really ugly and we need a better way of specifying + * DMA-capable regions of memory. + */ +void __init ixp4xx_adjust_zones(int node, unsigned long *zone_size, + unsigned long *zhole_size) +{ + unsigned int sz = SZ_64M >> PAGE_SHIFT; + + /* + * Only adjust if > 64M on current system + */ + if (node || (zone_size[0] <= sz)) + return; + + zone_size[1] = zone_size[0] - sz; + zone_size[0] = sz; + zhole_size[1] = zhole_size[0]; + zhole_size[0] = 0; +} + void __init ixp4xx_pci_preinit(void) { unsigned long processor_id; @@ -367,10 +371,11 @@ void __init ixp4xx_pci_preinit(void) asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :); /* - * Determine which PCI read method to use + * Determine which PCI read method to use. + * Rev 0 IXP425 requires workaround. */ - if (!(processor_id & 0xf)) { - printk("PCI: IXP4xx A0 silicon detected - " + if (!(processor_id & 0xf) && !cpu_is_ixp46x()) { + printk("PCI: IXP42x A0 silicon detected - " "PCI Non-Prefetch Workaround Enabled\n"); ixp4xx_pci_read = ixp4xx_pci_read_errata; } else @@ -445,7 +450,7 @@ void __init ixp4xx_pci_preinit(void) #ifdef __ARMEB__ *PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS | PCI_CSR_ADS; #else - *PCI_CSR = PCI_CSR_IC; + *PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE; #endif pr_debug("DONE\n"); @@ -458,7 +463,7 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys) if (nr >= 1) return 0; - res = kmalloc(sizeof(*res) * 2, GFP_KERNEL); + res = kzalloc(sizeof(*res) * 2, GFP_KERNEL); if (res == NULL) { /* * If we're out of memory this early, something is wrong, @@ -466,13 +471,12 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys) */ panic("PCI: unable to allocate resources?\n"); } - memset(res, 0, sizeof(*res) * 2); local_write_config(PCI_COMMAND, 2, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); res[0].name = "PCI I/O Space"; - res[0].start = 0x00001000; - res[0].end = 0xffff0000; + res[0].start = 0x00000000; + res[0].end = 0x0000ffff; res[0].flags = IORESOURCE_IO; res[1].name = "PCI Memory Space"; @@ -519,15 +523,6 @@ pci_set_dma_mask(struct pci_dev *dev, u64 mask) return -EIO; } -int -pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask) -{ - if (mask >= SZ_64M - 1 ) - return 0; - - return -EIO; -} - int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) { @@ -537,7 +532,6 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) return -EIO; } -EXPORT_SYMBOL(pci_set_dma_mask); -EXPORT_SYMBOL(pci_dac_set_dma_mask); -EXPORT_SYMBOL(pci_set_consistent_dma_mask); +EXPORT_SYMBOL(ixp4xx_pci_read); +EXPORT_SYMBOL(ixp4xx_pci_write);