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