/** * omap3_idle_init - Init routine for OMAP3 idle * * Registers the OMAP3 specific cpuidle driver with the cpuidle * framework with the valid set of states. */ int __init omap3_idle_init(void) { int i, count = 0; struct omap3_processor_cx *cx; struct cpuidle_state *state; struct cpuidle_device *dev; mpu_pd = pwrdm_lookup("mpu_pwrdm"); core_pd = pwrdm_lookup("core_pwrdm"); per_pd = pwrdm_lookup("per_pwrdm"); cam_pd = pwrdm_lookup("cam_pwrdm"); omap_init_power_states(); cpuidle_register_driver(&omap3_idle_driver); dev = &per_cpu(omap3_idle_dev, smp_processor_id()); for (i = OMAP3_STATE_C1; i < OMAP3_MAX_STATES; i++) { cx = &omap3_power_states[i]; state = &dev->states[count]; if (!cx->valid) continue; cpuidle_set_statedata(state, cx); state->exit_latency = cx->sleep_latency + cx->wakeup_latency; state->target_residency = cx->threshold; state->flags = cx->flags; state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ? omap3_enter_idle_bm : omap3_enter_idle; if (cx->type == OMAP3_STATE_C1) dev->safe_state = state; sprintf(state->name, "C%d", count+1); strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); count++; } if (!count) return -EINVAL; dev->state_count = count; if (enable_off_mode) omap3_cpuidle_update_states(PWRDM_POWER_OFF, PWRDM_POWER_OFF); else omap3_cpuidle_update_states(PWRDM_POWER_RET, PWRDM_POWER_RET); if (cpuidle_register_device(dev)) { printk(KERN_ERR "%s: CPUidle register device failed\n", __func__); return -EIO; } return 0; }
static __init int omap3_idle_init(void) { int i, count = 0; struct omap3_processor_cx *cx; struct cpuidle_state *state; struct cpuidle_device *dev; printk(KERN_INFO "OMAP CPU idle driver initializing.\n"); cpuidle_register_driver(&omap3_idle_driver); dev = &per_cpu(omap3_idle_dev, smp_processor_id()); for (i = 0; i < OMAP3_MAX_STATES; i++) { cx = &omap3_power_states[i]; state = &dev->states[count]; if (!cx->valid) continue; cpuidle_set_statedata(state, cx); state->exit_latency = cx->sleep_latency + cx->wakeup_latency; state->target_residency = cx->threshold; state->flags = cx->flags; state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ? omap3_enter_idle_bm : omap3_enter_idle; if (cx->type == OMAP3_STATE_C3) dev->safe_state = state; snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", count+1); count++; BUG_ON(count == CPUIDLE_STATE_MAX); /* harsh... oh well */ } if (!count) return -EINVAL; /* No valid states configured. */ dev->state_count = count; if (cpuidle_register_device(dev)) { printk(KERN_ERR "%s: CPUidle register device failed\n", __FUNCTION__); return -EIO; } create_pmproc_entry(); /* Initialize UART inactivity time */ uart_inactivity_timeout = msecs_to_jiffies(UART_TIME_OUT); uart_last_awake = jiffies; return 0; }
static void poll_idle_init(struct cpuidle_device *dev) { struct cpuidle_state *state = &dev->states[0]; cpuidle_set_statedata(state, NULL); snprintf(state->name, CPUIDLE_NAME_LEN, "POLL"); snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE"); state->exit_latency = 0; state->target_residency = 0; state->power_usage = -1; state->flags = 0; state->enter = poll_idle; }
/** * acpi_processor_setup_cpuidle_cx - prepares and configures CPUIDLE * device i.e. per-cpu data * * @pr: the ACPI processor */ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr) { int i, count = CPUIDLE_DRIVER_STATE_START; struct acpi_processor_cx *cx; struct cpuidle_state_usage *state_usage; struct cpuidle_device *dev = per_cpu(acpi_cpuidle_device, pr->id); if (!pr->flags.power_setup_done) return -EINVAL; if (pr->flags.power == 0) { return -EINVAL; } if (!dev) return -EINVAL; dev->cpu = pr->id; if (max_cstate == 0) max_cstate = 1; for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) { cx = &pr->power.states[i]; state_usage = &dev->states_usage[count]; if (!cx->valid) continue; #ifdef CONFIG_HOTPLUG_CPU if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) continue; #endif cpuidle_set_statedata(state_usage, cx); count++; if (count == CPUIDLE_STATE_MAX) break; } dev->state_count = count; if (!count) return -EINVAL; return 0; }
/** * omap4_idle_init - Init routine for OMAP4 idle * * Registers the OMAP4 specific cpuidle driver with the cpuidle * framework with the valid set of states. */ int __init omap4_idle_init(void) { int cpu_id, i, count = 0; struct omap4_processor_cx *cx; struct cpuidle_state *state; struct cpuidle_device *dev; mpu_pd = pwrdm_lookup("mpu_pwrdm"); cpu1_pd = pwrdm_lookup("cpu1_pwrdm"); core_pd = pwrdm_lookup("core_pwrdm"); omap_init_power_states(); cpuidle_register_driver(&omap4_idle_driver); for_each_cpu(cpu_id, cpu_online_mask) { pr_err("CPUidle for CPU%d registered\n", cpu_id); dev = &per_cpu(omap4_idle_dev, cpu_id); dev->cpu = cpu_id; count = 0; for (i = OMAP4_STATE_C1; i < OMAP4_MAX_STATES; i++) { cx = &omap4_power_states[i]; state = &dev->states[count]; if (!cx->valid) continue; cpuidle_set_statedata(state, cx); state->exit_latency = cx->sleep_latency + cx->wakeup_latency; state->target_residency = cx->threshold; state->flags = cx->flags; if (cx->type == OMAP4_STATE_C1) dev->safe_state = state; state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ? omap4_enter_idle_bm : omap4_enter_idle; sprintf(state->name, "C%d", count+1); strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); count++; } if (!count) return -EINVAL; dev->state_count = count; if (cpuidle_register_device(dev)) { printk(KERN_ERR "%s: CPUidle register device failed\n", __func__); return -EIO; } }
int omap3_idle_init(void) { int i, count = 0; struct omap3_processor_cx *cx; struct cpuidle_state *state; struct cpuidle_device *dev; omap_init_power_states(); cpuidle_register_driver(&omap3_idle_driver); dev = &per_cpu(omap3_idle_dev, smp_processor_id()); for (i = 0; i < OMAP3_MAX_STATES; i++) { cx = &omap3_power_states[i]; state = &dev->states[count]; if (!cx->valid) continue; cpuidle_set_statedata(state, cx); state->exit_latency = cx->sleep_latency + cx->wakeup_latency; state->target_residency = cx->threshold; state->flags = cx->flags; state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ? omap3_enter_idle_bm : omap3_enter_idle; if (cx->type == OMAP3_STATE_C2) dev->safe_state = state; sprintf(state->name, "C%d", count+1); count++; } if (!count) return -EINVAL; dev->state_count = count; if (cpuidle_register_device(dev)) { printk(KERN_ERR "%s: CPUidle register device failed\n", __FUNCTION__); return -EIO; } #ifdef CONFIG_PROC_FS create_pmproc_entry(); #endif /* #ifdef CONFIG_PROC_FS */ /* Initialize UART inactivity time */ awake_time_end = jiffies + msecs_to_jiffies(UART_TIME_OUT); return 0; }
/* Helper to fill the C-state common data and register the driver_data */ static inline struct omap3_idle_statedata *_fill_cstate( struct cpuidle_device *dev, int idx, const char *descr) { struct omap3_idle_statedata *cx = &omap3_idle_data[idx]; struct cpuidle_state *state = &dev->states[idx]; state->exit_latency = cpuidle_params_table[idx].exit_latency; state->target_residency = cpuidle_params_table[idx].target_residency; state->flags = CPUIDLE_FLAG_TIME_VALID; state->enter = omap3_enter_idle_bm; cx->valid = cpuidle_params_table[idx].valid; sprintf(state->name, "C%d", idx + 1); strncpy(state->desc, descr, CPUIDLE_DESC_LEN); cpuidle_set_statedata(state, cx); return cx; }
static void __devinit msm_cpuidle_set_cpu_statedata(struct cpuidle_device *dev) { int i = 0; int state_count = 0; struct cpuidle_state_usage *st_usage = NULL; struct msm_cpuidle_state *cstate = NULL; for (i = 0; i < ARRAY_SIZE(msm_cstates); i++) { cstate = &msm_cstates[i]; if (cstate->cpu != dev->cpu) continue; st_usage = &dev->states_usage[state_count]; cpuidle_set_statedata(st_usage, (void *)cstate->mode_nr); state_count++; BUG_ON(state_count > msm_cpuidle_driver.state_count); } }
void update_cpuidle_params(void) { int cpu_id = 0, i, count = 0; struct omap4_processor_cx *cx; struct cpuidle_state *state; struct cpuidle_device *dev; for_each_possible_cpu(cpu_id) { dev = &per_cpu(omap4_idle_dev, cpu_id); dev->cpu = cpu_id; count = 0; for (i = OMAP4_STATE_C1; i < OMAP4_MAX_STATES; i++) { cx = &omap4_power_states[i]; state = &dev->states[count]; if (!cx->valid) continue; cpuidle_set_statedata(state, cx); state->exit_latency = cx->exit_latency; state->target_residency = cx->target_residency; count++; } } }
/** * acpi_processor_setup_cpuidle - prepares and configures CPUIDLE * @pr: the ACPI processor */ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) { int i, count = CPUIDLE_DRIVER_STATE_START; struct acpi_processor_cx *cx; struct cpuidle_state *state; struct cpuidle_device *dev = &pr->power.dev; if (!pr->flags.power_setup_done) return -EINVAL; if (pr->flags.power == 0) { return -EINVAL; } dev->cpu = pr->id; for (i = 0; i < CPUIDLE_STATE_MAX; i++) { dev->states[i].name[0] = '\0'; dev->states[i].desc[0] = '\0'; } if (max_cstate == 0) max_cstate = 1; for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) { cx = &pr->power.states[i]; state = &dev->states[count]; if (!cx->valid) continue; #ifdef CONFIG_HOTPLUG_CPU if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) continue; #endif cpuidle_set_statedata(state, cx); snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i); strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); state->exit_latency = cx->latency; state->target_residency = cx->latency * latency_factor; state->power_usage = cx->power; state->flags = 0; switch (cx->type) { case ACPI_STATE_C1: state->flags |= CPUIDLE_FLAG_SHALLOW; if (cx->entry_method == ACPI_CSTATE_FFH) state->flags |= CPUIDLE_FLAG_TIME_VALID; state->enter = acpi_idle_enter_c1; dev->safe_state = state; break; case ACPI_STATE_C2: state->flags |= CPUIDLE_FLAG_BALANCED; state->flags |= CPUIDLE_FLAG_TIME_VALID; state->enter = acpi_idle_enter_simple; dev->safe_state = state; break; case ACPI_STATE_C3: state->flags |= CPUIDLE_FLAG_DEEP; state->flags |= CPUIDLE_FLAG_TIME_VALID; state->flags |= CPUIDLE_FLAG_CHECK_BM; state->enter = pr->flags.bm_check ? acpi_idle_enter_bm : acpi_idle_enter_simple; break; } count++; if (count == CPUIDLE_STATE_MAX) break; } dev->state_count = count; if (!count) return -EINVAL; return 0; }