Blame view
drivers/acpi/pci_link.c
23.5 KB
c942fddf8 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
1da177e4c Linux-2.6.12-rc2 |
2 3 4 5 6 7 8 |
/* * pci_link.c - ACPI PCI Interrupt Link Device Driver ($Revision: 34 $) * * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> * Copyright (C) 2002 Dominik Brodowski <devel@brodo.de> * |
c6237b210 ACPI: Fix whitesp... |
9 10 |
* TBD: * 1. Support more than one IRQ resource entry per link device (index). |
1da177e4c Linux-2.6.12-rc2 |
11 12 13 |
* 2. Implement start/stop mechanism and use ACPI Bus Driver facilities * for IRQ management (e.g. start()->_SRS). */ |
c3146df2b ACPI: Use syscore... |
14 |
#include <linux/syscore_ops.h> |
1da177e4c Linux-2.6.12-rc2 |
15 16 17 18 |
#include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/types.h> |
1da177e4c Linux-2.6.12-rc2 |
19 20 21 |
#include <linux/spinlock.h> #include <linux/pm.h> #include <linux/pci.h> |
36e430951 sem2mutex: acpi, ... |
22 |
#include <linux/mutex.h> |
5a0e3ad6a include cleanup: ... |
23 |
#include <linux/slab.h> |
8b48463f8 ACPI: Clean up in... |
24 |
#include <linux/acpi.h> |
103544d86 ACPI,PCI,IRQ: red... |
25 |
#include <linux/irq.h> |
1da177e4c Linux-2.6.12-rc2 |
26 |
|
c071b6040 ACPI / PCI: Inclu... |
27 |
#include "internal.h" |
1c9ca3a7d ACPI: pci_link: c... |
28 |
#define _COMPONENT ACPI_PCI_COMPONENT |
f52fd66d2 ACPI: clean up AC... |
29 |
ACPI_MODULE_NAME("pci_link"); |
1da177e4c Linux-2.6.12-rc2 |
30 |
#define ACPI_PCI_LINK_CLASS "pci_irq_routing" |
1da177e4c Linux-2.6.12-rc2 |
31 |
#define ACPI_PCI_LINK_DEVICE_NAME "PCI Interrupt Link" |
1c9ca3a7d ACPI: pci_link: c... |
32 |
#define ACPI_PCI_LINK_MAX_POSSIBLE 16 |
4daeaf683 ACPI / PCI: Make ... |
33 34 35 |
static int acpi_pci_link_add(struct acpi_device *device, const struct acpi_device_id *not_used); static void acpi_pci_link_remove(struct acpi_device *device); |
1da177e4c Linux-2.6.12-rc2 |
36 |
|
c97adf9e7 acpi: make ACPI d... |
37 |
static const struct acpi_device_id link_device_ids[] = { |
1ba90e3a8 ACPI: autoload mo... |
38 39 40 |
{"PNP0C0F", 0}, {"", 0}, }; |
1ba90e3a8 ACPI: autoload mo... |
41 |
|
4daeaf683 ACPI / PCI: Make ... |
42 |
static struct acpi_scan_handler pci_link_handler = { |
1ba90e3a8 ACPI: autoload mo... |
43 |
.ids = link_device_ids, |
4daeaf683 ACPI / PCI: Make ... |
44 45 |
.attach = acpi_pci_link_add, .detach = acpi_pci_link_remove, |
1da177e4c Linux-2.6.12-rc2 |
46 |
}; |
87bec66b9 [ACPI] suspend/re... |
47 48 49 50 |
/* * If a link is initialized, we never change its active and initialized * later even the link is disable. Instead, we just repick the active irq */ |
1da177e4c Linux-2.6.12-rc2 |
51 |
struct acpi_pci_link_irq { |
37c593913 ACPI, PCI, irq: r... |
52 |
u32 active; /* Current IRQ */ |
50eca3eb8 [ACPI] ACPICA 200... |
53 |
u8 triggering; /* All IRQs */ |
1c9ca3a7d ACPI: pci_link: c... |
54 |
u8 polarity; /* All IRQs */ |
4be44fcd3 [ACPI] Lindent al... |
55 56 |
u8 resource_type; u8 possible_count; |
37c593913 ACPI, PCI, irq: r... |
57 |
u32 possible[ACPI_PCI_LINK_MAX_POSSIBLE]; |
4be44fcd3 [ACPI] Lindent al... |
58 59 |
u8 initialized:1; u8 reserved:7; |
1da177e4c Linux-2.6.12-rc2 |
60 61 62 |
}; struct acpi_pci_link { |
5f0dccaa8 ACPI: pci_link: s... |
63 |
struct list_head list; |
1c9ca3a7d ACPI: pci_link: c... |
64 65 66 |
struct acpi_device *device; struct acpi_pci_link_irq irq; int refcnt; |
1da177e4c Linux-2.6.12-rc2 |
67 |
}; |
5f0dccaa8 ACPI: pci_link: s... |
68 |
static LIST_HEAD(acpi_link_list); |
e5685b9d3 ACPI: misc cleanups |
69 |
static DEFINE_MUTEX(acpi_link_lock); |
f1caa61df ACPI/PCI: pci_lin... |
70 |
static int sci_irq = -1, sci_penalty; |
1da177e4c Linux-2.6.12-rc2 |
71 |
|
1da177e4c Linux-2.6.12-rc2 |
72 73 74 75 76 77 78 |
/* -------------------------------------------------------------------------- PCI Link Device Management -------------------------------------------------------------------------- */ /* * set context (link) possible list from resource list */ |
1c9ca3a7d ACPI: pci_link: c... |
79 80 |
static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource, void *context) |
1da177e4c Linux-2.6.12-rc2 |
81 |
{ |
50dd09697 ACPI: Remove unne... |
82 |
struct acpi_pci_link *link = context; |
c9d624432 ACPI: pci_link: r... |
83 |
u32 i; |
1da177e4c Linux-2.6.12-rc2 |
84 |
|
eca008c81 [ACPI] handle ACP... |
85 |
switch (resource->type) { |
50eca3eb8 [ACPI] ACPICA 200... |
86 |
case ACPI_RESOURCE_TYPE_START_DEPENDENT: |
4a5e3638b ACPI: stop compla... |
87 |
case ACPI_RESOURCE_TYPE_END_TAG: |
d550d98d3 ACPI: delete trac... |
88 |
return AE_OK; |
50eca3eb8 [ACPI] ACPICA 200... |
89 |
case ACPI_RESOURCE_TYPE_IRQ: |
4be44fcd3 [ACPI] Lindent al... |
90 91 |
{ struct acpi_resource_irq *p = &resource->data.irq; |
50eca3eb8 [ACPI] ACPICA 200... |
92 |
if (!p || !p->interrupt_count) { |
4a5e3638b ACPI: stop compla... |
93 94 95 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Blank _PRS IRQ resource ")); |
d550d98d3 ACPI: delete trac... |
96 |
return AE_OK; |
1da177e4c Linux-2.6.12-rc2 |
97 |
} |
4be44fcd3 [ACPI] Lindent al... |
98 |
for (i = 0; |
50eca3eb8 [ACPI] ACPICA 200... |
99 |
(i < p->interrupt_count |
4be44fcd3 [ACPI] Lindent al... |
100 101 |
&& i < ACPI_PCI_LINK_MAX_POSSIBLE); i++) { if (!p->interrupts[i]) { |
4a5e3638b ACPI: stop compla... |
102 103 104 105 |
printk(KERN_WARNING PREFIX "Invalid _PRS IRQ %d ", p->interrupts[i]); |
4be44fcd3 [ACPI] Lindent al... |
106 107 108 109 110 |
continue; } link->irq.possible[i] = p->interrupts[i]; link->irq.possible_count++; } |
50eca3eb8 [ACPI] ACPICA 200... |
111 112 113 |
link->irq.triggering = p->triggering; link->irq.polarity = p->polarity; link->irq.resource_type = ACPI_RESOURCE_TYPE_IRQ; |
4be44fcd3 [ACPI] Lindent al... |
114 |
break; |
1da177e4c Linux-2.6.12-rc2 |
115 |
} |
50eca3eb8 [ACPI] ACPICA 200... |
116 |
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: |
4be44fcd3 [ACPI] Lindent al... |
117 |
{ |
50eca3eb8 [ACPI] ACPICA 200... |
118 |
struct acpi_resource_extended_irq *p = |
4be44fcd3 [ACPI] Lindent al... |
119 |
&resource->data.extended_irq; |
50eca3eb8 [ACPI] ACPICA 200... |
120 |
if (!p || !p->interrupt_count) { |
cece92969 ACPI: un-export A... |
121 |
printk(KERN_WARNING PREFIX |
4a5e3638b ACPI: stop compla... |
122 123 |
"Blank _PRS EXT IRQ resource "); |
d550d98d3 ACPI: delete trac... |
124 |
return AE_OK; |
4be44fcd3 [ACPI] Lindent al... |
125 126 |
} for (i = 0; |
50eca3eb8 [ACPI] ACPICA 200... |
127 |
(i < p->interrupt_count |
4be44fcd3 [ACPI] Lindent al... |
128 129 |
&& i < ACPI_PCI_LINK_MAX_POSSIBLE); i++) { if (!p->interrupts[i]) { |
4a5e3638b ACPI: stop compla... |
130 131 132 133 |
printk(KERN_WARNING PREFIX "Invalid _PRS IRQ %d ", p->interrupts[i]); |
4be44fcd3 [ACPI] Lindent al... |
134 135 136 137 |
continue; } link->irq.possible[i] = p->interrupts[i]; link->irq.possible_count++; |
1da177e4c Linux-2.6.12-rc2 |
138 |
} |
50eca3eb8 [ACPI] ACPICA 200... |
139 140 141 |
link->irq.triggering = p->triggering; link->irq.polarity = p->polarity; link->irq.resource_type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ; |
4be44fcd3 [ACPI] Lindent al... |
142 |
break; |
1da177e4c Linux-2.6.12-rc2 |
143 |
} |
1da177e4c Linux-2.6.12-rc2 |
144 |
default: |
4a5e3638b ACPI: stop compla... |
145 146 147 |
printk(KERN_ERR PREFIX "_PRS resource type 0x%x isn't an IRQ ", resource->type); |
d550d98d3 ACPI: delete trac... |
148 |
return AE_OK; |
1da177e4c Linux-2.6.12-rc2 |
149 |
} |
d550d98d3 ACPI: delete trac... |
150 |
return AE_CTRL_TERMINATE; |
1da177e4c Linux-2.6.12-rc2 |
151 |
} |
4be44fcd3 [ACPI] Lindent al... |
152 |
static int acpi_pci_link_get_possible(struct acpi_pci_link *link) |
1da177e4c Linux-2.6.12-rc2 |
153 |
{ |
4be44fcd3 [ACPI] Lindent al... |
154 |
acpi_status status; |
1da177e4c Linux-2.6.12-rc2 |
155 |
|
67a713657 ACPI: pci_link: U... |
156 |
status = acpi_walk_resources(link->device->handle, METHOD_NAME__PRS, |
4be44fcd3 [ACPI] Lindent al... |
157 |
acpi_pci_link_check_possible, link); |
1da177e4c Linux-2.6.12-rc2 |
158 |
if (ACPI_FAILURE(status)) { |
92d1b381f ACPI / PCI: pci_l... |
159 160 |
acpi_handle_debug(link->device->handle, "_PRS not present or invalid"); return 0; |
1da177e4c Linux-2.6.12-rc2 |
161 |
} |
4be44fcd3 [ACPI] Lindent al... |
162 163 164 165 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d possible IRQs ", link->irq.possible_count)); |
1da177e4c Linux-2.6.12-rc2 |
166 |
|
d550d98d3 ACPI: delete trac... |
167 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
168 |
} |
1c9ca3a7d ACPI: pci_link: c... |
169 170 |
static acpi_status acpi_pci_link_check_current(struct acpi_resource *resource, void *context) |
1da177e4c Linux-2.6.12-rc2 |
171 |
{ |
c9d624432 ACPI: pci_link: r... |
172 |
int *irq = context; |
1da177e4c Linux-2.6.12-rc2 |
173 |
|
eca008c81 [ACPI] handle ACP... |
174 |
switch (resource->type) { |
4a5e3638b ACPI: stop compla... |
175 176 177 |
case ACPI_RESOURCE_TYPE_START_DEPENDENT: case ACPI_RESOURCE_TYPE_END_TAG: return AE_OK; |
50eca3eb8 [ACPI] ACPICA 200... |
178 |
case ACPI_RESOURCE_TYPE_IRQ: |
4be44fcd3 [ACPI] Lindent al... |
179 180 |
{ struct acpi_resource_irq *p = &resource->data.irq; |
50eca3eb8 [ACPI] ACPICA 200... |
181 |
if (!p || !p->interrupt_count) { |
4be44fcd3 [ACPI] Lindent al... |
182 183 184 185 186 |
/* * IRQ descriptors may have no IRQ# bits set, * particularly those those w/ _STA disabled */ ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
4a5e3638b ACPI: stop compla... |
187 188 |
"Blank _CRS IRQ resource ")); |
d550d98d3 ACPI: delete trac... |
189 |
return AE_OK; |
4be44fcd3 [ACPI] Lindent al... |
190 191 192 |
} *irq = p->interrupts[0]; break; |
1da177e4c Linux-2.6.12-rc2 |
193 |
} |
50eca3eb8 [ACPI] ACPICA 200... |
194 |
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: |
4be44fcd3 [ACPI] Lindent al... |
195 |
{ |
50eca3eb8 [ACPI] ACPICA 200... |
196 |
struct acpi_resource_extended_irq *p = |
4be44fcd3 [ACPI] Lindent al... |
197 |
&resource->data.extended_irq; |
50eca3eb8 [ACPI] ACPICA 200... |
198 |
if (!p || !p->interrupt_count) { |
4be44fcd3 [ACPI] Lindent al... |
199 200 201 202 |
/* * extended IRQ descriptors must * return at least 1 IRQ */ |
cece92969 ACPI: un-export A... |
203 |
printk(KERN_WARNING PREFIX |
4a5e3638b ACPI: stop compla... |
204 205 |
"Blank _CRS EXT IRQ resource "); |
d550d98d3 ACPI: delete trac... |
206 |
return AE_OK; |
4be44fcd3 [ACPI] Lindent al... |
207 208 209 |
} *irq = p->interrupts[0]; break; |
1da177e4c Linux-2.6.12-rc2 |
210 |
} |
d4ec6c7cc [ACPI] remove "Re... |
211 |
break; |
1da177e4c Linux-2.6.12-rc2 |
212 |
default: |
4a5e3638b ACPI: stop compla... |
213 214 215 |
printk(KERN_ERR PREFIX "_CRS resource type 0x%x isn't an IRQ ", resource->type); |
d550d98d3 ACPI: delete trac... |
216 |
return AE_OK; |
1da177e4c Linux-2.6.12-rc2 |
217 |
} |
4a5e3638b ACPI: stop compla... |
218 |
|
d550d98d3 ACPI: delete trac... |
219 |
return AE_CTRL_TERMINATE; |
1da177e4c Linux-2.6.12-rc2 |
220 221 222 223 224 225 226 227 228 |
} /* * Run _CRS and set link->irq.active * * return value: * 0 - success * !0 - failure */ |
4be44fcd3 [ACPI] Lindent al... |
229 |
static int acpi_pci_link_get_current(struct acpi_pci_link *link) |
1da177e4c Linux-2.6.12-rc2 |
230 |
{ |
4be44fcd3 [ACPI] Lindent al... |
231 |
int result = 0; |
c9d624432 ACPI: pci_link: r... |
232 |
acpi_status status; |
4be44fcd3 [ACPI] Lindent al... |
233 |
int irq = 0; |
1da177e4c Linux-2.6.12-rc2 |
234 |
|
1da177e4c Linux-2.6.12-rc2 |
235 236 237 238 239 240 241 |
link->irq.active = 0; /* in practice, status disabled is meaningless, ignore it */ if (acpi_strict) { /* Query _STA, set link->device->status */ result = acpi_bus_get_status(link->device); if (result) { |
6468463ab ACPI: un-export A... |
242 243 |
printk(KERN_ERR PREFIX "Unable to read status "); |
1da177e4c Linux-2.6.12-rc2 |
244 245 246 247 248 249 |
goto end; } if (!link->device->status.enabled) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link disabled ")); |
d550d98d3 ACPI: delete trac... |
250 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
251 252 |
} } |
c6237b210 ACPI: Fix whitesp... |
253 254 |
/* * Query and parse _CRS to get the current IRQ assignment. |
1da177e4c Linux-2.6.12-rc2 |
255 |
*/ |
67a713657 ACPI: pci_link: U... |
256 |
status = acpi_walk_resources(link->device->handle, METHOD_NAME__CRS, |
4be44fcd3 [ACPI] Lindent al... |
257 |
acpi_pci_link_check_current, &irq); |
1da177e4c Linux-2.6.12-rc2 |
258 |
if (ACPI_FAILURE(status)) { |
a6fc67202 ACPI: Enable ACPI... |
259 |
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _CRS")); |
1da177e4c Linux-2.6.12-rc2 |
260 261 262 263 264 |
result = -ENODEV; goto end; } if (acpi_strict && !irq) { |
6468463ab ACPI: un-export A... |
265 266 |
printk(KERN_ERR PREFIX "_CRS returned 0 "); |
1da177e4c Linux-2.6.12-rc2 |
267 268 269 270 271 272 273 |
result = -ENODEV; } link->irq.active = irq; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link at IRQ %d ", link->irq.active)); |
4be44fcd3 [ACPI] Lindent al... |
274 |
end: |
d550d98d3 ACPI: delete trac... |
275 |
return result; |
1da177e4c Linux-2.6.12-rc2 |
276 |
} |
4be44fcd3 [ACPI] Lindent al... |
277 |
static int acpi_pci_link_set(struct acpi_pci_link *link, int irq) |
1da177e4c Linux-2.6.12-rc2 |
278 |
{ |
c9d624432 ACPI: pci_link: r... |
279 280 |
int result; acpi_status status; |
1da177e4c Linux-2.6.12-rc2 |
281 |
struct { |
4be44fcd3 [ACPI] Lindent al... |
282 283 284 285 |
struct acpi_resource res; struct acpi_resource end; } *resource; struct acpi_buffer buffer = { 0, NULL }; |
1da177e4c Linux-2.6.12-rc2 |
286 |
|
6eca4b4ca ACPI: pci_link: r... |
287 |
if (!irq) |
d550d98d3 ACPI: delete trac... |
288 |
return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
289 |
|
36bcbec7c ACPI: replace kma... |
290 |
resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL); |
4be44fcd3 [ACPI] Lindent al... |
291 |
if (!resource) |
d550d98d3 ACPI: delete trac... |
292 |
return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
293 |
|
4be44fcd3 [ACPI] Lindent al... |
294 |
buffer.length = sizeof(*resource) + 1; |
1da177e4c Linux-2.6.12-rc2 |
295 |
buffer.pointer = resource; |
4be44fcd3 [ACPI] Lindent al... |
296 |
switch (link->irq.resource_type) { |
50eca3eb8 [ACPI] ACPICA 200... |
297 298 |
case ACPI_RESOURCE_TYPE_IRQ: resource->res.type = ACPI_RESOURCE_TYPE_IRQ; |
1da177e4c Linux-2.6.12-rc2 |
299 |
resource->res.length = sizeof(struct acpi_resource); |
50eca3eb8 [ACPI] ACPICA 200... |
300 301 302 303 |
resource->res.data.irq.triggering = link->irq.triggering; resource->res.data.irq.polarity = link->irq.polarity; if (link->irq.triggering == ACPI_EDGE_SENSITIVE) |
c163f90cc ACPI/ACPICA: Triv... |
304 |
resource->res.data.irq.shareable = |
4be44fcd3 [ACPI] Lindent al... |
305 |
ACPI_EXCLUSIVE; |
1da177e4c Linux-2.6.12-rc2 |
306 |
else |
c163f90cc ACPI/ACPICA: Triv... |
307 |
resource->res.data.irq.shareable = ACPI_SHARED; |
50eca3eb8 [ACPI] ACPICA 200... |
308 |
resource->res.data.irq.interrupt_count = 1; |
1da177e4c Linux-2.6.12-rc2 |
309 310 |
resource->res.data.irq.interrupts[0] = irq; break; |
4be44fcd3 [ACPI] Lindent al... |
311 |
|
50eca3eb8 [ACPI] ACPICA 200... |
312 313 |
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: resource->res.type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ; |
1da177e4c Linux-2.6.12-rc2 |
314 |
resource->res.length = sizeof(struct acpi_resource); |
4be44fcd3 [ACPI] Lindent al... |
315 316 |
resource->res.data.extended_irq.producer_consumer = ACPI_CONSUMER; |
50eca3eb8 [ACPI] ACPICA 200... |
317 318 319 320 321 |
resource->res.data.extended_irq.triggering = link->irq.triggering; resource->res.data.extended_irq.polarity = link->irq.polarity; if (link->irq.triggering == ACPI_EDGE_SENSITIVE) |
1c5e1cdd7 ACPI/PCI: pci_lin... |
322 |
resource->res.data.extended_irq.shareable = |
4be44fcd3 [ACPI] Lindent al... |
323 |
ACPI_EXCLUSIVE; |
1da177e4c Linux-2.6.12-rc2 |
324 |
else |
1c5e1cdd7 ACPI/PCI: pci_lin... |
325 |
resource->res.data.extended_irq.shareable = ACPI_SHARED; |
50eca3eb8 [ACPI] ACPICA 200... |
326 |
resource->res.data.extended_irq.interrupt_count = 1; |
1da177e4c Linux-2.6.12-rc2 |
327 328 329 330 |
resource->res.data.extended_irq.interrupts[0] = irq; /* ignore resource_source, it's optional */ break; default: |
6468463ab ACPI: un-export A... |
331 332 |
printk(KERN_ERR PREFIX "Invalid Resource_type %d ", link->irq.resource_type); |
1da177e4c Linux-2.6.12-rc2 |
333 334 335 336 |
result = -EINVAL; goto end; } |
50eca3eb8 [ACPI] ACPICA 200... |
337 |
resource->end.type = ACPI_RESOURCE_TYPE_END_TAG; |
f084dbb93 ACPI: Set length ... |
338 |
resource->end.length = sizeof(struct acpi_resource); |
1da177e4c Linux-2.6.12-rc2 |
339 340 |
/* Attempt to set the resource */ |
67a713657 ACPI: pci_link: U... |
341 |
status = acpi_set_current_resources(link->device->handle, &buffer); |
1da177e4c Linux-2.6.12-rc2 |
342 343 344 |
/* check for total failure */ if (ACPI_FAILURE(status)) { |
a6fc67202 ACPI: Enable ACPI... |
345 |
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _SRS")); |
1da177e4c Linux-2.6.12-rc2 |
346 347 348 349 350 351 352 |
result = -ENODEV; goto end; } /* Query _STA, set device->status */ result = acpi_bus_get_status(link->device); if (result) { |
6468463ab ACPI: un-export A... |
353 354 |
printk(KERN_ERR PREFIX "Unable to read status "); |
1da177e4c Linux-2.6.12-rc2 |
355 356 357 |
goto end; } if (!link->device->status.enabled) { |
cece92969 ACPI: un-export A... |
358 359 360 |
printk(KERN_WARNING PREFIX "%s [%s] disabled and referenced, BIOS bug ", |
a6fc67202 ACPI: Enable ACPI... |
361 |
acpi_device_name(link->device), |
cece92969 ACPI: un-export A... |
362 |
acpi_device_bid(link->device)); |
1da177e4c Linux-2.6.12-rc2 |
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
} /* Query _CRS, set link->irq.active */ result = acpi_pci_link_get_current(link); if (result) { goto end; } /* * Is current setting not what we set? * set link->irq.active */ if (link->irq.active != irq) { /* * policy: when _CRS doesn't return what we just _SRS * assume _SRS worked and override _CRS value. */ |
cece92969 ACPI: un-export A... |
380 381 382 |
printk(KERN_WARNING PREFIX "%s [%s] BIOS reported IRQ %d, using IRQ %d ", |
a6fc67202 ACPI: Enable ACPI... |
383 |
acpi_device_name(link->device), |
cece92969 ACPI: un-export A... |
384 |
acpi_device_bid(link->device), link->irq.active, irq); |
1da177e4c Linux-2.6.12-rc2 |
385 386 387 388 389 |
link->irq.active = irq; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Set IRQ %d ", link->irq.active)); |
4be44fcd3 [ACPI] Lindent al... |
390 391 |
end: |
1da177e4c Linux-2.6.12-rc2 |
392 |
kfree(resource); |
d550d98d3 ACPI: delete trac... |
393 |
return result; |
1da177e4c Linux-2.6.12-rc2 |
394 |
} |
1da177e4c Linux-2.6.12-rc2 |
395 396 397 398 399 400 401 |
/* -------------------------------------------------------------------------- PCI Link IRQ Management -------------------------------------------------------------------------- */ /* * "acpi_irq_balance" (default in APIC mode) enables ACPI to use PIC Interrupt * Link Devices to move the PIRQs around to minimize sharing. |
c6237b210 ACPI: Fix whitesp... |
402 |
* |
1da177e4c Linux-2.6.12-rc2 |
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 |
* "acpi_irq_nobalance" (default in PIC mode) tells ACPI not to move any PIC IRQs * that the BIOS has already set to active. This is necessary because * ACPI has no automatic means of knowing what ISA IRQs are used. Note that * if the BIOS doesn't set a Link Device active, ACPI needs to program it * even if acpi_irq_nobalance is set. * * A tables of penalties avoids directing PCI interrupts to well known * ISA IRQs. Boot params are available to over-ride the default table: * * List interrupts that are free for PCI use. * acpi_irq_pci=n[,m] * * List interrupts that should not be used for PCI: * acpi_irq_isa=n[,m] * * Note that PCI IRQ routers have a list of possible IRQs, * which may not include the IRQs this table says are available. |
c6237b210 ACPI: Fix whitesp... |
420 |
* |
1da177e4c Linux-2.6.12-rc2 |
421 422 423 424 425 426 427 428 |
* Since this heuristic can't tell the difference between a link * that no device will attach to, vs. a link which may be shared * by multiple active devices -- it is not optimal. * * If interrupt performance is that important, get an IO-APIC system * with a pin dedicated to each device. Or for that matter, an MSI * enabled system. */ |
5c5087a55 ACPI,PCI,IRQ: red... |
429 |
#define ACPI_MAX_ISA_IRQS 16 |
1da177e4c Linux-2.6.12-rc2 |
430 |
|
1da177e4c Linux-2.6.12-rc2 |
431 432 433 434 435 |
#define PIRQ_PENALTY_PCI_POSSIBLE (16*16) #define PIRQ_PENALTY_PCI_USING (16*16*16) #define PIRQ_PENALTY_ISA_TYPICAL (16*16*16*16) #define PIRQ_PENALTY_ISA_USED (16*16*16*16*16) #define PIRQ_PENALTY_ISA_ALWAYS (16*16*16*16*16*16) |
5c5087a55 ACPI,PCI,IRQ: red... |
436 |
static int acpi_isa_irq_penalty[ACPI_MAX_ISA_IRQS] = { |
1da177e4c Linux-2.6.12-rc2 |
437 438 439 |
PIRQ_PENALTY_ISA_ALWAYS, /* IRQ0 timer */ PIRQ_PENALTY_ISA_ALWAYS, /* IRQ1 keyboard */ PIRQ_PENALTY_ISA_ALWAYS, /* IRQ2 cascade */ |
4be44fcd3 [ACPI] Lindent al... |
440 441 |
PIRQ_PENALTY_ISA_TYPICAL, /* IRQ3 serial */ PIRQ_PENALTY_ISA_TYPICAL, /* IRQ4 serial */ |
1da177e4c Linux-2.6.12-rc2 |
442 443 444 445 |
PIRQ_PENALTY_ISA_TYPICAL, /* IRQ5 sometimes SoundBlaster */ PIRQ_PENALTY_ISA_TYPICAL, /* IRQ6 */ PIRQ_PENALTY_ISA_TYPICAL, /* IRQ7 parallel, spurious */ PIRQ_PENALTY_ISA_TYPICAL, /* IRQ8 rtc, sometimes */ |
103544d86 ACPI,PCI,IRQ: red... |
446 447 448 |
0, /* IRQ9 PCI, often acpi */ 0, /* IRQ10 PCI */ 0, /* IRQ11 PCI */ |
1c9ca3a7d ACPI: pci_link: c... |
449 450 451 452 |
PIRQ_PENALTY_ISA_USED, /* IRQ12 mouse */ PIRQ_PENALTY_ISA_USED, /* IRQ13 fpe, sometimes */ PIRQ_PENALTY_ISA_USED, /* IRQ14 ide0 */ PIRQ_PENALTY_ISA_USED, /* IRQ15 ide1 */ |
e24971457 Revert "ACPI, PCI... |
453 |
/* >IRQ15 */ |
1da177e4c Linux-2.6.12-rc2 |
454 |
}; |
103544d86 ACPI,PCI,IRQ: red... |
455 456 457 458 |
static int acpi_irq_pci_sharing_penalty(int irq) { struct acpi_pci_link *link; int penalty = 0; |
4a6e68bf9 ACPI,PCI,IRQ: fac... |
459 |
int i; |
103544d86 ACPI,PCI,IRQ: red... |
460 461 462 463 464 465 466 467 |
list_for_each_entry(link, &acpi_link_list, list) { /* * If a link is active, penalize its IRQ heavily * so we try to choose a different IRQ. */ if (link->irq.active && link->irq.active == irq) penalty += PIRQ_PENALTY_PCI_USING; |
4a6e68bf9 ACPI,PCI,IRQ: fac... |
468 469 470 471 472 473 474 475 |
/* * penalize the IRQs PCI might use, but not as severely. */ for (i = 0; i < link->irq.possible_count; i++) if (link->irq.possible[i] == irq) penalty += PIRQ_PENALTY_PCI_POSSIBLE / link->irq.possible_count; |
103544d86 ACPI,PCI,IRQ: red... |
476 477 478 479 480 481 482 483 |
} return penalty; } static int acpi_irq_get_penalty(int irq) { int penalty = 0; |
f1caa61df ACPI/PCI: pci_lin... |
484 485 |
if (irq == sci_irq) penalty += sci_penalty; |
103544d86 ACPI,PCI,IRQ: red... |
486 |
|
f7eca374f ACPI,PCI,IRQ: sep... |
487 488 |
if (irq < ACPI_MAX_ISA_IRQS) return penalty + acpi_isa_irq_penalty[irq]; |
f1caa61df ACPI/PCI: pci_lin... |
489 |
return penalty + acpi_irq_pci_sharing_penalty(irq); |
103544d86 ACPI,PCI,IRQ: red... |
490 |
} |
487cf917e Revert "ACPI, PCI... |
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 |
int __init acpi_irq_penalty_init(void) { struct acpi_pci_link *link; int i; /* * Update penalties to facilitate IRQ balancing. */ list_for_each_entry(link, &acpi_link_list, list) { /* * reflect the possible and active irqs in the penalty table -- * useful for breaking ties. */ if (link->irq.possible_count) { int penalty = PIRQ_PENALTY_PCI_POSSIBLE / link->irq.possible_count; for (i = 0; i < link->irq.possible_count; i++) { if (link->irq.possible[i] < ACPI_MAX_ISA_IRQS) acpi_isa_irq_penalty[link->irq. possible[i]] += penalty; } } else if (link->irq.active && (link->irq.active < ACPI_MAX_ISA_IRQS)) { acpi_isa_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_POSSIBLE; } } return 0; } |
32836259f ACPI: pci_link: r... |
526 |
static int acpi_irq_balance = -1; /* 0: static, 1: balance */ |
1da177e4c Linux-2.6.12-rc2 |
527 |
|
4be44fcd3 [ACPI] Lindent al... |
528 |
static int acpi_pci_link_allocate(struct acpi_pci_link *link) |
1da177e4c Linux-2.6.12-rc2 |
529 |
{ |
4be44fcd3 [ACPI] Lindent al... |
530 531 |
int irq; int i; |
1da177e4c Linux-2.6.12-rc2 |
532 |
|
87bec66b9 [ACPI] suspend/re... |
533 534 535 536 |
if (link->irq.initialized) { if (link->refcnt == 0) /* This means the link is disabled but initialized */ acpi_pci_link_set(link, link->irq.active); |
d550d98d3 ACPI: delete trac... |
537 |
return 0; |
87bec66b9 [ACPI] suspend/re... |
538 |
} |
1da177e4c Linux-2.6.12-rc2 |
539 540 541 542 543 544 545 546 547 548 549 550 551 |
/* * search for active IRQ in list of possible IRQs. */ for (i = 0; i < link->irq.possible_count; ++i) { if (link->irq.active == link->irq.possible[i]) break; } /* * forget active IRQ that is not in possible list */ if (i == link->irq.possible_count) { if (acpi_strict) |
cece92969 ACPI: un-export A... |
552 553 554 |
printk(KERN_WARNING PREFIX "_CRS %d not found" " in _PRS ", link->irq.active); |
1da177e4c Linux-2.6.12-rc2 |
555 556 557 558 559 560 |
link->irq.active = 0; } /* * if active found, use it; else pick entry from end of possible list. */ |
1c9ca3a7d ACPI: pci_link: c... |
561 |
if (link->irq.active) |
1da177e4c Linux-2.6.12-rc2 |
562 |
irq = link->irq.active; |
1c9ca3a7d ACPI: pci_link: c... |
563 |
else |
1da177e4c Linux-2.6.12-rc2 |
564 |
irq = link->irq.possible[link->irq.possible_count - 1]; |
1da177e4c Linux-2.6.12-rc2 |
565 566 567 568 569 570 571 |
if (acpi_irq_balance || !link->irq.active) { /* * Select the best IRQ. This is done in reverse to promote * the use of IRQs 9, 10, 11, and >15. */ for (i = (link->irq.possible_count - 1); i >= 0; i--) { |
103544d86 ACPI,PCI,IRQ: red... |
572 573 |
if (acpi_irq_get_penalty(irq) > acpi_irq_get_penalty(link->irq.possible[i])) |
1da177e4c Linux-2.6.12-rc2 |
574 575 576 |
irq = link->irq.possible[i]; } } |
103544d86 ACPI,PCI,IRQ: red... |
577 |
if (acpi_irq_get_penalty(irq) >= PIRQ_PENALTY_ISA_ALWAYS) { |
5ebc76035 ACPI, PCI, irq: D... |
578 579 580 581 582 583 584 |
printk(KERN_ERR PREFIX "No IRQ available for %s [%s]. " "Try pci=noacpi or acpi=off ", acpi_device_name(link->device), acpi_device_bid(link->device)); return -ENODEV; } |
1da177e4c Linux-2.6.12-rc2 |
585 586 587 |
/* Attempt to enable the link device at this IRQ. */ if (acpi_pci_link_set(link, irq)) { |
6468463ab ACPI: un-export A... |
588 589 590 |
printk(KERN_ERR PREFIX "Unable to set IRQ for %s [%s]. " "Try pci=noacpi or acpi=off ", |
a6fc67202 ACPI: Enable ACPI... |
591 |
acpi_device_name(link->device), |
6468463ab ACPI: un-export A... |
592 |
acpi_device_bid(link->device)); |
d550d98d3 ACPI: delete trac... |
593 |
return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
594 |
} else { |
98756f531 ACPI/PCI: pci_lin... |
595 596 597 |
if (link->irq.active < ACPI_MAX_ISA_IRQS) acpi_isa_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING; |
90fd94e4a ACPI/PCI: pci_lin... |
598 599 |
pr_info("%s [%s] enabled at IRQ %d ", |
4be44fcd3 [ACPI] Lindent al... |
600 601 |
acpi_device_name(link->device), acpi_device_bid(link->device), link->irq.active); |
1da177e4c Linux-2.6.12-rc2 |
602 603 604 |
} link->irq.initialized = 1; |
d550d98d3 ACPI: delete trac... |
605 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
606 607 608 |
} /* |
87bec66b9 [ACPI] suspend/re... |
609 |
* acpi_pci_link_allocate_irq |
1da177e4c Linux-2.6.12-rc2 |
610 611 612 |
* success: return IRQ >= 0 * failure: return -1 */ |
1c9ca3a7d ACPI: pci_link: c... |
613 614 |
int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering, int *polarity, char **name) |
1da177e4c Linux-2.6.12-rc2 |
615 |
{ |
c9d624432 ACPI: pci_link: r... |
616 617 618 |
int result; struct acpi_device *device; struct acpi_pci_link *link; |
1da177e4c Linux-2.6.12-rc2 |
619 |
|
1da177e4c Linux-2.6.12-rc2 |
620 621 |
result = acpi_bus_get_device(handle, &device); if (result) { |
6468463ab ACPI: un-export A... |
622 623 |
printk(KERN_ERR PREFIX "Invalid link device "); |
d550d98d3 ACPI: delete trac... |
624 |
return -1; |
1da177e4c Linux-2.6.12-rc2 |
625 |
} |
50dd09697 ACPI: Remove unne... |
626 |
link = acpi_driver_data(device); |
1da177e4c Linux-2.6.12-rc2 |
627 |
if (!link) { |
6468463ab ACPI: un-export A... |
628 629 |
printk(KERN_ERR PREFIX "Invalid link context "); |
d550d98d3 ACPI: delete trac... |
630 |
return -1; |
1da177e4c Linux-2.6.12-rc2 |
631 632 633 634 |
} /* TBD: Support multiple index (IRQ) entries per Link Device */ if (index) { |
6468463ab ACPI: un-export A... |
635 636 |
printk(KERN_ERR PREFIX "Invalid index %d ", index); |
d550d98d3 ACPI: delete trac... |
637 |
return -1; |
1da177e4c Linux-2.6.12-rc2 |
638 |
} |
36e430951 sem2mutex: acpi, ... |
639 |
mutex_lock(&acpi_link_lock); |
87bec66b9 [ACPI] suspend/re... |
640 |
if (acpi_pci_link_allocate(link)) { |
36e430951 sem2mutex: acpi, ... |
641 |
mutex_unlock(&acpi_link_lock); |
d550d98d3 ACPI: delete trac... |
642 |
return -1; |
87bec66b9 [ACPI] suspend/re... |
643 |
} |
4be44fcd3 [ACPI] Lindent al... |
644 |
|
1da177e4c Linux-2.6.12-rc2 |
645 |
if (!link->irq.active) { |
36e430951 sem2mutex: acpi, ... |
646 |
mutex_unlock(&acpi_link_lock); |
6468463ab ACPI: un-export A... |
647 648 |
printk(KERN_ERR PREFIX "Link active IRQ is 0! "); |
d550d98d3 ACPI: delete trac... |
649 |
return -1; |
1da177e4c Linux-2.6.12-rc2 |
650 |
} |
4be44fcd3 [ACPI] Lindent al... |
651 |
link->refcnt++; |
36e430951 sem2mutex: acpi, ... |
652 |
mutex_unlock(&acpi_link_lock); |
1da177e4c Linux-2.6.12-rc2 |
653 |
|
50eca3eb8 [ACPI] ACPICA 200... |
654 655 656 657 |
if (triggering) *triggering = link->irq.triggering; if (polarity) *polarity = link->irq.polarity; |
4be44fcd3 [ACPI] Lindent al... |
658 659 |
if (name) *name = acpi_device_bid(link->device); |
87bec66b9 [ACPI] suspend/re... |
660 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
4be44fcd3 [ACPI] Lindent al... |
661 662 663 |
"Link %s is referenced ", acpi_device_bid(link->device))); |
8698fab1c ACPI/PCI: Remove ... |
664 |
return link->irq.active; |
1da177e4c Linux-2.6.12-rc2 |
665 |
} |
87bec66b9 [ACPI] suspend/re... |
666 667 668 669 |
/* * We don't change link's irq information here. After it is reenabled, we * continue use the info */ |
4be44fcd3 [ACPI] Lindent al... |
670 |
int acpi_pci_link_free_irq(acpi_handle handle) |
87bec66b9 [ACPI] suspend/re... |
671 |
{ |
c9d624432 ACPI: pci_link: r... |
672 673 |
struct acpi_device *device; struct acpi_pci_link *link; |
4be44fcd3 [ACPI] Lindent al... |
674 |
acpi_status result; |
87bec66b9 [ACPI] suspend/re... |
675 |
|
87bec66b9 [ACPI] suspend/re... |
676 677 |
result = acpi_bus_get_device(handle, &device); if (result) { |
6468463ab ACPI: un-export A... |
678 679 |
printk(KERN_ERR PREFIX "Invalid link device "); |
d550d98d3 ACPI: delete trac... |
680 |
return -1; |
87bec66b9 [ACPI] suspend/re... |
681 |
} |
1da177e4c Linux-2.6.12-rc2 |
682 |
|
50dd09697 ACPI: Remove unne... |
683 |
link = acpi_driver_data(device); |
87bec66b9 [ACPI] suspend/re... |
684 |
if (!link) { |
6468463ab ACPI: un-export A... |
685 686 |
printk(KERN_ERR PREFIX "Invalid link context "); |
d550d98d3 ACPI: delete trac... |
687 |
return -1; |
87bec66b9 [ACPI] suspend/re... |
688 |
} |
36e430951 sem2mutex: acpi, ... |
689 |
mutex_lock(&acpi_link_lock); |
87bec66b9 [ACPI] suspend/re... |
690 |
if (!link->irq.initialized) { |
36e430951 sem2mutex: acpi, ... |
691 |
mutex_unlock(&acpi_link_lock); |
6468463ab ACPI: un-export A... |
692 693 |
printk(KERN_ERR PREFIX "Link isn't initialized "); |
d550d98d3 ACPI: delete trac... |
694 |
return -1; |
87bec66b9 [ACPI] suspend/re... |
695 |
} |
ecc21ebe6 [ACPI] PCI interr... |
696 697 698 699 700 701 702 703 704 705 |
#ifdef FUTURE_USE /* * The Link reference count allows us to _DISable an unused link * and suspend time, and set it again on resume. * However, 2.6.12 still has irq_router.resume * which blindly restores the link state. * So we disable the reference count method * to prevent duplicate acpi_pci_link_set() * which would harm some systems */ |
4be44fcd3 [ACPI] Lindent al... |
706 |
link->refcnt--; |
ecc21ebe6 [ACPI] PCI interr... |
707 |
#endif |
87bec66b9 [ACPI] suspend/re... |
708 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
4be44fcd3 [ACPI] Lindent al... |
709 710 711 |
"Link %s is dereferenced ", acpi_device_bid(link->device))); |
87bec66b9 [ACPI] suspend/re... |
712 |
|
1c9ca3a7d ACPI: pci_link: c... |
713 |
if (link->refcnt == 0) |
383d7a11c ACPI: Fix possibl... |
714 |
acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL); |
1c9ca3a7d ACPI: pci_link: c... |
715 |
|
36e430951 sem2mutex: acpi, ... |
716 |
mutex_unlock(&acpi_link_lock); |
8698fab1c ACPI/PCI: Remove ... |
717 |
return link->irq.active; |
87bec66b9 [ACPI] suspend/re... |
718 |
} |
4be44fcd3 [ACPI] Lindent al... |
719 |
|
1da177e4c Linux-2.6.12-rc2 |
720 721 722 |
/* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ |
4daeaf683 ACPI / PCI: Make ... |
723 724 |
static int acpi_pci_link_add(struct acpi_device *device, const struct acpi_device_id *not_used) |
1da177e4c Linux-2.6.12-rc2 |
725 |
{ |
c9d624432 ACPI: pci_link: r... |
726 727 728 |
int result; struct acpi_pci_link *link; int i; |
4be44fcd3 [ACPI] Lindent al... |
729 |
int found = 0; |
1da177e4c Linux-2.6.12-rc2 |
730 |
|
36bcbec7c ACPI: replace kma... |
731 |
link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
732 |
if (!link) |
d550d98d3 ACPI: delete trac... |
733 |
return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
734 735 |
link->device = device; |
1da177e4c Linux-2.6.12-rc2 |
736 737 |
strcpy(acpi_device_name(device), ACPI_PCI_LINK_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS); |
db89b4f0d ACPI: catch calls... |
738 |
device->driver_data = link; |
1da177e4c Linux-2.6.12-rc2 |
739 |
|
36e430951 sem2mutex: acpi, ... |
740 |
mutex_lock(&acpi_link_lock); |
1da177e4c Linux-2.6.12-rc2 |
741 742 743 744 745 746 |
result = acpi_pci_link_get_possible(link); if (result) goto end; /* query and set link->irq.active */ acpi_pci_link_get_current(link); |
0dc070bb0 ACPI: drivers/acp... |
747 |
printk(KERN_INFO PREFIX "%s [%s] (IRQs", acpi_device_name(device), |
4be44fcd3 [ACPI] Lindent al... |
748 |
acpi_device_bid(device)); |
1da177e4c Linux-2.6.12-rc2 |
749 750 |
for (i = 0; i < link->irq.possible_count; i++) { if (link->irq.active == link->irq.possible[i]) { |
be96447e0 acpi: use KERN_CO... |
751 |
printk(KERN_CONT " *%d", link->irq.possible[i]); |
1da177e4c Linux-2.6.12-rc2 |
752 |
found = 1; |
4be44fcd3 [ACPI] Lindent al... |
753 |
} else |
be96447e0 acpi: use KERN_CO... |
754 |
printk(KERN_CONT " %d", link->irq.possible[i]); |
1da177e4c Linux-2.6.12-rc2 |
755 |
} |
be96447e0 acpi: use KERN_CO... |
756 |
printk(KERN_CONT ")"); |
1da177e4c Linux-2.6.12-rc2 |
757 758 |
if (!found) |
be96447e0 acpi: use KERN_CO... |
759 |
printk(KERN_CONT " *%d", link->irq.active); |
1da177e4c Linux-2.6.12-rc2 |
760 |
|
4be44fcd3 [ACPI] Lindent al... |
761 |
if (!link->device->status.enabled) |
be96447e0 acpi: use KERN_CO... |
762 |
printk(KERN_CONT ", disabled."); |
1da177e4c Linux-2.6.12-rc2 |
763 |
|
be96447e0 acpi: use KERN_CO... |
764 765 |
printk(KERN_CONT " "); |
1da177e4c Linux-2.6.12-rc2 |
766 |
|
5f0dccaa8 ACPI: pci_link: s... |
767 |
list_add_tail(&link->list, &acpi_link_list); |
1da177e4c Linux-2.6.12-rc2 |
768 |
|
4be44fcd3 [ACPI] Lindent al... |
769 |
end: |
1da177e4c Linux-2.6.12-rc2 |
770 |
/* disable all links -- to be activated on use */ |
383d7a11c ACPI: Fix possibl... |
771 |
acpi_evaluate_object(device->handle, "_DIS", NULL, NULL); |
36e430951 sem2mutex: acpi, ... |
772 |
mutex_unlock(&acpi_link_lock); |
1da177e4c Linux-2.6.12-rc2 |
773 774 775 |
if (result) kfree(link); |
4daeaf683 ACPI / PCI: Make ... |
776 |
return result < 0 ? result : 1; |
1da177e4c Linux-2.6.12-rc2 |
777 |
} |
4be44fcd3 [ACPI] Lindent al... |
778 |
static int acpi_pci_link_resume(struct acpi_pci_link *link) |
697a2d63a Revert ACPI inter... |
779 |
{ |
697a2d63a Revert ACPI inter... |
780 |
if (link->refcnt && link->irq.active && link->irq.initialized) |
d550d98d3 ACPI: delete trac... |
781 |
return (acpi_pci_link_set(link, link->irq.active)); |
1c9ca3a7d ACPI: pci_link: c... |
782 783 |
return 0; |
697a2d63a Revert ACPI inter... |
784 |
} |
c3146df2b ACPI: Use syscore... |
785 |
static void irqrouter_resume(void) |
1da177e4c Linux-2.6.12-rc2 |
786 |
{ |
c9d624432 ACPI: pci_link: r... |
787 |
struct acpi_pci_link *link; |
1da177e4c Linux-2.6.12-rc2 |
788 |
|
5f0dccaa8 ACPI: pci_link: s... |
789 |
list_for_each_entry(link, &acpi_link_list, list) { |
697a2d63a Revert ACPI inter... |
790 |
acpi_pci_link_resume(link); |
1da177e4c Linux-2.6.12-rc2 |
791 |
} |
1da177e4c Linux-2.6.12-rc2 |
792 |
} |
4daeaf683 ACPI / PCI: Make ... |
793 |
static void acpi_pci_link_remove(struct acpi_device *device) |
1da177e4c Linux-2.6.12-rc2 |
794 |
{ |
c9d624432 ACPI: pci_link: r... |
795 |
struct acpi_pci_link *link; |
1da177e4c Linux-2.6.12-rc2 |
796 |
|
50dd09697 ACPI: Remove unne... |
797 |
link = acpi_driver_data(device); |
1da177e4c Linux-2.6.12-rc2 |
798 |
|
36e430951 sem2mutex: acpi, ... |
799 |
mutex_lock(&acpi_link_lock); |
5f0dccaa8 ACPI: pci_link: s... |
800 |
list_del(&link->list); |
36e430951 sem2mutex: acpi, ... |
801 |
mutex_unlock(&acpi_link_lock); |
1da177e4c Linux-2.6.12-rc2 |
802 803 |
kfree(link); |
1da177e4c Linux-2.6.12-rc2 |
804 805 806 |
} /* |
5c5087a55 ACPI,PCI,IRQ: red... |
807 |
* modify acpi_isa_irq_penalty[] from cmdline |
1da177e4c Linux-2.6.12-rc2 |
808 809 810 811 812 813 814 815 |
*/ static int __init acpi_irq_penalty_update(char *str, int used) { int i; for (i = 0; i < 16; i++) { int retval; int irq; |
5c5087a55 ACPI,PCI,IRQ: red... |
816 |
int new_penalty; |
1da177e4c Linux-2.6.12-rc2 |
817 |
|
4be44fcd3 [ACPI] Lindent al... |
818 |
retval = get_option(&str, &irq); |
1da177e4c Linux-2.6.12-rc2 |
819 820 821 |
if (!retval) break; /* no number found */ |
5c5087a55 ACPI,PCI,IRQ: red... |
822 823 |
/* see if this is a ISA IRQ */ if ((irq < 0) || (irq >= ACPI_MAX_ISA_IRQS)) |
e24971457 Revert "ACPI, PCI... |
824 |
continue; |
1da177e4c Linux-2.6.12-rc2 |
825 |
if (used) |
eeaed4bb5 ACPI/PCI/IRQ: ass... |
826 |
new_penalty = acpi_isa_irq_penalty[irq] + |
5c5087a55 ACPI,PCI,IRQ: red... |
827 |
PIRQ_PENALTY_ISA_USED; |
1da177e4c Linux-2.6.12-rc2 |
828 |
else |
5c5087a55 ACPI,PCI,IRQ: red... |
829 |
new_penalty = 0; |
1da177e4c Linux-2.6.12-rc2 |
830 |
|
5c5087a55 ACPI,PCI,IRQ: red... |
831 |
acpi_isa_irq_penalty[irq] = new_penalty; |
1da177e4c Linux-2.6.12-rc2 |
832 833 834 835 836 837 838 839 840 841 842 843 844 |
if (retval != 2) /* no next number */ break; } return 1; } /* * We'd like PNP to call this routine for the * single ISA_USED value for each legacy device. * But instead it calls us with each POSSIBLE setting. * There is no ISA_POSSIBLE weight, so we simply use * the (small) PCI_USING penalty. */ |
c9c3e457d [ACPI] PNPACPI vs... |
845 |
void acpi_penalize_isa_irq(int irq, int active) |
1da177e4c Linux-2.6.12-rc2 |
846 |
{ |
5c5087a55 ACPI,PCI,IRQ: red... |
847 |
if ((irq >= 0) && (irq < ARRAY_SIZE(acpi_isa_irq_penalty))) |
eeaed4bb5 ACPI/PCI/IRQ: ass... |
848 |
acpi_isa_irq_penalty[irq] += |
54794580f ACPI,PCI,IRQ: cor... |
849 |
(active ? PIRQ_PENALTY_ISA_USED : PIRQ_PENALTY_PCI_USING); |
1da177e4c Linux-2.6.12-rc2 |
850 |
} |
5ebc76035 ACPI, PCI, irq: D... |
851 852 |
bool acpi_isa_irq_available(int irq) { |
5c5087a55 ACPI,PCI,IRQ: red... |
853 |
return irq >= 0 && (irq >= ARRAY_SIZE(acpi_isa_irq_penalty) || |
103544d86 ACPI,PCI,IRQ: red... |
854 |
acpi_irq_get_penalty(irq) < PIRQ_PENALTY_ISA_ALWAYS); |
5ebc76035 ACPI, PCI, irq: D... |
855 |
} |
f1caa61df ACPI/PCI: pci_lin... |
856 857 858 859 860 861 862 863 864 865 |
void acpi_penalize_sci_irq(int irq, int trigger, int polarity) { sci_irq = irq; if (trigger == ACPI_MADT_TRIGGER_LEVEL && polarity == ACPI_MADT_POLARITY_ACTIVE_LOW) sci_penalty = PIRQ_PENALTY_PCI_USING; else sci_penalty = PIRQ_PENALTY_ISA_ALWAYS; } |
5d0ddfebb ACPI, PCI: Penali... |
866 |
/* |
1da177e4c Linux-2.6.12-rc2 |
867 868 869 870 871 872 873 874 |
* Over-ride default table to reserve additional IRQs for use by ISA * e.g. acpi_irq_isa=5 * Useful for telling ACPI how not to interfere with your ISA sound card. */ static int __init acpi_irq_isa(char *str) { return acpi_irq_penalty_update(str, 1); } |
4be44fcd3 [ACPI] Lindent al... |
875 |
|
1da177e4c Linux-2.6.12-rc2 |
876 877 878 879 880 881 882 883 884 885 886 |
__setup("acpi_irq_isa=", acpi_irq_isa); /* * Over-ride default table to free additional IRQs for use by PCI * e.g. acpi_irq_pci=7,15 * Used for acpi_irq_balance to free up IRQs to reduce PCI IRQ sharing. */ static int __init acpi_irq_pci(char *str) { return acpi_irq_penalty_update(str, 0); } |
4be44fcd3 [ACPI] Lindent al... |
887 |
|
1da177e4c Linux-2.6.12-rc2 |
888 889 890 891 892 893 894 |
__setup("acpi_irq_pci=", acpi_irq_pci); static int __init acpi_irq_nobalance_set(char *str) { acpi_irq_balance = 0; return 1; } |
4be44fcd3 [ACPI] Lindent al... |
895 |
|
1da177e4c Linux-2.6.12-rc2 |
896 |
__setup("acpi_irq_nobalance", acpi_irq_nobalance_set); |
8a383ef0b ACPI: ec.c, pci_l... |
897 |
static int __init acpi_irq_balance_set(char *str) |
1da177e4c Linux-2.6.12-rc2 |
898 899 900 901 |
{ acpi_irq_balance = 1; return 1; } |
1da177e4c Linux-2.6.12-rc2 |
902 |
|
4be44fcd3 [ACPI] Lindent al... |
903 |
__setup("acpi_irq_balance", acpi_irq_balance_set); |
1da177e4c Linux-2.6.12-rc2 |
904 |
|
c3146df2b ACPI: Use syscore... |
905 |
static struct syscore_ops irqrouter_syscore_ops = { |
4be44fcd3 [ACPI] Lindent al... |
906 |
.resume = irqrouter_resume, |
1da177e4c Linux-2.6.12-rc2 |
907 |
}; |
4daeaf683 ACPI / PCI: Make ... |
908 |
void __init acpi_pci_link_init(void) |
1da177e4c Linux-2.6.12-rc2 |
909 |
{ |
1da177e4c Linux-2.6.12-rc2 |
910 |
if (acpi_noirq) |
4daeaf683 ACPI / PCI: Make ... |
911 |
return; |
1da177e4c Linux-2.6.12-rc2 |
912 |
|
32836259f ACPI: pci_link: r... |
913 914 915 916 917 918 919 |
if (acpi_irq_balance == -1) { /* no command line switch: enable balancing in IOAPIC mode */ if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) acpi_irq_balance = 1; else acpi_irq_balance = 0; } |
4daeaf683 ACPI / PCI: Make ... |
920 921 |
register_syscore_ops(&irqrouter_syscore_ops); acpi_scan_add_handler(&pci_link_handler); |
1da177e4c Linux-2.6.12-rc2 |
922 |
} |