diff options
Diffstat (limited to 'drivers/acpi/pci_link.c')
| -rw-r--r-- | drivers/acpi/pci_link.c | 38 | 
1 files changed, 21 insertions, 17 deletions
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index c983bf733ad3..bc3d914dfc3e 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -87,6 +87,7 @@ struct acpi_pci_link {  static LIST_HEAD(acpi_link_list);  static DEFINE_MUTEX(acpi_link_lock); +static int sci_irq = -1, sci_penalty;  /* --------------------------------------------------------------------------                              PCI Link Device Management @@ -496,25 +497,13 @@ static int acpi_irq_get_penalty(int irq)  {  	int penalty = 0; -	/* -	* 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; -	} +	if (irq == sci_irq) +		penalty += sci_penalty;  	if (irq < ACPI_MAX_ISA_IRQS)  		return penalty + acpi_isa_irq_penalty[irq]; -	penalty += acpi_irq_pci_sharing_penalty(irq); -	return penalty; +	return penalty + acpi_irq_pci_sharing_penalty(irq);  }  int __init acpi_irq_penalty_init(void) @@ -619,6 +608,10 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)  			    acpi_device_bid(link->device));  		return -ENODEV;  	} else { +		if (link->irq.active < ACPI_MAX_ISA_IRQS) +			acpi_isa_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); @@ -849,7 +842,7 @@ static int __init acpi_irq_penalty_update(char *str, int used)  			continue;  		if (used) -			new_penalty = acpi_irq_get_penalty(irq) + +			new_penalty = acpi_isa_irq_penalty[irq] +  					PIRQ_PENALTY_ISA_USED;  		else  			new_penalty = 0; @@ -871,7 +864,7 @@ 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_isa_irq_penalty))) -		acpi_isa_irq_penalty[irq] = acpi_irq_get_penalty(irq) + +		acpi_isa_irq_penalty[irq] +=  		  (active ? PIRQ_PENALTY_ISA_USED : PIRQ_PENALTY_PCI_USING);  } @@ -881,6 +874,17 @@ bool acpi_isa_irq_available(int irq)  		    acpi_irq_get_penalty(irq) < PIRQ_PENALTY_ISA_ALWAYS);  } +void acpi_penalize_sci_irq(int irq, int trigger, int polarity) +{ +	sci_irq = irq; + +	if (trigger == ACPI_MADT_TRIGGER_LEVEL && +	    polarity == ACPI_MADT_POLARITY_ACTIVE_LOW) +		sci_penalty = PIRQ_PENALTY_PCI_USING; +	else +		sci_penalty = PIRQ_PENALTY_ISA_ALWAYS; +} +  /*   * Over-ride default table to reserve additional IRQs for use by ISA   * e.g. acpi_irq_isa=5  |