0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #define pr_fmt(fmt) "ACPI: PCI: " fmt
0016
0017 #include <linux/syscore_ops.h>
0018 #include <linux/kernel.h>
0019 #include <linux/module.h>
0020 #include <linux/init.h>
0021 #include <linux/types.h>
0022 #include <linux/spinlock.h>
0023 #include <linux/pm.h>
0024 #include <linux/pci.h>
0025 #include <linux/mutex.h>
0026 #include <linux/slab.h>
0027 #include <linux/acpi.h>
0028 #include <linux/irq.h>
0029
0030 #include "internal.h"
0031
0032 #define ACPI_PCI_LINK_CLASS "pci_irq_routing"
0033 #define ACPI_PCI_LINK_DEVICE_NAME "PCI Interrupt Link"
0034 #define ACPI_PCI_LINK_MAX_POSSIBLE 16
0035
0036 static int acpi_pci_link_add(struct acpi_device *device,
0037 const struct acpi_device_id *not_used);
0038 static void acpi_pci_link_remove(struct acpi_device *device);
0039
0040 static const struct acpi_device_id link_device_ids[] = {
0041 {"PNP0C0F", 0},
0042 {"", 0},
0043 };
0044
0045 static struct acpi_scan_handler pci_link_handler = {
0046 .ids = link_device_ids,
0047 .attach = acpi_pci_link_add,
0048 .detach = acpi_pci_link_remove,
0049 };
0050
0051
0052
0053
0054
0055 struct acpi_pci_link_irq {
0056 u32 active;
0057 u8 triggering;
0058 u8 polarity;
0059 u8 resource_type;
0060 u8 possible_count;
0061 u32 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
0062 u8 initialized:1;
0063 u8 reserved:7;
0064 };
0065
0066 struct acpi_pci_link {
0067 struct list_head list;
0068 struct acpi_device *device;
0069 struct acpi_pci_link_irq irq;
0070 int refcnt;
0071 };
0072
0073 static LIST_HEAD(acpi_link_list);
0074 static DEFINE_MUTEX(acpi_link_lock);
0075 static int sci_irq = -1, sci_penalty;
0076
0077
0078
0079
0080
0081
0082
0083
0084 static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource,
0085 void *context)
0086 {
0087 struct acpi_pci_link *link = context;
0088 acpi_handle handle = link->device->handle;
0089 u32 i;
0090
0091 switch (resource->type) {
0092 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
0093 case ACPI_RESOURCE_TYPE_END_TAG:
0094 return AE_OK;
0095 case ACPI_RESOURCE_TYPE_IRQ:
0096 {
0097 struct acpi_resource_irq *p = &resource->data.irq;
0098 if (!p->interrupt_count) {
0099 acpi_handle_debug(handle,
0100 "Blank _PRS IRQ resource\n");
0101 return AE_OK;
0102 }
0103 for (i = 0;
0104 (i < p->interrupt_count
0105 && i < ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
0106 if (!p->interrupts[i]) {
0107 acpi_handle_debug(handle,
0108 "Invalid _PRS IRQ %d\n",
0109 p->interrupts[i]);
0110 continue;
0111 }
0112 link->irq.possible[i] = p->interrupts[i];
0113 link->irq.possible_count++;
0114 }
0115 link->irq.triggering = p->triggering;
0116 link->irq.polarity = p->polarity;
0117 link->irq.resource_type = ACPI_RESOURCE_TYPE_IRQ;
0118 break;
0119 }
0120 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
0121 {
0122 struct acpi_resource_extended_irq *p =
0123 &resource->data.extended_irq;
0124 if (!p->interrupt_count) {
0125 acpi_handle_debug(handle,
0126 "Blank _PRS EXT IRQ resource\n");
0127 return AE_OK;
0128 }
0129 for (i = 0;
0130 (i < p->interrupt_count
0131 && i < ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
0132 if (!p->interrupts[i]) {
0133 acpi_handle_debug(handle,
0134 "Invalid _PRS IRQ %d\n",
0135 p->interrupts[i]);
0136 continue;
0137 }
0138 link->irq.possible[i] = p->interrupts[i];
0139 link->irq.possible_count++;
0140 }
0141 link->irq.triggering = p->triggering;
0142 link->irq.polarity = p->polarity;
0143 link->irq.resource_type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ;
0144 break;
0145 }
0146 default:
0147 acpi_handle_debug(handle, "_PRS resource type 0x%x is not IRQ\n",
0148 resource->type);
0149 return AE_OK;
0150 }
0151
0152 return AE_CTRL_TERMINATE;
0153 }
0154
0155 static int acpi_pci_link_get_possible(struct acpi_pci_link *link)
0156 {
0157 acpi_handle handle = link->device->handle;
0158 acpi_status status;
0159
0160 status = acpi_walk_resources(handle, METHOD_NAME__PRS,
0161 acpi_pci_link_check_possible, link);
0162 if (ACPI_FAILURE(status)) {
0163 acpi_handle_debug(handle, "_PRS not present or invalid");
0164 return 0;
0165 }
0166
0167 acpi_handle_debug(handle, "Found %d possible IRQs\n",
0168 link->irq.possible_count);
0169
0170 return 0;
0171 }
0172
0173 static acpi_status acpi_pci_link_check_current(struct acpi_resource *resource,
0174 void *context)
0175 {
0176 int *irq = context;
0177
0178 switch (resource->type) {
0179 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
0180 case ACPI_RESOURCE_TYPE_END_TAG:
0181 return AE_OK;
0182 case ACPI_RESOURCE_TYPE_IRQ:
0183 {
0184 struct acpi_resource_irq *p = &resource->data.irq;
0185 if (!p->interrupt_count) {
0186
0187
0188
0189
0190 pr_debug("Blank _CRS IRQ resource\n");
0191 return AE_OK;
0192 }
0193 *irq = p->interrupts[0];
0194 break;
0195 }
0196 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
0197 {
0198 struct acpi_resource_extended_irq *p =
0199 &resource->data.extended_irq;
0200 if (!p->interrupt_count) {
0201
0202
0203
0204
0205 pr_debug("Blank _CRS EXT IRQ resource\n");
0206 return AE_OK;
0207 }
0208 *irq = p->interrupts[0];
0209 break;
0210 }
0211 break;
0212 default:
0213 pr_debug("_CRS resource type 0x%x is not IRQ\n",
0214 resource->type);
0215 return AE_OK;
0216 }
0217
0218 return AE_CTRL_TERMINATE;
0219 }
0220
0221
0222
0223
0224
0225
0226
0227
0228 static int acpi_pci_link_get_current(struct acpi_pci_link *link)
0229 {
0230 acpi_handle handle = link->device->handle;
0231 acpi_status status;
0232 int result = 0;
0233 int irq = 0;
0234
0235 link->irq.active = 0;
0236
0237
0238 if (acpi_strict) {
0239
0240 result = acpi_bus_get_status(link->device);
0241 if (result) {
0242 acpi_handle_err(handle, "Unable to read status\n");
0243 goto end;
0244 }
0245
0246 if (!link->device->status.enabled) {
0247 acpi_handle_debug(handle, "Link disabled\n");
0248 return 0;
0249 }
0250 }
0251
0252
0253
0254
0255
0256 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
0257 acpi_pci_link_check_current, &irq);
0258 if (ACPI_FAILURE(status)) {
0259 acpi_evaluation_failure_warn(handle, "_CRS", status);
0260 result = -ENODEV;
0261 goto end;
0262 }
0263
0264 if (acpi_strict && !irq) {
0265 acpi_handle_err(handle, "_CRS returned 0\n");
0266 result = -ENODEV;
0267 }
0268
0269 link->irq.active = irq;
0270
0271 acpi_handle_debug(handle, "Link at IRQ %d \n", link->irq.active);
0272
0273 end:
0274 return result;
0275 }
0276
0277 static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
0278 {
0279 struct {
0280 struct acpi_resource res;
0281 struct acpi_resource end;
0282 } *resource;
0283 struct acpi_buffer buffer = { 0, NULL };
0284 acpi_handle handle = link->device->handle;
0285 acpi_status status;
0286 int result;
0287
0288 if (!irq)
0289 return -EINVAL;
0290
0291 resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
0292 if (!resource)
0293 return -ENOMEM;
0294
0295 buffer.length = sizeof(*resource) + 1;
0296 buffer.pointer = resource;
0297
0298 switch (link->irq.resource_type) {
0299 case ACPI_RESOURCE_TYPE_IRQ:
0300 resource->res.type = ACPI_RESOURCE_TYPE_IRQ;
0301 resource->res.length = sizeof(struct acpi_resource);
0302 resource->res.data.irq.triggering = link->irq.triggering;
0303 resource->res.data.irq.polarity =
0304 link->irq.polarity;
0305 if (link->irq.triggering == ACPI_EDGE_SENSITIVE)
0306 resource->res.data.irq.shareable =
0307 ACPI_EXCLUSIVE;
0308 else
0309 resource->res.data.irq.shareable = ACPI_SHARED;
0310 resource->res.data.irq.interrupt_count = 1;
0311 resource->res.data.irq.interrupts[0] = irq;
0312 break;
0313
0314 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
0315 resource->res.type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ;
0316 resource->res.length = sizeof(struct acpi_resource);
0317 resource->res.data.extended_irq.producer_consumer =
0318 ACPI_CONSUMER;
0319 resource->res.data.extended_irq.triggering =
0320 link->irq.triggering;
0321 resource->res.data.extended_irq.polarity =
0322 link->irq.polarity;
0323 if (link->irq.triggering == ACPI_EDGE_SENSITIVE)
0324 resource->res.data.extended_irq.shareable =
0325 ACPI_EXCLUSIVE;
0326 else
0327 resource->res.data.extended_irq.shareable = ACPI_SHARED;
0328 resource->res.data.extended_irq.interrupt_count = 1;
0329 resource->res.data.extended_irq.interrupts[0] = irq;
0330
0331 break;
0332 default:
0333 acpi_handle_err(handle, "Invalid resource type %d\n",
0334 link->irq.resource_type);
0335 result = -EINVAL;
0336 goto end;
0337
0338 }
0339 resource->end.type = ACPI_RESOURCE_TYPE_END_TAG;
0340 resource->end.length = sizeof(struct acpi_resource);
0341
0342
0343 status = acpi_set_current_resources(link->device->handle, &buffer);
0344
0345
0346 if (ACPI_FAILURE(status)) {
0347 acpi_evaluation_failure_warn(handle, "_SRS", status);
0348 result = -ENODEV;
0349 goto end;
0350 }
0351
0352
0353 result = acpi_bus_get_status(link->device);
0354 if (result) {
0355 acpi_handle_err(handle, "Unable to read status\n");
0356 goto end;
0357 }
0358 if (!link->device->status.enabled)
0359 acpi_handle_warn(handle, "Disabled and referenced, BIOS bug\n");
0360
0361
0362 result = acpi_pci_link_get_current(link);
0363 if (result) {
0364 goto end;
0365 }
0366
0367
0368
0369
0370
0371 if (link->irq.active != irq) {
0372
0373
0374
0375
0376 acpi_handle_warn(handle, "BIOS reported IRQ %d, using IRQ %d\n",
0377 link->irq.active, irq);
0378 link->irq.active = irq;
0379 }
0380
0381 acpi_handle_debug(handle, "Set IRQ %d\n", link->irq.active);
0382
0383 end:
0384 kfree(resource);
0385 return result;
0386 }
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423 #define ACPI_MAX_ISA_IRQS 16
0424
0425 #define PIRQ_PENALTY_PCI_POSSIBLE (16*16)
0426 #define PIRQ_PENALTY_PCI_USING (16*16*16)
0427 #define PIRQ_PENALTY_ISA_TYPICAL (16*16*16*16)
0428 #define PIRQ_PENALTY_ISA_USED (16*16*16*16*16)
0429 #define PIRQ_PENALTY_ISA_ALWAYS (16*16*16*16*16*16)
0430
0431 static int acpi_isa_irq_penalty[ACPI_MAX_ISA_IRQS] = {
0432 PIRQ_PENALTY_ISA_ALWAYS,
0433 PIRQ_PENALTY_ISA_ALWAYS,
0434 PIRQ_PENALTY_ISA_ALWAYS,
0435 PIRQ_PENALTY_ISA_TYPICAL,
0436 PIRQ_PENALTY_ISA_TYPICAL,
0437 PIRQ_PENALTY_ISA_TYPICAL,
0438 PIRQ_PENALTY_ISA_TYPICAL,
0439 PIRQ_PENALTY_ISA_TYPICAL,
0440 PIRQ_PENALTY_ISA_TYPICAL,
0441 0,
0442 0,
0443 0,
0444 PIRQ_PENALTY_ISA_USED,
0445 PIRQ_PENALTY_ISA_USED,
0446 PIRQ_PENALTY_ISA_USED,
0447 PIRQ_PENALTY_ISA_USED,
0448
0449 };
0450
0451 static int acpi_irq_pci_sharing_penalty(int irq)
0452 {
0453 struct acpi_pci_link *link;
0454 int penalty = 0;
0455 int i;
0456
0457 list_for_each_entry(link, &acpi_link_list, list) {
0458
0459
0460
0461
0462 if (link->irq.active && link->irq.active == irq)
0463 penalty += PIRQ_PENALTY_PCI_USING;
0464
0465
0466
0467
0468 for (i = 0; i < link->irq.possible_count; i++)
0469 if (link->irq.possible[i] == irq)
0470 penalty += PIRQ_PENALTY_PCI_POSSIBLE /
0471 link->irq.possible_count;
0472 }
0473
0474 return penalty;
0475 }
0476
0477 static int acpi_irq_get_penalty(int irq)
0478 {
0479 int penalty = 0;
0480
0481 if (irq == sci_irq)
0482 penalty += sci_penalty;
0483
0484 if (irq < ACPI_MAX_ISA_IRQS)
0485 return penalty + acpi_isa_irq_penalty[irq];
0486
0487 return penalty + acpi_irq_pci_sharing_penalty(irq);
0488 }
0489
0490 int __init acpi_irq_penalty_init(void)
0491 {
0492 struct acpi_pci_link *link;
0493 int i;
0494
0495
0496
0497
0498 list_for_each_entry(link, &acpi_link_list, list) {
0499
0500
0501
0502
0503
0504 if (link->irq.possible_count) {
0505 int penalty =
0506 PIRQ_PENALTY_PCI_POSSIBLE /
0507 link->irq.possible_count;
0508
0509 for (i = 0; i < link->irq.possible_count; i++) {
0510 if (link->irq.possible[i] < ACPI_MAX_ISA_IRQS)
0511 acpi_isa_irq_penalty[link->irq.
0512 possible[i]] +=
0513 penalty;
0514 }
0515
0516 } else if (link->irq.active &&
0517 (link->irq.active < ACPI_MAX_ISA_IRQS)) {
0518 acpi_isa_irq_penalty[link->irq.active] +=
0519 PIRQ_PENALTY_PCI_POSSIBLE;
0520 }
0521 }
0522
0523 return 0;
0524 }
0525
0526 static int acpi_irq_balance = -1;
0527
0528 static int acpi_pci_link_allocate(struct acpi_pci_link *link)
0529 {
0530 acpi_handle handle = link->device->handle;
0531 int irq;
0532 int i;
0533
0534 if (link->irq.initialized) {
0535 if (link->refcnt == 0)
0536
0537 acpi_pci_link_set(link, link->irq.active);
0538 return 0;
0539 }
0540
0541
0542
0543
0544 for (i = 0; i < link->irq.possible_count; ++i) {
0545 if (link->irq.active == link->irq.possible[i])
0546 break;
0547 }
0548
0549
0550
0551 if (i == link->irq.possible_count) {
0552 if (acpi_strict)
0553 acpi_handle_warn(handle, "_CRS %d not found in _PRS\n",
0554 link->irq.active);
0555 link->irq.active = 0;
0556 }
0557
0558
0559
0560
0561 if (link->irq.active)
0562 irq = link->irq.active;
0563 else
0564 irq = link->irq.possible[link->irq.possible_count - 1];
0565
0566 if (acpi_irq_balance || !link->irq.active) {
0567
0568
0569
0570
0571 for (i = (link->irq.possible_count - 1); i >= 0; i--) {
0572 if (acpi_irq_get_penalty(irq) >
0573 acpi_irq_get_penalty(link->irq.possible[i]))
0574 irq = link->irq.possible[i];
0575 }
0576 }
0577 if (acpi_irq_get_penalty(irq) >= PIRQ_PENALTY_ISA_ALWAYS) {
0578 acpi_handle_err(handle,
0579 "No IRQ available. Try pci=noacpi or acpi=off\n");
0580 return -ENODEV;
0581 }
0582
0583
0584 if (acpi_pci_link_set(link, irq)) {
0585 acpi_handle_err(handle,
0586 "Unable to set IRQ. Try pci=noacpi or acpi=off\n");
0587 return -ENODEV;
0588 } else {
0589 if (link->irq.active < ACPI_MAX_ISA_IRQS)
0590 acpi_isa_irq_penalty[link->irq.active] +=
0591 PIRQ_PENALTY_PCI_USING;
0592
0593 acpi_handle_info(handle, "Enabled at IRQ %d\n",
0594 link->irq.active);
0595 }
0596
0597 link->irq.initialized = 1;
0598 return 0;
0599 }
0600
0601
0602
0603
0604
0605
0606 int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering,
0607 int *polarity, char **name)
0608 {
0609 struct acpi_device *device = acpi_fetch_acpi_dev(handle);
0610 struct acpi_pci_link *link;
0611
0612 if (!device) {
0613 acpi_handle_err(handle, "Invalid link device\n");
0614 return -1;
0615 }
0616
0617 link = acpi_driver_data(device);
0618 if (!link) {
0619 acpi_handle_err(handle, "Invalid link context\n");
0620 return -1;
0621 }
0622
0623
0624 if (index) {
0625 acpi_handle_err(handle, "Invalid index %d\n", index);
0626 return -1;
0627 }
0628
0629 mutex_lock(&acpi_link_lock);
0630 if (acpi_pci_link_allocate(link)) {
0631 mutex_unlock(&acpi_link_lock);
0632 return -1;
0633 }
0634
0635 if (!link->irq.active) {
0636 mutex_unlock(&acpi_link_lock);
0637 acpi_handle_err(handle, "Link active IRQ is 0!\n");
0638 return -1;
0639 }
0640 link->refcnt++;
0641 mutex_unlock(&acpi_link_lock);
0642
0643 if (triggering)
0644 *triggering = link->irq.triggering;
0645 if (polarity)
0646 *polarity = link->irq.polarity;
0647 if (name)
0648 *name = acpi_device_bid(link->device);
0649 acpi_handle_debug(handle, "Link is referenced\n");
0650 return link->irq.active;
0651 }
0652
0653
0654
0655
0656
0657 int acpi_pci_link_free_irq(acpi_handle handle)
0658 {
0659 struct acpi_device *device = acpi_fetch_acpi_dev(handle);
0660 struct acpi_pci_link *link;
0661
0662 if (!device) {
0663 acpi_handle_err(handle, "Invalid link device\n");
0664 return -1;
0665 }
0666
0667 link = acpi_driver_data(device);
0668 if (!link) {
0669 acpi_handle_err(handle, "Invalid link context\n");
0670 return -1;
0671 }
0672
0673 mutex_lock(&acpi_link_lock);
0674 if (!link->irq.initialized) {
0675 mutex_unlock(&acpi_link_lock);
0676 acpi_handle_err(handle, "Link isn't initialized\n");
0677 return -1;
0678 }
0679 #ifdef FUTURE_USE
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689 link->refcnt--;
0690 #endif
0691 acpi_handle_debug(handle, "Link is dereferenced\n");
0692
0693 if (link->refcnt == 0)
0694 acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL);
0695
0696 mutex_unlock(&acpi_link_lock);
0697 return link->irq.active;
0698 }
0699
0700
0701
0702
0703
0704 static int acpi_pci_link_add(struct acpi_device *device,
0705 const struct acpi_device_id *not_used)
0706 {
0707 acpi_handle handle = device->handle;
0708 struct acpi_pci_link *link;
0709 int result;
0710 int i;
0711
0712 link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL);
0713 if (!link)
0714 return -ENOMEM;
0715
0716 link->device = device;
0717 strcpy(acpi_device_name(device), ACPI_PCI_LINK_DEVICE_NAME);
0718 strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS);
0719 device->driver_data = link;
0720
0721 mutex_lock(&acpi_link_lock);
0722 result = acpi_pci_link_get_possible(link);
0723 if (result)
0724 goto end;
0725
0726
0727 acpi_pci_link_get_current(link);
0728
0729 pr_info("Interrupt link %s configured for IRQ %d\n",
0730 acpi_device_bid(device), link->irq.active);
0731
0732 for (i = 0; i < link->irq.possible_count; i++) {
0733 if (link->irq.active != link->irq.possible[i])
0734 acpi_handle_debug(handle, "Possible IRQ %d\n",
0735 link->irq.possible[i]);
0736 }
0737
0738 if (!link->device->status.enabled)
0739 pr_info("Interrupt link %s disabled\n", acpi_device_bid(device));
0740
0741 list_add_tail(&link->list, &acpi_link_list);
0742
0743 end:
0744
0745 acpi_evaluate_object(handle, "_DIS", NULL, NULL);
0746 mutex_unlock(&acpi_link_lock);
0747
0748 if (result)
0749 kfree(link);
0750
0751 return result < 0 ? result : 1;
0752 }
0753
0754 static int acpi_pci_link_resume(struct acpi_pci_link *link)
0755 {
0756 if (link->refcnt && link->irq.active && link->irq.initialized)
0757 return (acpi_pci_link_set(link, link->irq.active));
0758
0759 return 0;
0760 }
0761
0762 static void irqrouter_resume(void)
0763 {
0764 struct acpi_pci_link *link;
0765
0766 list_for_each_entry(link, &acpi_link_list, list) {
0767 acpi_pci_link_resume(link);
0768 }
0769 }
0770
0771 static void acpi_pci_link_remove(struct acpi_device *device)
0772 {
0773 struct acpi_pci_link *link;
0774
0775 link = acpi_driver_data(device);
0776
0777 mutex_lock(&acpi_link_lock);
0778 list_del(&link->list);
0779 mutex_unlock(&acpi_link_lock);
0780
0781 kfree(link);
0782 }
0783
0784
0785
0786
0787 static int __init acpi_irq_penalty_update(char *str, int used)
0788 {
0789 int i;
0790
0791 for (i = 0; i < 16; i++) {
0792 int retval;
0793 int irq;
0794 int new_penalty;
0795
0796 retval = get_option(&str, &irq);
0797
0798 if (!retval)
0799 break;
0800
0801
0802 if ((irq < 0) || (irq >= ACPI_MAX_ISA_IRQS))
0803 continue;
0804
0805 if (used)
0806 new_penalty = acpi_isa_irq_penalty[irq] +
0807 PIRQ_PENALTY_ISA_USED;
0808 else
0809 new_penalty = 0;
0810
0811 acpi_isa_irq_penalty[irq] = new_penalty;
0812 if (retval != 2)
0813 break;
0814 }
0815 return 1;
0816 }
0817
0818
0819
0820
0821
0822
0823
0824
0825 void acpi_penalize_isa_irq(int irq, int active)
0826 {
0827 if ((irq >= 0) && (irq < ARRAY_SIZE(acpi_isa_irq_penalty)))
0828 acpi_isa_irq_penalty[irq] +=
0829 (active ? PIRQ_PENALTY_ISA_USED : PIRQ_PENALTY_PCI_USING);
0830 }
0831
0832 bool acpi_isa_irq_available(int irq)
0833 {
0834 return irq >= 0 && (irq >= ARRAY_SIZE(acpi_isa_irq_penalty) ||
0835 acpi_irq_get_penalty(irq) < PIRQ_PENALTY_ISA_ALWAYS);
0836 }
0837
0838 void acpi_penalize_sci_irq(int irq, int trigger, int polarity)
0839 {
0840 sci_irq = irq;
0841
0842 if (trigger == ACPI_MADT_TRIGGER_LEVEL &&
0843 polarity == ACPI_MADT_POLARITY_ACTIVE_LOW)
0844 sci_penalty = PIRQ_PENALTY_PCI_USING;
0845 else
0846 sci_penalty = PIRQ_PENALTY_ISA_ALWAYS;
0847 }
0848
0849
0850
0851
0852
0853
0854 static int __init acpi_irq_isa(char *str)
0855 {
0856 return acpi_irq_penalty_update(str, 1);
0857 }
0858
0859 __setup("acpi_irq_isa=", acpi_irq_isa);
0860
0861
0862
0863
0864
0865
0866 static int __init acpi_irq_pci(char *str)
0867 {
0868 return acpi_irq_penalty_update(str, 0);
0869 }
0870
0871 __setup("acpi_irq_pci=", acpi_irq_pci);
0872
0873 static int __init acpi_irq_nobalance_set(char *str)
0874 {
0875 acpi_irq_balance = 0;
0876 return 1;
0877 }
0878
0879 __setup("acpi_irq_nobalance", acpi_irq_nobalance_set);
0880
0881 static int __init acpi_irq_balance_set(char *str)
0882 {
0883 acpi_irq_balance = 1;
0884 return 1;
0885 }
0886
0887 __setup("acpi_irq_balance", acpi_irq_balance_set);
0888
0889 static struct syscore_ops irqrouter_syscore_ops = {
0890 .resume = irqrouter_resume,
0891 };
0892
0893 void __init acpi_pci_link_init(void)
0894 {
0895 if (acpi_noirq)
0896 return;
0897
0898 if (acpi_irq_balance == -1) {
0899
0900 if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
0901 acpi_irq_balance = 1;
0902 else
0903 acpi_irq_balance = 0;
0904 }
0905 register_syscore_ops(&irqrouter_syscore_ops);
0906 acpi_scan_add_handler(&pci_link_handler);
0907 }