4
4
* Copyright (C) 2001, 2002 Andy Grover <[email protected] >
5
5
* Copyright (C) 2001, 2002 Paul Diefenbaugh <[email protected] >
6
6
* Copyright (C) 2002 Dominik Brodowski <[email protected] >
7
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
7
8
*
8
9
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9
10
*
@@ -67,12 +68,12 @@ static struct acpi_scan_handler pci_link_handler = {
67
68
* later even the link is disable. Instead, we just repick the active irq
68
69
*/
69
70
struct acpi_pci_link_irq {
70
- u8 active ; /* Current IRQ */
71
+ u32 active ; /* Current IRQ */
71
72
u8 triggering ; /* All IRQs */
72
73
u8 polarity ; /* All IRQs */
73
74
u8 resource_type ;
74
75
u8 possible_count ;
75
- u8 possible [ACPI_PCI_LINK_MAX_POSSIBLE ];
76
+ u32 possible [ACPI_PCI_LINK_MAX_POSSIBLE ];
76
77
u8 initialized :1 ;
77
78
u8 reserved :7 ;
78
79
};
@@ -437,7 +438,6 @@ 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
441
#define ACPI_MAX_ISA_IRQ 16
442
442
443
443
#define PIRQ_PENALTY_PCI_AVAILABLE (0)
@@ -447,7 +447,7 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
447
447
#define PIRQ_PENALTY_ISA_USED (16*16*16*16*16)
448
448
#define PIRQ_PENALTY_ISA_ALWAYS (16*16*16*16*16*16)
449
449
450
- static int acpi_irq_penalty [ ACPI_MAX_IRQS ] = {
450
+ static int acpi_irq_isa_penalty [ ACPI_MAX_ISA_IRQ ] = {
451
451
PIRQ_PENALTY_ISA_ALWAYS , /* IRQ0 timer */
452
452
PIRQ_PENALTY_ISA_ALWAYS , /* IRQ1 keyboard */
453
453
PIRQ_PENALTY_ISA_ALWAYS , /* IRQ2 cascade */
@@ -464,9 +464,68 @@ static int acpi_irq_penalty[ACPI_MAX_IRQS] = {
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
- /* >IRQ15 */
468
467
};
469
468
469
+ struct irq_penalty_info {
470
+ int irq ;
471
+ int penalty ;
472
+ struct list_head node ;
473
+ };
474
+
475
+ static LIST_HEAD (acpi_irq_penalty_list );
476
+
477
+ static int acpi_irq_get_penalty (int irq )
478
+ {
479
+ struct irq_penalty_info * irq_info ;
480
+
481
+ if (irq < ACPI_MAX_ISA_IRQ )
482
+ return acpi_irq_isa_penalty [irq ];
483
+
484
+ list_for_each_entry (irq_info , & acpi_irq_penalty_list , node ) {
485
+ if (irq_info -> irq == irq )
486
+ return irq_info -> penalty ;
487
+ }
488
+
489
+ return 0 ;
490
+ }
491
+
492
+ static int acpi_irq_set_penalty (int irq , int new_penalty )
493
+ {
494
+ struct irq_penalty_info * irq_info ;
495
+
496
+ /* see if this is a ISA IRQ */
497
+ if (irq < ACPI_MAX_ISA_IRQ ) {
498
+ acpi_irq_isa_penalty [irq ] = new_penalty ;
499
+ return 0 ;
500
+ }
501
+
502
+ /* next, try to locate from the dynamic list */
503
+ list_for_each_entry (irq_info , & acpi_irq_penalty_list , node ) {
504
+ if (irq_info -> irq == irq ) {
505
+ irq_info -> penalty = new_penalty ;
506
+ return 0 ;
507
+ }
508
+ }
509
+
510
+ /* nope, let's allocate a slot for this IRQ */
511
+ irq_info = kzalloc (sizeof (* irq_info ), GFP_KERNEL );
512
+ if (!irq_info )
513
+ return - ENOMEM ;
514
+
515
+ irq_info -> irq = irq ;
516
+ irq_info -> penalty = new_penalty ;
517
+ list_add_tail (& irq_info -> node , & acpi_irq_penalty_list );
518
+
519
+ return 0 ;
520
+ }
521
+
522
+ static void acpi_irq_add_penalty (int irq , int penalty )
523
+ {
524
+ int curpen = acpi_irq_get_penalty (irq );
525
+
526
+ acpi_irq_set_penalty (irq , curpen + penalty );
527
+ }
528
+
470
529
int __init acpi_irq_penalty_init (void )
471
530
{
472
531
struct acpi_pci_link * link ;
@@ -487,15 +546,16 @@ int __init acpi_irq_penalty_init(void)
487
546
link -> irq .possible_count ;
488
547
489
548
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 ;
549
+ if (link -> irq .possible [i ] < ACPI_MAX_ISA_IRQ ) {
550
+ int irqpos = link -> irq .possible [i ];
551
+
552
+ acpi_irq_add_penalty (irqpos , penalty );
553
+ }
494
554
}
495
555
496
556
} else if (link -> irq .active ) {
497
- acpi_irq_penalty [ link -> irq .active ] +=
498
- PIRQ_PENALTY_PCI_POSSIBLE ;
557
+ acpi_irq_add_penalty ( link -> irq .active ,
558
+ PIRQ_PENALTY_PCI_POSSIBLE ) ;
499
559
}
500
560
}
501
561
@@ -547,12 +607,12 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
547
607
* the use of IRQs 9, 10, 11, and >15.
548
608
*/
549
609
for (i = (link -> irq .possible_count - 1 ); i >= 0 ; i -- ) {
550
- if (acpi_irq_penalty [ irq ] >
551
- acpi_irq_penalty [ link -> irq .possible [i ]] )
610
+ if (acpi_irq_get_penalty ( irq ) >
611
+ acpi_irq_get_penalty ( link -> irq .possible [i ]) )
552
612
irq = link -> irq .possible [i ];
553
613
}
554
614
}
555
- if (acpi_irq_penalty [ irq ] >= PIRQ_PENALTY_ISA_ALWAYS ) {
615
+ if (acpi_irq_get_penalty ( irq ) >= PIRQ_PENALTY_ISA_ALWAYS ) {
556
616
printk (KERN_ERR PREFIX "No IRQ available for %s [%s]. "
557
617
"Try pci=noacpi or acpi=off\n" ,
558
618
acpi_device_name (link -> device ),
@@ -568,7 +628,8 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
568
628
acpi_device_bid (link -> device ));
569
629
return - ENODEV ;
570
630
} else {
571
- acpi_irq_penalty [link -> irq .active ] += PIRQ_PENALTY_PCI_USING ;
631
+ acpi_irq_add_penalty (link -> irq .active , PIRQ_PENALTY_PCI_USING );
632
+
572
633
printk (KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n" ,
573
634
acpi_device_name (link -> device ),
574
635
acpi_device_bid (link -> device ), link -> irq .active );
@@ -778,7 +839,7 @@ static void acpi_pci_link_remove(struct acpi_device *device)
778
839
}
779
840
780
841
/*
781
- * modify acpi_irq_penalty[] from cmdline
842
+ * modify penalty from cmdline
782
843
*/
783
844
static int __init acpi_irq_penalty_update (char * str , int used )
784
845
{
@@ -796,13 +857,10 @@ static int __init acpi_irq_penalty_update(char *str, int used)
796
857
if (irq < 0 )
797
858
continue ;
798
859
799
- if (irq >= ARRAY_SIZE (acpi_irq_penalty ))
800
- continue ;
801
-
802
860
if (used )
803
- acpi_irq_penalty [ irq ] += PIRQ_PENALTY_ISA_USED ;
861
+ acpi_irq_add_penalty ( irq , PIRQ_PENALTY_ISA_USED ) ;
804
862
else
805
- acpi_irq_penalty [ irq ] = PIRQ_PENALTY_PCI_AVAILABLE ;
863
+ acpi_irq_set_penalty ( irq , PIRQ_PENALTY_PCI_AVAILABLE ) ;
806
864
807
865
if (retval != 2 ) /* no next number */
808
866
break ;
@@ -819,18 +877,15 @@ static int __init acpi_irq_penalty_update(char *str, int used)
819
877
*/
820
878
void acpi_penalize_isa_irq (int irq , int active )
821
879
{
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
- }
880
+ if (irq >= 0 )
881
+ acpi_irq_add_penalty (irq , active ?
882
+ PIRQ_PENALTY_ISA_USED : PIRQ_PENALTY_PCI_USING );
828
883
}
829
884
830
885
bool acpi_isa_irq_available (int irq )
831
886
{
832
- return irq >= 0 && ( irq >= ARRAY_SIZE ( acpi_irq_penalty ) ||
833
- acpi_irq_penalty [ irq ] < PIRQ_PENALTY_ISA_ALWAYS );
887
+ return irq >= 0 &&
888
+ ( acpi_irq_get_penalty ( irq ) < PIRQ_PENALTY_ISA_ALWAYS );
834
889
}
835
890
836
891
/*
@@ -840,13 +895,18 @@ bool acpi_isa_irq_available(int irq)
840
895
*/
841
896
void acpi_penalize_sci_irq (int irq , int trigger , int polarity )
842
897
{
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
- }
898
+ int penalty ;
899
+
900
+ if (irq < 0 )
901
+ return ;
902
+
903
+ if (trigger != ACPI_MADT_TRIGGER_LEVEL ||
904
+ polarity != ACPI_MADT_POLARITY_ACTIVE_LOW )
905
+ penalty = PIRQ_PENALTY_ISA_ALWAYS ;
906
+ else
907
+ penalty = PIRQ_PENALTY_PCI_USING ;
908
+
909
+ acpi_irq_add_penalty (irq , penalty );
850
910
}
851
911
852
912
/*
0 commit comments