int psci_affinity_info(unsigned long target_affinity, unsigned int lowest_affinity_level) { int rc = PSCI_E_INVALID_PARAMS; unsigned int aff_state; aff_map_node *node; if (lowest_affinity_level > get_max_afflvl()) return rc; node = psci_get_aff_map_node(target_affinity, lowest_affinity_level); if (node && (node->state & PSCI_AFF_PRESENT)) { /* * TODO: For affinity levels higher than 0 i.e. cpu, the * state will always be either ON or OFF. Need to investigate * how critical is it to support ON_PENDING here. */ aff_state = psci_get_state(node); /* A suspended cpu is available & on for the OS */ if (aff_state == PSCI_STATE_SUSPEND) { aff_state = PSCI_STATE_ON; } rc = aff_state; } return rc; }
int psci_affinity_info(unsigned long target_affinity, unsigned int lowest_affinity_level) { int rc = PSCI_E_INVALID_PARAMS; unsigned int aff_state; aff_map_node *node; if (lowest_affinity_level > get_max_afflvl()) { goto exit; } node = psci_get_aff_map_node(target_affinity, lowest_affinity_level); if (node && (node->state & PSCI_AFF_PRESENT)) { aff_state = psci_get_state(node->state); /* A suspended cpu is available & on for the OS */ if (aff_state == PSCI_STATE_SUSPEND) { aff_state = PSCI_STATE_ON; } rc = aff_state; } exit: return rc; }
/******************************************************************************* * Routine to return the maximum affinity level to traverse to after a cpu has * been physically powered up. It is expected to be called immediately after * reset from assembler code. ******************************************************************************/ int get_power_on_target_afflvl(void) { int afflvl; #if DEBUG unsigned int state; aff_map_node_t *node; /* Retrieve our node from the topology tree */ node = psci_get_aff_map_node(read_mpidr_el1() & MPIDR_AFFINITY_MASK, MPIDR_AFFLVL0); assert(node); /* * Sanity check the state of the cpu. It should be either suspend or "on * pending" */ state = psci_get_state(node); assert(state == PSCI_STATE_SUSPEND || state == PSCI_STATE_ON_PENDING); #endif /* * Assume that this cpu was suspended and retrieve its target affinity * level. If it is invalid then it could only have been turned off * earlier. PLATFORM_MAX_AFFLVL will be the highest affinity level a * cpu can be turned off to. */ afflvl = psci_get_suspend_afflvl(); if (afflvl == PSCI_INVALID_DATA) afflvl = PLATFORM_MAX_AFFLVL; return afflvl; }
/******************************************************************************* * Simple routine to determine whether an affinity instance at a given level * in an mpidr exists or not. ******************************************************************************/ int psci_validate_mpidr(unsigned long mpidr, int level) { aff_map_node_t *node; node = psci_get_aff_map_node(mpidr, level); if (node && (node->state & PSCI_AFF_PRESENT)) return PSCI_E_SUCCESS; else return PSCI_E_INVALID_PARAMS; }