On 11/24, Viresh Kumar wrote: > diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c > index 37fad2eb0f47..2d5c726c920f 100644 > --- a/drivers/base/power/opp/core.c > +++ b/drivers/base/power/opp/core.c > @@ -235,21 +240,41 @@ unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev) > return 0; > } > > - reg = opp_table->regulator; > - if (IS_ERR(reg)) { > + count = opp_table->regulator_count; > + > + if (!count) { > /* Regulator may not be required for device */ > rcu_read_unlock(); > return 0; > } > > - list_for_each_entry_rcu(opp, &opp_table->opp_list, node) { > - if (!opp->available) > - continue; > + size = count * sizeof(*regulators); > + regulators = kmemdup(opp_table->regulators, size, GFP_KERNEL); Again, can't allocate with sleeping calls under RCU read lock as it may have disabled preemption. > + if (!regulators) { > + rcu_read_unlock(); > + return 0; > + } > + > + uV = kmalloc_array(count, sizeof(*uV), GFP_KERNEL); > + if (!uV) { > + kfree(regulators); > + rcu_read_unlock(); > + return 0; > + } > > - if (opp->supply.u_volt_min < min_uV) > - min_uV = opp->supply.u_volt_min; > - if (opp->supply.u_volt_max > max_uV) > - max_uV = opp->supply.u_volt_max; > + for (i = 0; i < count; i++) { > + uV[i].min = ~0; > + uV[i].max = 0; > + > + list_for_each_entry_rcu(opp, &opp_table->opp_list, node) { > + if (!opp->available) > + continue; > + > + if (opp->supplies[i].u_volt_min < uV[i].min) > + uV[i].min = opp->supplies[i].u_volt_min; > + if (opp->supplies[i].u_volt_max > uV[i].max) > + uV[i].max = opp->supplies[i].u_volt_max; > + } > } > > rcu_read_unlock(); > @@ -924,35 +960,50 @@ struct dev_pm_opp *_allocate_opp(struct device *dev, > struct opp_table **opp_table) > { > struct dev_pm_opp *opp; > + int count, supply_size; > + struct opp_table *table; > > - /* allocate new OPP node */ > - opp = kzalloc(sizeof(*opp), GFP_KERNEL); > - if (!opp) > + table = _add_opp_table(dev); > + if (!table) > return NULL; > > - INIT_LIST_HEAD(&opp->node); > + /* Allocate space for at least one supply */ > + count = table->regulator_count ? table->regulator_count : 1; > + supply_size = sizeof(*opp->supplies) * count; > > - *opp_table = _add_opp_table(dev); > - if (!*opp_table) { > - kfree(opp); > + /* allocate new OPP node + and supplies structures */ s/+// > + opp = kzalloc(sizeof(*opp) + supply_size, GFP_KERNEL); > + if (!opp) { > + kfree(table); > return NULL; > } > -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html