assert(cpu_node->level == MPIDR_AFFLVL0);
- /* State management: mark this cpu as turned off */
- psci_set_state(cpu_node, PSCI_STATE_OFF);
-
/*
* Generic management: Get the index for clearing any lingering re-entry
* information and allow the secure world to switch itself off
/* Sanity check the cluster level */
assert(cluster_node->level == MPIDR_AFFLVL1);
- /* State management: Decrement the cluster reference count */
- psci_set_state(cluster_node, PSCI_STATE_OFF);
-
/*
* Keep the physical state of this cluster handy to decide
* what action needs to be taken
/* Cannot go beyond this level */
assert(system_node->level == MPIDR_AFFLVL2);
- /* State management: Decrement the system reference count */
- psci_set_state(system_node, PSCI_STATE_OFF);
-
/*
* Keep the physical state of the system handy to decide what
* action needs to be taken
end_afflvl,
mpidr_nodes);
+ /*
+ * This function updates the state of each affinity instance
+ * corresponding to the mpidr in the range of affinity levels
+ * specified.
+ */
+ psci_do_afflvl_state_mgmt(start_afflvl,
+ end_afflvl,
+ mpidr_nodes,
+ PSCI_STATE_OFF);
/* Perform generic, architecture and platform specific handling */
rc = psci_call_off_handlers(mpidr_nodes,
start_afflvl,
/* Set the secure world (EL3) re-entry point after BL1 */
psci_entrypoint = (unsigned long) psci_aff_on_finish_entry;
- /* State management: Set this cpu's state as ON PENDING */
- psci_set_state(cpu_node, PSCI_STATE_ON_PENDING);
-
/*
* Plat. management: Give the platform the current state
* of the target cpu to allow it to perform the necessary
entrypoint,
context_id);
+ /*
+ * This function updates the state of each affinity instance
+ * corresponding to the mpidr in the range of affinity levels
+ * specified.
+ */
+ if (rc == PSCI_E_SUCCESS)
+ psci_do_afflvl_state_mgmt(start_afflvl,
+ end_afflvl,
+ target_cpu_nodes,
+ PSCI_STATE_ON_PENDING);
+
/*
* This loop releases the lock corresponding to each affinity level
* in the reverse order to which they were acquired.
*/
cm_prepare_el3_exit(NON_SECURE);
- /* State management: mark this cpu as on */
- psci_set_state(cpu_node, PSCI_STATE_ON);
-
/* Clean caches before re-entering normal world */
dcsw_op_louis(DCCSW);
assert(rc == PSCI_E_SUCCESS);
}
- /* State management: Increment the cluster reference count */
- psci_set_state(cluster_node, PSCI_STATE_ON);
-
return rc;
}
assert(rc == PSCI_E_SUCCESS);
}
- /* State management: Increment the system reference count */
- psci_set_state(system_node, PSCI_STATE_ON);
-
return rc;
}
psci_afflvl1_on_finish,
psci_afflvl2_on_finish,
};
-
if (psci_spd_pm && psci_spd_pm->svc_suspend)
psci_spd_pm->svc_suspend(power_state);
- /* State management: mark this cpu as suspended */
- psci_set_state(cpu_node, PSCI_STATE_SUSPEND);
-
/*
* Generic management: Store the re-entry information for the
* non-secure world
/* Sanity check the cluster level */
assert(cluster_node->level == MPIDR_AFFLVL1);
- /* State management: Decrement the cluster reference count */
- psci_set_state(cluster_node, PSCI_STATE_SUSPEND);
-
/*
* Keep the physical state of this cluster handy to decide
* what action needs to be taken
/* Cannot go beyond this */
assert(system_node->level == MPIDR_AFFLVL2);
- /* State management: Decrement the system reference count */
- psci_set_state(system_node, PSCI_STATE_SUSPEND);
-
/*
* Keep the physical state of the system handy to decide what
* action needs to be taken
end_afflvl,
mpidr_nodes);
+ /*
+ * This function updates the state of each affinity instance
+ * corresponding to the mpidr in the range of affinity levels
+ * specified.
+ */
+ psci_do_afflvl_state_mgmt(start_afflvl,
+ end_afflvl,
+ mpidr_nodes,
+ PSCI_STATE_SUSPEND);
/* Perform generic, architecture and platform specific handling */
rc = psci_call_suspend_handlers(mpidr_nodes,
start_afflvl,
*/
cm_prepare_el3_exit(NON_SECURE);
- /* State management: mark this cpu as on */
- psci_set_state(cpu_node, PSCI_STATE_ON);
-
/* Clean caches before re-entering normal world */
dcsw_op_louis(DCCSW);
assert(rc == PSCI_E_SUCCESS);
}
- /* State management: Increment the cluster reference count */
- psci_set_state(cluster_node, PSCI_STATE_ON);
-
return rc;
}
assert(rc == PSCI_E_SUCCESS);
}
- /* State management: Increment the system reference count */
- psci_set_state(system_node, PSCI_STATE_ON);
-
return rc;
}
return PSCI_E_SUCCESS;
}
+/*******************************************************************************
+ * This function is passed an array of pointers to affinity level nodes in the
+ * topology tree for an mpidr and the state which each node should transition
+ * to. It updates the state of each node between the specified affinity levels.
+ ******************************************************************************/
+void psci_do_afflvl_state_mgmt(uint32_t start_afflvl,
+ uint32_t end_afflvl,
+ mpidr_aff_map_nodes_t mpidr_nodes,
+ uint32_t state)
+{
+ uint32_t level;
+
+ for (level = start_afflvl; level <= end_afflvl; level++) {
+ if (mpidr_nodes[level] == NULL)
+ continue;
+ psci_set_state(mpidr_nodes[level], state);
+ }
+}
+
/*******************************************************************************
* This function is passed an array of pointers to affinity level nodes in the
* topology tree for an mpidr. It picks up locks for each affinity level bottom
if (rc != PSCI_E_SUCCESS)
panic();
+ /*
+ * This function updates the state of each affinity instance
+ * corresponding to the mpidr in the range of affinity levels
+ * specified.
+ */
+ psci_do_afflvl_state_mgmt(start_afflvl,
+ end_afflvl,
+ mpidr_nodes,
+ PSCI_STATE_ON);
+
/*
* This loop releases the lock corresponding to each affinity level
* in the reverse order to which they were acquired.
uint64_t entrypoint, uint64_t context_id,
uint32_t caller_scr_el3, uint32_t caller_sctlr_el1);
int psci_check_afflvl_range(int start_afflvl, int end_afflvl);
+void psci_do_afflvl_state_mgmt(uint32_t start_afflvl,
+ uint32_t end_afflvl,
+ mpidr_aff_map_nodes_t mpidr_nodes,
+ uint32_t state);
void psci_acquire_afflvl_locks(int start_afflvl,
int end_afflvl,
mpidr_aff_map_nodes_t mpidr_nodes);