/*1* linux/arch/arm/mach-integrator/pci-integrator.c2*3* Copyright (C) 1999 ARM Limited4* Copyright (C) 2000 Deep Blue Solutions Ltd5*6* This program is free software; you can redistribute it and/or modify7* it under the terms of the GNU General Public License as published by8* the Free Software Foundation; either version 2 of the License, or9* (at your option) any later version.10*11* This program is distributed in the hope that it will be useful,12* but WITHOUT ANY WARRANTY; without even the implied warranty of13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14* GNU General Public License for more details.15*16* You should have received a copy of the GNU General Public License17* along with this program; if not, write to the Free Software18* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA19*20*21* PCI functions for Integrator22*/23#include <linux/kernel.h>24#include <linux/pci.h>25#include <linux/interrupt.h>26#include <linux/init.h>2728#include <asm/irq.h>29#include <asm/system.h>30#include <asm/mach/pci.h>31#include <asm/mach-types.h>3233/*34* A small note about bridges and interrupts. The DECchip 21050 (and35* later) adheres to the PCI-PCI bridge specification. This says that36* the interrupts on the other side of a bridge are swizzled in the37* following manner:38*39* Dev Interrupt Interrupt40* Pin on Pin on41* Device Connector42*43* 4 A A44* B B45* C C46* D D47*48* 5 A B49* B C50* C D51* D A52*53* 6 A C54* B D55* C A56* D B57*58* 7 A D59* B A60* C B61* D C62*63* Where A = pin 1, B = pin 2 and so on and pin=0 = default = A.64* Thus, each swizzle is ((pin-1) + (device#-4)) % 465*/6667/*68* This routine handles multiple bridges.69*/70static u8 __init integrator_swizzle(struct pci_dev *dev, u8 *pinp)71{72int pin = *pinp;7374if (pin == 0)75pin = 1;7677while (dev->bus->self) {78pin = pci_swizzle_interrupt_pin(dev, pin);79/*80* move up the chain of bridges, swizzling as we go.81*/82dev = dev->bus->self;83}84*pinp = pin;8586return PCI_SLOT(dev->devfn);87}8889static int irq_tab[4] __initdata = {90IRQ_AP_PCIINT0, IRQ_AP_PCIINT1, IRQ_AP_PCIINT2, IRQ_AP_PCIINT391};9293/*94* map the specified device/slot/pin to an IRQ. This works out such95* that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.96*/97static int __init integrator_map_irq(struct pci_dev *dev, u8 slot, u8 pin)98{99int intnr = ((slot - 9) + (pin - 1)) & 3;100101return irq_tab[intnr];102}103104extern void pci_v3_init(void *);105106static struct hw_pci integrator_pci __initdata = {107.swizzle = integrator_swizzle,108.map_irq = integrator_map_irq,109.setup = pci_v3_setup,110.nr_controllers = 1,111.scan = pci_v3_scan_bus,112.preinit = pci_v3_preinit,113.postinit = pci_v3_postinit,114};115116static int __init integrator_pci_init(void)117{118if (machine_is_integrator())119pci_common_init(&integrator_pci);120return 0;121}122123subsys_initcall(integrator_pci_init);124125126