static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu) { int i, ret, count = 0; u32 *psci_states; struct device_node *state_node; /* * If the PSCI cpu_suspend function hook has not been initialized * idle states must not be enabled, so bail out */ if (!psci_ops.cpu_suspend) return -EOPNOTSUPP; /* Count idle states */ while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states", count))) { count++; of_node_put(state_node); } if (!count) return -ENODEV; psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL); if (!psci_states) return -ENOMEM; for (i = 0; i < count; i++) { u32 state; state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i); ret = of_property_read_u32(state_node, "arm,psci-suspend-param", &state); if (ret) { pr_warn(" * %s missing arm,psci-suspend-param property\n", state_node->full_name); of_node_put(state_node); goto free_mem; } of_node_put(state_node); pr_debug("psci-power-state %#x index %d\n", state, i); if (!psci_power_state_is_valid(state)) { pr_warn("Invalid PSCI power state %#x\n", state); ret = -EINVAL; goto free_mem; } psci_states[i] = state; } /* Idle states parsed correctly, initialize per-cpu pointer */ per_cpu(psci_power_state, cpu) = psci_states; return 0; free_mem: kfree(psci_states); return ret; }
static int __maybe_unused psci_acpi_cpu_init_idle(unsigned int cpu) { int i, count; u32 *psci_states; struct acpi_lpi_state *lpi; struct acpi_processor *pr = per_cpu(processors, cpu); if (unlikely(!pr || !pr->flags.has_lpi)) return -EINVAL; count = pr->power.count - 1; if (count <= 0) return -ENODEV; psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL); if (!psci_states) return -ENOMEM; for (i = 0; i < count; i++) { u32 state; lpi = &pr->power.lpi_states[i + 1]; /* * Only bits[31:0] represent a PSCI power_state while * bits[63:32] must be 0x0 as per ARM ACPI FFH Specification */ state = lpi->address; if (!psci_power_state_is_valid(state)) { pr_warn("Invalid PSCI power state %#x\n", state); kfree(psci_states); return -EINVAL; } psci_states[i] = state; } /* Idle states parsed correctly, initialize per-cpu pointer */ per_cpu(psci_power_state, cpu) = psci_states; return 0; }