aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
authorAlexey Starikovskiy <astarikovskiy@suse.de>2008-04-04 15:43:12 -0400
committerIngo Molnar <mingo@elte.hu>2008-04-17 11:41:36 -0400
commitcfa08d6cc3421bb08ebaa34467107e58999a7c28 (patch)
tree80b91ad7e8c74a11e262766994c0801075bb09b1 /arch/x86/kernel
parentc769bfee5731f2614983bd7a9079eb90514e4b9f (diff)
x86: unify mp_register_gsi
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/mpparse_32.c22
-rw-r--r--arch/x86/kernel/mpparse_64.c70
2 files changed, 82 insertions, 10 deletions
diff --git a/arch/x86/kernel/mpparse_32.c b/arch/x86/kernel/mpparse_32.c
index 1ad8a5d4e3ee..6376791cffe5 100644
--- a/arch/x86/kernel/mpparse_32.c
+++ b/arch/x86/kernel/mpparse_32.c
@@ -994,14 +994,15 @@ void __init mp_config_acpi_legacy_irqs(void)
994 } 994 }
995} 995}
996 996
997#define MAX_GSI_NUM 4096
998#define IRQ_COMPRESSION_START 64
999
1000int mp_register_gsi(u32 gsi, int triggering, int polarity) 997int mp_register_gsi(u32 gsi, int triggering, int polarity)
1001{ 998{
1002 int ioapic = -1; 999 int ioapic = -1;
1003 int ioapic_pin = 0; 1000 int ioapic_pin = 0;
1004 int idx, bit = 0; 1001 int idx, bit = 0;
1002#ifdef CONFIG_X86_32
1003#define MAX_GSI_NUM 4096
1004#define IRQ_COMPRESSION_START 64
1005
1005 static int pci_irq = IRQ_COMPRESSION_START; 1006 static int pci_irq = IRQ_COMPRESSION_START;
1006 /* 1007 /*
1007 * Mapping between Global System Interrupts, which 1008 * Mapping between Global System Interrupts, which
@@ -1009,6 +1010,11 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
1009 * assigned to actual devices. 1010 * assigned to actual devices.
1010 */ 1011 */
1011 static int gsi_to_irq[MAX_GSI_NUM]; 1012 static int gsi_to_irq[MAX_GSI_NUM];
1013#else
1014
1015 if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
1016 return gsi;
1017#endif
1012 1018
1013 /* Don't set up the ACPI SCI because it's already set up */ 1019 /* Don't set up the ACPI SCI because it's already set up */
1014 if (acpi_gbl_FADT.sci_interrupt == gsi) 1020 if (acpi_gbl_FADT.sci_interrupt == gsi)
@@ -1022,8 +1028,10 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
1022 1028
1023 ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base; 1029 ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
1024 1030
1031#ifdef CONFIG_X86_32
1025 if (ioapic_renumber_irq) 1032 if (ioapic_renumber_irq)
1026 gsi = ioapic_renumber_irq(ioapic, gsi); 1033 gsi = ioapic_renumber_irq(ioapic, gsi);
1034#endif
1027 1035
1028 /* 1036 /*
1029 * Avoid pin reprogramming. PRTs typically include entries 1037 * Avoid pin reprogramming. PRTs typically include entries
@@ -1041,11 +1049,15 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
1041 if ((1 << bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { 1049 if ((1 << bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
1042 Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", 1050 Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
1043 mp_ioapic_routing[ioapic].apic_id, ioapic_pin); 1051 mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
1052#ifdef CONFIG_X86_32
1044 return (gsi < IRQ_COMPRESSION_START ? gsi : gsi_to_irq[gsi]); 1053 return (gsi < IRQ_COMPRESSION_START ? gsi : gsi_to_irq[gsi]);
1054#else
1055 return gsi;
1056#endif
1045 } 1057 }
1046 1058
1047 mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1 << bit); 1059 mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1 << bit);
1048 1060#ifdef CONFIG_X86_32
1049 /* 1061 /*
1050 * For GSI >= 64, use IRQ compression 1062 * For GSI >= 64, use IRQ compression
1051 */ 1063 */
@@ -1079,7 +1091,7 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
1079 return gsi; 1091 return gsi;
1080 } 1092 }
1081 } 1093 }
1082 1094#endif
1083 io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, 1095 io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
1084 triggering == ACPI_EDGE_SENSITIVE ? 0 : 1, 1096 triggering == ACPI_EDGE_SENSITIVE ? 0 : 1,
1085 polarity == ACPI_ACTIVE_HIGH ? 0 : 1); 1097 polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
diff --git a/arch/x86/kernel/mpparse_64.c b/arch/x86/kernel/mpparse_64.c
index 8ad365136a6b..7d742577d68a 100644
--- a/arch/x86/kernel/mpparse_64.c
+++ b/arch/x86/kernel/mpparse_64.c
@@ -685,6 +685,8 @@ void __init find_smp_config(void)
685 685
686#ifdef CONFIG_ACPI 686#ifdef CONFIG_ACPI
687 687
688#ifdef CONFIG_X86_IO_APIC
689
688#define MP_ISA_BUS 0 690#define MP_ISA_BUS 0
689#define MP_MAX_IOAPIC_PIN 127 691#define MP_MAX_IOAPIC_PIN 127
690 692
@@ -770,7 +772,7 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
770 int ioapic = -1; 772 int ioapic = -1;
771 int pin = -1; 773 int pin = -1;
772 774
773 /* 775 /*
774 * Convert 'gsi' to 'ioapic.pin'. 776 * Convert 'gsi' to 'ioapic.pin'.
775 */ 777 */
776 ioapic = mp_find_ioapic(gsi); 778 ioapic = mp_find_ioapic(gsi);
@@ -780,7 +782,7 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
780 782
781 /* 783 /*
782 * TBD: This check is for faulty timer entries, where the override 784 * TBD: This check is for faulty timer entries, where the override
783 * erroneously sets the trigger to level, resulting in a HUGE 785 * erroneously sets the trigger to level, resulting in a HUGE
784 * increase of timer interrupts! 786 * increase of timer interrupts!
785 */ 787 */
786 if ((bus_irq == 0) && (trigger == 3)) 788 if ((bus_irq == 0) && (trigger == 3))
@@ -886,9 +888,22 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
886 int ioapic = -1; 888 int ioapic = -1;
887 int ioapic_pin = 0; 889 int ioapic_pin = 0;
888 int idx, bit = 0; 890 int idx, bit = 0;
891#ifdef CONFIG_X86_32
892#define MAX_GSI_NUM 4096
893#define IRQ_COMPRESSION_START 64
894
895 static int pci_irq = IRQ_COMPRESSION_START;
896 /*
897 * Mapping between Global System Interrupts, which
898 * represent all possible interrupts, and IRQs
899 * assigned to actual devices.
900 */
901 static int gsi_to_irq[MAX_GSI_NUM];
902#else
889 903
890 if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) 904 if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
891 return gsi; 905 return gsi;
906#endif
892 907
893 /* Don't set up the ACPI SCI because it's already set up */ 908 /* Don't set up the ACPI SCI because it's already set up */
894 if (acpi_gbl_FADT.sci_interrupt == gsi) 909 if (acpi_gbl_FADT.sci_interrupt == gsi)
@@ -902,8 +917,13 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
902 917
903 ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base; 918 ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
904 919
905 /* 920#ifdef CONFIG_X86_32
906 * Avoid pin reprogramming. PRTs typically include entries 921 if (ioapic_renumber_irq)
922 gsi = ioapic_renumber_irq(ioapic, gsi);
923#endif
924
925 /*
926 * Avoid pin reprogramming. PRTs typically include entries
907 * with redundant pin->gsi mappings (but unique PCI devices); 927 * with redundant pin->gsi mappings (but unique PCI devices);
908 * we only program the IOAPIC on the first. 928 * we only program the IOAPIC on the first.
909 */ 929 */
@@ -918,14 +938,54 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
918 if ((1 << bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { 938 if ((1 << bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
919 Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", 939 Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
920 mp_ioapic_routing[ioapic].apic_id, ioapic_pin); 940 mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
941#ifdef CONFIG_X86_32
942 return (gsi < IRQ_COMPRESSION_START ? gsi : gsi_to_irq[gsi]);
943#else
921 return gsi; 944 return gsi;
945#endif
922 } 946 }
923 947
924 mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1 << bit); 948 mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1 << bit);
925 949#ifdef CONFIG_X86_32
950 /*
951 * For GSI >= 64, use IRQ compression
952 */
953 if ((gsi >= IRQ_COMPRESSION_START)
954 && (triggering == ACPI_LEVEL_SENSITIVE)) {
955 /*
956 * For PCI devices assign IRQs in order, avoiding gaps
957 * due to unused I/O APIC pins.
958 */
959 int irq = gsi;
960 if (gsi < MAX_GSI_NUM) {
961 /*
962 * Retain the VIA chipset work-around (gsi > 15), but
963 * avoid a problem where the 8254 timer (IRQ0) is setup
964 * via an override (so it's not on pin 0 of the ioapic),
965 * and at the same time, the pin 0 interrupt is a PCI
966 * type. The gsi > 15 test could cause these two pins
967 * to be shared as IRQ0, and they are not shareable.
968 * So test for this condition, and if necessary, avoid
969 * the pin collision.
970 */
971 gsi = pci_irq++;
972 /*
973 * Don't assign IRQ used by ACPI SCI
974 */
975 if (gsi == acpi_gbl_FADT.sci_interrupt)
976 gsi = pci_irq++;
977 gsi_to_irq[irq] = gsi;
978 } else {
979 printk(KERN_ERR "GSI %u is too high\n", gsi);
980 return gsi;
981 }
982 }
983#endif
926 io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, 984 io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
927 triggering == ACPI_EDGE_SENSITIVE ? 0 : 1, 985 triggering == ACPI_EDGE_SENSITIVE ? 0 : 1,
928 polarity == ACPI_ACTIVE_HIGH ? 0 : 1); 986 polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
929 return gsi; 987 return gsi;
930} 988}
989
990#endif /* CONFIG_X86_IO_APIC */
931#endif /* CONFIG_ACPI */ 991#endif /* CONFIG_ACPI */