[ACPI] PNPACPI vs sound IRQ
[linux-2.6/verdex.git] / drivers / acpi / pci_link.c
blob6ad0e77df9b320ca2661fc483778f10ced28d4c9
1 /*
2 * pci_link.c - ACPI PCI Interrupt Link Device Driver ($Revision: 34 $)
4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6 * Copyright (C) 2002 Dominik Brodowski <devel@brodo.de>
8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
24 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26 * TBD:
27 * 1. Support more than one IRQ resource entry per link device (index).
28 * 2. Implement start/stop mechanism and use ACPI Bus Driver facilities
29 * for IRQ management (e.g. start()->_SRS).
32 #include <linux/sysdev.h>
33 #include <linux/kernel.h>
34 #include <linux/module.h>
35 #include <linux/init.h>
36 #include <linux/types.h>
37 #include <linux/proc_fs.h>
38 #include <linux/spinlock.h>
39 #include <linux/pm.h>
40 #include <linux/pci.h>
42 #include <acpi/acpi_bus.h>
43 #include <acpi/acpi_drivers.h>
46 #define _COMPONENT ACPI_PCI_COMPONENT
47 ACPI_MODULE_NAME ("pci_link")
49 #define ACPI_PCI_LINK_CLASS "pci_irq_routing"
50 #define ACPI_PCI_LINK_HID "PNP0C0F"
51 #define ACPI_PCI_LINK_DRIVER_NAME "ACPI PCI Interrupt Link Driver"
52 #define ACPI_PCI_LINK_DEVICE_NAME "PCI Interrupt Link"
53 #define ACPI_PCI_LINK_FILE_INFO "info"
54 #define ACPI_PCI_LINK_FILE_STATUS "state"
56 #define ACPI_PCI_LINK_MAX_POSSIBLE 16
58 static int acpi_pci_link_add (struct acpi_device *device);
59 static int acpi_pci_link_remove (struct acpi_device *device, int type);
61 static struct acpi_driver acpi_pci_link_driver = {
62 .name = ACPI_PCI_LINK_DRIVER_NAME,
63 .class = ACPI_PCI_LINK_CLASS,
64 .ids = ACPI_PCI_LINK_HID,
65 .ops = {
66 .add = acpi_pci_link_add,
67 .remove = acpi_pci_link_remove,
71 struct acpi_pci_link_irq {
72 u8 active; /* Current IRQ */
73 u8 edge_level; /* All IRQs */
74 u8 active_high_low; /* All IRQs */
75 u8 resource_type;
76 u8 possible_count;
77 u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
78 u8 initialized:1;
79 u8 suspend_resume:1;
80 u8 reserved:6;
83 struct acpi_pci_link {
84 struct list_head node;
85 struct acpi_device *device;
86 acpi_handle handle;
87 struct acpi_pci_link_irq irq;
90 static struct {
91 int count;
92 struct list_head entries;
93 } acpi_link;
96 /* --------------------------------------------------------------------------
97 PCI Link Device Management
98 -------------------------------------------------------------------------- */
101 * set context (link) possible list from resource list
103 static acpi_status
104 acpi_pci_link_check_possible (
105 struct acpi_resource *resource,
106 void *context)
108 struct acpi_pci_link *link = (struct acpi_pci_link *) context;
109 u32 i = 0;
111 ACPI_FUNCTION_TRACE("acpi_pci_link_check_possible");
113 switch (resource->id) {
114 case ACPI_RSTYPE_START_DPF:
115 return_ACPI_STATUS(AE_OK);
116 case ACPI_RSTYPE_IRQ:
118 struct acpi_resource_irq *p = &resource->data.irq;
119 if (!p || !p->number_of_interrupts) {
120 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Blank IRQ resource\n"));
121 return_ACPI_STATUS(AE_OK);
123 for (i = 0; (i<p->number_of_interrupts && i<ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
124 if (!p->interrupts[i]) {
125 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ %d\n", p->interrupts[i]));
126 continue;
128 link->irq.possible[i] = p->interrupts[i];
129 link->irq.possible_count++;
131 link->irq.edge_level = p->edge_level;
132 link->irq.active_high_low = p->active_high_low;
133 link->irq.resource_type = ACPI_RSTYPE_IRQ;
134 break;
136 case ACPI_RSTYPE_EXT_IRQ:
138 struct acpi_resource_ext_irq *p = &resource->data.extended_irq;
139 if (!p || !p->number_of_interrupts) {
140 ACPI_DEBUG_PRINT((ACPI_DB_WARN,
141 "Blank EXT IRQ resource\n"));
142 return_ACPI_STATUS(AE_OK);
144 for (i = 0; (i<p->number_of_interrupts && i<ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
145 if (!p->interrupts[i]) {
146 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ %d\n", p->interrupts[i]));
147 continue;
149 link->irq.possible[i] = p->interrupts[i];
150 link->irq.possible_count++;
152 link->irq.edge_level = p->edge_level;
153 link->irq.active_high_low = p->active_high_low;
154 link->irq.resource_type = ACPI_RSTYPE_EXT_IRQ;
155 break;
157 default:
158 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
159 "Resource is not an IRQ entry\n"));
160 return_ACPI_STATUS(AE_OK);
163 return_ACPI_STATUS(AE_CTRL_TERMINATE);
167 static int
168 acpi_pci_link_get_possible (
169 struct acpi_pci_link *link)
171 acpi_status status;
173 ACPI_FUNCTION_TRACE("acpi_pci_link_get_possible");
175 if (!link)
176 return_VALUE(-EINVAL);
178 status = acpi_walk_resources(link->handle, METHOD_NAME__PRS,
179 acpi_pci_link_check_possible, link);
180 if (ACPI_FAILURE(status)) {
181 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRS\n"));
182 return_VALUE(-ENODEV);
185 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
186 "Found %d possible IRQs\n", link->irq.possible_count));
188 return_VALUE(0);
192 static acpi_status
193 acpi_pci_link_check_current (
194 struct acpi_resource *resource,
195 void *context)
197 int *irq = (int *) context;
199 ACPI_FUNCTION_TRACE("acpi_pci_link_check_current");
201 switch (resource->id) {
202 case ACPI_RSTYPE_IRQ:
204 struct acpi_resource_irq *p = &resource->data.irq;
205 if (!p || !p->number_of_interrupts) {
207 * IRQ descriptors may have no IRQ# bits set,
208 * particularly those those w/ _STA disabled
210 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
211 "Blank IRQ resource\n"));
212 return_ACPI_STATUS(AE_OK);
214 *irq = p->interrupts[0];
215 break;
217 case ACPI_RSTYPE_EXT_IRQ:
219 struct acpi_resource_ext_irq *p = &resource->data.extended_irq;
220 if (!p || !p->number_of_interrupts) {
222 * extended IRQ descriptors must
223 * return at least 1 IRQ
225 ACPI_DEBUG_PRINT((ACPI_DB_WARN,
226 "Blank EXT IRQ resource\n"));
227 return_ACPI_STATUS(AE_OK);
229 *irq = p->interrupts[0];
230 break;
232 default:
233 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
234 "Resource isn't an IRQ\n"));
235 return_ACPI_STATUS(AE_OK);
237 return_ACPI_STATUS(AE_CTRL_TERMINATE);
241 * Run _CRS and set link->irq.active
243 * return value:
244 * 0 - success
245 * !0 - failure
247 static int
248 acpi_pci_link_get_current (
249 struct acpi_pci_link *link)
251 int result = 0;
252 acpi_status status = AE_OK;
253 int irq = 0;
255 ACPI_FUNCTION_TRACE("acpi_pci_link_get_current");
257 if (!link || !link->handle)
258 return_VALUE(-EINVAL);
260 link->irq.active = 0;
262 /* in practice, status disabled is meaningless, ignore it */
263 if (acpi_strict) {
264 /* Query _STA, set link->device->status */
265 result = acpi_bus_get_status(link->device);
266 if (result) {
267 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to read status\n"));
268 goto end;
271 if (!link->device->status.enabled) {
272 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link disabled\n"));
273 return_VALUE(0);
278 * Query and parse _CRS to get the current IRQ assignment.
281 status = acpi_walk_resources(link->handle, METHOD_NAME__CRS,
282 acpi_pci_link_check_current, &irq);
283 if (ACPI_FAILURE(status)) {
284 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _CRS\n"));
285 result = -ENODEV;
286 goto end;
289 if (acpi_strict && !irq) {
290 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "_CRS returned 0\n"));
291 result = -ENODEV;
294 link->irq.active = irq;
296 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link at IRQ %d \n", link->irq.active));
298 end:
299 return_VALUE(result);
302 static int
303 acpi_pci_link_set (
304 struct acpi_pci_link *link,
305 int irq)
307 int result = 0;
308 acpi_status status = AE_OK;
309 struct {
310 struct acpi_resource res;
311 struct acpi_resource end;
312 } *resource;
313 struct acpi_buffer buffer = {0, NULL};
315 ACPI_FUNCTION_TRACE("acpi_pci_link_set");
317 if (!link || !irq)
318 return_VALUE(-EINVAL);
320 resource = kmalloc( sizeof(*resource)+1, GFP_KERNEL);
321 if(!resource)
322 return_VALUE(-ENOMEM);
324 memset(resource, 0, sizeof(*resource)+1);
325 buffer.length = sizeof(*resource) +1;
326 buffer.pointer = resource;
328 switch(link->irq.resource_type) {
329 case ACPI_RSTYPE_IRQ:
330 resource->res.id = ACPI_RSTYPE_IRQ;
331 resource->res.length = sizeof(struct acpi_resource);
332 resource->res.data.irq.edge_level = link->irq.edge_level;
333 resource->res.data.irq.active_high_low = link->irq.active_high_low;
334 if (link->irq.edge_level == ACPI_EDGE_SENSITIVE)
335 resource->res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
336 else
337 resource->res.data.irq.shared_exclusive = ACPI_SHARED;
338 resource->res.data.irq.number_of_interrupts = 1;
339 resource->res.data.irq.interrupts[0] = irq;
340 break;
342 case ACPI_RSTYPE_EXT_IRQ:
343 resource->res.id = ACPI_RSTYPE_EXT_IRQ;
344 resource->res.length = sizeof(struct acpi_resource);
345 resource->res.data.extended_irq.producer_consumer = ACPI_CONSUMER;
346 resource->res.data.extended_irq.edge_level = link->irq.edge_level;
347 resource->res.data.extended_irq.active_high_low = link->irq.active_high_low;
348 if (link->irq.edge_level == ACPI_EDGE_SENSITIVE)
349 resource->res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
350 else
351 resource->res.data.irq.shared_exclusive = ACPI_SHARED;
352 resource->res.data.extended_irq.number_of_interrupts = 1;
353 resource->res.data.extended_irq.interrupts[0] = irq;
354 /* ignore resource_source, it's optional */
355 break;
356 default:
357 printk("ACPI BUG: resource_type %d\n", link->irq.resource_type);
358 result = -EINVAL;
359 goto end;
362 resource->end.id = ACPI_RSTYPE_END_TAG;
364 /* Attempt to set the resource */
365 status = acpi_set_current_resources(link->handle, &buffer);
367 /* check for total failure */
368 if (ACPI_FAILURE(status)) {
369 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _SRS\n"));
370 result = -ENODEV;
371 goto end;
374 /* Query _STA, set device->status */
375 result = acpi_bus_get_status(link->device);
376 if (result) {
377 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to read status\n"));
378 goto end;
380 if (!link->device->status.enabled) {
381 printk(KERN_WARNING PREFIX
382 "%s [%s] disabled and referenced, BIOS bug.\n",
383 acpi_device_name(link->device),
384 acpi_device_bid(link->device));
387 /* Query _CRS, set link->irq.active */
388 result = acpi_pci_link_get_current(link);
389 if (result) {
390 goto end;
394 * Is current setting not what we set?
395 * set link->irq.active
397 if (link->irq.active != irq) {
399 * policy: when _CRS doesn't return what we just _SRS
400 * assume _SRS worked and override _CRS value.
402 printk(KERN_WARNING PREFIX
403 "%s [%s] BIOS reported IRQ %d, using IRQ %d\n",
404 acpi_device_name(link->device),
405 acpi_device_bid(link->device),
406 link->irq.active, irq);
407 link->irq.active = irq;
410 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Set IRQ %d\n", link->irq.active));
412 end:
413 kfree(resource);
414 return_VALUE(result);
418 /* --------------------------------------------------------------------------
419 PCI Link IRQ Management
420 -------------------------------------------------------------------------- */
423 * "acpi_irq_balance" (default in APIC mode) enables ACPI to use PIC Interrupt
424 * Link Devices to move the PIRQs around to minimize sharing.
426 * "acpi_irq_nobalance" (default in PIC mode) tells ACPI not to move any PIC IRQs
427 * that the BIOS has already set to active. This is necessary because
428 * ACPI has no automatic means of knowing what ISA IRQs are used. Note that
429 * if the BIOS doesn't set a Link Device active, ACPI needs to program it
430 * even if acpi_irq_nobalance is set.
432 * A tables of penalties avoids directing PCI interrupts to well known
433 * ISA IRQs. Boot params are available to over-ride the default table:
435 * List interrupts that are free for PCI use.
436 * acpi_irq_pci=n[,m]
438 * List interrupts that should not be used for PCI:
439 * acpi_irq_isa=n[,m]
441 * Note that PCI IRQ routers have a list of possible IRQs,
442 * which may not include the IRQs this table says are available.
444 * Since this heuristic can't tell the difference between a link
445 * that no device will attach to, vs. a link which may be shared
446 * by multiple active devices -- it is not optimal.
448 * If interrupt performance is that important, get an IO-APIC system
449 * with a pin dedicated to each device. Or for that matter, an MSI
450 * enabled system.
453 #define ACPI_MAX_IRQS 256
454 #define ACPI_MAX_ISA_IRQ 16
456 #define PIRQ_PENALTY_PCI_AVAILABLE (0)
457 #define PIRQ_PENALTY_PCI_POSSIBLE (16*16)
458 #define PIRQ_PENALTY_PCI_USING (16*16*16)
459 #define PIRQ_PENALTY_ISA_TYPICAL (16*16*16*16)
460 #define PIRQ_PENALTY_ISA_USED (16*16*16*16*16)
461 #define PIRQ_PENALTY_ISA_ALWAYS (16*16*16*16*16*16)
463 static int acpi_irq_penalty[ACPI_MAX_IRQS] = {
464 PIRQ_PENALTY_ISA_ALWAYS, /* IRQ0 timer */
465 PIRQ_PENALTY_ISA_ALWAYS, /* IRQ1 keyboard */
466 PIRQ_PENALTY_ISA_ALWAYS, /* IRQ2 cascade */
467 PIRQ_PENALTY_ISA_TYPICAL, /* IRQ3 serial */
468 PIRQ_PENALTY_ISA_TYPICAL, /* IRQ4 serial */
469 PIRQ_PENALTY_ISA_TYPICAL, /* IRQ5 sometimes SoundBlaster */
470 PIRQ_PENALTY_ISA_TYPICAL, /* IRQ6 */
471 PIRQ_PENALTY_ISA_TYPICAL, /* IRQ7 parallel, spurious */
472 PIRQ_PENALTY_ISA_TYPICAL, /* IRQ8 rtc, sometimes */
473 PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ9 PCI, often acpi */
474 PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ10 PCI */
475 PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ11 PCI */
476 PIRQ_PENALTY_ISA_USED, /* IRQ12 mouse */
477 PIRQ_PENALTY_ISA_USED, /* IRQ13 fpe, sometimes */
478 PIRQ_PENALTY_ISA_USED, /* IRQ14 ide0 */
479 PIRQ_PENALTY_ISA_USED, /* IRQ15 ide1 */
480 /* >IRQ15 */
483 int __init
484 acpi_irq_penalty_init(void)
486 struct list_head *node = NULL;
487 struct acpi_pci_link *link = NULL;
488 int i = 0;
490 ACPI_FUNCTION_TRACE("acpi_irq_penalty_init");
493 * Update penalties to facilitate IRQ balancing.
495 list_for_each(node, &acpi_link.entries) {
497 link = list_entry(node, struct acpi_pci_link, node);
498 if (!link) {
499 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
500 continue;
504 * reflect the possible and active irqs in the penalty table --
505 * useful for breaking ties.
507 if (link->irq.possible_count) {
508 int penalty = PIRQ_PENALTY_PCI_POSSIBLE / link->irq.possible_count;
510 for (i = 0; i < link->irq.possible_count; i++) {
511 if (link->irq.possible[i] < ACPI_MAX_ISA_IRQ)
512 acpi_irq_penalty[link->irq.possible[i]] += penalty;
515 } else if (link->irq.active) {
516 acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_POSSIBLE;
519 /* Add a penalty for the SCI */
520 acpi_irq_penalty[acpi_fadt.sci_int] += PIRQ_PENALTY_PCI_USING;
522 return_VALUE(0);
525 static int acpi_irq_balance; /* 0: static, 1: balance */
527 static int acpi_pci_link_allocate(
528 struct acpi_pci_link *link)
530 int irq;
531 int i;
533 ACPI_FUNCTION_TRACE("acpi_pci_link_allocate");
535 if (link->irq.suspend_resume) {
536 acpi_pci_link_set(link, link->irq.active);
537 link->irq.suspend_resume = 0;
539 if (link->irq.initialized)
540 return_VALUE(0);
543 * search for active IRQ in list of possible IRQs.
545 for (i = 0; i < link->irq.possible_count; ++i) {
546 if (link->irq.active == link->irq.possible[i])
547 break;
550 * forget active IRQ that is not in possible list
552 if (i == link->irq.possible_count) {
553 if (acpi_strict)
554 printk(KERN_WARNING PREFIX "_CRS %d not found"
555 " in _PRS\n", link->irq.active);
556 link->irq.active = 0;
560 * if active found, use it; else pick entry from end of possible list.
562 if (link->irq.active) {
563 irq = link->irq.active;
564 } else {
565 irq = link->irq.possible[link->irq.possible_count - 1];
568 if (acpi_irq_balance || !link->irq.active) {
570 * Select the best IRQ. This is done in reverse to promote
571 * the use of IRQs 9, 10, 11, and >15.
573 for (i = (link->irq.possible_count - 1); i >= 0; i--) {
574 if (acpi_irq_penalty[irq] > acpi_irq_penalty[link->irq.possible[i]])
575 irq = link->irq.possible[i];
579 /* Attempt to enable the link device at this IRQ. */
580 if (acpi_pci_link_set(link, irq)) {
581 printk(PREFIX "Unable to set IRQ for %s [%s] (likely buggy ACPI BIOS).\n"
582 "Try pci=noacpi or acpi=off\n",
583 acpi_device_name(link->device),
584 acpi_device_bid(link->device));
585 return_VALUE(-ENODEV);
586 } else {
587 acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING;
588 printk(PREFIX "%s [%s] enabled at IRQ %d\n",
589 acpi_device_name(link->device),
590 acpi_device_bid(link->device), link->irq.active);
593 link->irq.initialized = 1;
595 return_VALUE(0);
599 * acpi_pci_link_get_irq
600 * success: return IRQ >= 0
601 * failure: return -1
605 acpi_pci_link_get_irq (
606 acpi_handle handle,
607 int index,
608 int *edge_level,
609 int *active_high_low,
610 char **name)
612 int result = 0;
613 struct acpi_device *device = NULL;
614 struct acpi_pci_link *link = NULL;
616 ACPI_FUNCTION_TRACE("acpi_pci_link_get_irq");
618 result = acpi_bus_get_device(handle, &device);
619 if (result) {
620 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link device\n"));
621 return_VALUE(-1);
624 link = (struct acpi_pci_link *) acpi_driver_data(device);
625 if (!link) {
626 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
627 return_VALUE(-1);
630 /* TBD: Support multiple index (IRQ) entries per Link Device */
631 if (index) {
632 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid index %d\n", index));
633 return_VALUE(-1);
636 if (acpi_pci_link_allocate(link))
637 return_VALUE(-1);
639 if (!link->irq.active) {
640 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link active IRQ is 0!\n"));
641 return_VALUE(-1);
644 if (edge_level) *edge_level = link->irq.edge_level;
645 if (active_high_low) *active_high_low = link->irq.active_high_low;
646 if (name) *name = acpi_device_bid(link->device);
647 return_VALUE(link->irq.active);
651 /* --------------------------------------------------------------------------
652 Driver Interface
653 -------------------------------------------------------------------------- */
655 static int
656 acpi_pci_link_add (
657 struct acpi_device *device)
659 int result = 0;
660 struct acpi_pci_link *link = NULL;
661 int i = 0;
662 int found = 0;
664 ACPI_FUNCTION_TRACE("acpi_pci_link_add");
666 if (!device)
667 return_VALUE(-EINVAL);
669 link = kmalloc(sizeof(struct acpi_pci_link), GFP_KERNEL);
670 if (!link)
671 return_VALUE(-ENOMEM);
672 memset(link, 0, sizeof(struct acpi_pci_link));
674 link->device = device;
675 link->handle = device->handle;
676 strcpy(acpi_device_name(device), ACPI_PCI_LINK_DEVICE_NAME);
677 strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS);
678 acpi_driver_data(device) = link;
680 result = acpi_pci_link_get_possible(link);
681 if (result)
682 goto end;
684 /* query and set link->irq.active */
685 acpi_pci_link_get_current(link);
687 printk(PREFIX "%s [%s] (IRQs", acpi_device_name(device),
688 acpi_device_bid(device));
689 for (i = 0; i < link->irq.possible_count; i++) {
690 if (link->irq.active == link->irq.possible[i]) {
691 printk(" *%d", link->irq.possible[i]);
692 found = 1;
694 else
695 printk(" %d", link->irq.possible[i]);
698 printk(")");
700 if (!found)
701 printk(" *%d", link->irq.active);
703 if(!link->device->status.enabled)
704 printk(", disabled.");
706 printk("\n");
708 /* TBD: Acquire/release lock */
709 list_add_tail(&link->node, &acpi_link.entries);
710 acpi_link.count++;
712 end:
713 /* disable all links -- to be activated on use */
714 acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL);
716 if (result)
717 kfree(link);
719 return_VALUE(result);
722 static int
723 irqrouter_suspend(
724 struct sys_device *dev,
725 u32 state)
727 struct list_head *node = NULL;
728 struct acpi_pci_link *link = NULL;
730 ACPI_FUNCTION_TRACE("irqrouter_suspend");
732 list_for_each(node, &acpi_link.entries) {
733 link = list_entry(node, struct acpi_pci_link, node);
734 if (!link) {
735 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
736 continue;
738 if (link->irq.active && link->irq.initialized)
739 link->irq.suspend_resume = 1;
741 return_VALUE(0);
745 static int
746 acpi_pci_link_remove (
747 struct acpi_device *device,
748 int type)
750 struct acpi_pci_link *link = NULL;
752 ACPI_FUNCTION_TRACE("acpi_pci_link_remove");
754 if (!device || !acpi_driver_data(device))
755 return_VALUE(-EINVAL);
757 link = (struct acpi_pci_link *) acpi_driver_data(device);
759 /* TBD: Acquire/release lock */
760 list_del(&link->node);
762 kfree(link);
764 return_VALUE(0);
768 * modify acpi_irq_penalty[] from cmdline
770 static int __init acpi_irq_penalty_update(char *str, int used)
772 int i;
774 for (i = 0; i < 16; i++) {
775 int retval;
776 int irq;
778 retval = get_option(&str,&irq);
780 if (!retval)
781 break; /* no number found */
783 if (irq < 0)
784 continue;
786 if (irq >= ACPI_MAX_IRQS)
787 continue;
789 if (used)
790 acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED;
791 else
792 acpi_irq_penalty[irq] = PIRQ_PENALTY_PCI_AVAILABLE;
794 if (retval != 2) /* no next number */
795 break;
797 return 1;
801 * We'd like PNP to call this routine for the
802 * single ISA_USED value for each legacy device.
803 * But instead it calls us with each POSSIBLE setting.
804 * There is no ISA_POSSIBLE weight, so we simply use
805 * the (small) PCI_USING penalty.
807 void acpi_penalize_isa_irq(int irq, int active)
809 if (active)
810 acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED;
811 else
812 acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING;
816 * Over-ride default table to reserve additional IRQs for use by ISA
817 * e.g. acpi_irq_isa=5
818 * Useful for telling ACPI how not to interfere with your ISA sound card.
820 static int __init acpi_irq_isa(char *str)
822 return acpi_irq_penalty_update(str, 1);
824 __setup("acpi_irq_isa=", acpi_irq_isa);
827 * Over-ride default table to free additional IRQs for use by PCI
828 * e.g. acpi_irq_pci=7,15
829 * Used for acpi_irq_balance to free up IRQs to reduce PCI IRQ sharing.
831 static int __init acpi_irq_pci(char *str)
833 return acpi_irq_penalty_update(str, 0);
835 __setup("acpi_irq_pci=", acpi_irq_pci);
837 static int __init acpi_irq_nobalance_set(char *str)
839 acpi_irq_balance = 0;
840 return 1;
842 __setup("acpi_irq_nobalance", acpi_irq_nobalance_set);
844 int __init acpi_irq_balance_set(char *str)
846 acpi_irq_balance = 1;
847 return 1;
849 __setup("acpi_irq_balance", acpi_irq_balance_set);
852 static struct sysdev_class irqrouter_sysdev_class = {
853 set_kset_name("irqrouter"),
854 .suspend = irqrouter_suspend,
858 static struct sys_device device_irqrouter = {
859 .id = 0,
860 .cls = &irqrouter_sysdev_class,
864 static int __init irqrouter_init_sysfs(void)
866 int error;
868 ACPI_FUNCTION_TRACE("irqrouter_init_sysfs");
870 if (acpi_disabled || acpi_noirq)
871 return_VALUE(0);
873 error = sysdev_class_register(&irqrouter_sysdev_class);
874 if (!error)
875 error = sysdev_register(&device_irqrouter);
877 return_VALUE(error);
880 device_initcall(irqrouter_init_sysfs);
883 static int __init acpi_pci_link_init (void)
885 ACPI_FUNCTION_TRACE("acpi_pci_link_init");
887 if (acpi_noirq)
888 return_VALUE(0);
890 acpi_link.count = 0;
891 INIT_LIST_HEAD(&acpi_link.entries);
893 if (acpi_bus_register_driver(&acpi_pci_link_driver) < 0)
894 return_VALUE(-ENODEV);
896 return_VALUE(0);
899 subsys_initcall(acpi_pci_link_init);