aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/io_apic.c
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2006-09-26 04:52:30 -0400
committerAndi Kleen <andi@basil.nowhere.org>2006-09-26 04:52:30 -0400
commiteea0e11c1f0d6ef89e64182b2f1223a4ca2b74a2 (patch)
tree83d9513a49194e07142505bb4e3d7bf2e5da827b /arch/x86_64/kernel/io_apic.c
parentc1a58b42b428e717afbbb298356e041cea54ad17 (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.c82
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
114union entry_union {
115 struct { u32 w1, w2; };
116 struct IO_APIC_route_entry entry;
117};
118
119static 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
130static 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
115static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) 142static 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)
196static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) 223static 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
219static void clear_IO_APIC (void) 239static 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;