aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic_64.c
diff options
context:
space:
mode:
authorCyrill Gorcunov <gorcunov@gmail.com>2008-08-16 15:21:53 -0400
committerIngo Molnar <mingo@elte.hu>2008-08-17 08:41:49 -0400
commit274cfe5912eebe9d4e1a4c451fe617289a181fcf (patch)
tree27c9a5c5cfd0d2ddf2c062168a0c9cbf25b35f53 /arch/x86/kernel/apic_64.c
parent24968cfdd4c3cf61338495dd0f9bb8a6907d2087 (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.c48
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,
81static void lapic_timer_broadcast(cpumask_t mask); 81static void lapic_timer_broadcast(cpumask_t mask);
82static void apic_pm_activate(void); 82static void apic_pm_activate(void);
83 83
84/*
85 * The local apic timer can be used for any function which is CPU local.
86 */
84static struct clock_event_device lapic_clockevent = { 87static 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 */
130void xapic_wait_icr_idle(void) 138void 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
177struct apic_ops __read_mostly *apic_ops = &xapic_ops; 185struct apic_ops __read_mostly *apic_ops = &xapic_ops;
178
179EXPORT_SYMBOL_GPL(apic_ops); 186EXPORT_SYMBOL_GPL(apic_ops);
180 187
181static void x2apic_wait_icr_idle(void) 188static 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
261static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) 271static 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)
474void __init setup_boot_APIC_clock(void) 484void __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 */
1251void disconnect_bsp_APIC(int virt_wire_setup) 1272void 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
1349static struct { 1370static 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
1461static struct sysdev_class lapic_sysclass = { 1489static struct sysdev_class lapic_sysclass = {
1462 .name = "lapic", 1490 .name = "lapic",
1463 .resume = lapic_resume, 1491 .resume = lapic_resume,