Path: blob/master/arch/sh/drivers/pci/fixups-cayman.c
10819 views
#include <linux/kernel.h>1#include <linux/init.h>2#include <linux/pci.h>3#include <linux/types.h>4#include <cpu/irq.h>5#include "pci-sh5.h"67int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin)8{9int result = -1;1011/* The complication here is that the PCI IRQ lines from the Cayman's 2125V slots get into the CPU via a different path from the IRQ lines13from the 3 3.3V slots. Thus, we have to detect whether the card's14interrupts go via the 5V or 3.3V path, i.e. the 'bridge swizzling'15at the point where we cross from 5V to 3.3V is not the normal case.1617The added complication is that we don't know that the 5V slots are18always bus 2, because a card containing a PCI-PCI bridge may be19plugged into a 3.3V slot, and this changes the bus numbering.2021Also, the Cayman has an intermediate PCI bus that goes a custom22expansion board header (and to the secondary bridge). This bus has23never been used in practice.2425The 1ary onboard PCI-PCI bridge is device 3 on bus 026The 2ary onboard PCI-PCI bridge is device 0 on the 2ary bus of27the 1ary bridge.28*/2930struct slot_pin {31int slot;32int pin;33} path[4];34int i=0;3536while (dev->bus->number > 0) {3738slot = path[i].slot = PCI_SLOT(dev->devfn);39pin = path[i].pin = pci_swizzle_interrupt_pin(dev, pin);40dev = dev->bus->self;41i++;42if (i > 3) panic("PCI path to root bus too long!\n");43}4445slot = PCI_SLOT(dev->devfn);46/* This is the slot on bus 0 through which the device is eventually47reachable. */4849/* Now work back up. */50if ((slot < 3) || (i == 0)) {51/* Bus 0 (incl. PCI-PCI bridge itself) : perform the final52swizzle now. */53result = IRQ_INTA + pci_swizzle_interrupt_pin(dev, pin) - 1;54} else {55i--;56slot = path[i].slot;57pin = path[i].pin;58if (slot > 0) {59panic("PCI expansion bus device found - not handled!\n");60} else {61if (i > 0) {62/* 5V slots */63i--;64slot = path[i].slot;65pin = path[i].pin;66/* 'pin' was swizzled earlier wrt slot, don't do it again. */67result = IRQ_P2INTA + (pin - 1);68} else {69/* IRQ for 2ary PCI-PCI bridge : unused */70result = -1;71}72}73}7475return result;76}777879