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