Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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