Skip to content

Commit

Permalink
cpu: Do an isync after setting LPCR
Browse files Browse the repository at this point in the history
This is required by the architecture and the implementations, I've
observed failures to wake up on big cores without this.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
  • Loading branch information
ozbenh authored and stewartsmith committed May 24, 2018
1 parent 98ad450 commit a8700b5
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 0 deletions.
3 changes: 3 additions & 0 deletions core/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ static void cpu_idle_p8(enum cpu_wake_cause wake_on)
lpcr |= SPR_LPCR_P8_PECE2 | SPR_LPCR_P8_PECE3;
mtspr(SPR_LPCR, lpcr);
}
isync();

/* Enter nap */
enter_p8_pm_state(false);
Expand Down Expand Up @@ -404,6 +405,7 @@ static void cpu_idle_p9(enum cpu_wake_cause wake_on)
}

mtspr(SPR_LPCR, lpcr);
isync();

if (sreset_enabled) {
/* stop with EC=1 (sreset) and ESL=1 (enable thread switch). */
Expand Down Expand Up @@ -973,6 +975,7 @@ static void enable_large_dec(bool on)
lpcr &= ~SPR_LPCR_P9_LD;

mtspr(SPR_LPCR, lpcr);
isync();
}

#define HIGH_BIT (1ull << 63)
Expand Down
1 change: 1 addition & 0 deletions core/fast-reboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ static void check_split_core(void)
/* Setup LPCR to wakeup on external interrupts only */
mtspr(SPR_LPCR, ((mfspr(SPR_LPCR) & ~SPR_LPCR_P8_PECE) |
SPR_LPCR_P8_PECE2));
isync();
/* Go to nap (doesn't return) */
enter_nap();
}
Expand Down
2 changes: 2 additions & 0 deletions hw/slw.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ static void slw_do_rvwinkle(void *data)

/* Setup LPCR to wakeup on external interrupts only */
mtspr(SPR_LPCR, ((lpcr & ~SPR_LPCR_P8_PECE) | SPR_LPCR_P8_PECE2));
isync();

prlog(PR_DEBUG, "SLW: CPU PIR 0x%04x goint to rvwinkle...\n",
cpu->pir);
Expand All @@ -99,6 +100,7 @@ static void slw_do_rvwinkle(void *data)

/* Restore LPCR */
mtspr(SPR_LPCR, lpcr);
isync();

/* If we are passed a master pointer we are the designated
* waker, let's proceed. If not, return, we are finished.
Expand Down

0 comments on commit a8700b5

Please sign in to comment.