diff options
author | Andi Kleen <ak@suse.de> | 2006-09-26 04:52:30 -0400 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-09-26 04:52:30 -0400 |
commit | eea0e11c1f0d6ef89e64182b2f1223a4ca2b74a2 (patch) | |
tree | 83d9513a49194e07142505bb4e3d7bf2e5da827b /arch/x86_64/kernel/io_apic.c | |
parent | c1a58b42b428e717afbbb298356e041cea54ad17 (diff) |
[PATCH] Factor out common io apic routing entry access
The IO APIC code had lots of duplicated code to read/write 64bit
routing entries into the IO-APIC. Factor this out int common read/write
functions
In a few cases the IO APIC lock is taken more often now, but this
isn't a problem because it's all initialization/shutdown only
slow path code.
Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/x86_64/kernel/io_apic.c')
-rw-r--r-- | arch/x86_64/kernel/io_apic.c | 82 |
1 files changed, 41 insertions, 41 deletions
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 97e90f6abcc4..1ccf1b41c3ed 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c | |||
@@ -111,6 +111,33 @@ int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1}; | |||
111 | FINAL; \ | 111 | FINAL; \ |
112 | } | 112 | } |
113 | 113 | ||
114 | union entry_union { | ||
115 | struct { u32 w1, w2; }; | ||
116 | struct IO_APIC_route_entry entry; | ||
117 | }; | ||
118 | |||
119 | static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) | ||
120 | { | ||
121 | union entry_union eu; | ||
122 | unsigned long flags; | ||
123 | spin_lock_irqsave(&ioapic_lock, flags); | ||
124 | eu.w1 = io_apic_read(apic, 0x10 + 2 * pin); | ||
125 | eu.w2 = io_apic_read(apic, 0x11 + 2 * pin); | ||
126 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
127 | return eu.entry; | ||
128 | } | ||
129 | |||
130 | static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) | ||
131 | { | ||
132 | unsigned long flags; | ||
133 | union entry_union eu; | ||
134 | eu.entry = e; | ||
135 | spin_lock_irqsave(&ioapic_lock, flags); | ||
136 | io_apic_write(apic, 0x10 + 2*pin, eu.w1); | ||
137 | io_apic_write(apic, 0x11 + 2*pin, eu.w2); | ||
138 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
139 | } | ||
140 | |||
114 | #ifdef CONFIG_SMP | 141 | #ifdef CONFIG_SMP |
115 | static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) | 142 | static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) |
116 | { | 143 | { |
@@ -196,13 +223,9 @@ static void unmask_IO_APIC_irq (unsigned int irq) | |||
196 | static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) | 223 | static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) |
197 | { | 224 | { |
198 | struct IO_APIC_route_entry entry; | 225 | struct IO_APIC_route_entry entry; |
199 | unsigned long flags; | ||
200 | 226 | ||
201 | /* Check delivery_mode to be sure we're not clearing an SMI pin */ | 227 | /* Check delivery_mode to be sure we're not clearing an SMI pin */ |
202 | spin_lock_irqsave(&ioapic_lock, flags); | 228 | entry = ioapic_read_entry(apic, pin); |
203 | *(((int*)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin); | ||
204 | *(((int*)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin); | ||
205 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
206 | if (entry.delivery_mode == dest_SMI) | 229 | if (entry.delivery_mode == dest_SMI) |
207 | return; | 230 | return; |
208 | /* | 231 | /* |
@@ -210,10 +233,7 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) | |||
210 | */ | 233 | */ |
211 | memset(&entry, 0, sizeof(entry)); | 234 | memset(&entry, 0, sizeof(entry)); |
212 | entry.mask = 1; | 235 | entry.mask = 1; |
213 | spin_lock_irqsave(&ioapic_lock, flags); | 236 | ioapic_write_entry(apic, pin, entry); |
214 | io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry) + 0)); | ||
215 | io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry) + 1)); | ||
216 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
217 | } | 237 | } |
218 | 238 | ||
219 | static void clear_IO_APIC (void) | 239 | static void clear_IO_APIC (void) |
@@ -838,9 +858,9 @@ static void __init setup_IO_APIC_irqs(void) | |||
838 | if (!apic && (irq < 16)) | 858 | if (!apic && (irq < 16)) |
839 | disable_8259A_irq(irq); | 859 | disable_8259A_irq(irq); |
840 | } | 860 | } |
861 | ioapic_write_entry(apic, pin, entry); | ||
862 | |||
841 | spin_lock_irqsave(&ioapic_lock, flags); | 863 | spin_lock_irqsave(&ioapic_lock, flags); |
842 | io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1)); | ||
843 | io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0)); | ||
844 | set_native_irq_info(irq, TARGET_CPUS); | 864 | set_native_irq_info(irq, TARGET_CPUS); |
845 | spin_unlock_irqrestore(&ioapic_lock, flags); | 865 | spin_unlock_irqrestore(&ioapic_lock, flags); |
846 | } | 866 | } |
@@ -978,10 +998,7 @@ void __apicdebuginit print_IO_APIC(void) | |||
978 | for (i = 0; i <= reg_01.bits.entries; i++) { | 998 | for (i = 0; i <= reg_01.bits.entries; i++) { |
979 | struct IO_APIC_route_entry entry; | 999 | struct IO_APIC_route_entry entry; |
980 | 1000 | ||
981 | spin_lock_irqsave(&ioapic_lock, flags); | 1001 | entry = ioapic_read_entry(apic, i); |
982 | *(((int *)&entry)+0) = io_apic_read(apic, 0x10+i*2); | ||
983 | *(((int *)&entry)+1) = io_apic_read(apic, 0x11+i*2); | ||
984 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
985 | 1002 | ||
986 | printk(KERN_DEBUG " %02x %03X %02X ", | 1003 | printk(KERN_DEBUG " %02x %03X %02X ", |
987 | i, | 1004 | i, |
@@ -1191,11 +1208,7 @@ static void __init enable_IO_APIC(void) | |||
1191 | /* See if any of the pins is in ExtINT mode */ | 1208 | /* See if any of the pins is in ExtINT mode */ |
1192 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { | 1209 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { |
1193 | struct IO_APIC_route_entry entry; | 1210 | struct IO_APIC_route_entry entry; |
1194 | spin_lock_irqsave(&ioapic_lock, flags); | 1211 | entry = ioapic_read_entry(apic, pin); |
1195 | *(((int *)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin); | ||
1196 | *(((int *)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin); | ||
1197 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
1198 | |||
1199 | 1212 | ||
1200 | /* If the interrupt line is enabled and in ExtInt mode | 1213 | /* If the interrupt line is enabled and in ExtInt mode |
1201 | * I have found the pin where the i8259 is connected. | 1214 | * I have found the pin where the i8259 is connected. |
@@ -1247,7 +1260,6 @@ void disable_IO_APIC(void) | |||
1247 | */ | 1260 | */ |
1248 | if (ioapic_i8259.pin != -1) { | 1261 | if (ioapic_i8259.pin != -1) { |
1249 | struct IO_APIC_route_entry entry; | 1262 | struct IO_APIC_route_entry entry; |
1250 | unsigned long flags; | ||
1251 | 1263 | ||
1252 | memset(&entry, 0, sizeof(entry)); | 1264 | memset(&entry, 0, sizeof(entry)); |
1253 | entry.mask = 0; /* Enabled */ | 1265 | entry.mask = 0; /* Enabled */ |
@@ -1264,12 +1276,7 @@ void disable_IO_APIC(void) | |||
1264 | /* | 1276 | /* |
1265 | * Add it to the IO-APIC irq-routing table: | 1277 | * Add it to the IO-APIC irq-routing table: |
1266 | */ | 1278 | */ |
1267 | spin_lock_irqsave(&ioapic_lock, flags); | 1279 | ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry); |
1268 | io_apic_write(ioapic_i8259.apic, 0x11+2*ioapic_i8259.pin, | ||
1269 | *(((int *)&entry)+1)); | ||
1270 | io_apic_write(ioapic_i8259.apic, 0x10+2*ioapic_i8259.pin, | ||
1271 | *(((int *)&entry)+0)); | ||
1272 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
1273 | } | 1280 | } |
1274 | 1281 | ||
1275 | disconnect_bsp_APIC(ioapic_i8259.pin != -1); | 1282 | disconnect_bsp_APIC(ioapic_i8259.pin != -1); |
@@ -1879,17 +1886,12 @@ static int ioapic_suspend(struct sys_device *dev, pm_message_t state) | |||
1879 | { | 1886 | { |
1880 | struct IO_APIC_route_entry *entry; | 1887 | struct IO_APIC_route_entry *entry; |
1881 | struct sysfs_ioapic_data *data; | 1888 | struct sysfs_ioapic_data *data; |
1882 | unsigned long flags; | ||
1883 | int i; | 1889 | int i; |
1884 | 1890 | ||
1885 | data = container_of(dev, struct sysfs_ioapic_data, dev); | 1891 | data = container_of(dev, struct sysfs_ioapic_data, dev); |
1886 | entry = data->entry; | 1892 | entry = data->entry; |
1887 | spin_lock_irqsave(&ioapic_lock, flags); | 1893 | for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) |
1888 | for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { | 1894 | *entry = ioapic_read_entry(dev->id, i); |
1889 | *(((int *)entry) + 1) = io_apic_read(dev->id, 0x11 + 2 * i); | ||
1890 | *(((int *)entry) + 0) = io_apic_read(dev->id, 0x10 + 2 * i); | ||
1891 | } | ||
1892 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
1893 | 1895 | ||
1894 | return 0; | 1896 | return 0; |
1895 | } | 1897 | } |
@@ -1911,11 +1913,9 @@ static int ioapic_resume(struct sys_device *dev) | |||
1911 | reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid; | 1913 | reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid; |
1912 | io_apic_write(dev->id, 0, reg_00.raw); | 1914 | io_apic_write(dev->id, 0, reg_00.raw); |
1913 | } | 1915 | } |
1914 | for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { | ||
1915 | io_apic_write(dev->id, 0x11+2*i, *(((int *)entry)+1)); | ||
1916 | io_apic_write(dev->id, 0x10+2*i, *(((int *)entry)+0)); | ||
1917 | } | ||
1918 | spin_unlock_irqrestore(&ioapic_lock, flags); | 1916 | spin_unlock_irqrestore(&ioapic_lock, flags); |
1917 | for (i = 0; i < nr_ioapic_registers[dev->id]; i++) | ||
1918 | ioapic_write_entry(dev->id, i, entry[i]); | ||
1919 | 1919 | ||
1920 | return 0; | 1920 | return 0; |
1921 | } | 1921 | } |
@@ -2040,10 +2040,10 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p | |||
2040 | if (!ioapic && (irq < 16)) | 2040 | if (!ioapic && (irq < 16)) |
2041 | disable_8259A_irq(irq); | 2041 | disable_8259A_irq(irq); |
2042 | 2042 | ||
2043 | ioapic_write_entry(ioapic, pin, entry); | ||
2044 | |||
2043 | spin_lock_irqsave(&ioapic_lock, flags); | 2045 | spin_lock_irqsave(&ioapic_lock, flags); |
2044 | io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1)); | 2046 | set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS); |
2045 | io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0)); | ||
2046 | set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS); | ||
2047 | spin_unlock_irqrestore(&ioapic_lock, flags); | 2047 | spin_unlock_irqrestore(&ioapic_lock, flags); |
2048 | 2048 | ||
2049 | return 0; | 2049 | return 0; |