diff options
Diffstat (limited to 'arch/arm/mach-ixp2000/pci.c')
| -rw-r--r-- | arch/arm/mach-ixp2000/pci.c | 252 | 
1 files changed, 0 insertions, 252 deletions
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c deleted file mode 100644 index 9c02de932fa..00000000000 --- a/arch/arm/mach-ixp2000/pci.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * arch/arm/mach-ixp2000/pci.c - * - * PCI routines for IXDP2400/IXDP2800 boards - * - * Original Author: Naeem Afzal <naeem.m.afzal@intel.com> - * Maintained by: Deepak Saxena <dsaxena@plexity.net> - * - * Copyright 2002 Intel Corp. - * Copyright (C) 2003-2004 MontaVista Software, Inc. - * - *  This program is free software; you can redistribute  it and/or modify it - *  under  the terms of  the GNU General  Public License as published by the - *  Free Software Foundation;  either version 2 of the  License, or (at your - *  option) any later version. - */ - -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/interrupt.h> -#include <linux/mm.h> -#include <linux/init.h> -#include <linux/ioport.h> -#include <linux/delay.h> -#include <linux/io.h> - -#include <asm/irq.h> -#include <mach/hardware.h> - -#include <asm/mach/pci.h> - -static volatile int pci_master_aborts = 0; - -static int clear_master_aborts(void); - -u32 * -ixp2000_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where) -{ -	u32 *paddress; - -	if (PCI_SLOT(devfn) > 7) -		return 0; - -	/* Must be dword aligned */ -	where &= ~3; - -	/* -	 * For top bus, generate type 0, else type 1 -	 */ -	if (!bus_nr) { -		/* only bits[23:16] are used for IDSEL */ -		paddress = (u32 *) (IXP2000_PCI_CFG0_VIRT_BASE -				    | (1 << (PCI_SLOT(devfn) + 16)) -				    | (PCI_FUNC(devfn) << 8) | where); -	} else { -		paddress = (u32 *) (IXP2000_PCI_CFG1_VIRT_BASE  -				    | (bus_nr << 16) -				    | (PCI_SLOT(devfn) << 11) -				    | (PCI_FUNC(devfn) << 8) | where); -	} - -	return paddress; -} - -/* - * Mask table, bits to mask for quantity of size 1, 2 or 4 bytes. - * 0 and 3 are not valid indexes... - */ -static u32 bytemask[] = { -	/*0*/	0, -	/*1*/	0xff, -	/*2*/	0xffff, -	/*3*/	0, -	/*4*/	0xffffffff, -}; - - -int ixp2000_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, -				int size, u32 *value) -{ -	u32 n; -	u32 *addr; - -	n = where % 4; - -	addr = ixp2000_pci_config_addr(bus->number, devfn, where); -	if (!addr) -		return PCIBIOS_DEVICE_NOT_FOUND; - -	pci_master_aborts = 0; -	*value = (*addr >> (8*n)) & bytemask[size]; -	if (pci_master_aborts) { -		pci_master_aborts = 0; -		*value = 0xffffffff; -		return PCIBIOS_DEVICE_NOT_FOUND; -	} - -	return PCIBIOS_SUCCESSFUL; -} - -/* - * We don't do error checks by calling clear_master_aborts() b/c the - * assumption is that the caller did a read first to make sure a device - * exists. - */ -int ixp2000_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, -				int size, u32 value) -{ -	u32 mask; -	u32 *addr; -	u32 temp; - -	mask = ~(bytemask[size] << ((where % 0x4) * 8)); -	addr = ixp2000_pci_config_addr(bus->number, devfn, where); -	if (!addr) -		return PCIBIOS_DEVICE_NOT_FOUND; -	temp = (u32) (value) << ((where % 0x4) * 8); -	*addr = (*addr & mask) | temp; - -	clear_master_aborts(); - -	return PCIBIOS_SUCCESSFUL; -} - - -static struct pci_ops ixp2000_pci_ops = { -	.read	= ixp2000_pci_read_config, -	.write	= ixp2000_pci_write_config -}; - -struct pci_bus *ixp2000_pci_scan_bus(int nr, struct pci_sys_data *sysdata) -{ -	return pci_scan_root_bus(NULL, sysdata->busnr, &ixp2000_pci_ops, -				 sysdata, &sysdata->resources); -} - - -int ixp2000_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs) -{ - -	volatile u32 temp; -	unsigned long flags; - -	pci_master_aborts = 1; - -	local_irq_save(flags); -	temp = *(IXP2000_PCI_CONTROL); -	if (temp & ((1 << 8) | (1 << 5))) { -		ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp); -	} - -	temp = *(IXP2000_PCI_CMDSTAT); -	if (temp & (1 << 29)) { -		while (temp & (1 << 29)) {	 -			ixp2000_reg_write(IXP2000_PCI_CMDSTAT, temp); -			temp = *(IXP2000_PCI_CMDSTAT); -		} -	} -	local_irq_restore(flags); - -	/* -	 * If it was an imprecise abort, then we need to correct the -	 * return address to be _after_ the instruction. -	 */ -	if (fsr & (1 << 10)) -		regs->ARM_pc += 4; - -	return 0; -} - -int -clear_master_aborts(void) -{ -	volatile u32 temp; -	unsigned long flags; - -	local_irq_save(flags); -	temp = *(IXP2000_PCI_CONTROL); -	if (temp & ((1 << 8) | (1 << 5))) { -		ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp); -	} - -	temp = *(IXP2000_PCI_CMDSTAT); -	if (temp & (1 << 29)) { -		while (temp & (1 << 29)) { -			ixp2000_reg_write(IXP2000_PCI_CMDSTAT, temp); -			temp = *(IXP2000_PCI_CMDSTAT); -		} -	} -	local_irq_restore(flags); - -	return 0; -} - -void __init -ixp2000_pci_preinit(void) -{ -	pci_set_flags(0); - -	pcibios_min_io = 0; -	pcibios_min_mem = 0; - -#ifndef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO -	/* -	 * Configure the PCI unit to properly byteswap I/O transactions, -	 * and verify that it worked. -	 */ -	ixp2000_reg_write(IXP2000_PCI_CONTROL, -			  (*IXP2000_PCI_CONTROL | PCI_CONTROL_IEE)); - -	if ((*IXP2000_PCI_CONTROL & PCI_CONTROL_IEE) == 0) -		panic("IXP2000: PCI I/O is broken on this ixp model, and " -			"the needed workaround has not been configured in"); -#endif - -	hook_fault_code(16+6, ixp2000_pci_abort_handler, SIGBUS, 0, -				"PCI config cycle to non-existent device"); -} - - -/* - * IXP2000 systems often have large resource requirements, so we just - * use our own resource space. - */ -static struct resource ixp2000_pci_mem_space = { -	.start	= 0xe0000000, -	.end	= 0xffffffff, -	.flags	= IORESOURCE_MEM, -	.name	= "PCI Mem Space" -}; - -static struct resource ixp2000_pci_io_space = { -	.start	= 0x00010000, -	.end	= 0x0001ffff, -	.flags	= IORESOURCE_IO, -	.name	= "PCI I/O Space" -}; - -int ixp2000_pci_setup(int nr, struct pci_sys_data *sys) -{ -	if (nr >= 1) -		return 0; - -	pci_add_resource_offset(&sys->resources, -				&ixp2000_pci_io_space, sys->io_offset); -	pci_add_resource_offset(&sys->resources, -				&ixp2000_pci_mem_space, sys->mem_offset); - -	return 1; -} -  |