Skip to content

Commit

Permalink
Merge tag 'acpi-4.7-rc7' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/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
  • Loading branch information
torvalds committed Jul 8, 2016
2 parents c09230f + b6d9015 commit 7ed18e2
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 25 deletions.
1 change: 1 addition & 0 deletions arch/x86/pci/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,7 @@ int __init pci_acpi_init(void)
return -ENODEV;

printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
acpi_irq_penalty_init();
pcibios_enable_irq = acpi_pci_irq_enable;
pcibios_disable_irq = acpi_pci_irq_disable;
x86_init.pci.init_irq = x86_init_noop;
Expand Down
4 changes: 2 additions & 2 deletions drivers/acpi/acpi_dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
ret = n;
out:
acpi_aml_unlock_fifo(ACPI_AML_OUT_USER, !ret);
acpi_aml_unlock_fifo(ACPI_AML_OUT_USER, ret >= 0);
return ret;
}

Expand Down Expand Up @@ -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);
ret = n;
out:
acpi_aml_unlock_fifo(ACPI_AML_IN_USER, !ret);
acpi_aml_unlock_fifo(ACPI_AML_IN_USER, ret >= 0);
return n;
}

Expand Down
7 changes: 6 additions & 1 deletion drivers/acpi/acpica/nsload.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "acnamesp.h"
#include "acdispat.h"
#include "actables.h"
#include "acinterp.h"

#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME("nsload")
Expand Down Expand Up @@ -78,6 +79,8 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)

ACPI_FUNCTION_TRACE(ns_load_table);

acpi_ex_enter_interpreter();

/*
* Parse the table and load the namespace with all named
* objects found within. Control methods are NOT parsed
Expand All @@ -89,7 +92,7 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)
*/
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
goto unlock_interp;
}

/* If table already loaded into namespace, just return */
Expand Down Expand Up @@ -130,6 +133,8 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)

unlock:
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
unlock_interp:
(void)acpi_ex_exit_interpreter();

if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
Expand Down
9 changes: 2 additions & 7 deletions drivers/acpi/acpica/nsparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
#include "acparser.h"
#include "acdispat.h"
#include "actables.h"
#include "acinterp.h"

#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME("nsparse")
Expand Down Expand Up @@ -171,8 +170,6 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)

ACPI_FUNCTION_TRACE(ns_parse_table);

acpi_ex_enter_interpreter();

/*
* AML Parse, pass 1
*
Expand All @@ -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,
table_index, start_node);
if (ACPI_FAILURE(status)) {
goto error_exit;
return_ACPI_STATUS(status);
}

/*
Expand All @@ -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,
table_index, start_node);
if (ACPI_FAILURE(status)) {
goto error_exit;
return_ACPI_STATUS(status);
}

error_exit:
acpi_ex_exit_interpreter();
return_ACPI_STATUS(status);
}
63 changes: 48 additions & 15 deletions drivers/acpi/pci_link.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,7 @@ static int acpi_irq_pci_sharing_penalty(int irq)
{
struct acpi_pci_link *link;
int penalty = 0;
int i;

list_for_each_entry(link, &acpi_link_list, list) {
/*
Expand All @@ -478,18 +479,14 @@ static int acpi_irq_pci_sharing_penalty(int irq)
*/
if (link->irq.active && link->irq.active == irq)
penalty += PIRQ_PENALTY_PCI_USING;
else {
int i;

/*
* If a link is inactive, penalize the IRQs it
* might use, but not as severely.
*/
for (i = 0; i < link->irq.possible_count; i++)
if (link->irq.possible[i] == irq)
penalty += PIRQ_PENALTY_PCI_POSSIBLE /
link->irq.possible_count;
}

/*
* penalize the IRQs PCI might use, but not as severely.
*/
for (i = 0; i < link->irq.possible_count; i++)
if (link->irq.possible[i] == irq)
penalty += PIRQ_PENALTY_PCI_POSSIBLE /
link->irq.possible_count;
}

return penalty;
Expand All @@ -499,9 +496,6 @@ static int acpi_irq_get_penalty(int irq)
{
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
* with PCI IRQ attributes, mark ACPI SCI as ISA_ALWAYS so it won't be
Expand All @@ -516,10 +510,49 @@ static int acpi_irq_get_penalty(int irq)
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);
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_pci_link_allocate(struct acpi_pci_link *link)
Expand Down
1 change: 1 addition & 0 deletions include/acpi/acpi_drivers.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@

/* 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 *polarity, char **name);
int acpi_pci_link_free_irq(acpi_handle handle);
Expand Down

0 comments on commit 7ed18e2

Please sign in to comment.