aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2010-12-07 15:42:05 -0800
committerH. Peter Anvin <hpa@linux.intel.com>2010-12-14 10:48:42 -0800
commit6e8e44079b629ab7dd32c37b6c6b3f79a8b6e5cc (patch)
tree8b8b57bd9b71223e4770615d1288272781e3d47b
parent660c1e391d880836aea879f2be69ec1c344bd318 (diff)
downloadmrst-s0i3-test-6e8e44079b629ab7dd32c37b6c6b3f79a8b6e5cc.tar.gz
mrst-s0i3-test-6e8e44079b629ab7dd32c37b6c6b3f79a8b6e5cc.tar.xz
mrst-s0i3-test-6e8e44079b629ab7dd32c37b6c6b3f79a8b6e5cc.zip
s0i3: parameterize the delays in wakeup_secondary_cpu_via_init()
Moorestown wants shorter delays in wakeup_secondary_cpu_via_init() when used for S0i3, so parameterize them. We should probably wrap this into a mrst_wakeup_secondary_cpu() and just use that one. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r--arch/x86/include/asm/apic.h7
-rw-r--r--arch/x86/kernel/smpboot.c21
-rw-r--r--drivers/idle/mrst_s0i3.c11
3 files changed, 35 insertions, 4 deletions
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 01374bffb06..52ecbcfd367 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -370,7 +370,14 @@ extern struct apic *apic;
#ifdef CONFIG_SMP
extern atomic_t init_deasserted;
extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip);
+struct init_wakeup_delays {
+ unsigned long assert_init;
+ unsigned long icr_accept;
+ unsigned long cpu_accept;
+};
extern int wakeup_secondary_cpu_via_init(int apicid, unsigned long start_eip);
+extern int wakeup_secondary_cpu_via_init_delays(int apicid,
+ unsigned long start_eip, const struct init_wakeup_delays *);
#endif
#ifdef CONFIG_X86_LOCAL_APIC
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index acca8594ccb..51934b761fb 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -583,6 +583,21 @@ wakeup_secondary_cpu_via_nmi(int logical_apicid, unsigned long start_eip)
int __cpuinit
wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
{
+ static const struct init_wakeup_delays delays =
+ {
+ .assert_init = 10000,
+ .icr_accept = 300,
+ .cpu_accept = 200,
+ };
+
+ return wakeup_secondary_cpu_via_init_delays(phys_apicid, start_eip,
+ &delays);
+}
+
+int __cpuinit
+wakeup_secondary_cpu_via_init_delays(int phys_apicid,
+ unsigned long start_eip, const struct init_wakeup_delays *delays)
+{
unsigned long send_status, accept_status = 0;
int maxlvt, num_starts, j;
@@ -611,7 +626,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
pr_debug("Waiting for send to finish...\n");
send_status = safe_apic_wait_icr_idle();
- mdelay(10);
+ udelay(delays->assert_init);
pr_debug("Deasserting INIT.\n");
@@ -668,7 +683,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
/*
* Give the other CPU some time to accept the IPI.
*/
- udelay(300);
+ udelay(delays->icr_accept);
pr_debug("Startup point 1.\n");
@@ -678,7 +693,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
/*
* Give the other CPU some time to accept the IPI.
*/
- udelay(200);
+ udelay(delays->cpu_accept);
if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
apic_write(APIC_ESR, 0);
accept_status = (apic_read(APIC_ESR) & 0xEF);
diff --git a/drivers/idle/mrst_s0i3.c b/drivers/idle/mrst_s0i3.c
index 3044cae899d..782d927b0b6 100644
--- a/drivers/idle/mrst_s0i3.c
+++ b/drivers/idle/mrst_s0i3.c
@@ -203,10 +203,19 @@ static void s0i3_restore_lapic(void)
* Leaving S0i3 will have put the other CPU thread into wait for SIPI;
* we need to put it back into C6 in order to be able to use S0i3
* again.
+ *
+ * XXX: this should probably be turned into a
+ * mrst_wakeup_secondary_cpu function.
*/
static void s0i3_poke_other_cpu(void)
{
- wakeup_secondary_cpu_via_init(1, s0i3_trampoline_phys);
+ const struct init_wakeup_delays delays = {
+ .assert_init = 0,
+ .icr_accept = 30,
+ .cpu_accept = 20,
+ };
+
+ wakeup_secondary_cpu_via_init_delays(1, s0i3_trampoline_phys, &delays);
}
/*