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
@@ -437,17 +438,15 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
437
438
* enabled system.
438
439
*/
439
440
440
- #define ACPI_MAX_IRQS 256
441
- #define ACPI_MAX_ISA_IRQ 16
441
+ #define ACPI_MAX_ISA_IRQS 16
442
442
443
- #define PIRQ_PENALTY_PCI_AVAILABLE (0)
444
443
#define PIRQ_PENALTY_PCI_POSSIBLE (16*16)
445
444
#define PIRQ_PENALTY_PCI_USING (16*16*16)
446
445
#define PIRQ_PENALTY_ISA_TYPICAL (16*16*16*16)
447
446
#define PIRQ_PENALTY_ISA_USED (16*16*16*16*16)
448
447
#define PIRQ_PENALTY_ISA_ALWAYS (16*16*16*16*16*16)
449
448
450
- static int acpi_irq_penalty [ ACPI_MAX_IRQS ] = {
449
+ static int acpi_isa_irq_penalty [ ACPI_MAX_ISA_IRQS ] = {
451
450
PIRQ_PENALTY_ISA_ALWAYS , /* IRQ0 timer */
452
451
PIRQ_PENALTY_ISA_ALWAYS , /* IRQ1 keyboard */
453
452
PIRQ_PENALTY_ISA_ALWAYS , /* IRQ2 cascade */
@@ -457,49 +456,68 @@ static int acpi_irq_penalty[ACPI_MAX_IRQS] = {
457
456
PIRQ_PENALTY_ISA_TYPICAL , /* IRQ6 */
458
457
PIRQ_PENALTY_ISA_TYPICAL , /* IRQ7 parallel, spurious */
459
458
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 */
459
+ 0 , /* IRQ9 PCI, often acpi */
460
+ 0 , /* IRQ10 PCI */
461
+ 0 , /* IRQ11 PCI */
463
462
PIRQ_PENALTY_ISA_USED , /* IRQ12 mouse */
464
463
PIRQ_PENALTY_ISA_USED , /* IRQ13 fpe, sometimes */
465
464
PIRQ_PENALTY_ISA_USED , /* IRQ14 ide0 */
466
465
PIRQ_PENALTY_ISA_USED , /* IRQ15 ide1 */
467
466
/* >IRQ15 */
468
467
};
469
468
470
- int __init acpi_irq_penalty_init ( void )
469
+ static int acpi_irq_pci_sharing_penalty ( int irq )
471
470
{
472
471
struct acpi_pci_link * link ;
473
- int i ;
472
+ int penalty = 0 ;
474
473
475
- /*
476
- * Update penalties to facilitate IRQ balancing.
477
- */
478
474
list_for_each_entry (link , & acpi_link_list , list ) {
479
-
480
475
/*
481
- * reflect the possible and active irqs in the penalty table --
482
- * useful for breaking ties .
476
+ * If a link is active, penalize its IRQ heavily
477
+ * so we try to choose a different IRQ .
483
478
*/
484
- if (link -> irq .possible_count ) {
485
- int penalty =
486
- PIRQ_PENALTY_PCI_POSSIBLE /
487
- link -> irq .possible_count ;
488
-
489
- for (i = 0 ; i < link -> irq .possible_count ; i ++ ) {
490
- if (link -> irq .possible [i ] < ACPI_MAX_ISA_IRQ )
491
- acpi_irq_penalty [link -> irq .
492
- possible [i ]] +=
493
- penalty ;
494
- }
495
-
496
- } else if (link -> irq .active ) {
497
- acpi_irq_penalty [link -> irq .active ] +=
498
- PIRQ_PENALTY_PCI_POSSIBLE ;
479
+ if (link -> irq .active && link -> irq .active == irq )
480
+ penalty += PIRQ_PENALTY_PCI_USING ;
481
+ else {
482
+ int i ;
483
+
484
+ /*
485
+ * If a link is inactive, penalize the IRQs it
486
+ * might use, but not as severely.
487
+ */
488
+ for (i = 0 ; i < link -> irq .possible_count ; i ++ )
489
+ if (link -> irq .possible [i ] == irq )
490
+ penalty += PIRQ_PENALTY_PCI_POSSIBLE /
491
+ link -> irq .possible_count ;
499
492
}
500
493
}
501
494
502
- return 0 ;
495
+ return penalty ;
496
+ }
497
+
498
+ static int acpi_irq_get_penalty (int irq )
499
+ {
500
+ int penalty = 0 ;
501
+
502
+ if (irq < ACPI_MAX_ISA_IRQS )
503
+ penalty += acpi_isa_irq_penalty [irq ];
504
+
505
+ /*
506
+ * Penalize IRQ used by ACPI SCI. If ACPI SCI pin attributes conflict
507
+ * with PCI IRQ attributes, mark ACPI SCI as ISA_ALWAYS so it won't be
508
+ * use for PCI IRQs.
509
+ */
510
+ if (irq == acpi_gbl_FADT .sci_interrupt ) {
511
+ u32 type = irq_get_trigger_type (irq ) & IRQ_TYPE_SENSE_MASK ;
512
+
513
+ if (type != IRQ_TYPE_LEVEL_LOW )
514
+ penalty += PIRQ_PENALTY_ISA_ALWAYS ;
515
+ else
516
+ penalty += PIRQ_PENALTY_PCI_USING ;
517
+ }
518
+
519
+ penalty += acpi_irq_pci_sharing_penalty (irq );
520
+ return penalty ;
503
521
}
504
522
505
523
static int acpi_irq_balance = -1 ; /* 0: static, 1: balance */
@@ -547,12 +565,12 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
547
565
* the use of IRQs 9, 10, 11, and >15.
548
566
*/
549
567
for (i = (link -> irq .possible_count - 1 ); i >= 0 ; i -- ) {
550
- if (acpi_irq_penalty [ irq ] >
551
- acpi_irq_penalty [ link -> irq .possible [i ]] )
568
+ if (acpi_irq_get_penalty ( irq ) >
569
+ acpi_irq_get_penalty ( link -> irq .possible [i ]) )
552
570
irq = link -> irq .possible [i ];
553
571
}
554
572
}
555
- if (acpi_irq_penalty [ irq ] >= PIRQ_PENALTY_ISA_ALWAYS ) {
573
+ if (acpi_irq_get_penalty ( irq ) >= PIRQ_PENALTY_ISA_ALWAYS ) {
556
574
printk (KERN_ERR PREFIX "No IRQ available for %s [%s]. "
557
575
"Try pci=noacpi or acpi=off\n" ,
558
576
acpi_device_name (link -> device ),
@@ -568,7 +586,6 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
568
586
acpi_device_bid (link -> device ));
569
587
return - ENODEV ;
570
588
} else {
571
- acpi_irq_penalty [link -> irq .active ] += PIRQ_PENALTY_PCI_USING ;
572
589
printk (KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n" ,
573
590
acpi_device_name (link -> device ),
574
591
acpi_device_bid (link -> device ), link -> irq .active );
@@ -778,7 +795,7 @@ static void acpi_pci_link_remove(struct acpi_device *device)
778
795
}
779
796
780
797
/*
781
- * modify acpi_irq_penalty [] from cmdline
798
+ * modify acpi_isa_irq_penalty [] from cmdline
782
799
*/
783
800
static int __init acpi_irq_penalty_update (char * str , int used )
784
801
{
@@ -787,23 +804,24 @@ static int __init acpi_irq_penalty_update(char *str, int used)
787
804
for (i = 0 ; i < 16 ; i ++ ) {
788
805
int retval ;
789
806
int irq ;
807
+ int new_penalty ;
790
808
791
809
retval = get_option (& str , & irq );
792
810
793
811
if (!retval )
794
812
break ; /* no number found */
795
813
796
- if (irq < 0 )
797
- continue ;
798
-
799
- if (irq >= ARRAY_SIZE (acpi_irq_penalty ))
814
+ /* see if this is a ISA IRQ */
815
+ if ((irq < 0 ) || (irq >= ACPI_MAX_ISA_IRQS ))
800
816
continue ;
801
817
802
818
if (used )
803
- acpi_irq_penalty [irq ] += PIRQ_PENALTY_ISA_USED ;
819
+ new_penalty = acpi_irq_get_penalty (irq ) +
820
+ PIRQ_PENALTY_ISA_USED ;
804
821
else
805
- acpi_irq_penalty [ irq ] = PIRQ_PENALTY_PCI_AVAILABLE ;
822
+ new_penalty = 0 ;
806
823
824
+ acpi_isa_irq_penalty [irq ] = new_penalty ;
807
825
if (retval != 2 ) /* no next number */
808
826
break ;
809
827
}
@@ -819,34 +837,15 @@ static int __init acpi_irq_penalty_update(char *str, int used)
819
837
*/
820
838
void acpi_penalize_isa_irq (int irq , int active )
821
839
{
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
- }
840
+ if ((irq >= 0 ) && (irq < ARRAY_SIZE (acpi_isa_irq_penalty )))
841
+ acpi_isa_irq_penalty [irq ] = acpi_irq_get_penalty (irq ) +
842
+ active ? PIRQ_PENALTY_ISA_USED : PIRQ_PENALTY_PCI_USING ;
828
843
}
829
844
830
845
bool acpi_isa_irq_available (int irq )
831
846
{
832
- return irq >= 0 && (irq >= ARRAY_SIZE (acpi_irq_penalty ) ||
833
- acpi_irq_penalty [irq ] < PIRQ_PENALTY_ISA_ALWAYS );
834
- }
835
-
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
- void acpi_penalize_sci_irq (int irq , int trigger , int polarity )
842
- {
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
- }
847
+ return irq >= 0 && (irq >= ARRAY_SIZE (acpi_isa_irq_penalty ) ||
848
+ acpi_irq_get_penalty (irq ) < PIRQ_PENALTY_ISA_ALWAYS );
850
849
}
851
850
852
851
/*
0 commit comments