Rev 1633 | Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1627 | serge | 1 | |
2 | #include |
||
3 | #include |
||
4 | #include |
||
5 | #include |
||
6 | #include |
||
7 | |||
8 | |||
9 | #include "acpi_bus.h" |
||
10 | |||
11 | |||
12 | |||
13 | |||
14 | { |
||
15 | struct list_head list; |
||
16 | ACPI_PCI_ID id; |
||
17 | u8 pin; |
||
18 | ACPI_HANDLE link; |
||
19 | u32 index; /* GSI, or link _CRS index */ |
||
20 | }; |
||
21 | |||
22 | |||
23 | static DEFINE_SPINLOCK(acpi_prt_lock); |
||
24 | |||
25 | |||
26 | { |
||
27 | return 'A' + pin - 1; |
||
28 | } |
||
29 | |||
30 | |||
31 | |||
32 | struct acpi_pci_routing_table *prt) |
||
33 | { |
||
34 | struct acpi_prt_entry *entry; |
||
35 | |||
36 | |||
37 | if (!entry) |
||
38 | return -ENOMEM; |
||
39 | |||
40 | |||
41 | * Note that the _PRT uses 0=INTA, 1=INTB, etc, while PCI uses |
||
42 | * 1=INTA, 2=INTB. We use the PCI encoding throughout, so convert |
||
43 | * it here. |
||
44 | */ |
||
45 | entry->id.Segment = pci_domain_nr(bus); |
||
46 | entry->id.Bus = bus->number; |
||
47 | entry->id.Device = (prt->Address >> 16) & 0xFFFF; |
||
48 | entry->pin = prt->Pin + 1; |
||
49 | |||
50 | |||
51 | |||
52 | |||
53 | |||
54 | |||
55 | * Type 1: Dynamic |
||
56 | * --------------- |
||
57 | * The 'source' field specifies the PCI interrupt link device used to |
||
58 | * configure the IRQ assigned to this slot|dev|pin. The 'source_index' |
||
59 | * indicates which resource descriptor in the resource template (of |
||
60 | * the link device) this interrupt is allocated from. |
||
61 | * |
||
62 | * NOTE: Don't query the Link Device for IRQ information at this time |
||
63 | * because Link Device enumeration may not have occurred yet |
||
64 | * (e.g. exists somewhere 'below' this _PRT entry in the ACPI |
||
65 | * namespace). |
||
66 | */ |
||
67 | if (prt->Source[0]) |
||
68 | AcpiGetHandle(handle, prt->Source, &entry->link); |
||
69 | |||
70 | |||
71 | * Type 2: Static |
||
72 | * -------------- |
||
73 | * The 'source' field is NULL, and the 'source_index' field specifies |
||
74 | * the IRQ value, which is hardwired to specific interrupt inputs on |
||
75 | * the interrupt controller. |
||
76 | */ |
||
77 | |||
78 | |||
79 | entry->id.Segment, entry->id.Bus, |
||
80 | entry->id.Device, pin_name(entry->pin), |
||
81 | prt->Source, entry->index); |
||
82 | |||
83 | |||
84 | list_add_tail(&entry->list, &acpi_prt_list); |
||
85 | spin_unlock(&acpi_prt_lock); |
||
86 | |||
87 | |||
88 | } |
||
89 | |||
90 | |||
91 | |||
92 | |||
93 | { |
||
94 | ACPI_STATUS status; |
||
95 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
||
96 | struct acpi_pci_routing_table *entry; |
||
97 | |||
98 | |||
99 | status = AcpiGetName(handle, ACPI_FULL_PATHNAME, &buffer); |
||
100 | if (ACPI_FAILURE(status)) |
||
101 | return -ENODEV; |
||
102 | |||
103 | |||
104 | (char *) buffer.Pointer); |
||
105 | |||
106 | |||
107 | |||
108 | |||
109 | buffer.Pointer = NULL; |
||
110 | |||
111 | |||
112 | if (ACPI_FAILURE(status)) |
||
113 | { |
||
114 | dbgprintf("AcpiGetIrqRoutingTable failed " |
||
115 | "evaluating _PRT [%s]\n",AcpiFormatException(status)); |
||
116 | kfree(buffer.Pointer); |
||
117 | return -ENODEV; |
||
118 | } |
||
119 | |||
120 | |||
121 | while (entry && (entry->Length > 0)) { |
||
122 | acpi_pci_irq_add_entry(handle, bus, entry); |
||
123 | entry = (struct acpi_pci_routing_table *) |
||
124 | ((unsigned long)entry + entry->Length); |
||
125 | } |
||
126 | |||
127 | |||
128 | return 0; |
||
129 | } |
||
130 |