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