910 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * pci_link.c - ACPI PCI Interrupt Link Device Driver ($Revision: 34 $)4 *5 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>6 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>7 * Copyright (C) 2002 Dominik Brodowski <devel@brodo.de>8 *9 * TBD:10 * 1. Support more than one IRQ resource entry per link device (index).11 * 2. Implement start/stop mechanism and use ACPI Bus Driver facilities12 * for IRQ management (e.g. start()->_SRS).13 */14 15#define pr_fmt(fmt) "ACPI: PCI: " fmt16 17#include <linux/syscore_ops.h>18#include <linux/kernel.h>19#include <linux/module.h>20#include <linux/init.h>21#include <linux/types.h>22#include <linux/spinlock.h>23#include <linux/pm.h>24#include <linux/pci.h>25#include <linux/mutex.h>26#include <linux/slab.h>27#include <linux/acpi.h>28#include <linux/irq.h>29 30#include "internal.h"31 32#define ACPI_PCI_LINK_CLASS "pci_irq_routing"33#define ACPI_PCI_LINK_DEVICE_NAME "PCI Interrupt Link"34#define ACPI_PCI_LINK_MAX_POSSIBLE 1635 36static int acpi_pci_link_add(struct acpi_device *device,37 const struct acpi_device_id *not_used);38static void acpi_pci_link_remove(struct acpi_device *device);39 40static const struct acpi_device_id link_device_ids[] = {41 {"PNP0C0F", 0},42 {"", 0},43};44 45static struct acpi_scan_handler pci_link_handler = {46 .ids = link_device_ids,47 .attach = acpi_pci_link_add,48 .detach = acpi_pci_link_remove,49};50 51/*52 * If a link is initialized, we never change its active and initialized53 * later even the link is disable. Instead, we just repick the active irq54 */55struct acpi_pci_link_irq {56 u32 active; /* Current IRQ */57 u8 triggering; /* All IRQs */58 u8 polarity; /* All IRQs */59 u8 resource_type;60 u8 possible_count;61 u32 possible[ACPI_PCI_LINK_MAX_POSSIBLE];62 u8 initialized:1;63 u8 reserved:7;64};65 66struct acpi_pci_link {67 struct list_head list;68 struct acpi_device *device;69 struct acpi_pci_link_irq irq;70 int refcnt;71};72 73static LIST_HEAD(acpi_link_list);74static DEFINE_MUTEX(acpi_link_lock);75static int sci_irq = -1, sci_penalty;76 77/* --------------------------------------------------------------------------78 PCI Link Device Management79 -------------------------------------------------------------------------- */80 81/*82 * set context (link) possible list from resource list83 */84static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource,85 void *context)86{87 struct acpi_pci_link *link = context;88 acpi_handle handle = link->device->handle;89 u32 i;90 91 switch (resource->type) {92 case ACPI_RESOURCE_TYPE_START_DEPENDENT:93 case ACPI_RESOURCE_TYPE_END_TAG:94 return AE_OK;95 case ACPI_RESOURCE_TYPE_IRQ:96 {97 struct acpi_resource_irq *p = &resource->data.irq;98 if (!p->interrupt_count) {99 acpi_handle_debug(handle,100 "Blank _PRS IRQ resource\n");101 return AE_OK;102 }103 for (i = 0;104 (i < p->interrupt_count105 && i < ACPI_PCI_LINK_MAX_POSSIBLE); i++) {106 if (!p->interrupts[i]) {107 acpi_handle_debug(handle,108 "Invalid _PRS IRQ %d\n",109 p->interrupts[i]);110 continue;111 }112 link->irq.possible[i] = p->interrupts[i];113 link->irq.possible_count++;114 }115 link->irq.triggering = p->triggering;116 link->irq.polarity = p->polarity;117 link->irq.resource_type = ACPI_RESOURCE_TYPE_IRQ;118 break;119 }120 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:121 {122 struct acpi_resource_extended_irq *p =123 &resource->data.extended_irq;124 if (!p->interrupt_count) {125 acpi_handle_debug(handle,126 "Blank _PRS EXT IRQ resource\n");127 return AE_OK;128 }129 for (i = 0;130 (i < p->interrupt_count131 && i < ACPI_PCI_LINK_MAX_POSSIBLE); i++) {132 if (!p->interrupts[i]) {133 acpi_handle_debug(handle,134 "Invalid _PRS IRQ %d\n",135 p->interrupts[i]);136 continue;137 }138 link->irq.possible[i] = p->interrupts[i];139 link->irq.possible_count++;140 }141 link->irq.triggering = p->triggering;142 link->irq.polarity = p->polarity;143 link->irq.resource_type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ;144 break;145 }146 default:147 acpi_handle_debug(handle, "_PRS resource type 0x%x is not IRQ\n",148 resource->type);149 return AE_OK;150 }151 152 return AE_CTRL_TERMINATE;153}154 155static int acpi_pci_link_get_possible(struct acpi_pci_link *link)156{157 acpi_handle handle = link->device->handle;158 acpi_status status;159 160 status = acpi_walk_resources(handle, METHOD_NAME__PRS,161 acpi_pci_link_check_possible, link);162 if (ACPI_FAILURE(status)) {163 acpi_handle_debug(handle, "_PRS not present or invalid");164 return 0;165 }166 167 acpi_handle_debug(handle, "Found %d possible IRQs\n",168 link->irq.possible_count);169 170 return 0;171}172 173static acpi_status acpi_pci_link_check_current(struct acpi_resource *resource,174 void *context)175{176 int *irq = context;177 178 switch (resource->type) {179 case ACPI_RESOURCE_TYPE_START_DEPENDENT:180 case ACPI_RESOURCE_TYPE_END_TAG:181 return AE_OK;182 case ACPI_RESOURCE_TYPE_IRQ:183 {184 struct acpi_resource_irq *p = &resource->data.irq;185 if (!p->interrupt_count) {186 /*187 * IRQ descriptors may have no IRQ# bits set,188 * particularly those w/ _STA disabled189 */190 pr_debug("Blank _CRS IRQ resource\n");191 return AE_OK;192 }193 *irq = p->interrupts[0];194 break;195 }196 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:197 {198 struct acpi_resource_extended_irq *p =199 &resource->data.extended_irq;200 if (!p->interrupt_count) {201 /*202 * extended IRQ descriptors must203 * return at least 1 IRQ204 */205 pr_debug("Blank _CRS EXT IRQ resource\n");206 return AE_OK;207 }208 *irq = p->interrupts[0];209 break;210 }211 break;212 default:213 pr_debug("_CRS resource type 0x%x is not IRQ\n",214 resource->type);215 return AE_OK;216 }217 218 return AE_CTRL_TERMINATE;219}220 221/*222 * Run _CRS and set link->irq.active223 *224 * return value:225 * 0 - success226 * !0 - failure227 */228static int acpi_pci_link_get_current(struct acpi_pci_link *link)229{230 acpi_handle handle = link->device->handle;231 acpi_status status;232 int result = 0;233 int irq = 0;234 235 link->irq.active = 0;236 237 /* in practice, status disabled is meaningless, ignore it */238 if (acpi_strict) {239 /* Query _STA, set link->device->status */240 result = acpi_bus_get_status(link->device);241 if (result) {242 acpi_handle_err(handle, "Unable to read status\n");243 goto end;244 }245 246 if (!link->device->status.enabled) {247 acpi_handle_debug(handle, "Link disabled\n");248 return 0;249 }250 }251 252 /*253 * Query and parse _CRS to get the current IRQ assignment.254 */255 256 status = acpi_walk_resources(handle, METHOD_NAME__CRS,257 acpi_pci_link_check_current, &irq);258 if (ACPI_FAILURE(status)) {259 acpi_evaluation_failure_warn(handle, "_CRS", status);260 result = -ENODEV;261 goto end;262 }263 264 if (acpi_strict && !irq) {265 acpi_handle_err(handle, "_CRS returned 0\n");266 result = -ENODEV;267 }268 269 link->irq.active = irq;270 271 acpi_handle_debug(handle, "Link at IRQ %d \n", link->irq.active);272 273 end:274 return result;275}276 277static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)278{279 struct {280 struct acpi_resource res;281 struct acpi_resource end;282 } *resource;283 struct acpi_buffer buffer = { 0, NULL };284 acpi_handle handle = link->device->handle;285 acpi_status status;286 int result;287 288 if (!irq)289 return -EINVAL;290 291 resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);292 if (!resource)293 return -ENOMEM;294 295 buffer.length = sizeof(*resource) + 1;296 buffer.pointer = resource;297 298 switch (link->irq.resource_type) {299 case ACPI_RESOURCE_TYPE_IRQ:300 resource->res.type = ACPI_RESOURCE_TYPE_IRQ;301 resource->res.length = sizeof(struct acpi_resource);302 resource->res.data.irq.triggering = link->irq.triggering;303 resource->res.data.irq.polarity =304 link->irq.polarity;305 if (link->irq.triggering == ACPI_EDGE_SENSITIVE)306 resource->res.data.irq.shareable =307 ACPI_EXCLUSIVE;308 else309 resource->res.data.irq.shareable = ACPI_SHARED;310 resource->res.data.irq.interrupt_count = 1;311 resource->res.data.irq.interrupts[0] = irq;312 break;313 314 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:315 resource->res.type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ;316 resource->res.length = sizeof(struct acpi_resource);317 resource->res.data.extended_irq.producer_consumer =318 ACPI_CONSUMER;319 resource->res.data.extended_irq.triggering =320 link->irq.triggering;321 resource->res.data.extended_irq.polarity =322 link->irq.polarity;323 if (link->irq.triggering == ACPI_EDGE_SENSITIVE)324 resource->res.data.extended_irq.shareable =325 ACPI_EXCLUSIVE;326 else327 resource->res.data.extended_irq.shareable = ACPI_SHARED;328 resource->res.data.extended_irq.interrupt_count = 1;329 resource->res.data.extended_irq.interrupts[0] = irq;330 /* ignore resource_source, it's optional */331 break;332 default:333 acpi_handle_err(handle, "Invalid resource type %d\n",334 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 /* Attempt to set the resource */343 status = acpi_set_current_resources(link->device->handle, &buffer);344 345 /* check for total failure */346 if (ACPI_FAILURE(status)) {347 acpi_evaluation_failure_warn(handle, "_SRS", status);348 result = -ENODEV;349 goto end;350 }351 352 /* Query _STA, set device->status */353 result = acpi_bus_get_status(link->device);354 if (result) {355 acpi_handle_err(handle, "Unable to read status\n");356 goto end;357 }358 if (!link->device->status.enabled)359 acpi_handle_warn(handle, "Disabled and referenced, BIOS bug\n");360 361 /* Query _CRS, set link->irq.active */362 result = acpi_pci_link_get_current(link);363 if (result) {364 goto end;365 }366 367 /*368 * Is current setting not what we set?369 * set link->irq.active370 */371 if (link->irq.active != irq) {372 /*373 * policy: when _CRS doesn't return what we just _SRS374 * assume _SRS worked and override _CRS value.375 */376 acpi_handle_warn(handle, "BIOS reported IRQ %d, using IRQ %d\n",377 link->irq.active, irq);378 link->irq.active = irq;379 }380 381 acpi_handle_debug(handle, "Set IRQ %d\n", link->irq.active);382 383 end:384 kfree(resource);385 return result;386}387 388/* --------------------------------------------------------------------------389 PCI Link IRQ Management390 -------------------------------------------------------------------------- */391 392/*393 * "acpi_irq_balance" (default in APIC mode) enables ACPI to use PIC Interrupt394 * Link Devices to move the PIRQs around to minimize sharing.395 *396 * "acpi_irq_nobalance" (default in PIC mode) tells ACPI not to move any PIC IRQs397 * that the BIOS has already set to active. This is necessary because398 * ACPI has no automatic means of knowing what ISA IRQs are used. Note that399 * if the BIOS doesn't set a Link Device active, ACPI needs to program it400 * even if acpi_irq_nobalance is set.401 *402 * A tables of penalties avoids directing PCI interrupts to well known403 * ISA IRQs. Boot params are available to over-ride the default table:404 *405 * List interrupts that are free for PCI use.406 * acpi_irq_pci=n[,m]407 *408 * List interrupts that should not be used for PCI:409 * acpi_irq_isa=n[,m]410 *411 * Note that PCI IRQ routers have a list of possible IRQs,412 * which may not include the IRQs this table says are available.413 *414 * Since this heuristic can't tell the difference between a link415 * that no device will attach to, vs. a link which may be shared416 * by multiple active devices -- it is not optimal.417 *418 * If interrupt performance is that important, get an IO-APIC system419 * with a pin dedicated to each device. Or for that matter, an MSI420 * enabled system.421 */422 423#define ACPI_MAX_ISA_IRQS 16424 425#define PIRQ_PENALTY_PCI_POSSIBLE (16*16)426#define PIRQ_PENALTY_PCI_USING (16*16*16)427#define PIRQ_PENALTY_ISA_TYPICAL (16*16*16*16)428#define PIRQ_PENALTY_ISA_USED (16*16*16*16*16)429#define PIRQ_PENALTY_ISA_ALWAYS (16*16*16*16*16*16)430 431static int acpi_isa_irq_penalty[ACPI_MAX_ISA_IRQS] = {432 PIRQ_PENALTY_ISA_ALWAYS, /* IRQ0 timer */433 PIRQ_PENALTY_ISA_ALWAYS, /* IRQ1 keyboard */434 PIRQ_PENALTY_ISA_ALWAYS, /* IRQ2 cascade */435 PIRQ_PENALTY_ISA_TYPICAL, /* IRQ3 serial */436 PIRQ_PENALTY_ISA_TYPICAL, /* IRQ4 serial */437 PIRQ_PENALTY_ISA_TYPICAL, /* IRQ5 sometimes SoundBlaster */438 PIRQ_PENALTY_ISA_TYPICAL, /* IRQ6 */439 PIRQ_PENALTY_ISA_TYPICAL, /* IRQ7 parallel, spurious */440 PIRQ_PENALTY_ISA_TYPICAL, /* IRQ8 rtc, sometimes */441 0, /* IRQ9 PCI, often acpi */442 0, /* IRQ10 PCI */443 0, /* IRQ11 PCI */444 PIRQ_PENALTY_ISA_USED, /* IRQ12 mouse */445 PIRQ_PENALTY_ISA_USED, /* IRQ13 fpe, sometimes */446 PIRQ_PENALTY_ISA_USED, /* IRQ14 ide0 */447 PIRQ_PENALTY_ISA_USED, /* IRQ15 ide1 */448 /* >IRQ15 */449};450 451static int acpi_irq_pci_sharing_penalty(int irq)452{453 struct acpi_pci_link *link;454 int penalty = 0;455 int i;456 457 list_for_each_entry(link, &acpi_link_list, list) {458 /*459 * If a link is active, penalize its IRQ heavily460 * so we try to choose a different IRQ.461 */462 if (link->irq.active && link->irq.active == irq)463 penalty += PIRQ_PENALTY_PCI_USING;464 465 /*466 * penalize the IRQs PCI might use, but not as severely.467 */468 for (i = 0; i < link->irq.possible_count; i++)469 if (link->irq.possible[i] == irq)470 penalty += PIRQ_PENALTY_PCI_POSSIBLE /471 link->irq.possible_count;472 }473 474 return penalty;475}476 477static int acpi_irq_get_penalty(int irq)478{479 int penalty = 0;480 481 if (irq == sci_irq)482 penalty += sci_penalty;483 484 if (irq < ACPI_MAX_ISA_IRQS)485 return penalty + acpi_isa_irq_penalty[irq];486 487 return penalty + acpi_irq_pci_sharing_penalty(irq);488}489 490int __init acpi_irq_penalty_init(void)491{492 struct acpi_pci_link *link;493 int i;494 495 /*496 * Update penalties to facilitate IRQ balancing.497 */498 list_for_each_entry(link, &acpi_link_list, list) {499 500 /*501 * reflect the possible and active irqs in the penalty table --502 * useful for breaking ties.503 */504 if (link->irq.possible_count) {505 int penalty =506 PIRQ_PENALTY_PCI_POSSIBLE /507 link->irq.possible_count;508 509 for (i = 0; i < link->irq.possible_count; i++) {510 if (link->irq.possible[i] < ACPI_MAX_ISA_IRQS)511 acpi_isa_irq_penalty[link->irq.512 possible[i]] +=513 penalty;514 }515 516 } else if (link->irq.active &&517 (link->irq.active < ACPI_MAX_ISA_IRQS)) {518 acpi_isa_irq_penalty[link->irq.active] +=519 PIRQ_PENALTY_PCI_POSSIBLE;520 }521 }522 523 return 0;524}525 526static int acpi_irq_balance = -1; /* 0: static, 1: balance */527 528static int acpi_pci_link_allocate(struct acpi_pci_link *link)529{530 acpi_handle handle = link->device->handle;531 int irq;532 int i;533 534 if (link->irq.initialized) {535 if (link->refcnt == 0)536 /* This means the link is disabled but initialized */537 acpi_pci_link_set(link, link->irq.active);538 return 0;539 }540 541 /*542 * search for active IRQ in list of possible IRQs.543 */544 for (i = 0; i < link->irq.possible_count; ++i) {545 if (link->irq.active == link->irq.possible[i])546 break;547 }548 /*549 * forget active IRQ that is not in possible list550 */551 if (i == link->irq.possible_count) {552 if (acpi_strict)553 acpi_handle_warn(handle, "_CRS %d not found in _PRS\n",554 link->irq.active);555 link->irq.active = 0;556 }557 558 /*559 * if active found, use it; else pick entry from end of possible list.560 */561 if (link->irq.active)562 irq = link->irq.active;563 else564 irq = link->irq.possible[link->irq.possible_count - 1];565 566 if (acpi_irq_balance || !link->irq.active) {567 /*568 * Select the best IRQ. This is done in reverse to promote569 * the use of IRQs 9, 10, 11, and >15.570 */571 for (i = (link->irq.possible_count - 1); i >= 0; i--) {572 if (acpi_irq_get_penalty(irq) >573 acpi_irq_get_penalty(link->irq.possible[i]))574 irq = link->irq.possible[i];575 }576 }577 if (acpi_irq_get_penalty(irq) >= PIRQ_PENALTY_ISA_ALWAYS) {578 acpi_handle_err(handle,579 "No IRQ available. Try pci=noacpi or acpi=off\n");580 return -ENODEV;581 }582 583 /* Attempt to enable the link device at this IRQ. */584 if (acpi_pci_link_set(link, irq)) {585 acpi_handle_err(handle,586 "Unable to set IRQ. Try pci=noacpi or acpi=off\n");587 return -ENODEV;588 } else {589 if (link->irq.active < ACPI_MAX_ISA_IRQS)590 acpi_isa_irq_penalty[link->irq.active] +=591 PIRQ_PENALTY_PCI_USING;592 593 acpi_handle_info(handle, "Enabled at IRQ %d\n",594 link->irq.active);595 }596 597 link->irq.initialized = 1;598 return 0;599}600 601/*602 * acpi_pci_link_allocate_irq603 * success: return IRQ >= 0604 * failure: return -1605 */606int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering,607 int *polarity, char **name)608{609 struct acpi_device *device = acpi_fetch_acpi_dev(handle);610 struct acpi_pci_link *link;611 612 if (!device) {613 acpi_handle_err(handle, "Invalid link device\n");614 return -1;615 }616 617 link = acpi_driver_data(device);618 if (!link) {619 acpi_handle_err(handle, "Invalid link context\n");620 return -1;621 }622 623 /* TBD: Support multiple index (IRQ) entries per Link Device */624 if (index) {625 acpi_handle_err(handle, "Invalid index %d\n", index);626 return -1;627 }628 629 mutex_lock(&acpi_link_lock);630 if (acpi_pci_link_allocate(link)) {631 mutex_unlock(&acpi_link_lock);632 return -1;633 }634 635 if (!link->irq.active) {636 mutex_unlock(&acpi_link_lock);637 acpi_handle_err(handle, "Link active IRQ is 0!\n");638 return -1;639 }640 link->refcnt++;641 mutex_unlock(&acpi_link_lock);642 643 if (triggering)644 *triggering = link->irq.triggering;645 if (polarity)646 *polarity = link->irq.polarity;647 if (name)648 *name = acpi_device_bid(link->device);649 acpi_handle_debug(handle, "Link is referenced\n");650 return link->irq.active;651}652 653/*654 * We don't change link's irq information here. After it is reenabled, we655 * continue use the info656 */657int acpi_pci_link_free_irq(acpi_handle handle)658{659 struct acpi_device *device = acpi_fetch_acpi_dev(handle);660 struct acpi_pci_link *link;661 662 if (!device) {663 acpi_handle_err(handle, "Invalid link device\n");664 return -1;665 }666 667 link = acpi_driver_data(device);668 if (!link) {669 acpi_handle_err(handle, "Invalid link context\n");670 return -1;671 }672 673 mutex_lock(&acpi_link_lock);674 if (!link->irq.initialized) {675 mutex_unlock(&acpi_link_lock);676 acpi_handle_err(handle, "Link isn't initialized\n");677 return -1;678 }679#ifdef FUTURE_USE680 /*681 * The Link reference count allows us to _DISable an unused link682 * and suspend time, and set it again on resume.683 * However, 2.6.12 still has irq_router.resume684 * which blindly restores the link state.685 * So we disable the reference count method686 * to prevent duplicate acpi_pci_link_set()687 * which would harm some systems688 */689 link->refcnt--;690#endif691 acpi_handle_debug(handle, "Link is dereferenced\n");692 693 if (link->refcnt == 0)694 acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL);695 696 mutex_unlock(&acpi_link_lock);697 return link->irq.active;698}699 700/* --------------------------------------------------------------------------701 Driver Interface702 -------------------------------------------------------------------------- */703 704static int acpi_pci_link_add(struct acpi_device *device,705 const struct acpi_device_id *not_used)706{707 acpi_handle handle = device->handle;708 struct acpi_pci_link *link;709 int result;710 int i;711 712 link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL);713 if (!link)714 return -ENOMEM;715 716 link->device = device;717 strcpy(acpi_device_name(device), ACPI_PCI_LINK_DEVICE_NAME);718 strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS);719 device->driver_data = link;720 721 mutex_lock(&acpi_link_lock);722 result = acpi_pci_link_get_possible(link);723 if (result)724 goto end;725 726 /* query and set link->irq.active */727 acpi_pci_link_get_current(link);728 729 pr_info("Interrupt link %s configured for IRQ %d\n",730 acpi_device_bid(device), link->irq.active);731 732 for (i = 0; i < link->irq.possible_count; i++) {733 if (link->irq.active != link->irq.possible[i])734 acpi_handle_debug(handle, "Possible IRQ %d\n",735 link->irq.possible[i]);736 }737 738 if (!link->device->status.enabled)739 pr_info("Interrupt link %s disabled\n", acpi_device_bid(device));740 741 list_add_tail(&link->list, &acpi_link_list);742 743 end:744 /* disable all links -- to be activated on use */745 acpi_evaluate_object(handle, "_DIS", NULL, NULL);746 mutex_unlock(&acpi_link_lock);747 748 if (result)749 kfree(link);750 751 acpi_dev_clear_dependencies(device);752 753 return result < 0 ? result : 1;754}755 756static int acpi_pci_link_resume(struct acpi_pci_link *link)757{758 if (link->refcnt && link->irq.active && link->irq.initialized)759 return (acpi_pci_link_set(link, link->irq.active));760 761 return 0;762}763 764static void irqrouter_resume(void)765{766 struct acpi_pci_link *link;767 768 list_for_each_entry(link, &acpi_link_list, list) {769 acpi_pci_link_resume(link);770 }771}772 773static void acpi_pci_link_remove(struct acpi_device *device)774{775 struct acpi_pci_link *link;776 777 link = acpi_driver_data(device);778 779 mutex_lock(&acpi_link_lock);780 list_del(&link->list);781 mutex_unlock(&acpi_link_lock);782 783 kfree(link);784}785 786/*787 * modify acpi_isa_irq_penalty[] from cmdline788 */789static int __init acpi_irq_penalty_update(char *str, int used)790{791 int i;792 793 for (i = 0; i < 16; i++) {794 int retval;795 int irq;796 int new_penalty;797 798 retval = get_option(&str, &irq);799 800 if (!retval)801 break; /* no number found */802 803 /* see if this is a ISA IRQ */804 if ((irq < 0) || (irq >= ACPI_MAX_ISA_IRQS))805 continue;806 807 if (used)808 new_penalty = acpi_isa_irq_penalty[irq] +809 PIRQ_PENALTY_ISA_USED;810 else811 new_penalty = 0;812 813 acpi_isa_irq_penalty[irq] = new_penalty;814 if (retval != 2) /* no next number */815 break;816 }817 return 1;818}819 820/*821 * We'd like PNP to call this routine for the822 * single ISA_USED value for each legacy device.823 * But instead it calls us with each POSSIBLE setting.824 * There is no ISA_POSSIBLE weight, so we simply use825 * the (small) PCI_USING penalty.826 */827void acpi_penalize_isa_irq(int irq, int active)828{829 if ((irq >= 0) && (irq < ARRAY_SIZE(acpi_isa_irq_penalty)))830 acpi_isa_irq_penalty[irq] +=831 (active ? PIRQ_PENALTY_ISA_USED : PIRQ_PENALTY_PCI_USING);832}833 834bool acpi_isa_irq_available(int irq)835{836 return irq >= 0 && (irq >= ARRAY_SIZE(acpi_isa_irq_penalty) ||837 acpi_irq_get_penalty(irq) < PIRQ_PENALTY_ISA_ALWAYS);838}839 840void acpi_penalize_sci_irq(int irq, int trigger, int polarity)841{842 sci_irq = irq;843 844 if (trigger == ACPI_MADT_TRIGGER_LEVEL &&845 polarity == ACPI_MADT_POLARITY_ACTIVE_LOW)846 sci_penalty = PIRQ_PENALTY_PCI_USING;847 else848 sci_penalty = PIRQ_PENALTY_ISA_ALWAYS;849}850 851/*852 * Over-ride default table to reserve additional IRQs for use by ISA853 * e.g. acpi_irq_isa=5854 * Useful for telling ACPI how not to interfere with your ISA sound card.855 */856static int __init acpi_irq_isa(char *str)857{858 return acpi_irq_penalty_update(str, 1);859}860 861__setup("acpi_irq_isa=", acpi_irq_isa);862 863/*864 * Over-ride default table to free additional IRQs for use by PCI865 * e.g. acpi_irq_pci=7,15866 * Used for acpi_irq_balance to free up IRQs to reduce PCI IRQ sharing.867 */868static int __init acpi_irq_pci(char *str)869{870 return acpi_irq_penalty_update(str, 0);871}872 873__setup("acpi_irq_pci=", acpi_irq_pci);874 875static int __init acpi_irq_nobalance_set(char *str)876{877 acpi_irq_balance = 0;878 return 1;879}880 881__setup("acpi_irq_nobalance", acpi_irq_nobalance_set);882 883static int __init acpi_irq_balance_set(char *str)884{885 acpi_irq_balance = 1;886 return 1;887}888 889__setup("acpi_irq_balance", acpi_irq_balance_set);890 891static struct syscore_ops irqrouter_syscore_ops = {892 .resume = irqrouter_resume,893};894 895void __init acpi_pci_link_init(void)896{897 if (acpi_noirq)898 return;899 900 if (acpi_irq_balance == -1) {901 /* no command line switch: enable balancing in IOAPIC mode */902 if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)903 acpi_irq_balance = 1;904 else905 acpi_irq_balance = 0;906 }907 register_syscore_ops(&irqrouter_syscore_ops);908 acpi_scan_add_handler(&pci_link_handler);909}910