/* * arm64_idle_sprd_init * * Registers the arm64 specific cpuidle driver with the cpuidle * framework. It relies on core code to parse the idle states * and initialize them using driver data structures accordingly. */ int __init arm64_idle_sprd_init(void) { int i, ret; const char *entry_method; struct device_node *idle_states_node; const struct cpu_suspend_ops *suspend_init; struct cpuidle_driver *drv = &arm64_idle_driver; idle_states_node = of_find_node_by_path("/cpus/idle-states"); if (!idle_states_node) { return -ENOENT; } if (of_property_read_string(idle_states_node, "entry-method", &entry_method)) { pr_warn(" * %s missing entry-method property\n", idle_states_node->full_name); of_node_put(idle_states_node); return -EOPNOTSUPP; } /* * State at index 0 is standby wfi and considered standard * on all ARM platforms. If in some platforms simple wfi * can't be used as "state 0", DT bindings must be implemented * to work around this issue and allow installing a special * handler for idle state index 0. */ drv->states[0].exit_latency = 1; drv->states[0].target_residency = 1; drv->states[0].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TIMER_STOP; strncpy(drv->states[0].name, "ARM WFI", CPUIDLE_NAME_LEN); strncpy(drv->states[0].desc, "ARM WFI", CPUIDLE_DESC_LEN); drv->cpumask = (struct cpumask *) cpu_possible_mask; /* * Start at index 1, request idle state nodes to be filled */ ret = of_init_idle_driver(drv, state_nodes, 1, true); if (ret) { return ret; } for (i = 0; i < drv->state_count; i++) drv->states[i].enter = arm_enter_idle_state; printk("[CPUIDLE]<arm64_idle_sprd_init> init OK. \n"); return cpuidle_register(drv, NULL); }
static int __init exynos_idle_state_init(struct cpuidle_driver *idle_drv, const struct cpumask *mask) { int i, ret; const char *entry_method; struct device_node *idle_states_node; const struct cpu_suspend_ops *suspend_init; struct cpuidle_driver *drv = idle_drv; idle_states_node = of_find_node_by_path("/cpus/idle-states"); if (!idle_states_node) return -ENOENT; if (of_property_read_string(idle_states_node, "entry-method", &entry_method)) { pr_warn(" * %s missing entry-method property\n", idle_states_node->full_name); of_node_put(idle_states_node); return -EOPNOTSUPP; } suspend_init = get_suspend_ops(entry_method); if (!suspend_init) { pr_warn("Missing suspend initializer\n"); of_node_put(idle_states_node); return -EOPNOTSUPP; } drv->cpumask = (struct cpumask *)mask; ret = of_init_idle_driver(drv, state_nodes, 0, true); if (ret) return ret; if (suspend_init->init_fn(drv, state_nodes)) return -EOPNOTSUPP; for (i = 0; i < drv->state_count; i++) drv->states[i].enter = exynos_enter_idle_state; return 0; }