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