aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Lippert <rlippert@google.com>2017-11-20 11:41:25 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-11-20 20:36:07 -0600
commitd665e102ef3760d590a35b9051a8941062e22df5 (patch)
treeb76e5ae4b382e7eb4b1bd0fc692d07404b4dac20
parentc5cf392b75dceee478a2e73012bbcf3b439fc0c1 (diff)
downloadskiboot-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>
-rw-r--r--hw/dts.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/hw/dts.c b/hw/dts.c
index 72a392b..d881f96 100644
--- a/hw/dts.c
+++ b/hw/dts.c
@@ -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) {