diff options
author | Cyrill Gorcunov <gorcunov@gmail.com> | 2008-08-16 15:21:53 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-08-17 08:41:49 -0400 |
commit | 274cfe5912eebe9d4e1a4c451fe617289a181fcf (patch) | |
tree | 27c9a5c5cfd0d2ddf2c062168a0c9cbf25b35f53 /arch/x86/kernel/apic_64.c | |
parent | 24968cfdd4c3cf61338495dd0f9bb8a6907d2087 (diff) |
x86: apic - rearrange functions and comments
Rearrange functions and comments to find differences
easier.
Also use apic_printk in setup_boot_APIC_clock for
64bit mode.
Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/apic_64.c')
-rw-r--r-- | arch/x86/kernel/apic_64.c | 48 |
1 files changed, 38 insertions, 10 deletions
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c index 13dea935b4eb..46523c0cc6f6 100644 --- a/arch/x86/kernel/apic_64.c +++ b/arch/x86/kernel/apic_64.c | |||
@@ -81,6 +81,9 @@ static void lapic_timer_setup(enum clock_event_mode mode, | |||
81 | static void lapic_timer_broadcast(cpumask_t mask); | 81 | static void lapic_timer_broadcast(cpumask_t mask); |
82 | static void apic_pm_activate(void); | 82 | static void apic_pm_activate(void); |
83 | 83 | ||
84 | /* | ||
85 | * The local apic timer can be used for any function which is CPU local. | ||
86 | */ | ||
84 | static struct clock_event_device lapic_clockevent = { | 87 | static struct clock_event_device lapic_clockevent = { |
85 | .name = "lapic", | 88 | .name = "lapic", |
86 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | 89 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
@@ -127,6 +130,11 @@ static int modern_apic(void) | |||
127 | return lapic_get_version() >= 0x14; | 130 | return lapic_get_version() >= 0x14; |
128 | } | 131 | } |
129 | 132 | ||
133 | /* | ||
134 | * Paravirt kernels also might be using these below ops. So we still | ||
135 | * use generic apic_read()/apic_write(), which might be pointing to different | ||
136 | * ops in PARAVIRT case. | ||
137 | */ | ||
130 | void xapic_wait_icr_idle(void) | 138 | void xapic_wait_icr_idle(void) |
131 | { | 139 | { |
132 | while (apic_read(APIC_ICR) & APIC_ICR_BUSY) | 140 | while (apic_read(APIC_ICR) & APIC_ICR_BUSY) |
@@ -175,7 +183,6 @@ static struct apic_ops xapic_ops = { | |||
175 | }; | 183 | }; |
176 | 184 | ||
177 | struct apic_ops __read_mostly *apic_ops = &xapic_ops; | 185 | struct apic_ops __read_mostly *apic_ops = &xapic_ops; |
178 | |||
179 | EXPORT_SYMBOL_GPL(apic_ops); | 186 | EXPORT_SYMBOL_GPL(apic_ops); |
180 | 187 | ||
181 | static void x2apic_wait_icr_idle(void) | 188 | static void x2apic_wait_icr_idle(void) |
@@ -244,6 +251,10 @@ int lapic_get_maxlvt(void) | |||
244 | return APIC_INTEGRATED(GET_APIC_VERSION(v)) ? GET_APIC_MAXLVT(v) : 2; | 251 | return APIC_INTEGRATED(GET_APIC_VERSION(v)) ? GET_APIC_MAXLVT(v) : 2; |
245 | } | 252 | } |
246 | 253 | ||
254 | /* | ||
255 | * Local APIC timer | ||
256 | */ | ||
257 | |||
247 | /* Clock divisor is set to 1 */ | 258 | /* Clock divisor is set to 1 */ |
248 | #define APIC_DIVISOR 1 | 259 | #define APIC_DIVISOR 1 |
249 | 260 | ||
@@ -257,7 +268,6 @@ int lapic_get_maxlvt(void) | |||
257 | * We do reads before writes even if unnecessary, to get around the | 268 | * We do reads before writes even if unnecessary, to get around the |
258 | * P5 APIC double write bug. | 269 | * P5 APIC double write bug. |
259 | */ | 270 | */ |
260 | |||
261 | static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) | 271 | static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) |
262 | { | 272 | { |
263 | unsigned int lvtt_value, tmp_value; | 273 | unsigned int lvtt_value, tmp_value; |
@@ -474,10 +484,10 @@ static int __init calibrate_APIC_clock(void) | |||
474 | void __init setup_boot_APIC_clock(void) | 484 | void __init setup_boot_APIC_clock(void) |
475 | { | 485 | { |
476 | /* | 486 | /* |
477 | * The local apic timer can be disabled via the kernel commandline. | 487 | * The local apic timer can be disabled via the kernel |
478 | * Register the lapic timer as a dummy clock event source on SMP | 488 | * commandline or from the CPU detection code. Register the lapic |
479 | * systems, so the broadcast mechanism is used. On UP systems simply | 489 | * timer as a dummy clock event source on SMP systems, so the |
480 | * ignore it. | 490 | * broadcast mechanism is used. On UP systems simply ignore it. |
481 | */ | 491 | */ |
482 | if (disable_apic_timer) { | 492 | if (disable_apic_timer) { |
483 | printk(KERN_INFO "Disabling APIC timer\n"); | 493 | printk(KERN_INFO "Disabling APIC timer\n"); |
@@ -489,7 +499,9 @@ void __init setup_boot_APIC_clock(void) | |||
489 | return; | 499 | return; |
490 | } | 500 | } |
491 | 501 | ||
492 | printk(KERN_INFO "Using local APIC timer interrupts.\n"); | 502 | apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n" |
503 | "calibrating APIC timer ...\n"); | ||
504 | |||
493 | if (calibrate_APIC_clock()) { | 505 | if (calibrate_APIC_clock()) { |
494 | /* No broadcast on UP ! */ | 506 | /* No broadcast on UP ! */ |
495 | if (num_possible_cpus() > 1) | 507 | if (num_possible_cpus() > 1) |
@@ -508,6 +520,7 @@ void __init setup_boot_APIC_clock(void) | |||
508 | printk(KERN_WARNING "APIC timer registered as dummy," | 520 | printk(KERN_WARNING "APIC timer registered as dummy," |
509 | " due to nmi_watchdog=%d!\n", nmi_watchdog); | 521 | " due to nmi_watchdog=%d!\n", nmi_watchdog); |
510 | 522 | ||
523 | /* Setup the lapic or request the broadcast */ | ||
511 | setup_APIC_timer(); | 524 | setup_APIC_timer(); |
512 | } | 525 | } |
513 | 526 | ||
@@ -577,6 +590,7 @@ void smp_apic_timer_interrupt(struct pt_regs *regs) | |||
577 | irq_enter(); | 590 | irq_enter(); |
578 | local_apic_timer_interrupt(); | 591 | local_apic_timer_interrupt(); |
579 | irq_exit(); | 592 | irq_exit(); |
593 | |||
580 | set_irq_regs(old_regs); | 594 | set_irq_regs(old_regs); |
581 | } | 595 | } |
582 | 596 | ||
@@ -1248,6 +1262,13 @@ void __init connect_bsp_APIC(void) | |||
1248 | enable_apic_mode(); | 1262 | enable_apic_mode(); |
1249 | } | 1263 | } |
1250 | 1264 | ||
1265 | /** | ||
1266 | * disconnect_bsp_APIC - detach the APIC from the interrupt system | ||
1267 | * @virt_wire_setup: indicates, whether virtual wire mode is selected | ||
1268 | * | ||
1269 | * Virtual wire mode is necessary to deliver legacy interrupts even when the | ||
1270 | * APIC is disabled. | ||
1271 | */ | ||
1251 | void disconnect_bsp_APIC(int virt_wire_setup) | 1272 | void disconnect_bsp_APIC(int virt_wire_setup) |
1252 | { | 1273 | { |
1253 | /* Go back to Virtual Wire compatibility mode */ | 1274 | /* Go back to Virtual Wire compatibility mode */ |
@@ -1347,9 +1368,11 @@ int hard_smp_processor_id(void) | |||
1347 | #ifdef CONFIG_PM | 1368 | #ifdef CONFIG_PM |
1348 | 1369 | ||
1349 | static struct { | 1370 | static struct { |
1350 | /* 'active' is true if the local APIC was enabled by us and | 1371 | /* |
1351 | not the BIOS; this signifies that we are also responsible | 1372 | * 'active' is true if the local APIC was enabled by us and |
1352 | for disabling it before entering apm/acpi suspend */ | 1373 | * not the BIOS; this signifies that we are also responsible |
1374 | * for disabling it before entering apm/acpi suspend | ||
1375 | */ | ||
1353 | int active; | 1376 | int active; |
1354 | /* r/w apic fields */ | 1377 | /* r/w apic fields */ |
1355 | unsigned int apic_id; | 1378 | unsigned int apic_id; |
@@ -1458,6 +1481,11 @@ static int lapic_resume(struct sys_device *dev) | |||
1458 | return 0; | 1481 | return 0; |
1459 | } | 1482 | } |
1460 | 1483 | ||
1484 | /* | ||
1485 | * This device has no shutdown method - fully functioning local APICs | ||
1486 | * are needed on every CPU up until machine_halt/restart/poweroff. | ||
1487 | */ | ||
1488 | |||
1461 | static struct sysdev_class lapic_sysclass = { | 1489 | static struct sysdev_class lapic_sysclass = { |
1462 | .name = "lapic", | 1490 | .name = "lapic", |
1463 | .resume = lapic_resume, | 1491 | .resume = lapic_resume, |