On Wed, 2016-06-08 at 11:54 -0500, Shreyas B. Prabhu wrote: > > /* > * States for dedicated partition case. > */ > @@ -167,6 +183,8 @@ static int powernv_add_idle_states(void) > int nr_idle_states = 1; /* Snooze */ > int dt_idle_states; > u32 *latency_ns, *residency_ns, *flags; > + u64 *psscr_val = NULL; > + const char *names[CPUIDLE_STATE_MAX]; > int i, rc; > > /* Currently we have snooze statically defined */ > @@ -199,12 +217,41 @@ static int powernv_add_idle_states(void) > goto out_free_latency; > } > > + rc = of_property_read_string_array(power_mgt, > + "ibm,cpu-idle-state-names", names, > + dt_idle_states);
Ok so from this I assume that dt_idle_states is the number of entries, which has been checked properly to be < CPUIDLE_STATE_MAX correct ? Beause ... > + if (rc < 0) { > + pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-names in > DT\n"); > + goto out_free_latency; > + } > + > + /* > + * If the idle states use stop instruction, probe for psscr values > + * which are necessary to specify required stop level. > + */ > + if (flags[0] & (OPAL_PM_STOP_INST_FAST | OPAL_PM_STOP_INST_DEEP)) { > + psscr_val = kcalloc(dt_idle_states, sizeof(*psscr_val), > + GFP_KERNEL); > + rc = of_property_read_u64_array(power_mgt, > + "ibm,cpu-idle-state-psscr", > + psscr_val, dt_idle_states); Here, psscr val is only one u64 ... shouldn't you kmalloc sizeof(..) * dt_idle_states ? > + if (rc) { > + pr_warn("cpuidle-powernv: missing > ibm,cpu-idle-states-psscr in DT\n"); > + goto out_free_psscr; > + } > + } > residency_ns = kzalloc(sizeof(*residency_ns) * dt_idle_states, > GFP_KERNEL); Just like we do here > rc = of_property_read_u32_array(power_mgt, > "ibm,cpu-idle-state-residency-ns", residency_ns, dt_idle_states); > for (i = 0; i < dt_idle_states; i++) { > - > + /* > + * If an idle state has exit latency beyond > + * POWERNV_THRESHOLD_LATENCY_NS then don't use it > + * in cpu-idle. > + */ > + if (latency_ns[i] > POWERNV_THRESHOLD_LATENCY_NS) > + continue; > /* > * Cpuidle accepts exit_latency and target_residency in us. > * Use default target_residency values if f/w does not expose > it. > @@ -216,6 +263,16 @@ static int powernv_add_idle_states(void) > powernv_states[nr_idle_states].flags = 0; > powernv_states[nr_idle_states].target_residency = 100; > powernv_states[nr_idle_states].enter = &nap_loop; > + } else if ((flags[i] & OPAL_PM_STOP_INST_FAST) && > + !(flags[i] & OPAL_PM_TIMEBASE_STOP)) { > + strncpy(powernv_states[nr_idle_states].name, > + names[i], CPUIDLE_NAME_LEN); > + strncpy(powernv_states[nr_idle_states].desc, > + names[i], CPUIDLE_NAME_LEN); > + powernv_states[nr_idle_states].flags = 0; > + > + powernv_states[nr_idle_states].enter = stop_loop; > + stop_psscr_table[nr_idle_states] = psscr_val[i]; > } > > /* > @@ -231,6 +288,16 @@ static int powernv_add_idle_states(void) > powernv_states[nr_idle_states].flags = > CPUIDLE_FLAG_TIMER_STOP; > powernv_states[nr_idle_states].target_residency = > 300000; > powernv_states[nr_idle_states].enter = &fastsleep_loop; > + } else if ((flags[i] & OPAL_PM_STOP_INST_DEEP) && > + (flags[i] & OPAL_PM_TIMEBASE_STOP)) { > + strncpy(powernv_states[nr_idle_states].name, > + names[i], CPUIDLE_NAME_LEN); > + strncpy(powernv_states[nr_idle_states].desc, > + names[i], CPUIDLE_NAME_LEN); > + > + powernv_states[nr_idle_states].flags = > CPUIDLE_FLAG_TIMER_STOP; > + powernv_states[nr_idle_states].enter = stop_loop; > + stop_psscr_table[nr_idle_states] = psscr_val[i]; > } > #endif > powernv_states[nr_idle_states].exit_latency = > @@ -245,6 +312,8 @@ static int powernv_add_idle_states(void) > } > > kfree(residency_ns); > +out_free_psscr: > + kfree(psscr_val); > out_free_latency: > kfree(latency_ns); > out_free_flags: _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev