1b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt#include <linux/kernel.h> 2b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt#include <linux/init.h> 3b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt#include <linux/pci.h> 4b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt#include <linux/types.h> 5f15cbe6f1a4b4d9df59142fc8e4abb973302cf44Paul Mundt#include <cpu/irq.h> 6b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt#include "pci-sh5.h" 7b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt 8d5341942d784134f2997b3ff82cd63cf71d1f932Ralf Baechleint __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) 9b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt{ 10b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt int result = -1; 11b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt 12b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt /* The complication here is that the PCI IRQ lines from the Cayman's 2 13b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt 5V slots get into the CPU via a different path from the IRQ lines 14b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt from the 3 3.3V slots. Thus, we have to detect whether the card's 15b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt interrupts go via the 5V or 3.3V path, i.e. the 'bridge swizzling' 16b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt at the point where we cross from 5V to 3.3V is not the normal case. 17b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt 18b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt The added complication is that we don't know that the 5V slots are 19b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt always bus 2, because a card containing a PCI-PCI bridge may be 20b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt plugged into a 3.3V slot, and this changes the bus numbering. 21b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt 22b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt Also, the Cayman has an intermediate PCI bus that goes a custom 23b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt expansion board header (and to the secondary bridge). This bus has 24b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt never been used in practice. 25b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt 26b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt The 1ary onboard PCI-PCI bridge is device 3 on bus 0 27b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt The 2ary onboard PCI-PCI bridge is device 0 on the 2ary bus of 28b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt the 1ary bridge. 29b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt */ 30b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt 31b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt struct slot_pin { 32b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt int slot; 33b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt int pin; 34b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt } path[4]; 35b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt int i=0; 36b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt 37b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt while (dev->bus->number > 0) { 38b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt 39b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt slot = path[i].slot = PCI_SLOT(dev->devfn); 406aa6e4981741013e4a8c7c3ee7b90c24e89fae24Bjorn Helgaas pin = path[i].pin = pci_swizzle_interrupt_pin(dev, pin); 41b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt dev = dev->bus->self; 42b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt i++; 43b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt if (i > 3) panic("PCI path to root bus too long!\n"); 44b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt } 45b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt 46b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt slot = PCI_SLOT(dev->devfn); 47b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt /* This is the slot on bus 0 through which the device is eventually 48b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt reachable. */ 49b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt 50b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt /* Now work back up. */ 51b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt if ((slot < 3) || (i == 0)) { 52b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt /* Bus 0 (incl. PCI-PCI bridge itself) : perform the final 53b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt swizzle now. */ 546aa6e4981741013e4a8c7c3ee7b90c24e89fae24Bjorn Helgaas result = IRQ_INTA + pci_swizzle_interrupt_pin(dev, pin) - 1; 55b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt } else { 56b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt i--; 57b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt slot = path[i].slot; 58b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt pin = path[i].pin; 59b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt if (slot > 0) { 60b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt panic("PCI expansion bus device found - not handled!\n"); 61b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt } else { 62b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt if (i > 0) { 63b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt /* 5V slots */ 64b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt i--; 65b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt slot = path[i].slot; 66b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt pin = path[i].pin; 67b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt /* 'pin' was swizzled earlier wrt slot, don't do it again. */ 68b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt result = IRQ_P2INTA + (pin - 1); 69b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt } else { 70b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt /* IRQ for 2ary PCI-PCI bridge : unused */ 71b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt result = -1; 72b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt } 73b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt } 74b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt } 75b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt 76b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt return result; 77b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt} 78