|
@@ -1017,3 +1017,64 @@ int pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
|
|
|
|
|
|
if (!pwrdm) {
|
|
if (!pwrdm) {
|
|
WARN(1, "powerdomain: %s: pwrdm is null\n", __func__);
|
|
WARN(1, "powerdomain: %s: pwrdm is null\n", __func__);
|
|
|
|
+ return -ENODEV;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ count = pwrdm->state_counter[PWRDM_POWER_OFF];
|
|
|
|
+ count += pwrdm->ret_logic_off_counter;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < pwrdm->banks; i++)
|
|
|
|
+ count += pwrdm->ret_mem_off_counter[i];
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Context loss count has to be a non-negative value. Clear the sign
|
|
|
|
+ * bit to get a value range from 0 to INT_MAX.
|
|
|
|
+ */
|
|
|
|
+ count &= INT_MAX;
|
|
|
|
+
|
|
|
|
+ pr_debug("powerdomain: %s: context loss count = %d\n",
|
|
|
|
+ pwrdm->name, count);
|
|
|
|
+
|
|
|
|
+ return count;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * pwrdm_can_ever_lose_context - can this powerdomain ever lose context?
|
|
|
|
+ * @pwrdm: struct powerdomain *
|
|
|
|
+ *
|
|
|
|
+ * Given a struct powerdomain * @pwrdm, returns 1 if the powerdomain
|
|
|
|
+ * can lose either memory or logic context or if @pwrdm is invalid, or
|
|
|
|
+ * returns 0 otherwise. This function is not concerned with how the
|
|
|
|
+ * powerdomain registers are programmed (i.e., to go off or not); it's
|
|
|
|
+ * concerned with whether it's ever possible for this powerdomain to
|
|
|
|
+ * go off while some other part of the chip is active. This function
|
|
|
|
+ * assumes that every powerdomain can go to either ON or INACTIVE.
|
|
|
|
+ */
|
|
|
|
+bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm)
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ if (IS_ERR_OR_NULL(pwrdm)) {
|
|
|
|
+ pr_debug("powerdomain: %s: invalid powerdomain pointer\n",
|
|
|
|
+ __func__);
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (pwrdm->pwrsts & PWRSTS_OFF)
|
|
|
|
+ return 1;
|
|
|
|
+
|
|
|
|
+ if (pwrdm->pwrsts & PWRSTS_RET) {
|
|
|
|
+ if (pwrdm->pwrsts_logic_ret & PWRSTS_OFF)
|
|
|
|
+ return 1;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < pwrdm->banks; i++)
|
|
|
|
+ if (pwrdm->pwrsts_mem_ret[i] & PWRSTS_OFF)
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < pwrdm->banks; i++)
|
|
|
|
+ if (pwrdm->pwrsts_mem_on[i] & PWRSTS_OFF)
|
|
|
|
+ return 1;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|