36
36
#include <linux/mutex.h>
37
37
#include <linux/slab.h>
38
38
#include <linux/acpi.h>
39
+ #include <linux/irq.h>
39
40
40
41
#include "internal.h"
41
42
@@ -440,7 +441,6 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
440
441
#define ACPI_MAX_IRQS 256
441
442
#define ACPI_MAX_ISA_IRQ 16
442
443
443
- #define PIRQ_PENALTY_PCI_AVAILABLE (0)
444
444
#define PIRQ_PENALTY_PCI_POSSIBLE (16*16)
445
445
#define PIRQ_PENALTY_PCI_USING (16*16*16)
446
446
#define PIRQ_PENALTY_ISA_TYPICAL (16*16*16*16)
@@ -457,16 +457,70 @@ static int acpi_irq_penalty[ACPI_MAX_IRQS] = {
457
457
PIRQ_PENALTY_ISA_TYPICAL , /* IRQ6 */
458
458
PIRQ_PENALTY_ISA_TYPICAL , /* IRQ7 parallel, spurious */
459
459
PIRQ_PENALTY_ISA_TYPICAL , /* IRQ8 rtc, sometimes */
460
- PIRQ_PENALTY_PCI_AVAILABLE , /* IRQ9 PCI, often acpi */
461
- PIRQ_PENALTY_PCI_AVAILABLE , /* IRQ10 PCI */
462
- PIRQ_PENALTY_PCI_AVAILABLE , /* IRQ11 PCI */
460
+ 0 , /* IRQ9 PCI, often acpi */
461
+ 0 , /* IRQ10 PCI */
462
+ 0 , /* IRQ11 PCI */
463
463
PIRQ_PENALTY_ISA_USED , /* IRQ12 mouse */
464
464
PIRQ_PENALTY_ISA_USED , /* IRQ13 fpe, sometimes */
465
465
PIRQ_PENALTY_ISA_USED , /* IRQ14 ide0 */
466
466
PIRQ_PENALTY_ISA_USED , /* IRQ15 ide1 */
467
467
/* >IRQ15 */
468
468
};
469
469
470
+ static int acpi_irq_pci_sharing_penalty (int irq )
471
+ {
472
+ struct acpi_pci_link * link ;
473
+ int penalty = 0 ;
474
+
475
+ list_for_each_entry (link , & acpi_link_list , list ) {
476
+ /*
477
+ * If a link is active, penalize its IRQ heavily
478
+ * so we try to choose a different IRQ.
479
+ */
480
+ if (link -> irq .active && link -> irq .active == irq )
481
+ penalty += PIRQ_PENALTY_PCI_USING ;
482
+ else {
483
+ int i ;
484
+
485
+ /*
486
+ * If a link is inactive, penalize the IRQs it
487
+ * might use, but not as severely.
488
+ */
489
+ for (i = 0 ; i < link -> irq .possible_count ; i ++ )
490
+ if (link -> irq .possible [i ] == irq )
491
+ penalty += PIRQ_PENALTY_PCI_POSSIBLE /
492
+ link -> irq .possible_count ;
493
+ }
494
+ }
495
+
496
+ return penalty ;
497
+ }
498
+
499
+ static int acpi_irq_get_penalty (int irq )
500
+ {
501
+ int penalty = 0 ;
502
+
503
+ if (irq < ACPI_MAX_ISA_IRQ )
504
+ penalty += acpi_irq_penalty [irq ];
505
+
506
+ /*
507
+ * Penalize IRQ used by ACPI SCI. If ACPI SCI pin attributes conflict
508
+ * with PCI IRQ attributes, mark ACPI SCI as ISA_ALWAYS so it won't be
509
+ * use for PCI IRQs.
510
+ */
511
+ if (irq == acpi_gbl_FADT .sci_interrupt ) {
512
+ u32 type = irq_get_trigger_type (irq ) & IRQ_TYPE_SENSE_MASK ;
513
+
514
+ if (type != IRQ_TYPE_LEVEL_LOW )
515
+ penalty += PIRQ_PENALTY_ISA_ALWAYS ;
516
+ else
517
+ penalty += PIRQ_PENALTY_PCI_USING ;
518
+ }
519
+
520
+ penalty += acpi_irq_pci_sharing_penalty (irq );
521
+ return penalty ;
522
+ }
523
+
470
524
int __init acpi_irq_penalty_init (void )
471
525
{
472
526
struct acpi_pci_link * link ;
@@ -547,12 +601,12 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
547
601
* the use of IRQs 9, 10, 11, and >15.
548
602
*/
549
603
for (i = (link -> irq .possible_count - 1 ); i >= 0 ; i -- ) {
550
- if (acpi_irq_penalty [ irq ] >
551
- acpi_irq_penalty [ link -> irq .possible [i ]] )
604
+ if (acpi_irq_get_penalty ( irq ) >
605
+ acpi_irq_get_penalty ( link -> irq .possible [i ]) )
552
606
irq = link -> irq .possible [i ];
553
607
}
554
608
}
555
- if (acpi_irq_penalty [ irq ] >= PIRQ_PENALTY_ISA_ALWAYS ) {
609
+ if (acpi_irq_get_penalty ( irq ) >= PIRQ_PENALTY_ISA_ALWAYS ) {
556
610
printk (KERN_ERR PREFIX "No IRQ available for %s [%s]. "
557
611
"Try pci=noacpi or acpi=off\n" ,
558
612
acpi_device_name (link -> device ),
@@ -568,7 +622,6 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
568
622
acpi_device_bid (link -> device ));
569
623
return - ENODEV ;
570
624
} else {
571
- acpi_irq_penalty [link -> irq .active ] += PIRQ_PENALTY_PCI_USING ;
572
625
printk (KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n" ,
573
626
acpi_device_name (link -> device ),
574
627
acpi_device_bid (link -> device ), link -> irq .active );
@@ -800,9 +853,10 @@ static int __init acpi_irq_penalty_update(char *str, int used)
800
853
continue ;
801
854
802
855
if (used )
803
- acpi_irq_penalty [irq ] += PIRQ_PENALTY_ISA_USED ;
856
+ acpi_irq_penalty [irq ] = acpi_irq_get_penalty (irq ) +
857
+ PIRQ_PENALTY_ISA_USED ;
804
858
else
805
- acpi_irq_penalty [irq ] = PIRQ_PENALTY_PCI_AVAILABLE ;
859
+ acpi_irq_penalty [irq ] = 0 ;
806
860
807
861
if (retval != 2 ) /* no next number */
808
862
break ;
@@ -819,34 +873,19 @@ static int __init acpi_irq_penalty_update(char *str, int used)
819
873
*/
820
874
void acpi_penalize_isa_irq (int irq , int active )
821
875
{
822
- if (irq >= 0 && irq < ARRAY_SIZE (acpi_irq_penalty )) {
823
- if (active )
824
- acpi_irq_penalty [irq ] += PIRQ_PENALTY_ISA_USED ;
825
- else
826
- acpi_irq_penalty [irq ] += PIRQ_PENALTY_PCI_USING ;
827
- }
876
+ if (irq >= 0 && irq < ARRAY_SIZE (acpi_irq_penalty ))
877
+ acpi_irq_penalty [irq ] = acpi_irq_get_penalty (irq ) +
878
+ active ? PIRQ_PENALTY_ISA_USED : PIRQ_PENALTY_PCI_USING ;
828
879
}
829
880
830
881
bool acpi_isa_irq_available (int irq )
831
882
{
832
883
return irq >= 0 && (irq >= ARRAY_SIZE (acpi_irq_penalty ) ||
833
- acpi_irq_penalty [ irq ] < PIRQ_PENALTY_ISA_ALWAYS );
884
+ acpi_irq_get_penalty ( irq ) < PIRQ_PENALTY_ISA_ALWAYS );
834
885
}
835
886
836
- /*
837
- * Penalize IRQ used by ACPI SCI. If ACPI SCI pin attributes conflict with
838
- * PCI IRQ attributes, mark ACPI SCI as ISA_ALWAYS so it won't be use for
839
- * PCI IRQs.
840
- */
841
887
void acpi_penalize_sci_irq (int irq , int trigger , int polarity )
842
888
{
843
- if (irq >= 0 && irq < ARRAY_SIZE (acpi_irq_penalty )) {
844
- if (trigger != ACPI_MADT_TRIGGER_LEVEL ||
845
- polarity != ACPI_MADT_POLARITY_ACTIVE_LOW )
846
- acpi_irq_penalty [irq ] += PIRQ_PENALTY_ISA_ALWAYS ;
847
- else
848
- acpi_irq_penalty [irq ] += PIRQ_PENALTY_PCI_USING ;
849
- }
850
889
}
851
890
852
891
/*
0 commit comments