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