Revert "ACPI, PCI, irq: remove interrupt count restriction"
Revert commit b5bd02695471 (ACPI, PCI, irq: remove interrupt count restriction) that introduced a boot regression on some systems where it caused kmalloc() to be used too early. Link: http://marc.info/?l=linux-acpi&m=145580159209240&w=2 Reported-by: Nalla, Ravikanth <ravikanth.nalla@hpe.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
5ec5d10682
commit
e249714571
@ -4,7 +4,6 @@
|
|||||||
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
|
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
|
||||||
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
|
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
|
||||||
* Copyright (C) 2002 Dominik Brodowski <devel@brodo.de>
|
* Copyright (C) 2002 Dominik Brodowski <devel@brodo.de>
|
||||||
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
|
||||||
*
|
*
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
*
|
*
|
||||||
@ -438,6 +437,7 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
|
|||||||
* enabled system.
|
* enabled system.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define ACPI_MAX_IRQS 256
|
||||||
#define ACPI_MAX_ISA_IRQ 16
|
#define ACPI_MAX_ISA_IRQ 16
|
||||||
|
|
||||||
#define PIRQ_PENALTY_PCI_AVAILABLE (0)
|
#define PIRQ_PENALTY_PCI_AVAILABLE (0)
|
||||||
@ -447,7 +447,7 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
|
|||||||
#define PIRQ_PENALTY_ISA_USED (16*16*16*16*16)
|
#define PIRQ_PENALTY_ISA_USED (16*16*16*16*16)
|
||||||
#define PIRQ_PENALTY_ISA_ALWAYS (16*16*16*16*16*16)
|
#define PIRQ_PENALTY_ISA_ALWAYS (16*16*16*16*16*16)
|
||||||
|
|
||||||
static int acpi_irq_isa_penalty[ACPI_MAX_ISA_IRQ] = {
|
static int acpi_irq_penalty[ACPI_MAX_IRQS] = {
|
||||||
PIRQ_PENALTY_ISA_ALWAYS, /* IRQ0 timer */
|
PIRQ_PENALTY_ISA_ALWAYS, /* IRQ0 timer */
|
||||||
PIRQ_PENALTY_ISA_ALWAYS, /* IRQ1 keyboard */
|
PIRQ_PENALTY_ISA_ALWAYS, /* IRQ1 keyboard */
|
||||||
PIRQ_PENALTY_ISA_ALWAYS, /* IRQ2 cascade */
|
PIRQ_PENALTY_ISA_ALWAYS, /* IRQ2 cascade */
|
||||||
@ -464,68 +464,9 @@ static int acpi_irq_isa_penalty[ACPI_MAX_ISA_IRQ] = {
|
|||||||
PIRQ_PENALTY_ISA_USED, /* IRQ13 fpe, sometimes */
|
PIRQ_PENALTY_ISA_USED, /* IRQ13 fpe, sometimes */
|
||||||
PIRQ_PENALTY_ISA_USED, /* IRQ14 ide0 */
|
PIRQ_PENALTY_ISA_USED, /* IRQ14 ide0 */
|
||||||
PIRQ_PENALTY_ISA_USED, /* IRQ15 ide1 */
|
PIRQ_PENALTY_ISA_USED, /* IRQ15 ide1 */
|
||||||
|
/* >IRQ15 */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct irq_penalty_info {
|
|
||||||
int irq;
|
|
||||||
int penalty;
|
|
||||||
struct list_head node;
|
|
||||||
};
|
|
||||||
|
|
||||||
static LIST_HEAD(acpi_irq_penalty_list);
|
|
||||||
|
|
||||||
static int acpi_irq_get_penalty(int irq)
|
|
||||||
{
|
|
||||||
struct irq_penalty_info *irq_info;
|
|
||||||
|
|
||||||
if (irq < ACPI_MAX_ISA_IRQ)
|
|
||||||
return acpi_irq_isa_penalty[irq];
|
|
||||||
|
|
||||||
list_for_each_entry(irq_info, &acpi_irq_penalty_list, node) {
|
|
||||||
if (irq_info->irq == irq)
|
|
||||||
return irq_info->penalty;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int acpi_irq_set_penalty(int irq, int new_penalty)
|
|
||||||
{
|
|
||||||
struct irq_penalty_info *irq_info;
|
|
||||||
|
|
||||||
/* see if this is a ISA IRQ */
|
|
||||||
if (irq < ACPI_MAX_ISA_IRQ) {
|
|
||||||
acpi_irq_isa_penalty[irq] = new_penalty;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* next, try to locate from the dynamic list */
|
|
||||||
list_for_each_entry(irq_info, &acpi_irq_penalty_list, node) {
|
|
||||||
if (irq_info->irq == irq) {
|
|
||||||
irq_info->penalty = new_penalty;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* nope, let's allocate a slot for this IRQ */
|
|
||||||
irq_info = kzalloc(sizeof(*irq_info), GFP_KERNEL);
|
|
||||||
if (!irq_info)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
irq_info->irq = irq;
|
|
||||||
irq_info->penalty = new_penalty;
|
|
||||||
list_add_tail(&irq_info->node, &acpi_irq_penalty_list);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void acpi_irq_add_penalty(int irq, int penalty)
|
|
||||||
{
|
|
||||||
int curpen = acpi_irq_get_penalty(irq);
|
|
||||||
|
|
||||||
acpi_irq_set_penalty(irq, curpen + penalty);
|
|
||||||
}
|
|
||||||
|
|
||||||
int __init acpi_irq_penalty_init(void)
|
int __init acpi_irq_penalty_init(void)
|
||||||
{
|
{
|
||||||
struct acpi_pci_link *link;
|
struct acpi_pci_link *link;
|
||||||
@ -546,16 +487,15 @@ int __init acpi_irq_penalty_init(void)
|
|||||||
link->irq.possible_count;
|
link->irq.possible_count;
|
||||||
|
|
||||||
for (i = 0; i < link->irq.possible_count; i++) {
|
for (i = 0; i < link->irq.possible_count; i++) {
|
||||||
if (link->irq.possible[i] < ACPI_MAX_ISA_IRQ) {
|
if (link->irq.possible[i] < ACPI_MAX_ISA_IRQ)
|
||||||
int irqpos = link->irq.possible[i];
|
acpi_irq_penalty[link->irq.
|
||||||
|
possible[i]] +=
|
||||||
acpi_irq_add_penalty(irqpos, penalty);
|
penalty;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (link->irq.active) {
|
} else if (link->irq.active) {
|
||||||
acpi_irq_add_penalty(link->irq.active,
|
acpi_irq_penalty[link->irq.active] +=
|
||||||
PIRQ_PENALTY_PCI_POSSIBLE);
|
PIRQ_PENALTY_PCI_POSSIBLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -607,12 +547,12 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
|
|||||||
* the use of IRQs 9, 10, 11, and >15.
|
* the use of IRQs 9, 10, 11, and >15.
|
||||||
*/
|
*/
|
||||||
for (i = (link->irq.possible_count - 1); i >= 0; i--) {
|
for (i = (link->irq.possible_count - 1); i >= 0; i--) {
|
||||||
if (acpi_irq_get_penalty(irq) >
|
if (acpi_irq_penalty[irq] >
|
||||||
acpi_irq_get_penalty(link->irq.possible[i]))
|
acpi_irq_penalty[link->irq.possible[i]])
|
||||||
irq = link->irq.possible[i];
|
irq = link->irq.possible[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (acpi_irq_get_penalty(irq) >= PIRQ_PENALTY_ISA_ALWAYS) {
|
if (acpi_irq_penalty[irq] >= PIRQ_PENALTY_ISA_ALWAYS) {
|
||||||
printk(KERN_ERR PREFIX "No IRQ available for %s [%s]. "
|
printk(KERN_ERR PREFIX "No IRQ available for %s [%s]. "
|
||||||
"Try pci=noacpi or acpi=off\n",
|
"Try pci=noacpi or acpi=off\n",
|
||||||
acpi_device_name(link->device),
|
acpi_device_name(link->device),
|
||||||
@ -628,8 +568,7 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
|
|||||||
acpi_device_bid(link->device));
|
acpi_device_bid(link->device));
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} else {
|
} else {
|
||||||
acpi_irq_add_penalty(link->irq.active, PIRQ_PENALTY_PCI_USING);
|
acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING;
|
||||||
|
|
||||||
printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n",
|
printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n",
|
||||||
acpi_device_name(link->device),
|
acpi_device_name(link->device),
|
||||||
acpi_device_bid(link->device), link->irq.active);
|
acpi_device_bid(link->device), link->irq.active);
|
||||||
@ -839,7 +778,7 @@ static void acpi_pci_link_remove(struct acpi_device *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* modify penalty from cmdline
|
* modify acpi_irq_penalty[] from cmdline
|
||||||
*/
|
*/
|
||||||
static int __init acpi_irq_penalty_update(char *str, int used)
|
static int __init acpi_irq_penalty_update(char *str, int used)
|
||||||
{
|
{
|
||||||
@ -857,10 +796,13 @@ static int __init acpi_irq_penalty_update(char *str, int used)
|
|||||||
if (irq < 0)
|
if (irq < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (irq >= ARRAY_SIZE(acpi_irq_penalty))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (used)
|
if (used)
|
||||||
acpi_irq_add_penalty(irq, PIRQ_PENALTY_ISA_USED);
|
acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED;
|
||||||
else
|
else
|
||||||
acpi_irq_set_penalty(irq, PIRQ_PENALTY_PCI_AVAILABLE);
|
acpi_irq_penalty[irq] = PIRQ_PENALTY_PCI_AVAILABLE;
|
||||||
|
|
||||||
if (retval != 2) /* no next number */
|
if (retval != 2) /* no next number */
|
||||||
break;
|
break;
|
||||||
@ -877,23 +819,18 @@ static int __init acpi_irq_penalty_update(char *str, int used)
|
|||||||
*/
|
*/
|
||||||
void acpi_penalize_isa_irq(int irq, int active)
|
void acpi_penalize_isa_irq(int irq, int active)
|
||||||
{
|
{
|
||||||
int penalty;
|
if (irq >= 0 && irq < ARRAY_SIZE(acpi_irq_penalty)) {
|
||||||
|
if (active)
|
||||||
if (irq < 0)
|
acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED;
|
||||||
return;
|
else
|
||||||
|
acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING;
|
||||||
if (active)
|
}
|
||||||
penalty = PIRQ_PENALTY_ISA_USED;
|
|
||||||
else
|
|
||||||
penalty = PIRQ_PENALTY_PCI_USING;
|
|
||||||
|
|
||||||
acpi_irq_add_penalty(irq, penalty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool acpi_isa_irq_available(int irq)
|
bool acpi_isa_irq_available(int irq)
|
||||||
{
|
{
|
||||||
return irq >= 0 &&
|
return irq >= 0 && (irq >= ARRAY_SIZE(acpi_irq_penalty) ||
|
||||||
(acpi_irq_get_penalty(irq) < PIRQ_PENALTY_ISA_ALWAYS);
|
acpi_irq_penalty[irq] < PIRQ_PENALTY_ISA_ALWAYS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -903,18 +840,13 @@ bool acpi_isa_irq_available(int irq)
|
|||||||
*/
|
*/
|
||||||
void acpi_penalize_sci_irq(int irq, int trigger, int polarity)
|
void acpi_penalize_sci_irq(int irq, int trigger, int polarity)
|
||||||
{
|
{
|
||||||
int penalty;
|
if (irq >= 0 && irq < ARRAY_SIZE(acpi_irq_penalty)) {
|
||||||
|
if (trigger != ACPI_MADT_TRIGGER_LEVEL ||
|
||||||
if (irq < 0)
|
polarity != ACPI_MADT_POLARITY_ACTIVE_LOW)
|
||||||
return;
|
acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_ALWAYS;
|
||||||
|
else
|
||||||
if (trigger != ACPI_MADT_TRIGGER_LEVEL ||
|
acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING;
|
||||||
polarity != ACPI_MADT_POLARITY_ACTIVE_LOW)
|
}
|
||||||
penalty = PIRQ_PENALTY_ISA_ALWAYS;
|
|
||||||
else
|
|
||||||
penalty = PIRQ_PENALTY_PCI_USING;
|
|
||||||
|
|
||||||
acpi_irq_add_penalty(irq, penalty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user