On 4/26/2016 2:36 PM, Bjorn Helgaas wrote: > On Sun, Apr 17, 2016 at 01:36:53PM -0400, Sinan Kaya wrote: >> Code has been redesigned to calculate penalty requirements on the fly. This >> significantly simplifies the implementation and removes some of the init >> calls from x86 architecture. >> >> Signed-off-by: Sinan Kaya <okaya@xxxxxxxxxxxxxx> > > For all four patches: > > Acked-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx> Thanks, can the HPE developers in CC test the series in order to avoid another revert? > >> --- >> drivers/acpi/pci_link.c | 97 ++++++++++++++++++++++++++++++++++--------------- >> 1 file changed, 68 insertions(+), 29 deletions(-) >> >> diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c >> index ededa90..cc0ba16 100644 >> --- a/drivers/acpi/pci_link.c >> +++ b/drivers/acpi/pci_link.c >> @@ -36,6 +36,7 @@ >> #include <linux/mutex.h> >> #include <linux/slab.h> >> #include <linux/acpi.h> >> +#include <linux/irq.h> >> >> #include "internal.h" >> >> @@ -440,7 +441,6 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq) >> #define ACPI_MAX_IRQS 256 >> #define ACPI_MAX_ISA_IRQ 16 >> >> -#define PIRQ_PENALTY_PCI_AVAILABLE (0) >> #define PIRQ_PENALTY_PCI_POSSIBLE (16*16) >> #define PIRQ_PENALTY_PCI_USING (16*16*16) >> #define PIRQ_PENALTY_ISA_TYPICAL (16*16*16*16) >> @@ -457,9 +457,9 @@ static int acpi_irq_penalty[ACPI_MAX_IRQS] = { >> PIRQ_PENALTY_ISA_TYPICAL, /* IRQ6 */ >> PIRQ_PENALTY_ISA_TYPICAL, /* IRQ7 parallel, spurious */ >> PIRQ_PENALTY_ISA_TYPICAL, /* IRQ8 rtc, sometimes */ >> - PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ9 PCI, often acpi */ >> - PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ10 PCI */ >> - PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ11 PCI */ >> + 0, /* IRQ9 PCI, often acpi */ >> + 0, /* IRQ10 PCI */ >> + 0, /* IRQ11 PCI */ >> PIRQ_PENALTY_ISA_USED, /* IRQ12 mouse */ >> PIRQ_PENALTY_ISA_USED, /* IRQ13 fpe, sometimes */ >> PIRQ_PENALTY_ISA_USED, /* IRQ14 ide0 */ >> @@ -467,6 +467,60 @@ static int acpi_irq_penalty[ACPI_MAX_IRQS] = { >> /* >IRQ15 */ >> }; >> >> +static int acpi_irq_pci_sharing_penalty(int irq) >> +{ >> + struct acpi_pci_link *link; >> + int penalty = 0; >> + >> + list_for_each_entry(link, &acpi_link_list, list) { >> + /* >> + * If a link is active, penalize its IRQ heavily >> + * so we try to choose a different 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; >> + } >> + } >> + >> + return penalty; >> +} >> + >> +static int acpi_irq_get_penalty(int irq) >> +{ >> + int penalty = 0; >> + >> + if (irq < ACPI_MAX_ISA_IRQ) >> + penalty += acpi_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 >> + * use for PCI IRQs. >> + */ >> + if (irq == acpi_gbl_FADT.sci_interrupt) { >> + u32 type = irq_get_trigger_type(irq) & IRQ_TYPE_SENSE_MASK; >> + >> + if (type != IRQ_TYPE_LEVEL_LOW) >> + penalty += PIRQ_PENALTY_ISA_ALWAYS; >> + else >> + penalty += PIRQ_PENALTY_PCI_USING; >> + } >> + >> + penalty += acpi_irq_pci_sharing_penalty(irq); >> + return penalty; >> +} >> + >> int __init acpi_irq_penalty_init(void) >> { >> struct acpi_pci_link *link; >> @@ -547,12 +601,12 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link) >> * the use of IRQs 9, 10, 11, and >15. >> */ >> for (i = (link->irq.possible_count - 1); i >= 0; i--) { >> - if (acpi_irq_penalty[irq] > >> - acpi_irq_penalty[link->irq.possible[i]]) >> + if (acpi_irq_get_penalty(irq) > >> + acpi_irq_get_penalty(link->irq.possible[i])) >> irq = link->irq.possible[i]; >> } >> } >> - if (acpi_irq_penalty[irq] >= PIRQ_PENALTY_ISA_ALWAYS) { >> + if (acpi_irq_get_penalty(irq) >= PIRQ_PENALTY_ISA_ALWAYS) { >> printk(KERN_ERR PREFIX "No IRQ available for %s [%s]. " >> "Try pci=noacpi or acpi=off\n", >> acpi_device_name(link->device), >> @@ -568,7 +622,6 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link) >> acpi_device_bid(link->device)); >> return -ENODEV; >> } else { >> - acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING; >> printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n", >> acpi_device_name(link->device), >> acpi_device_bid(link->device), link->irq.active); >> @@ -800,9 +853,10 @@ static int __init acpi_irq_penalty_update(char *str, int used) >> continue; >> >> if (used) >> - acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED; >> + acpi_irq_penalty[irq] = acpi_irq_get_penalty(irq) + >> + PIRQ_PENALTY_ISA_USED; >> else >> - acpi_irq_penalty[irq] = PIRQ_PENALTY_PCI_AVAILABLE; >> + acpi_irq_penalty[irq] = 0; >> >> if (retval != 2) /* no next number */ >> break; >> @@ -819,34 +873,19 @@ static int __init acpi_irq_penalty_update(char *str, int used) >> */ >> void acpi_penalize_isa_irq(int irq, int active) >> { >> - if (irq >= 0 && irq < ARRAY_SIZE(acpi_irq_penalty)) { >> - if (active) >> - acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED; >> - else >> - acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING; >> - } >> + if (irq >= 0 && irq < ARRAY_SIZE(acpi_irq_penalty)) >> + acpi_irq_penalty[irq] = acpi_irq_get_penalty(irq) + >> + active ? PIRQ_PENALTY_ISA_USED : PIRQ_PENALTY_PCI_USING; >> } >> >> bool acpi_isa_irq_available(int irq) >> { >> return irq >= 0 && (irq >= ARRAY_SIZE(acpi_irq_penalty) || >> - acpi_irq_penalty[irq] < PIRQ_PENALTY_ISA_ALWAYS); >> + acpi_irq_get_penalty(irq) < PIRQ_PENALTY_ISA_ALWAYS); >> } >> >> -/* >> - * 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 use for >> - * PCI IRQs. >> - */ >> void acpi_penalize_sci_irq(int irq, int trigger, int polarity) >> { >> - if (irq >= 0 && irq < ARRAY_SIZE(acpi_irq_penalty)) { >> - if (trigger != ACPI_MADT_TRIGGER_LEVEL || >> - polarity != ACPI_MADT_POLARITY_ACTIVE_LOW) >> - acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_ALWAYS; >> - else >> - acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING; >> - } >> } >> >> /* >> -- >> 1.8.2.1 >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-pci" in >> the body of a message to majordomo@xxxxxxxxxxxxxxx >> More majordomo info at http://vger.kernel.org/majordomo-info.html -- Sinan Kaya Qualcomm Technologies, Inc. on behalf of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html