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
drivers
of
of_pci_irq.c
Go to the documentation of this file.
1
#include <linux/kernel.h>
2
#include <
linux/of_pci.h
>
3
#include <
linux/of_irq.h
>
4
#include <linux/export.h>
5
#include <asm/prom.h>
6
18
int
of_irq_map_pci
(
const
struct
pci_dev
*pdev,
struct
of_irq *out_irq)
19
{
20
struct
device_node
*
dn
, *ppnode;
21
struct
pci_dev
*ppdev;
22
u32
lspec;
23
__be32
lspec_be;
24
__be32
laddr
[3];
25
u8
pin
;
26
int
rc
;
27
28
/* Check if we have a device node, if yes, fallback to standard
29
* device tree parsing
30
*/
31
dn = pci_device_to_OF_node(pdev);
32
if
(dn) {
33
rc =
of_irq_map_one
(dn, 0, out_irq);
34
if
(!rc)
35
return
rc
;
36
}
37
38
/* Ok, we don't, time to have fun. Let's start by building up an
39
* interrupt spec. we assume #interrupt-cells is 1, which is standard
40
* for PCI. If you do different, then don't use that routine.
41
*/
42
rc = pci_read_config_byte(pdev,
PCI_INTERRUPT_PIN
, &pin);
43
if
(rc != 0)
44
return
rc
;
45
/* No pin, exit */
46
if
(pin == 0)
47
return
-
ENODEV
;
48
49
/* Now we walk up the PCI tree */
50
lspec =
pin
;
51
for
(;;) {
52
/* Get the pci_dev of our parent */
53
ppdev = pdev->
bus
->self;
54
55
/* Ouch, it's a host bridge... */
56
if
(ppdev ==
NULL
) {
57
ppnode = pci_bus_to_OF_node(pdev->
bus
);
58
59
/* No node for host bridge ? give up */
60
if
(ppnode ==
NULL
)
61
return
-
EINVAL
;
62
}
else
{
63
/* We found a P2P bridge, check if it has a node */
64
ppnode = pci_device_to_OF_node(ppdev);
65
}
66
67
/* Ok, we have found a parent with a device-node, hand over to
68
* the OF parsing code.
69
* We build a unit address from the linux device to be used for
70
* resolution. Note that we use the linux bus number which may
71
* not match your firmware bus numbering.
72
* Fortunately, in most cases, interrupt-map-mask doesn't
73
* include the bus number as part of the matching.
74
* You should still be careful about that though if you intend
75
* to rely on this function (you ship a firmware that doesn't
76
* create device nodes for all PCI devices).
77
*/
78
if
(ppnode)
79
break
;
80
81
/* We can only get here if we hit a P2P bridge with no node,
82
* let's do standard swizzling and try again
83
*/
84
lspec =
pci_swizzle_interrupt_pin
(pdev, lspec);
85
pdev = ppdev;
86
}
87
88
lspec_be =
cpu_to_be32
(lspec);
89
laddr[0] =
cpu_to_be32
((pdev->
bus
->number << 16) | (pdev->
devfn
<< 8));
90
laddr[1] = laddr[2] =
cpu_to_be32
(0);
91
return
of_irq_map_raw
(ppnode, &lspec_be, 1, laddr, out_irq);
92
}
93
EXPORT_SYMBOL_GPL
(
of_irq_map_pci
);
Generated on Thu Jan 10 2013 14:13:36 for Linux Kernel by
1.8.2