mirror of https://gitee.com/openkylin/linux.git
ACPI fixes for v4.7-rc7
- Fix a lock ordering issue in ACPICA introduced by a recent commit that attempted to fix a deadlock in the dynamic table loading code which in turn appeared after changes related to the handling of module-level AML also made in this cycle (Lv Zheng). - Fix a recent regression in the ACPI IRQ management code that may cause PCI drivers to be unable to register an IRQ if that IRQ happens to be shared with a device on the ISA bus, like the parallel port, by reverting one commit entirely and restoring the previous behavior in two other places (Sinan Kaya). - Fix a recent regression in the ACPI AML debugger introduced by the commit that removed incorrect usage of IS_ERR_VALUE() from multiple places (Lv Zheng). -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABCAAGBQJXfuIeAAoJEILEb/54YlRxWbIP/iLT8J15RhFOoRYX4HXyULym UxeqEHVySKaqQLYhkBRz0opclW6sJQ7GaKYpVR31V4eeoll1+iQeYBYWdyuezjwp em3LvtLXTiLWWfRVNHg9AUOv4wc4q41m98MZ5ZScgTsUcexv2R1tt0KzLE/HNy1T NU/7JyWBEF4AiFsfYBuqtknWudV7JF3/siJO+Q1o+HSA9DW5cdqR0K9oM+Sl9pTD 3yLpVY8DNJGLSA/7MyJlyLmZ6eJmTQbxcLO7oCQliqJ9jjBKkC4r3fgfQcOcoltT S6O7ODcJwvqCA1sv271VyOckkhJmyT7zJi/L/yJOgiGRU1//0Vfyg6iRVou9OZmE VcQT79W+6W6saWucoNDX1CLm6GzLIHP2e6leooL710nNmtTUgrSc6C4FT1KGGs0R UTNPYKYtiaK54krsa48XonSCdGFIszeK8sa3DIjf6C/5AYX/eGBuGFm5dZlU/qzs BNv+GyT/Vt/Cu3cNJUrsMugwDL5sp31u44mfM1c99LMXmnwzkPylRGR1aaO4TYOy jE5LDwMryi5gpAF8/Es0AiU4Xa8O3p+AlD7PjZIUSEyMd9zr3fdpvF6dZwaiHP26 FX6paRbXi10mkXYGnRCbTOBV8i3PuNiplaZUT+XotHlEXOvAyMhVCVSM2XCAo1Wm 3IWSGzc5gwq1Pl4fihWi =vKn9 -----END PGP SIGNATURE----- Merge tag 'acpi-4.7-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull ACPI fixes from Rafael Wysocki: "All of these fix recent regressions in ACPICA, in the ACPI PCI IRQ management code and in the ACPI AML debugger. Specifics: - Fix a lock ordering issue in ACPICA introduced by a recent commit that attempted to fix a deadlock in the dynamic table loading code which in turn appeared after changes related to the handling of module-level AML also made in this cycle (Lv Zheng). - Fix a recent regression in the ACPI IRQ management code that may cause PCI drivers to be unable to register an IRQ if that IRQ happens to be shared with a device on the ISA bus, like the parallel port, by reverting one commit entirely and restoring the previous behavior in two other places (Sinan Kaya). - Fix a recent regression in the ACPI AML debugger introduced by the commit that removed incorrect usage of IS_ERR_VALUE() from multiple places (Lv Zheng)" * tag 'acpi-4.7-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: ACPI / debugger: Fix regression introduced by IS_ERR_VALUE() removal ACPICA: Namespace: Fix namespace/interpreter lock ordering ACPI,PCI,IRQ: separate ISA penalty calculation Revert "ACPI, PCI, IRQ: remove redundant code in acpi_irq_penalty_init()" ACPI,PCI,IRQ: factor in PCI possible
This commit is contained in:
commit
7ed18e2d1b
|
@ -396,6 +396,7 @@ int __init pci_acpi_init(void)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
|
printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
|
||||||
|
acpi_irq_penalty_init();
|
||||||
pcibios_enable_irq = acpi_pci_irq_enable;
|
pcibios_enable_irq = acpi_pci_irq_enable;
|
||||||
pcibios_disable_irq = acpi_pci_irq_disable;
|
pcibios_disable_irq = acpi_pci_irq_disable;
|
||||||
x86_init.pci.init_irq = x86_init_noop;
|
x86_init.pci.init_irq = x86_init_noop;
|
||||||
|
|
|
@ -602,7 +602,7 @@ static int acpi_aml_read_user(char __user *buf, int len)
|
||||||
crc->tail = (crc->tail + n) & (ACPI_AML_BUF_SIZE - 1);
|
crc->tail = (crc->tail + n) & (ACPI_AML_BUF_SIZE - 1);
|
||||||
ret = n;
|
ret = n;
|
||||||
out:
|
out:
|
||||||
acpi_aml_unlock_fifo(ACPI_AML_OUT_USER, !ret);
|
acpi_aml_unlock_fifo(ACPI_AML_OUT_USER, ret >= 0);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -672,7 +672,7 @@ static int acpi_aml_write_user(const char __user *buf, int len)
|
||||||
crc->head = (crc->head + n) & (ACPI_AML_BUF_SIZE - 1);
|
crc->head = (crc->head + n) & (ACPI_AML_BUF_SIZE - 1);
|
||||||
ret = n;
|
ret = n;
|
||||||
out:
|
out:
|
||||||
acpi_aml_unlock_fifo(ACPI_AML_IN_USER, !ret);
|
acpi_aml_unlock_fifo(ACPI_AML_IN_USER, ret >= 0);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include "acnamesp.h"
|
#include "acnamesp.h"
|
||||||
#include "acdispat.h"
|
#include "acdispat.h"
|
||||||
#include "actables.h"
|
#include "actables.h"
|
||||||
|
#include "acinterp.h"
|
||||||
|
|
||||||
#define _COMPONENT ACPI_NAMESPACE
|
#define _COMPONENT ACPI_NAMESPACE
|
||||||
ACPI_MODULE_NAME("nsload")
|
ACPI_MODULE_NAME("nsload")
|
||||||
|
@ -78,6 +79,8 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ns_load_table);
|
ACPI_FUNCTION_TRACE(ns_load_table);
|
||||||
|
|
||||||
|
acpi_ex_enter_interpreter();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse the table and load the namespace with all named
|
* Parse the table and load the namespace with all named
|
||||||
* objects found within. Control methods are NOT parsed
|
* objects found within. Control methods are NOT parsed
|
||||||
|
@ -89,7 +92,7 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)
|
||||||
*/
|
*/
|
||||||
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
|
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status)) {
|
||||||
return_ACPI_STATUS(status);
|
goto unlock_interp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If table already loaded into namespace, just return */
|
/* If table already loaded into namespace, just return */
|
||||||
|
@ -130,6 +133,8 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
|
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
|
||||||
|
unlock_interp:
|
||||||
|
(void)acpi_ex_exit_interpreter();
|
||||||
|
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status)) {
|
||||||
return_ACPI_STATUS(status);
|
return_ACPI_STATUS(status);
|
||||||
|
|
|
@ -47,7 +47,6 @@
|
||||||
#include "acparser.h"
|
#include "acparser.h"
|
||||||
#include "acdispat.h"
|
#include "acdispat.h"
|
||||||
#include "actables.h"
|
#include "actables.h"
|
||||||
#include "acinterp.h"
|
|
||||||
|
|
||||||
#define _COMPONENT ACPI_NAMESPACE
|
#define _COMPONENT ACPI_NAMESPACE
|
||||||
ACPI_MODULE_NAME("nsparse")
|
ACPI_MODULE_NAME("nsparse")
|
||||||
|
@ -171,8 +170,6 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ns_parse_table);
|
ACPI_FUNCTION_TRACE(ns_parse_table);
|
||||||
|
|
||||||
acpi_ex_enter_interpreter();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AML Parse, pass 1
|
* AML Parse, pass 1
|
||||||
*
|
*
|
||||||
|
@ -188,7 +185,7 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
|
||||||
status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1,
|
status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1,
|
||||||
table_index, start_node);
|
table_index, start_node);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status)) {
|
||||||
goto error_exit;
|
return_ACPI_STATUS(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -204,10 +201,8 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
|
||||||
status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2,
|
status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2,
|
||||||
table_index, start_node);
|
table_index, start_node);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status)) {
|
||||||
goto error_exit;
|
return_ACPI_STATUS(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
error_exit:
|
|
||||||
acpi_ex_exit_interpreter();
|
|
||||||
return_ACPI_STATUS(status);
|
return_ACPI_STATUS(status);
|
||||||
}
|
}
|
||||||
|
|
|
@ -470,6 +470,7 @@ static int acpi_irq_pci_sharing_penalty(int irq)
|
||||||
{
|
{
|
||||||
struct acpi_pci_link *link;
|
struct acpi_pci_link *link;
|
||||||
int penalty = 0;
|
int penalty = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
list_for_each_entry(link, &acpi_link_list, list) {
|
list_for_each_entry(link, &acpi_link_list, list) {
|
||||||
/*
|
/*
|
||||||
|
@ -478,18 +479,14 @@ static int acpi_irq_pci_sharing_penalty(int irq)
|
||||||
*/
|
*/
|
||||||
if (link->irq.active && link->irq.active == irq)
|
if (link->irq.active && link->irq.active == irq)
|
||||||
penalty += PIRQ_PENALTY_PCI_USING;
|
penalty += PIRQ_PENALTY_PCI_USING;
|
||||||
else {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If a link is inactive, penalize the IRQs it
|
* penalize the IRQs PCI might use, but not as severely.
|
||||||
* might use, but not as severely.
|
*/
|
||||||
*/
|
for (i = 0; i < link->irq.possible_count; i++)
|
||||||
for (i = 0; i < link->irq.possible_count; i++)
|
if (link->irq.possible[i] == irq)
|
||||||
if (link->irq.possible[i] == irq)
|
penalty += PIRQ_PENALTY_PCI_POSSIBLE /
|
||||||
penalty += PIRQ_PENALTY_PCI_POSSIBLE /
|
link->irq.possible_count;
|
||||||
link->irq.possible_count;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return penalty;
|
return penalty;
|
||||||
|
@ -499,9 +496,6 @@ static int acpi_irq_get_penalty(int irq)
|
||||||
{
|
{
|
||||||
int penalty = 0;
|
int penalty = 0;
|
||||||
|
|
||||||
if (irq < ACPI_MAX_ISA_IRQS)
|
|
||||||
penalty += acpi_isa_irq_penalty[irq];
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Penalize IRQ used by ACPI SCI. If ACPI SCI pin attributes conflict
|
* Penalize IRQ used by ACPI SCI. If ACPI SCI pin attributes conflict
|
||||||
* with PCI IRQ attributes, mark ACPI SCI as ISA_ALWAYS so it won't be
|
* with PCI IRQ attributes, mark ACPI SCI as ISA_ALWAYS so it won't be
|
||||||
|
@ -516,10 +510,49 @@ static int acpi_irq_get_penalty(int irq)
|
||||||
penalty += PIRQ_PENALTY_PCI_USING;
|
penalty += PIRQ_PENALTY_PCI_USING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (irq < ACPI_MAX_ISA_IRQS)
|
||||||
|
return penalty + acpi_isa_irq_penalty[irq];
|
||||||
|
|
||||||
penalty += acpi_irq_pci_sharing_penalty(irq);
|
penalty += acpi_irq_pci_sharing_penalty(irq);
|
||||||
return penalty;
|
return penalty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __init acpi_irq_penalty_init(void)
|
||||||
|
{
|
||||||
|
struct acpi_pci_link *link;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update penalties to facilitate IRQ balancing.
|
||||||
|
*/
|
||||||
|
list_for_each_entry(link, &acpi_link_list, list) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reflect the possible and active irqs in the penalty table --
|
||||||
|
* useful for breaking ties.
|
||||||
|
*/
|
||||||
|
if (link->irq.possible_count) {
|
||||||
|
int penalty =
|
||||||
|
PIRQ_PENALTY_PCI_POSSIBLE /
|
||||||
|
link->irq.possible_count;
|
||||||
|
|
||||||
|
for (i = 0; i < link->irq.possible_count; i++) {
|
||||||
|
if (link->irq.possible[i] < ACPI_MAX_ISA_IRQS)
|
||||||
|
acpi_isa_irq_penalty[link->irq.
|
||||||
|
possible[i]] +=
|
||||||
|
penalty;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (link->irq.active &&
|
||||||
|
(link->irq.active < ACPI_MAX_ISA_IRQS)) {
|
||||||
|
acpi_isa_irq_penalty[link->irq.active] +=
|
||||||
|
PIRQ_PENALTY_PCI_POSSIBLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int acpi_irq_balance = -1; /* 0: static, 1: balance */
|
static int acpi_irq_balance = -1; /* 0: static, 1: balance */
|
||||||
|
|
||||||
static int acpi_pci_link_allocate(struct acpi_pci_link *link)
|
static int acpi_pci_link_allocate(struct acpi_pci_link *link)
|
||||||
|
|
|
@ -78,6 +78,7 @@
|
||||||
|
|
||||||
/* ACPI PCI Interrupt Link (pci_link.c) */
|
/* ACPI PCI Interrupt Link (pci_link.c) */
|
||||||
|
|
||||||
|
int acpi_irq_penalty_init(void);
|
||||||
int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering,
|
int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering,
|
||||||
int *polarity, char **name);
|
int *polarity, char **name);
|
||||||
int acpi_pci_link_free_irq(acpi_handle handle);
|
int acpi_pci_link_free_irq(acpi_handle handle);
|
||||||
|
|
Loading…
Reference in New Issue