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#include <linux/syscore_ops.h>
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/types.h>
33#include <linux/spinlock.h>
34#include <linux/pm.h>
35#include <linux/pci.h>
36#include <linux/mutex.h>
37#include <linux/slab.h>
38#include <linux/acpi.h>
39#include <linux/irq.h>
40
41#include "internal.h"
42
43#define _COMPONENT ACPI_PCI_COMPONENT
44ACPI_MODULE_NAME("pci_link");
45#define ACPI_PCI_LINK_CLASS "pci_irq_routing"
46#define ACPI_PCI_LINK_DEVICE_NAME "PCI Interrupt Link"
47#define ACPI_PCI_LINK_FILE_INFO "info"
48#define ACPI_PCI_LINK_FILE_STATUS "state"
49#define ACPI_PCI_LINK_MAX_POSSIBLE 16
50
51static int acpi_pci_link_add(struct acpi_device *device,
52 const struct acpi_device_id *not_used);
53static void acpi_pci_link_remove(struct acpi_device *device);
54
55static const struct acpi_device_id link_device_ids[] = {
56 {"PNP0C0F", 0},
57 {"", 0},
58};
59
60static struct acpi_scan_handler pci_link_handler = {
61 .ids = link_device_ids,
62 .attach = acpi_pci_link_add,
63 .detach = acpi_pci_link_remove,
64};
65
66
67
68
69
70struct acpi_pci_link_irq {
71 u32 active;
72 u8 triggering;
73 u8 polarity;
74 u8 resource_type;
75 u8 possible_count;
76 u32 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
77 u8 initialized:1;
78 u8 reserved:7;
79};
80
81struct acpi_pci_link {
82 struct list_head list;
83 struct acpi_device *device;
84 struct acpi_pci_link_irq irq;
85 int refcnt;
86};
87
88static LIST_HEAD(acpi_link_list);
89static DEFINE_MUTEX(acpi_link_lock);
90static int sci_irq = -1, sci_penalty;
91
92
93
94
95
96
97
98
99static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource,
100 void *context)
101{
102 struct acpi_pci_link *link = context;
103 u32 i;
104
105 switch (resource->type) {
106 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
107 case ACPI_RESOURCE_TYPE_END_TAG:
108 return AE_OK;
109 case ACPI_RESOURCE_TYPE_IRQ:
110 {
111 struct acpi_resource_irq *p = &resource->data.irq;
112 if (!p || !p->interrupt_count) {
113 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
114 "Blank _PRS IRQ resource\n"));
115 return AE_OK;
116 }
117 for (i = 0;
118 (i < p->interrupt_count
119 && i < ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
120 if (!p->interrupts[i]) {
121 printk(KERN_WARNING PREFIX
122 "Invalid _PRS IRQ %d\n",
123 p->interrupts[i]);
124 continue;
125 }
126 link->irq.possible[i] = p->interrupts[i];
127 link->irq.possible_count++;
128 }
129 link->irq.triggering = p->triggering;
130 link->irq.polarity = p->polarity;
131 link->irq.resource_type = ACPI_RESOURCE_TYPE_IRQ;
132 break;
133 }
134 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
135 {
136 struct acpi_resource_extended_irq *p =
137 &resource->data.extended_irq;
138 if (!p || !p->interrupt_count) {
139 printk(KERN_WARNING PREFIX
140 "Blank _PRS EXT IRQ resource\n");
141 return AE_OK;
142 }
143 for (i = 0;
144 (i < p->interrupt_count
145 && i < ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
146 if (!p->interrupts[i]) {
147 printk(KERN_WARNING PREFIX
148 "Invalid _PRS IRQ %d\n",
149 p->interrupts[i]);
150 continue;
151 }
152 link->irq.possible[i] = p->interrupts[i];
153 link->irq.possible_count++;
154 }
155 link->irq.triggering = p->triggering;
156 link->irq.polarity = p->polarity;
157 link->irq.resource_type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ;
158 break;
159 }
160 default:
161 printk(KERN_ERR PREFIX "_PRS resource type 0x%x isn't an IRQ\n",
162 resource->type);
163 return AE_OK;
164 }
165
166 return AE_CTRL_TERMINATE;
167}
168
169static int acpi_pci_link_get_possible(struct acpi_pci_link *link)
170{
171 acpi_status status;
172
173 status = acpi_walk_resources(link->device->handle, METHOD_NAME__PRS,
174 acpi_pci_link_check_possible, link);
175 if (ACPI_FAILURE(status)) {
176 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRS"));
177 return -ENODEV;
178 }
179
180 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
181 "Found %d possible IRQs\n",
182 link->irq.possible_count));
183
184 return 0;
185}
186
187static acpi_status acpi_pci_link_check_current(struct acpi_resource *resource,
188 void *context)
189{
190 int *irq = context;
191
192 switch (resource->type) {
193 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
194 case ACPI_RESOURCE_TYPE_END_TAG:
195 return AE_OK;
196 case ACPI_RESOURCE_TYPE_IRQ:
197 {
198 struct acpi_resource_irq *p = &resource->data.irq;
199 if (!p || !p->interrupt_count) {
200
201
202
203
204 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
205 "Blank _CRS IRQ resource\n"));
206 return AE_OK;
207 }
208 *irq = p->interrupts[0];
209 break;
210 }
211 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
212 {
213 struct acpi_resource_extended_irq *p =
214 &resource->data.extended_irq;
215 if (!p || !p->interrupt_count) {
216
217
218
219
220 printk(KERN_WARNING PREFIX
221 "Blank _CRS EXT IRQ resource\n");
222 return AE_OK;
223 }
224 *irq = p->interrupts[0];
225 break;
226 }
227 break;
228 default:
229 printk(KERN_ERR PREFIX "_CRS resource type 0x%x isn't an IRQ\n",
230 resource->type);
231 return AE_OK;
232 }
233
234 return AE_CTRL_TERMINATE;
235}
236
237
238
239
240
241
242
243
244static int acpi_pci_link_get_current(struct acpi_pci_link *link)
245{
246 int result = 0;
247 acpi_status status;
248 int irq = 0;
249
250 link->irq.active = 0;
251
252
253 if (acpi_strict) {
254
255 result = acpi_bus_get_status(link->device);
256 if (result) {
257 printk(KERN_ERR PREFIX "Unable to read status\n");
258 goto end;
259 }
260
261 if (!link->device->status.enabled) {
262 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link disabled\n"));
263 return 0;
264 }
265 }
266
267
268
269
270
271 status = acpi_walk_resources(link->device->handle, METHOD_NAME__CRS,
272 acpi_pci_link_check_current, &irq);
273 if (ACPI_FAILURE(status)) {
274 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _CRS"));
275 result = -ENODEV;
276 goto end;
277 }
278
279 if (acpi_strict && !irq) {
280 printk(KERN_ERR PREFIX "_CRS returned 0\n");
281 result = -ENODEV;
282 }
283
284 link->irq.active = irq;
285
286 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link at IRQ %d \n", link->irq.active));
287
288 end:
289 return result;
290}
291
292static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
293{
294 int result;
295 acpi_status status;
296 struct {
297 struct acpi_resource res;
298 struct acpi_resource end;
299 } *resource;
300 struct acpi_buffer buffer = { 0, NULL };
301
302 if (!irq)
303 return -EINVAL;
304
305 resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
306 if (!resource)
307 return -ENOMEM;
308
309 buffer.length = sizeof(*resource) + 1;
310 buffer.pointer = resource;
311
312 switch (link->irq.resource_type) {
313 case ACPI_RESOURCE_TYPE_IRQ:
314 resource->res.type = ACPI_RESOURCE_TYPE_IRQ;
315 resource->res.length = sizeof(struct acpi_resource);
316 resource->res.data.irq.triggering = link->irq.triggering;
317 resource->res.data.irq.polarity =
318 link->irq.polarity;
319 if (link->irq.triggering == ACPI_EDGE_SENSITIVE)
320 resource->res.data.irq.sharable =
321 ACPI_EXCLUSIVE;
322 else
323 resource->res.data.irq.sharable = ACPI_SHARED;
324 resource->res.data.irq.interrupt_count = 1;
325 resource->res.data.irq.interrupts[0] = irq;
326 break;
327
328 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
329 resource->res.type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ;
330 resource->res.length = sizeof(struct acpi_resource);
331 resource->res.data.extended_irq.producer_consumer =
332 ACPI_CONSUMER;
333 resource->res.data.extended_irq.triggering =
334 link->irq.triggering;
335 resource->res.data.extended_irq.polarity =
336 link->irq.polarity;
337 if (link->irq.triggering == ACPI_EDGE_SENSITIVE)
338 resource->res.data.irq.sharable =
339 ACPI_EXCLUSIVE;
340 else
341 resource->res.data.irq.sharable = ACPI_SHARED;
342 resource->res.data.extended_irq.interrupt_count = 1;
343 resource->res.data.extended_irq.interrupts[0] = irq;
344
345 break;
346 default:
347 printk(KERN_ERR PREFIX "Invalid Resource_type %d\n", link->irq.resource_type);
348 result = -EINVAL;
349 goto end;
350
351 }
352 resource->end.type = ACPI_RESOURCE_TYPE_END_TAG;
353 resource->end.length = sizeof(struct acpi_resource);
354
355
356 status = acpi_set_current_resources(link->device->handle, &buffer);
357
358
359 if (ACPI_FAILURE(status)) {
360 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _SRS"));
361 result = -ENODEV;
362 goto end;
363 }
364
365
366 result = acpi_bus_get_status(link->device);
367 if (result) {
368 printk(KERN_ERR PREFIX "Unable to read status\n");
369 goto end;
370 }
371 if (!link->device->status.enabled) {
372 printk(KERN_WARNING PREFIX
373 "%s [%s] disabled and referenced, BIOS bug\n",
374 acpi_device_name(link->device),
375 acpi_device_bid(link->device));
376 }
377
378
379 result = acpi_pci_link_get_current(link);
380 if (result) {
381 goto end;
382 }
383
384
385
386
387
388 if (link->irq.active != irq) {
389
390
391
392
393 printk(KERN_WARNING PREFIX
394 "%s [%s] BIOS reported IRQ %d, using IRQ %d\n",
395 acpi_device_name(link->device),
396 acpi_device_bid(link->device), link->irq.active, irq);
397 link->irq.active = irq;
398 }
399
400 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Set IRQ %d\n", link->irq.active));
401
402 end:
403 kfree(resource);
404 return result;
405}
406
407
408
409
410
411
412
413
414
415
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#define ACPI_MAX_ISA_IRQS 16
443
444#define PIRQ_PENALTY_PCI_POSSIBLE (16*16)
445#define PIRQ_PENALTY_PCI_USING (16*16*16)
446#define PIRQ_PENALTY_ISA_TYPICAL (16*16*16*16)
447#define PIRQ_PENALTY_ISA_USED (16*16*16*16*16)
448#define PIRQ_PENALTY_ISA_ALWAYS (16*16*16*16*16*16)
449
450static int acpi_isa_irq_penalty[ACPI_MAX_ISA_IRQS] = {
451 PIRQ_PENALTY_ISA_ALWAYS,
452 PIRQ_PENALTY_ISA_ALWAYS,
453 PIRQ_PENALTY_ISA_ALWAYS,
454 PIRQ_PENALTY_ISA_TYPICAL,
455 PIRQ_PENALTY_ISA_TYPICAL,
456 PIRQ_PENALTY_ISA_TYPICAL,
457 PIRQ_PENALTY_ISA_TYPICAL,
458 PIRQ_PENALTY_ISA_TYPICAL,
459 PIRQ_PENALTY_ISA_TYPICAL,
460 0,
461 0,
462 0,
463 PIRQ_PENALTY_ISA_USED,
464 PIRQ_PENALTY_ISA_USED,
465 PIRQ_PENALTY_ISA_USED,
466 PIRQ_PENALTY_ISA_USED,
467
468};
469
470static int acpi_irq_pci_sharing_penalty(int irq)
471{
472 struct acpi_pci_link *link;
473 int penalty = 0;
474 int i;
475
476 list_for_each_entry(link, &acpi_link_list, list) {
477
478
479
480
481 if (link->irq.active && link->irq.active == irq)
482 penalty += PIRQ_PENALTY_PCI_USING;
483
484
485
486
487 for (i = 0; i < link->irq.possible_count; i++)
488 if (link->irq.possible[i] == irq)
489 penalty += PIRQ_PENALTY_PCI_POSSIBLE /
490 link->irq.possible_count;
491 }
492
493 return penalty;
494}
495
496static int acpi_irq_get_penalty(int irq)
497{
498 int penalty = 0;
499
500 if (irq == sci_irq)
501 penalty += sci_penalty;
502
503 if (irq < ACPI_MAX_ISA_IRQS)
504 return penalty + acpi_isa_irq_penalty[irq];
505
506 return penalty + acpi_irq_pci_sharing_penalty(irq);
507}
508
509int __init acpi_irq_penalty_init(void)
510{
511 struct acpi_pci_link *link;
512 int i;
513
514
515
516
517 list_for_each_entry(link, &acpi_link_list, list) {
518
519
520
521
522
523 if (link->irq.possible_count) {
524 int penalty =
525 PIRQ_PENALTY_PCI_POSSIBLE /
526 link->irq.possible_count;
527
528 for (i = 0; i < link->irq.possible_count; i++) {
529 if (link->irq.possible[i] < ACPI_MAX_ISA_IRQS)
530 acpi_isa_irq_penalty[link->irq.
531 possible[i]] +=
532 penalty;
533 }
534
535 } else if (link->irq.active &&
536 (link->irq.active < ACPI_MAX_ISA_IRQS)) {
537 acpi_isa_irq_penalty[link->irq.active] +=
538 PIRQ_PENALTY_PCI_POSSIBLE;
539 }
540 }
541
542 return 0;
543}
544
545static int acpi_irq_balance = -1;
546
547static int acpi_pci_link_allocate(struct acpi_pci_link *link)
548{
549 int irq;
550 int i;
551
552 if (link->irq.initialized) {
553 if (link->refcnt == 0)
554
555 acpi_pci_link_set(link, link->irq.active);
556 return 0;
557 }
558
559
560
561
562 for (i = 0; i < link->irq.possible_count; ++i) {
563 if (link->irq.active == link->irq.possible[i])
564 break;
565 }
566
567
568
569 if (i == link->irq.possible_count) {
570 if (acpi_strict)
571 printk(KERN_WARNING PREFIX "_CRS %d not found"
572 " in _PRS\n", link->irq.active);
573 link->irq.active = 0;
574 }
575
576
577
578
579 if (link->irq.active)
580 irq = link->irq.active;
581 else
582 irq = link->irq.possible[link->irq.possible_count - 1];
583
584 if (acpi_irq_balance || !link->irq.active) {
585
586
587
588
589 for (i = (link->irq.possible_count - 1); i >= 0; i--) {
590 if (acpi_irq_get_penalty(irq) >
591 acpi_irq_get_penalty(link->irq.possible[i]))
592 irq = link->irq.possible[i];
593 }
594 }
595 if (acpi_irq_get_penalty(irq) >= PIRQ_PENALTY_ISA_ALWAYS) {
596 printk(KERN_ERR PREFIX "No IRQ available for %s [%s]. "
597 "Try pci=noacpi or acpi=off\n",
598 acpi_device_name(link->device),
599 acpi_device_bid(link->device));
600 return -ENODEV;
601 }
602
603
604 if (acpi_pci_link_set(link, irq)) {
605 printk(KERN_ERR PREFIX "Unable to set IRQ for %s [%s]. "
606 "Try pci=noacpi or acpi=off\n",
607 acpi_device_name(link->device),
608 acpi_device_bid(link->device));
609 return -ENODEV;
610 } else {
611 if (link->irq.active < ACPI_MAX_ISA_IRQS)
612 acpi_isa_irq_penalty[link->irq.active] +=
613 PIRQ_PENALTY_PCI_USING;
614
615 printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n",
616 acpi_device_name(link->device),
617 acpi_device_bid(link->device), link->irq.active);
618 }
619
620 link->irq.initialized = 1;
621 return 0;
622}
623
624
625
626
627
628
629int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering,
630 int *polarity, char **name)
631{
632 int result;
633 struct acpi_device *device;
634 struct acpi_pci_link *link;
635
636 result = acpi_bus_get_device(handle, &device);
637 if (result) {
638 printk(KERN_ERR PREFIX "Invalid link device\n");
639 return -1;
640 }
641
642 link = acpi_driver_data(device);
643 if (!link) {
644 printk(KERN_ERR PREFIX "Invalid link context\n");
645 return -1;
646 }
647
648
649 if (index) {
650 printk(KERN_ERR PREFIX "Invalid index %d\n", index);
651 return -1;
652 }
653
654 mutex_lock(&acpi_link_lock);
655 if (acpi_pci_link_allocate(link)) {
656 mutex_unlock(&acpi_link_lock);
657 return -1;
658 }
659
660 if (!link->irq.active) {
661 mutex_unlock(&acpi_link_lock);
662 printk(KERN_ERR PREFIX "Link active IRQ is 0!\n");
663 return -1;
664 }
665 link->refcnt++;
666 mutex_unlock(&acpi_link_lock);
667
668 if (triggering)
669 *triggering = link->irq.triggering;
670 if (polarity)
671 *polarity = link->irq.polarity;
672 if (name)
673 *name = acpi_device_bid(link->device);
674 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
675 "Link %s is referenced\n",
676 acpi_device_bid(link->device)));
677 return (link->irq.active);
678}
679
680
681
682
683
684int acpi_pci_link_free_irq(acpi_handle handle)
685{
686 struct acpi_device *device;
687 struct acpi_pci_link *link;
688 acpi_status result;
689
690 result = acpi_bus_get_device(handle, &device);
691 if (result) {
692 printk(KERN_ERR PREFIX "Invalid link device\n");
693 return -1;
694 }
695
696 link = acpi_driver_data(device);
697 if (!link) {
698 printk(KERN_ERR PREFIX "Invalid link context\n");
699 return -1;
700 }
701
702 mutex_lock(&acpi_link_lock);
703 if (!link->irq.initialized) {
704 mutex_unlock(&acpi_link_lock);
705 printk(KERN_ERR PREFIX "Link isn't initialized\n");
706 return -1;
707 }
708#ifdef FUTURE_USE
709
710
711
712
713
714
715
716
717
718 link->refcnt--;
719#endif
720 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
721 "Link %s is dereferenced\n",
722 acpi_device_bid(link->device)));
723
724 if (link->refcnt == 0)
725 acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL);
726
727 mutex_unlock(&acpi_link_lock);
728 return (link->irq.active);
729}
730
731
732
733
734
735static int acpi_pci_link_add(struct acpi_device *device,
736 const struct acpi_device_id *not_used)
737{
738 int result;
739 struct acpi_pci_link *link;
740 int i;
741 int found = 0;
742
743 link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL);
744 if (!link)
745 return -ENOMEM;
746
747 link->device = device;
748 strcpy(acpi_device_name(device), ACPI_PCI_LINK_DEVICE_NAME);
749 strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS);
750 device->driver_data = link;
751
752 mutex_lock(&acpi_link_lock);
753 result = acpi_pci_link_get_possible(link);
754 if (result)
755 goto end;
756
757
758 acpi_pci_link_get_current(link);
759
760 printk(KERN_INFO PREFIX "%s [%s] (IRQs", acpi_device_name(device),
761 acpi_device_bid(device));
762 for (i = 0; i < link->irq.possible_count; i++) {
763 if (link->irq.active == link->irq.possible[i]) {
764 printk(KERN_CONT " *%d", link->irq.possible[i]);
765 found = 1;
766 } else
767 printk(KERN_CONT " %d", link->irq.possible[i]);
768 }
769
770 printk(KERN_CONT ")");
771
772 if (!found)
773 printk(KERN_CONT " *%d", link->irq.active);
774
775 if (!link->device->status.enabled)
776 printk(KERN_CONT ", disabled.");
777
778 printk(KERN_CONT "\n");
779
780 list_add_tail(&link->list, &acpi_link_list);
781
782 end:
783
784 acpi_evaluate_object(device->handle, "_DIS", NULL, NULL);
785 mutex_unlock(&acpi_link_lock);
786
787 if (result)
788 kfree(link);
789
790 return result < 0 ? result : 1;
791}
792
793static int acpi_pci_link_resume(struct acpi_pci_link *link)
794{
795 if (link->refcnt && link->irq.active && link->irq.initialized)
796 return (acpi_pci_link_set(link, link->irq.active));
797
798 return 0;
799}
800
801static void irqrouter_resume(void)
802{
803 struct acpi_pci_link *link;
804
805 list_for_each_entry(link, &acpi_link_list, list) {
806 acpi_pci_link_resume(link);
807 }
808}
809
810static void acpi_pci_link_remove(struct acpi_device *device)
811{
812 struct acpi_pci_link *link;
813
814 link = acpi_driver_data(device);
815
816 mutex_lock(&acpi_link_lock);
817 list_del(&link->list);
818 mutex_unlock(&acpi_link_lock);
819
820 kfree(link);
821}
822
823
824
825
826static int __init acpi_irq_penalty_update(char *str, int used)
827{
828 int i;
829
830 for (i = 0; i < 16; i++) {
831 int retval;
832 int irq;
833 int new_penalty;
834
835 retval = get_option(&str, &irq);
836
837 if (!retval)
838 break;
839
840
841 if ((irq < 0) || (irq >= ACPI_MAX_ISA_IRQS))
842 continue;
843
844 if (used)
845 new_penalty = acpi_isa_irq_penalty[irq] +
846 PIRQ_PENALTY_ISA_USED;
847 else
848 new_penalty = 0;
849
850 acpi_isa_irq_penalty[irq] = new_penalty;
851 if (retval != 2)
852 break;
853 }
854 return 1;
855}
856
857
858
859
860
861
862
863
864void acpi_penalize_isa_irq(int irq, int active)
865{
866 if ((irq >= 0) && (irq < ARRAY_SIZE(acpi_isa_irq_penalty)))
867 acpi_isa_irq_penalty[irq] +=
868 (active ? PIRQ_PENALTY_ISA_USED : PIRQ_PENALTY_PCI_USING);
869}
870
871bool acpi_isa_irq_available(int irq)
872{
873 return irq >= 0 && (irq >= ARRAY_SIZE(acpi_isa_irq_penalty) ||
874 acpi_irq_get_penalty(irq) < PIRQ_PENALTY_ISA_ALWAYS);
875}
876
877void acpi_penalize_sci_irq(int irq, int trigger, int polarity)
878{
879 sci_irq = irq;
880
881 if (trigger == ACPI_MADT_TRIGGER_LEVEL &&
882 polarity == ACPI_MADT_POLARITY_ACTIVE_LOW)
883 sci_penalty = PIRQ_PENALTY_PCI_USING;
884 else
885 sci_penalty = PIRQ_PENALTY_ISA_ALWAYS;
886}
887
888
889
890
891
892
893static int __init acpi_irq_isa(char *str)
894{
895 return acpi_irq_penalty_update(str, 1);
896}
897
898__setup("acpi_irq_isa=", acpi_irq_isa);
899
900
901
902
903
904
905static int __init acpi_irq_pci(char *str)
906{
907 return acpi_irq_penalty_update(str, 0);
908}
909
910__setup("acpi_irq_pci=", acpi_irq_pci);
911
912static int __init acpi_irq_nobalance_set(char *str)
913{
914 acpi_irq_balance = 0;
915 return 1;
916}
917
918__setup("acpi_irq_nobalance", acpi_irq_nobalance_set);
919
920static int __init acpi_irq_balance_set(char *str)
921{
922 acpi_irq_balance = 1;
923 return 1;
924}
925
926__setup("acpi_irq_balance", acpi_irq_balance_set);
927
928static struct syscore_ops irqrouter_syscore_ops = {
929 .resume = irqrouter_resume,
930};
931
932void __init acpi_pci_link_init(void)
933{
934 if (acpi_noirq)
935 return;
936
937 if (acpi_irq_balance == -1) {
938
939 if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
940 acpi_irq_balance = 1;
941 else
942 acpi_irq_balance = 0;
943 }
944 register_syscore_ops(&irqrouter_syscore_ops);
945 acpi_scan_add_handler(&pci_link_handler);
946}
947