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