Blame view
drivers/acpi/pci_link.c
23.1 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
/* * 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> * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * TBD: * 1. Support more than one IRQ resource entry per link device (index). * 2. Implement start/stop mechanism and use ACPI Bus Driver facilities * for IRQ management (e.g. start()->_SRS). */ |
c3146df2b ACPI: Use syscore... |
31 |
#include <linux/syscore_ops.h> |
1da177e4c Linux-2.6.12-rc2 |
32 33 34 35 |
#include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/types.h> |
1da177e4c Linux-2.6.12-rc2 |
36 37 38 |
#include <linux/spinlock.h> #include <linux/pm.h> #include <linux/pci.h> |
36e430951 sem2mutex: acpi, ... |
39 |
#include <linux/mutex.h> |
5a0e3ad6a include cleanup: ... |
40 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
41 42 43 |
#include <acpi/acpi_bus.h> #include <acpi/acpi_drivers.h> |
a192a9580 ACPI: Move defini... |
44 |
#define PREFIX "ACPI: " |
1c9ca3a7d ACPI: pci_link: c... |
45 |
#define _COMPONENT ACPI_PCI_COMPONENT |
f52fd66d2 ACPI: clean up AC... |
46 |
ACPI_MODULE_NAME("pci_link"); |
1da177e4c Linux-2.6.12-rc2 |
47 |
#define ACPI_PCI_LINK_CLASS "pci_irq_routing" |
1da177e4c Linux-2.6.12-rc2 |
48 49 50 |
#define ACPI_PCI_LINK_DEVICE_NAME "PCI Interrupt Link" #define ACPI_PCI_LINK_FILE_INFO "info" #define ACPI_PCI_LINK_FILE_STATUS "state" |
1c9ca3a7d ACPI: pci_link: c... |
51 |
#define ACPI_PCI_LINK_MAX_POSSIBLE 16 |
4be44fcd3 [ACPI] Lindent al... |
52 53 |
static int acpi_pci_link_add(struct acpi_device *device); static int acpi_pci_link_remove(struct acpi_device *device, int type); |
1da177e4c Linux-2.6.12-rc2 |
54 |
|
c97adf9e7 acpi: make ACPI d... |
55 |
static const struct acpi_device_id link_device_ids[] = { |
1ba90e3a8 ACPI: autoload mo... |
56 57 58 59 |
{"PNP0C0F", 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, link_device_ids); |
1da177e4c Linux-2.6.12-rc2 |
60 |
static struct acpi_driver acpi_pci_link_driver = { |
c2b6705b7 ACPI: fix acpi_dr... |
61 |
.name = "pci_link", |
4be44fcd3 [ACPI] Lindent al... |
62 |
.class = ACPI_PCI_LINK_CLASS, |
1ba90e3a8 ACPI: autoload mo... |
63 |
.ids = link_device_ids, |
4be44fcd3 [ACPI] Lindent al... |
64 65 66 |
.ops = { .add = acpi_pci_link_add, .remove = acpi_pci_link_remove, |
1c9ca3a7d ACPI: pci_link: c... |
67 |
}, |
1da177e4c Linux-2.6.12-rc2 |
68 |
}; |
87bec66b9 [ACPI] suspend/re... |
69 70 71 72 |
/* * 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 |
73 |
struct acpi_pci_link_irq { |
4be44fcd3 [ACPI] Lindent al... |
74 |
u8 active; /* Current IRQ */ |
50eca3eb8 [ACPI] ACPICA 200... |
75 |
u8 triggering; /* All IRQs */ |
1c9ca3a7d ACPI: pci_link: c... |
76 |
u8 polarity; /* All IRQs */ |
4be44fcd3 [ACPI] Lindent al... |
77 78 79 80 81 |
u8 resource_type; u8 possible_count; u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE]; u8 initialized:1; u8 reserved:7; |
1da177e4c Linux-2.6.12-rc2 |
82 83 84 |
}; struct acpi_pci_link { |
5f0dccaa8 ACPI: pci_link: s... |
85 |
struct list_head list; |
1c9ca3a7d ACPI: pci_link: c... |
86 87 88 |
struct acpi_device *device; struct acpi_pci_link_irq irq; int refcnt; |
1da177e4c Linux-2.6.12-rc2 |
89 |
}; |
5f0dccaa8 ACPI: pci_link: s... |
90 |
static LIST_HEAD(acpi_link_list); |
e5685b9d3 ACPI: misc cleanups |
91 |
static DEFINE_MUTEX(acpi_link_lock); |
1da177e4c Linux-2.6.12-rc2 |
92 |
|
1da177e4c Linux-2.6.12-rc2 |
93 94 95 96 97 98 99 |
/* -------------------------------------------------------------------------- PCI Link Device Management -------------------------------------------------------------------------- */ /* * set context (link) possible list from resource list */ |
1c9ca3a7d ACPI: pci_link: c... |
100 101 |
static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource, void *context) |
1da177e4c Linux-2.6.12-rc2 |
102 |
{ |
50dd09697 ACPI: Remove unne... |
103 |
struct acpi_pci_link *link = context; |
c9d624432 ACPI: pci_link: r... |
104 |
u32 i; |
1da177e4c Linux-2.6.12-rc2 |
105 |
|
eca008c81 [ACPI] handle ACP... |
106 |
switch (resource->type) { |
50eca3eb8 [ACPI] ACPICA 200... |
107 |
case ACPI_RESOURCE_TYPE_START_DEPENDENT: |
4a5e3638b ACPI: stop compla... |
108 |
case ACPI_RESOURCE_TYPE_END_TAG: |
d550d98d3 ACPI: delete trac... |
109 |
return AE_OK; |
50eca3eb8 [ACPI] ACPICA 200... |
110 |
case ACPI_RESOURCE_TYPE_IRQ: |
4be44fcd3 [ACPI] Lindent al... |
111 112 |
{ struct acpi_resource_irq *p = &resource->data.irq; |
50eca3eb8 [ACPI] ACPICA 200... |
113 |
if (!p || !p->interrupt_count) { |
4a5e3638b ACPI: stop compla... |
114 115 116 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Blank _PRS IRQ resource ")); |
d550d98d3 ACPI: delete trac... |
117 |
return AE_OK; |
1da177e4c Linux-2.6.12-rc2 |
118 |
} |
4be44fcd3 [ACPI] Lindent al... |
119 |
for (i = 0; |
50eca3eb8 [ACPI] ACPICA 200... |
120 |
(i < p->interrupt_count |
4be44fcd3 [ACPI] Lindent al... |
121 122 |
&& i < ACPI_PCI_LINK_MAX_POSSIBLE); i++) { if (!p->interrupts[i]) { |
4a5e3638b ACPI: stop compla... |
123 124 125 126 |
printk(KERN_WARNING PREFIX "Invalid _PRS IRQ %d ", p->interrupts[i]); |
4be44fcd3 [ACPI] Lindent al... |
127 128 129 130 131 |
continue; } link->irq.possible[i] = p->interrupts[i]; link->irq.possible_count++; } |
50eca3eb8 [ACPI] ACPICA 200... |
132 133 134 |
link->irq.triggering = p->triggering; link->irq.polarity = p->polarity; link->irq.resource_type = ACPI_RESOURCE_TYPE_IRQ; |
4be44fcd3 [ACPI] Lindent al... |
135 |
break; |
1da177e4c Linux-2.6.12-rc2 |
136 |
} |
50eca3eb8 [ACPI] ACPICA 200... |
137 |
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: |
4be44fcd3 [ACPI] Lindent al... |
138 |
{ |
50eca3eb8 [ACPI] ACPICA 200... |
139 |
struct acpi_resource_extended_irq *p = |
4be44fcd3 [ACPI] Lindent al... |
140 |
&resource->data.extended_irq; |
50eca3eb8 [ACPI] ACPICA 200... |
141 |
if (!p || !p->interrupt_count) { |
cece92969 ACPI: un-export A... |
142 |
printk(KERN_WARNING PREFIX |
4a5e3638b ACPI: stop compla... |
143 144 |
"Blank _PRS EXT IRQ resource "); |
d550d98d3 ACPI: delete trac... |
145 |
return AE_OK; |
4be44fcd3 [ACPI] Lindent al... |
146 147 |
} for (i = 0; |
50eca3eb8 [ACPI] ACPICA 200... |
148 |
(i < p->interrupt_count |
4be44fcd3 [ACPI] Lindent al... |
149 150 |
&& i < ACPI_PCI_LINK_MAX_POSSIBLE); i++) { if (!p->interrupts[i]) { |
4a5e3638b ACPI: stop compla... |
151 152 153 154 |
printk(KERN_WARNING PREFIX "Invalid _PRS IRQ %d ", p->interrupts[i]); |
4be44fcd3 [ACPI] Lindent al... |
155 156 157 158 |
continue; } link->irq.possible[i] = p->interrupts[i]; link->irq.possible_count++; |
1da177e4c Linux-2.6.12-rc2 |
159 |
} |
50eca3eb8 [ACPI] ACPICA 200... |
160 161 162 |
link->irq.triggering = p->triggering; link->irq.polarity = p->polarity; link->irq.resource_type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ; |
4be44fcd3 [ACPI] Lindent al... |
163 |
break; |
1da177e4c Linux-2.6.12-rc2 |
164 |
} |
1da177e4c Linux-2.6.12-rc2 |
165 |
default: |
4a5e3638b ACPI: stop compla... |
166 167 168 |
printk(KERN_ERR PREFIX "_PRS resource type 0x%x isn't an IRQ ", resource->type); |
d550d98d3 ACPI: delete trac... |
169 |
return AE_OK; |
1da177e4c Linux-2.6.12-rc2 |
170 |
} |
d550d98d3 ACPI: delete trac... |
171 |
return AE_CTRL_TERMINATE; |
1da177e4c Linux-2.6.12-rc2 |
172 |
} |
4be44fcd3 [ACPI] Lindent al... |
173 |
static int acpi_pci_link_get_possible(struct acpi_pci_link *link) |
1da177e4c Linux-2.6.12-rc2 |
174 |
{ |
4be44fcd3 [ACPI] Lindent al... |
175 |
acpi_status status; |
1da177e4c Linux-2.6.12-rc2 |
176 |
|
67a713657 ACPI: pci_link: U... |
177 |
status = acpi_walk_resources(link->device->handle, METHOD_NAME__PRS, |
4be44fcd3 [ACPI] Lindent al... |
178 |
acpi_pci_link_check_possible, link); |
1da177e4c Linux-2.6.12-rc2 |
179 |
if (ACPI_FAILURE(status)) { |
a6fc67202 ACPI: Enable ACPI... |
180 |
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRS")); |
d550d98d3 ACPI: delete trac... |
181 |
return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
182 |
} |
4be44fcd3 [ACPI] Lindent al... |
183 184 185 186 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d possible IRQs ", link->irq.possible_count)); |
1da177e4c Linux-2.6.12-rc2 |
187 |
|
d550d98d3 ACPI: delete trac... |
188 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
189 |
} |
1c9ca3a7d ACPI: pci_link: c... |
190 191 |
static acpi_status acpi_pci_link_check_current(struct acpi_resource *resource, void *context) |
1da177e4c Linux-2.6.12-rc2 |
192 |
{ |
c9d624432 ACPI: pci_link: r... |
193 |
int *irq = context; |
1da177e4c Linux-2.6.12-rc2 |
194 |
|
eca008c81 [ACPI] handle ACP... |
195 |
switch (resource->type) { |
4a5e3638b ACPI: stop compla... |
196 197 198 |
case ACPI_RESOURCE_TYPE_START_DEPENDENT: case ACPI_RESOURCE_TYPE_END_TAG: return AE_OK; |
50eca3eb8 [ACPI] ACPICA 200... |
199 |
case ACPI_RESOURCE_TYPE_IRQ: |
4be44fcd3 [ACPI] Lindent al... |
200 201 |
{ struct acpi_resource_irq *p = &resource->data.irq; |
50eca3eb8 [ACPI] ACPICA 200... |
202 |
if (!p || !p->interrupt_count) { |
4be44fcd3 [ACPI] Lindent al... |
203 204 205 206 207 |
/* * IRQ descriptors may have no IRQ# bits set, * particularly those those w/ _STA disabled */ ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
4a5e3638b ACPI: stop compla... |
208 209 |
"Blank _CRS IRQ resource ")); |
d550d98d3 ACPI: delete trac... |
210 |
return AE_OK; |
4be44fcd3 [ACPI] Lindent al... |
211 212 213 |
} *irq = p->interrupts[0]; break; |
1da177e4c Linux-2.6.12-rc2 |
214 |
} |
50eca3eb8 [ACPI] ACPICA 200... |
215 |
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: |
4be44fcd3 [ACPI] Lindent al... |
216 |
{ |
50eca3eb8 [ACPI] ACPICA 200... |
217 |
struct acpi_resource_extended_irq *p = |
4be44fcd3 [ACPI] Lindent al... |
218 |
&resource->data.extended_irq; |
50eca3eb8 [ACPI] ACPICA 200... |
219 |
if (!p || !p->interrupt_count) { |
4be44fcd3 [ACPI] Lindent al... |
220 221 222 223 |
/* * extended IRQ descriptors must * return at least 1 IRQ */ |
cece92969 ACPI: un-export A... |
224 |
printk(KERN_WARNING PREFIX |
4a5e3638b ACPI: stop compla... |
225 226 |
"Blank _CRS EXT IRQ resource "); |
d550d98d3 ACPI: delete trac... |
227 |
return AE_OK; |
4be44fcd3 [ACPI] Lindent al... |
228 229 230 |
} *irq = p->interrupts[0]; break; |
1da177e4c Linux-2.6.12-rc2 |
231 |
} |
d4ec6c7cc [ACPI] remove "Re... |
232 |
break; |
1da177e4c Linux-2.6.12-rc2 |
233 |
default: |
4a5e3638b ACPI: stop compla... |
234 235 236 |
printk(KERN_ERR PREFIX "_CRS resource type 0x%x isn't an IRQ ", resource->type); |
d550d98d3 ACPI: delete trac... |
237 |
return AE_OK; |
1da177e4c Linux-2.6.12-rc2 |
238 |
} |
4a5e3638b ACPI: stop compla... |
239 |
|
d550d98d3 ACPI: delete trac... |
240 |
return AE_CTRL_TERMINATE; |
1da177e4c Linux-2.6.12-rc2 |
241 242 243 244 245 246 247 248 249 |
} /* * Run _CRS and set link->irq.active * * return value: * 0 - success * !0 - failure */ |
4be44fcd3 [ACPI] Lindent al... |
250 |
static int acpi_pci_link_get_current(struct acpi_pci_link *link) |
1da177e4c Linux-2.6.12-rc2 |
251 |
{ |
4be44fcd3 [ACPI] Lindent al... |
252 |
int result = 0; |
c9d624432 ACPI: pci_link: r... |
253 |
acpi_status status; |
4be44fcd3 [ACPI] Lindent al... |
254 |
int irq = 0; |
1da177e4c Linux-2.6.12-rc2 |
255 |
|
1da177e4c Linux-2.6.12-rc2 |
256 257 258 259 260 261 262 |
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... |
263 264 |
printk(KERN_ERR PREFIX "Unable to read status "); |
1da177e4c Linux-2.6.12-rc2 |
265 266 267 268 269 270 |
goto end; } if (!link->device->status.enabled) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link disabled ")); |
d550d98d3 ACPI: delete trac... |
271 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
272 273 274 275 276 277 |
} } /* * Query and parse _CRS to get the current IRQ assignment. */ |
67a713657 ACPI: pci_link: U... |
278 |
status = acpi_walk_resources(link->device->handle, METHOD_NAME__CRS, |
4be44fcd3 [ACPI] Lindent al... |
279 |
acpi_pci_link_check_current, &irq); |
1da177e4c Linux-2.6.12-rc2 |
280 |
if (ACPI_FAILURE(status)) { |
a6fc67202 ACPI: Enable ACPI... |
281 |
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _CRS")); |
1da177e4c Linux-2.6.12-rc2 |
282 283 284 285 286 |
result = -ENODEV; goto end; } if (acpi_strict && !irq) { |
6468463ab ACPI: un-export A... |
287 288 |
printk(KERN_ERR PREFIX "_CRS returned 0 "); |
1da177e4c Linux-2.6.12-rc2 |
289 290 291 292 293 294 295 |
result = -ENODEV; } link->irq.active = irq; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link at IRQ %d ", link->irq.active)); |
4be44fcd3 [ACPI] Lindent al... |
296 |
end: |
d550d98d3 ACPI: delete trac... |
297 |
return result; |
1da177e4c Linux-2.6.12-rc2 |
298 |
} |
4be44fcd3 [ACPI] Lindent al... |
299 |
static int acpi_pci_link_set(struct acpi_pci_link *link, int irq) |
1da177e4c Linux-2.6.12-rc2 |
300 |
{ |
c9d624432 ACPI: pci_link: r... |
301 302 |
int result; acpi_status status; |
1da177e4c Linux-2.6.12-rc2 |
303 |
struct { |
4be44fcd3 [ACPI] Lindent al... |
304 305 306 307 |
struct acpi_resource res; struct acpi_resource end; } *resource; struct acpi_buffer buffer = { 0, NULL }; |
1da177e4c Linux-2.6.12-rc2 |
308 |
|
6eca4b4ca ACPI: pci_link: r... |
309 |
if (!irq) |
d550d98d3 ACPI: delete trac... |
310 |
return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
311 |
|
36bcbec7c ACPI: replace kma... |
312 |
resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL); |
4be44fcd3 [ACPI] Lindent al... |
313 |
if (!resource) |
d550d98d3 ACPI: delete trac... |
314 |
return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
315 |
|
4be44fcd3 [ACPI] Lindent al... |
316 |
buffer.length = sizeof(*resource) + 1; |
1da177e4c Linux-2.6.12-rc2 |
317 |
buffer.pointer = resource; |
4be44fcd3 [ACPI] Lindent al... |
318 |
switch (link->irq.resource_type) { |
50eca3eb8 [ACPI] ACPICA 200... |
319 320 |
case ACPI_RESOURCE_TYPE_IRQ: resource->res.type = ACPI_RESOURCE_TYPE_IRQ; |
1da177e4c Linux-2.6.12-rc2 |
321 |
resource->res.length = sizeof(struct acpi_resource); |
50eca3eb8 [ACPI] ACPICA 200... |
322 323 324 325 326 |
resource->res.data.irq.triggering = link->irq.triggering; resource->res.data.irq.polarity = link->irq.polarity; if (link->irq.triggering == ACPI_EDGE_SENSITIVE) resource->res.data.irq.sharable = |
4be44fcd3 [ACPI] Lindent al... |
327 |
ACPI_EXCLUSIVE; |
1da177e4c Linux-2.6.12-rc2 |
328 |
else |
50eca3eb8 [ACPI] ACPICA 200... |
329 330 |
resource->res.data.irq.sharable = ACPI_SHARED; resource->res.data.irq.interrupt_count = 1; |
1da177e4c Linux-2.6.12-rc2 |
331 332 |
resource->res.data.irq.interrupts[0] = irq; break; |
4be44fcd3 [ACPI] Lindent al... |
333 |
|
50eca3eb8 [ACPI] ACPICA 200... |
334 335 |
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: resource->res.type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ; |
1da177e4c Linux-2.6.12-rc2 |
336 |
resource->res.length = sizeof(struct acpi_resource); |
4be44fcd3 [ACPI] Lindent al... |
337 338 |
resource->res.data.extended_irq.producer_consumer = ACPI_CONSUMER; |
50eca3eb8 [ACPI] ACPICA 200... |
339 340 341 342 343 344 |
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) resource->res.data.irq.sharable = |
4be44fcd3 [ACPI] Lindent al... |
345 |
ACPI_EXCLUSIVE; |
1da177e4c Linux-2.6.12-rc2 |
346 |
else |
50eca3eb8 [ACPI] ACPICA 200... |
347 348 |
resource->res.data.irq.sharable = ACPI_SHARED; resource->res.data.extended_irq.interrupt_count = 1; |
1da177e4c Linux-2.6.12-rc2 |
349 350 351 352 |
resource->res.data.extended_irq.interrupts[0] = irq; /* ignore resource_source, it's optional */ break; default: |
6468463ab ACPI: un-export A... |
353 354 |
printk(KERN_ERR PREFIX "Invalid Resource_type %d ", link->irq.resource_type); |
1da177e4c Linux-2.6.12-rc2 |
355 356 357 358 |
result = -EINVAL; goto end; } |
50eca3eb8 [ACPI] ACPICA 200... |
359 |
resource->end.type = ACPI_RESOURCE_TYPE_END_TAG; |
1da177e4c Linux-2.6.12-rc2 |
360 361 |
/* Attempt to set the resource */ |
67a713657 ACPI: pci_link: U... |
362 |
status = acpi_set_current_resources(link->device->handle, &buffer); |
1da177e4c Linux-2.6.12-rc2 |
363 364 365 |
/* check for total failure */ if (ACPI_FAILURE(status)) { |
a6fc67202 ACPI: Enable ACPI... |
366 |
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _SRS")); |
1da177e4c Linux-2.6.12-rc2 |
367 368 369 370 371 372 373 |
result = -ENODEV; goto end; } /* Query _STA, set device->status */ result = acpi_bus_get_status(link->device); if (result) { |
6468463ab ACPI: un-export A... |
374 375 |
printk(KERN_ERR PREFIX "Unable to read status "); |
1da177e4c Linux-2.6.12-rc2 |
376 377 378 |
goto end; } if (!link->device->status.enabled) { |
cece92969 ACPI: un-export A... |
379 380 381 |
printk(KERN_WARNING PREFIX "%s [%s] disabled and referenced, BIOS bug ", |
a6fc67202 ACPI: Enable ACPI... |
382 |
acpi_device_name(link->device), |
cece92969 ACPI: un-export A... |
383 |
acpi_device_bid(link->device)); |
1da177e4c Linux-2.6.12-rc2 |
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 |
} /* 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... |
401 402 403 |
printk(KERN_WARNING PREFIX "%s [%s] BIOS reported IRQ %d, using IRQ %d ", |
a6fc67202 ACPI: Enable ACPI... |
404 |
acpi_device_name(link->device), |
cece92969 ACPI: un-export A... |
405 |
acpi_device_bid(link->device), link->irq.active, irq); |
1da177e4c Linux-2.6.12-rc2 |
406 407 408 409 410 |
link->irq.active = irq; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Set IRQ %d ", link->irq.active)); |
4be44fcd3 [ACPI] Lindent al... |
411 412 |
end: |
1da177e4c Linux-2.6.12-rc2 |
413 |
kfree(resource); |
d550d98d3 ACPI: delete trac... |
414 |
return result; |
1da177e4c Linux-2.6.12-rc2 |
415 |
} |
1da177e4c Linux-2.6.12-rc2 |
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 |
/* -------------------------------------------------------------------------- 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. * * "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. * * 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. */ #define ACPI_MAX_IRQS 256 #define ACPI_MAX_ISA_IRQ 16 #define PIRQ_PENALTY_PCI_AVAILABLE (0) #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) static int acpi_irq_penalty[ACPI_MAX_IRQS] = { PIRQ_PENALTY_ISA_ALWAYS, /* IRQ0 timer */ PIRQ_PENALTY_ISA_ALWAYS, /* IRQ1 keyboard */ PIRQ_PENALTY_ISA_ALWAYS, /* IRQ2 cascade */ |
4be44fcd3 [ACPI] Lindent al... |
465 466 |
PIRQ_PENALTY_ISA_TYPICAL, /* IRQ3 serial */ PIRQ_PENALTY_ISA_TYPICAL, /* IRQ4 serial */ |
1da177e4c Linux-2.6.12-rc2 |
467 468 469 470 471 472 473 |
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 */ PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ9 PCI, often acpi */ PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ10 PCI */ PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ11 PCI */ |
1c9ca3a7d ACPI: pci_link: c... |
474 475 476 477 |
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 */ |
4be44fcd3 [ACPI] Lindent al... |
478 |
/* >IRQ15 */ |
1da177e4c Linux-2.6.12-rc2 |
479 |
}; |
4be44fcd3 [ACPI] Lindent al... |
480 |
int __init acpi_irq_penalty_init(void) |
1da177e4c Linux-2.6.12-rc2 |
481 |
{ |
c9d624432 ACPI: pci_link: r... |
482 483 |
struct acpi_pci_link *link; int i; |
1da177e4c Linux-2.6.12-rc2 |
484 |
|
1da177e4c Linux-2.6.12-rc2 |
485 486 487 |
/* * Update penalties to facilitate IRQ balancing. */ |
5f0dccaa8 ACPI: pci_link: s... |
488 |
list_for_each_entry(link, &acpi_link_list, list) { |
1da177e4c Linux-2.6.12-rc2 |
489 490 491 492 493 494 |
/* * reflect the possible and active irqs in the penalty table -- * useful for breaking ties. */ if (link->irq.possible_count) { |
4be44fcd3 [ACPI] Lindent al... |
495 496 497 |
int penalty = PIRQ_PENALTY_PCI_POSSIBLE / link->irq.possible_count; |
1da177e4c Linux-2.6.12-rc2 |
498 499 500 |
for (i = 0; i < link->irq.possible_count; i++) { if (link->irq.possible[i] < ACPI_MAX_ISA_IRQ) |
4be44fcd3 [ACPI] Lindent al... |
501 502 503 |
acpi_irq_penalty[link->irq. possible[i]] += penalty; |
1da177e4c Linux-2.6.12-rc2 |
504 505 506 |
} } else if (link->irq.active) { |
4be44fcd3 [ACPI] Lindent al... |
507 508 |
acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_POSSIBLE; |
1da177e4c Linux-2.6.12-rc2 |
509 510 511 |
} } /* Add a penalty for the SCI */ |
cee324b14 ACPICA: use new A... |
512 |
acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] += PIRQ_PENALTY_PCI_USING; |
d550d98d3 ACPI: delete trac... |
513 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
514 |
} |
32836259f ACPI: pci_link: r... |
515 |
static int acpi_irq_balance = -1; /* 0: static, 1: balance */ |
1da177e4c Linux-2.6.12-rc2 |
516 |
|
4be44fcd3 [ACPI] Lindent al... |
517 |
static int acpi_pci_link_allocate(struct acpi_pci_link *link) |
1da177e4c Linux-2.6.12-rc2 |
518 |
{ |
4be44fcd3 [ACPI] Lindent al... |
519 520 |
int irq; int i; |
1da177e4c Linux-2.6.12-rc2 |
521 |
|
87bec66b9 [ACPI] suspend/re... |
522 523 524 525 |
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... |
526 |
return 0; |
87bec66b9 [ACPI] suspend/re... |
527 |
} |
1da177e4c Linux-2.6.12-rc2 |
528 529 530 531 532 533 534 535 536 537 538 539 540 |
/* * 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... |
541 542 543 |
printk(KERN_WARNING PREFIX "_CRS %d not found" " in _PRS ", link->irq.active); |
1da177e4c Linux-2.6.12-rc2 |
544 545 546 547 548 549 |
link->irq.active = 0; } /* * if active found, use it; else pick entry from end of possible list. */ |
1c9ca3a7d ACPI: pci_link: c... |
550 |
if (link->irq.active) |
1da177e4c Linux-2.6.12-rc2 |
551 |
irq = link->irq.active; |
1c9ca3a7d ACPI: pci_link: c... |
552 |
else |
1da177e4c Linux-2.6.12-rc2 |
553 |
irq = link->irq.possible[link->irq.possible_count - 1]; |
1da177e4c Linux-2.6.12-rc2 |
554 555 556 557 558 559 560 |
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--) { |
4be44fcd3 [ACPI] Lindent al... |
561 562 |
if (acpi_irq_penalty[irq] > acpi_irq_penalty[link->irq.possible[i]]) |
1da177e4c Linux-2.6.12-rc2 |
563 564 565 566 567 568 |
irq = link->irq.possible[i]; } } /* Attempt to enable the link device at this IRQ. */ if (acpi_pci_link_set(link, irq)) { |
6468463ab ACPI: un-export A... |
569 570 571 |
printk(KERN_ERR PREFIX "Unable to set IRQ for %s [%s]. " "Try pci=noacpi or acpi=off ", |
a6fc67202 ACPI: Enable ACPI... |
572 |
acpi_device_name(link->device), |
6468463ab ACPI: un-export A... |
573 |
acpi_device_bid(link->device)); |
d550d98d3 ACPI: delete trac... |
574 |
return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
575 576 |
} else { acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING; |
4d9391557 ACPI: add missing... |
577 578 |
printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d ", |
4be44fcd3 [ACPI] Lindent al... |
579 580 |
acpi_device_name(link->device), acpi_device_bid(link->device), link->irq.active); |
1da177e4c Linux-2.6.12-rc2 |
581 582 583 |
} link->irq.initialized = 1; |
d550d98d3 ACPI: delete trac... |
584 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
585 586 587 |
} /* |
87bec66b9 [ACPI] suspend/re... |
588 |
* acpi_pci_link_allocate_irq |
1da177e4c Linux-2.6.12-rc2 |
589 590 591 |
* success: return IRQ >= 0 * failure: return -1 */ |
1c9ca3a7d ACPI: pci_link: c... |
592 593 |
int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering, int *polarity, char **name) |
1da177e4c Linux-2.6.12-rc2 |
594 |
{ |
c9d624432 ACPI: pci_link: r... |
595 596 597 |
int result; struct acpi_device *device; struct acpi_pci_link *link; |
1da177e4c Linux-2.6.12-rc2 |
598 |
|
1da177e4c Linux-2.6.12-rc2 |
599 600 |
result = acpi_bus_get_device(handle, &device); if (result) { |
6468463ab ACPI: un-export A... |
601 602 |
printk(KERN_ERR PREFIX "Invalid link device "); |
d550d98d3 ACPI: delete trac... |
603 |
return -1; |
1da177e4c Linux-2.6.12-rc2 |
604 |
} |
50dd09697 ACPI: Remove unne... |
605 |
link = acpi_driver_data(device); |
1da177e4c Linux-2.6.12-rc2 |
606 |
if (!link) { |
6468463ab ACPI: un-export A... |
607 608 |
printk(KERN_ERR PREFIX "Invalid link context "); |
d550d98d3 ACPI: delete trac... |
609 |
return -1; |
1da177e4c Linux-2.6.12-rc2 |
610 611 612 613 |
} /* TBD: Support multiple index (IRQ) entries per Link Device */ if (index) { |
6468463ab ACPI: un-export A... |
614 615 |
printk(KERN_ERR PREFIX "Invalid index %d ", index); |
d550d98d3 ACPI: delete trac... |
616 |
return -1; |
1da177e4c Linux-2.6.12-rc2 |
617 |
} |
36e430951 sem2mutex: acpi, ... |
618 |
mutex_lock(&acpi_link_lock); |
87bec66b9 [ACPI] suspend/re... |
619 |
if (acpi_pci_link_allocate(link)) { |
36e430951 sem2mutex: acpi, ... |
620 |
mutex_unlock(&acpi_link_lock); |
d550d98d3 ACPI: delete trac... |
621 |
return -1; |
87bec66b9 [ACPI] suspend/re... |
622 |
} |
4be44fcd3 [ACPI] Lindent al... |
623 |
|
1da177e4c Linux-2.6.12-rc2 |
624 |
if (!link->irq.active) { |
36e430951 sem2mutex: acpi, ... |
625 |
mutex_unlock(&acpi_link_lock); |
6468463ab ACPI: un-export A... |
626 627 |
printk(KERN_ERR PREFIX "Link active IRQ is 0! "); |
d550d98d3 ACPI: delete trac... |
628 |
return -1; |
1da177e4c Linux-2.6.12-rc2 |
629 |
} |
4be44fcd3 [ACPI] Lindent al... |
630 |
link->refcnt++; |
36e430951 sem2mutex: acpi, ... |
631 |
mutex_unlock(&acpi_link_lock); |
1da177e4c Linux-2.6.12-rc2 |
632 |
|
50eca3eb8 [ACPI] ACPICA 200... |
633 634 635 636 |
if (triggering) *triggering = link->irq.triggering; if (polarity) *polarity = link->irq.polarity; |
4be44fcd3 [ACPI] Lindent al... |
637 638 |
if (name) *name = acpi_device_bid(link->device); |
87bec66b9 [ACPI] suspend/re... |
639 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
4be44fcd3 [ACPI] Lindent al... |
640 641 642 |
"Link %s is referenced ", acpi_device_bid(link->device))); |
d550d98d3 ACPI: delete trac... |
643 |
return (link->irq.active); |
1da177e4c Linux-2.6.12-rc2 |
644 |
} |
87bec66b9 [ACPI] suspend/re... |
645 646 647 648 |
/* * We don't change link's irq information here. After it is reenabled, we * continue use the info */ |
4be44fcd3 [ACPI] Lindent al... |
649 |
int acpi_pci_link_free_irq(acpi_handle handle) |
87bec66b9 [ACPI] suspend/re... |
650 |
{ |
c9d624432 ACPI: pci_link: r... |
651 652 |
struct acpi_device *device; struct acpi_pci_link *link; |
4be44fcd3 [ACPI] Lindent al... |
653 |
acpi_status result; |
87bec66b9 [ACPI] suspend/re... |
654 |
|
87bec66b9 [ACPI] suspend/re... |
655 656 |
result = acpi_bus_get_device(handle, &device); if (result) { |
6468463ab ACPI: un-export A... |
657 658 |
printk(KERN_ERR PREFIX "Invalid link device "); |
d550d98d3 ACPI: delete trac... |
659 |
return -1; |
87bec66b9 [ACPI] suspend/re... |
660 |
} |
1da177e4c Linux-2.6.12-rc2 |
661 |
|
50dd09697 ACPI: Remove unne... |
662 |
link = acpi_driver_data(device); |
87bec66b9 [ACPI] suspend/re... |
663 |
if (!link) { |
6468463ab ACPI: un-export A... |
664 665 |
printk(KERN_ERR PREFIX "Invalid link context "); |
d550d98d3 ACPI: delete trac... |
666 |
return -1; |
87bec66b9 [ACPI] suspend/re... |
667 |
} |
36e430951 sem2mutex: acpi, ... |
668 |
mutex_lock(&acpi_link_lock); |
87bec66b9 [ACPI] suspend/re... |
669 |
if (!link->irq.initialized) { |
36e430951 sem2mutex: acpi, ... |
670 |
mutex_unlock(&acpi_link_lock); |
6468463ab ACPI: un-export A... |
671 672 |
printk(KERN_ERR PREFIX "Link isn't initialized "); |
d550d98d3 ACPI: delete trac... |
673 |
return -1; |
87bec66b9 [ACPI] suspend/re... |
674 |
} |
ecc21ebe6 [ACPI] PCI interr... |
675 676 677 678 679 680 681 682 683 684 |
#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... |
685 |
link->refcnt--; |
ecc21ebe6 [ACPI] PCI interr... |
686 |
#endif |
87bec66b9 [ACPI] suspend/re... |
687 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
4be44fcd3 [ACPI] Lindent al... |
688 689 690 |
"Link %s is dereferenced ", acpi_device_bid(link->device))); |
87bec66b9 [ACPI] suspend/re... |
691 |
|
1c9ca3a7d ACPI: pci_link: c... |
692 |
if (link->refcnt == 0) |
383d7a11c ACPI: Fix possibl... |
693 |
acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL); |
1c9ca3a7d ACPI: pci_link: c... |
694 |
|
36e430951 sem2mutex: acpi, ... |
695 |
mutex_unlock(&acpi_link_lock); |
d550d98d3 ACPI: delete trac... |
696 |
return (link->irq.active); |
87bec66b9 [ACPI] suspend/re... |
697 |
} |
4be44fcd3 [ACPI] Lindent al... |
698 |
|
1da177e4c Linux-2.6.12-rc2 |
699 700 701 |
/* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ |
4be44fcd3 [ACPI] Lindent al... |
702 |
static int acpi_pci_link_add(struct acpi_device *device) |
1da177e4c Linux-2.6.12-rc2 |
703 |
{ |
c9d624432 ACPI: pci_link: r... |
704 705 706 |
int result; struct acpi_pci_link *link; int i; |
4be44fcd3 [ACPI] Lindent al... |
707 |
int found = 0; |
1da177e4c Linux-2.6.12-rc2 |
708 |
|
36bcbec7c ACPI: replace kma... |
709 |
link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
710 |
if (!link) |
d550d98d3 ACPI: delete trac... |
711 |
return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
712 713 |
link->device = device; |
1da177e4c Linux-2.6.12-rc2 |
714 715 |
strcpy(acpi_device_name(device), ACPI_PCI_LINK_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS); |
db89b4f0d ACPI: catch calls... |
716 |
device->driver_data = link; |
1da177e4c Linux-2.6.12-rc2 |
717 |
|
36e430951 sem2mutex: acpi, ... |
718 |
mutex_lock(&acpi_link_lock); |
1da177e4c Linux-2.6.12-rc2 |
719 720 721 722 723 724 |
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... |
725 |
printk(KERN_INFO PREFIX "%s [%s] (IRQs", acpi_device_name(device), |
4be44fcd3 [ACPI] Lindent al... |
726 |
acpi_device_bid(device)); |
1da177e4c Linux-2.6.12-rc2 |
727 728 729 730 |
for (i = 0; i < link->irq.possible_count; i++) { if (link->irq.active == link->irq.possible[i]) { printk(" *%d", link->irq.possible[i]); found = 1; |
4be44fcd3 [ACPI] Lindent al... |
731 |
} else |
1da177e4c Linux-2.6.12-rc2 |
732 733 734 735 736 737 738 |
printk(" %d", link->irq.possible[i]); } printk(")"); if (!found) printk(" *%d", link->irq.active); |
4be44fcd3 [ACPI] Lindent al... |
739 |
if (!link->device->status.enabled) |
1da177e4c Linux-2.6.12-rc2 |
740 741 742 743 |
printk(", disabled."); printk(" "); |
5f0dccaa8 ACPI: pci_link: s... |
744 |
list_add_tail(&link->list, &acpi_link_list); |
1da177e4c Linux-2.6.12-rc2 |
745 |
|
4be44fcd3 [ACPI] Lindent al... |
746 |
end: |
1da177e4c Linux-2.6.12-rc2 |
747 |
/* disable all links -- to be activated on use */ |
383d7a11c ACPI: Fix possibl... |
748 |
acpi_evaluate_object(device->handle, "_DIS", NULL, NULL); |
36e430951 sem2mutex: acpi, ... |
749 |
mutex_unlock(&acpi_link_lock); |
1da177e4c Linux-2.6.12-rc2 |
750 751 752 |
if (result) kfree(link); |
d550d98d3 ACPI: delete trac... |
753 |
return result; |
1da177e4c Linux-2.6.12-rc2 |
754 |
} |
4be44fcd3 [ACPI] Lindent al... |
755 |
static int acpi_pci_link_resume(struct acpi_pci_link *link) |
697a2d63a Revert ACPI inter... |
756 |
{ |
697a2d63a Revert ACPI inter... |
757 |
if (link->refcnt && link->irq.active && link->irq.initialized) |
d550d98d3 ACPI: delete trac... |
758 |
return (acpi_pci_link_set(link, link->irq.active)); |
1c9ca3a7d ACPI: pci_link: c... |
759 760 |
return 0; |
697a2d63a Revert ACPI inter... |
761 |
} |
c3146df2b ACPI: Use syscore... |
762 |
static void irqrouter_resume(void) |
1da177e4c Linux-2.6.12-rc2 |
763 |
{ |
c9d624432 ACPI: pci_link: r... |
764 |
struct acpi_pci_link *link; |
1da177e4c Linux-2.6.12-rc2 |
765 |
|
5f0dccaa8 ACPI: pci_link: s... |
766 |
list_for_each_entry(link, &acpi_link_list, list) { |
697a2d63a Revert ACPI inter... |
767 |
acpi_pci_link_resume(link); |
1da177e4c Linux-2.6.12-rc2 |
768 |
} |
1da177e4c Linux-2.6.12-rc2 |
769 |
} |
4be44fcd3 [ACPI] Lindent al... |
770 |
static int acpi_pci_link_remove(struct acpi_device *device, int type) |
1da177e4c Linux-2.6.12-rc2 |
771 |
{ |
c9d624432 ACPI: pci_link: r... |
772 |
struct acpi_pci_link *link; |
1da177e4c Linux-2.6.12-rc2 |
773 |
|
50dd09697 ACPI: Remove unne... |
774 |
link = acpi_driver_data(device); |
1da177e4c Linux-2.6.12-rc2 |
775 |
|
36e430951 sem2mutex: acpi, ... |
776 |
mutex_lock(&acpi_link_lock); |
5f0dccaa8 ACPI: pci_link: s... |
777 |
list_del(&link->list); |
36e430951 sem2mutex: acpi, ... |
778 |
mutex_unlock(&acpi_link_lock); |
1da177e4c Linux-2.6.12-rc2 |
779 780 |
kfree(link); |
d550d98d3 ACPI: delete trac... |
781 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
782 783 784 785 786 787 788 789 790 791 792 793 |
} /* * modify acpi_irq_penalty[] from cmdline */ static int __init acpi_irq_penalty_update(char *str, int used) { int i; for (i = 0; i < 16; i++) { int retval; int irq; |
4be44fcd3 [ACPI] Lindent al... |
794 |
retval = get_option(&str, &irq); |
1da177e4c Linux-2.6.12-rc2 |
795 796 797 798 799 800 |
if (!retval) break; /* no number found */ if (irq < 0) continue; |
4be44fcd3 [ACPI] Lindent al... |
801 |
|
fa46d3526 ACPI: bounds chec... |
802 |
if (irq >= ARRAY_SIZE(acpi_irq_penalty)) |
1da177e4c Linux-2.6.12-rc2 |
803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 |
continue; if (used) acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED; else acpi_irq_penalty[irq] = PIRQ_PENALTY_PCI_AVAILABLE; 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... |
823 |
void acpi_penalize_isa_irq(int irq, int active) |
1da177e4c Linux-2.6.12-rc2 |
824 |
{ |
fa46d3526 ACPI: bounds chec... |
825 826 827 828 829 830 |
if (irq >= 0 && irq < ARRAY_SIZE(acpi_irq_penalty)) { if (active) acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED; else acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING; } |
1da177e4c Linux-2.6.12-rc2 |
831 832 833 834 835 836 837 838 839 840 841 |
} /* * 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... |
842 |
|
1da177e4c Linux-2.6.12-rc2 |
843 844 845 846 847 848 849 850 851 852 853 |
__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... |
854 |
|
1da177e4c Linux-2.6.12-rc2 |
855 856 857 858 859 860 861 |
__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... |
862 |
|
1da177e4c Linux-2.6.12-rc2 |
863 |
__setup("acpi_irq_nobalance", acpi_irq_nobalance_set); |
8a383ef0b ACPI: ec.c, pci_l... |
864 |
static int __init acpi_irq_balance_set(char *str) |
1da177e4c Linux-2.6.12-rc2 |
865 866 867 868 |
{ acpi_irq_balance = 1; return 1; } |
1da177e4c Linux-2.6.12-rc2 |
869 |
|
4be44fcd3 [ACPI] Lindent al... |
870 |
__setup("acpi_irq_balance", acpi_irq_balance_set); |
1da177e4c Linux-2.6.12-rc2 |
871 |
|
c3146df2b ACPI: Use syscore... |
872 |
static struct syscore_ops irqrouter_syscore_ops = { |
4be44fcd3 [ACPI] Lindent al... |
873 |
.resume = irqrouter_resume, |
1da177e4c Linux-2.6.12-rc2 |
874 |
}; |
c3146df2b ACPI: Use syscore... |
875 |
static int __init irqrouter_init_ops(void) |
1da177e4c Linux-2.6.12-rc2 |
876 |
{ |
c3146df2b ACPI: Use syscore... |
877 878 |
if (!acpi_disabled && !acpi_noirq) register_syscore_ops(&irqrouter_syscore_ops); |
1da177e4c Linux-2.6.12-rc2 |
879 |
|
c3146df2b ACPI: Use syscore... |
880 |
return 0; |
4be44fcd3 [ACPI] Lindent al... |
881 |
} |
1da177e4c Linux-2.6.12-rc2 |
882 |
|
c3146df2b ACPI: Use syscore... |
883 |
device_initcall(irqrouter_init_ops); |
1da177e4c Linux-2.6.12-rc2 |
884 |
|
4be44fcd3 [ACPI] Lindent al... |
885 |
static int __init acpi_pci_link_init(void) |
1da177e4c Linux-2.6.12-rc2 |
886 |
{ |
1da177e4c Linux-2.6.12-rc2 |
887 |
if (acpi_noirq) |
d550d98d3 ACPI: delete trac... |
888 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
889 |
|
32836259f ACPI: pci_link: r... |
890 891 892 893 894 895 896 |
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; } |
1da177e4c Linux-2.6.12-rc2 |
897 |
if (acpi_bus_register_driver(&acpi_pci_link_driver) < 0) |
d550d98d3 ACPI: delete trac... |
898 |
return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
899 |
|
d550d98d3 ACPI: delete trac... |
900 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
901 902 903 |
} subsys_initcall(acpi_pci_link_init); |