diff options
author | Robert Lippert <rlippert@google.com> | 2017-11-20 11:41:25 +0530 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2017-11-20 20:36:07 -0600 |
commit | d665e102ef3760d590a35b9051a8941062e22df5 (patch) | |
tree | b76e5ae4b382e7eb4b1bd0fc692d07404b4dac20 /hw | |
parent | c5cf392b75dceee478a2e73012bbcf3b439fc0c1 (diff) | |
download | skiboot-d665e102ef3760d590a35b9051a8941062e22df5.zip skiboot-d665e102ef3760d590a35b9051a8941062e22df5.tar.gz skiboot-d665e102ef3760d590a35b9051a8941062e22df5.tar.bz2 |
hw/dts: retry special wakeup operation if core still gated
It has been observed that in some cases the special wakeup
operation can "succeed" but the core is still in a gated/offline
state.
Check for this state after attempting to wakeup a core and retry
the wakeup if necessary.
Change-Id: Ia6b1b75dcab590c299bed3ee0a42031f09c39eda
Signed-off-by: Robert Lippert <rlippert@google.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/dts.c | 30 |
1 files changed, 29 insertions, 1 deletions
@@ -236,6 +236,34 @@ static int dts_read_core_temp_p9(uint32_t pir, struct dts *dts) return 0; } +static int dts_wakeup_core(struct cpu_thread *cpu) +{ + int retries = 10; + int rc; + + while (retries-- > 0) { + rc = dctl_set_special_wakeup(cpu); + if (rc) { + prerror("Failed to set special wakeup on %d (%d)\n", + cpu->pir, rc); + return rc; + } + + if (!dctl_core_is_gated(cpu)) + break; + + prlog(PR_NOTICE, "Retrying special wakeup on %d\n", cpu->pir); + rc = dctl_clear_special_wakeup(cpu); + if (rc) { + prerror("Failed to clear special wakeup on %d (%d)\n", + cpu->pir, rc); + return rc; + } + } + + return rc; +} + static void dts_async_read_temp(struct timer *t __unused, void *data, u64 now __unused) { @@ -243,7 +271,7 @@ static void dts_async_read_temp(struct timer *t __unused, void *data, int rc, swkup_rc; struct cpu_thread *cpu = data; - swkup_rc = dctl_set_special_wakeup(cpu); + swkup_rc = dts_wakeup_core(cpu); rc = dts_read_core_temp_p9(cpu->pir, &dts); if (!rc) { |