Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755324AbcK2AzW (ORCPT ); Mon, 28 Nov 2016 19:55:22 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:45086 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754978AbcK2AzO (ORCPT ); Mon, 28 Nov 2016 19:55:14 -0500 DMARC-Filter: OpenDMARC Filter v1.3.1 smtp.codeaurora.org C9BA5613A9 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=pass smtp.mailfrom=sboyd@codeaurora.org Date: Mon, 28 Nov 2016 16:55:12 -0800 From: Stephen Boyd To: Viresh Kumar Cc: Rafael Wysocki , nm@ti.com, Viresh Kumar , linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Vincent Guittot , robh@kernel.org, d-gerlach@ti.com, broonie@kernel.org, devicetree@vger.kernel.org Subject: Re: [PATCH V4 06/10] PM / OPP: Add infrastructure to manage multiple regulators Message-ID: <20161129005512.GQ6095@codeaurora.org> References: <9ef150da6d3344d2ad4ce884f777174a3aef5dc1.1479986491.git.viresh.kumar@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <9ef150da6d3344d2ad4ce884f777174a3aef5dc1.1479986491.git.viresh.kumar@linaro.org> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2626 Lines: 95 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