2022-07-01 16:22:41

by Pierre Gondois

[permalink] [raw]
Subject: [PATCH v1 1/2] ACPI/PCI: Make _SRS optional for link device

From: Pierre Gondois <[email protected]>

In ACPI 6.4, s6.2.13 "_PRT (PCI Routing Table)", PCI legacy
interrupts can be described though a link device (first model).
From s6.2.16 "_SRS (Set Resource Settings)":
"This optional control method [...]"

Make it optional to have a _SRS method for link devices.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=215560
Signed-off-by: Pierre Gondois <[email protected]>
---
drivers/acpi/pci_link.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 58647051c948..129e3e7e80ee 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -288,6 +288,13 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
if (!irq)
return -EINVAL;

+ if (!acpi_has_method(handle, METHOD_NAME__SRS)) {
+ if (link->irq.active == irq)
+ return 0;
+ acpi_handle_err(handle, "Unable to set IRQ %d: No _SRS.\n", irq);
+ return -ENODEV;
+ }
+
resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
if (!resource)
return -ENOMEM;
--
2.25.1


2022-07-01 16:36:59

by Pierre Gondois

[permalink] [raw]
Subject: [PATCH v1 2/2] ACPI/PCI: Make _PRS optional for link device

From: Pierre Gondois <[email protected]>

In ACPI 6.4, s6.2.13 "_PRT (PCI Routing Table)", PCI legacy
interrupts can be described though a link device (first model).
From s6.2.12 "_PRS (Possible Resource Settings)":
"This optional object evaluates [...]"

It is currently checked that the interrupt advertised in _CRS
is one of the interrupts available in _PRS.
Make this check conditional to the presence of _PRS.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=215560
Signed-off-by: Pierre Gondois <[email protected]>
---
drivers/acpi/pci_link.c | 39 +++++++++++++++++++++++++--------------
1 file changed, 25 insertions(+), 14 deletions(-)

diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 129e3e7e80ee..b5a41866f135 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -532,19 +532,10 @@ int __init acpi_irq_penalty_init(void)

static int acpi_irq_balance = -1; /* 0: static, 1: balance */

-static int acpi_pci_link_allocate(struct acpi_pci_link *link)
+static int select_from_possible(struct acpi_pci_link *link)
{
- acpi_handle handle = link->device->handle;
- int irq;
int i;

- if (link->irq.initialized) {
- if (link->refcnt == 0)
- /* This means the link is disabled but initialized */
- acpi_pci_link_set(link, link->irq.active);
- return 0;
- }
-
/*
* search for active IRQ in list of possible IRQs.
*/
@@ -557,8 +548,9 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
*/
if (i == link->irq.possible_count) {
if (acpi_strict)
- acpi_handle_warn(handle, "_CRS %d not found in _PRS\n",
- link->irq.active);
+ acpi_handle_warn(link->device->handle,
+ "_CRS %d not found in _PRS\n",
+ link->irq.active);
link->irq.active = 0;
}

@@ -566,9 +558,28 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
* if active found, use it; else pick entry from end of possible list.
*/
if (link->irq.active)
- irq = link->irq.active;
+ return link->irq.active;
+ else
+ return link->irq.possible[link->irq.possible_count - 1];
+}
+
+static int acpi_pci_link_allocate(struct acpi_pci_link *link)
+{
+ acpi_handle handle = link->device->handle;
+ int irq;
+ int i;
+
+ if (link->irq.initialized) {
+ if (link->refcnt == 0)
+ /* This means the link is disabled but initialized */
+ acpi_pci_link_set(link, link->irq.active);
+ return 0;
+ }
+
+ if (link->irq.possible_count)
+ irq = select_from_possible(link);
else
- irq = link->irq.possible[link->irq.possible_count - 1];
+ irq = link->irq.active;

if (acpi_irq_balance || !link->irq.active) {
/*
--
2.25.1