Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757597AbcCUTSt (ORCPT ); Mon, 21 Mar 2016 15:18:49 -0400 Received: from mezzanine.sirena.org.uk ([106.187.55.193]:50728 "EHLO mezzanine.sirena.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757404AbcCUTSq (ORCPT ); Mon, 21 Mar 2016 15:18:46 -0400 From: Mark Brown To: Ivaylo Dimitrov , Liam Girdwood Cc: linux-kernel@vger.kernel.org, Mark Brown Date: Mon, 21 Mar 2016 19:18:32 +0000 Message-Id: <1458587912-32665-2-git-send-email-broonie@kernel.org> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1458587912-32665-1-git-send-email-broonie@kernel.org> References: <1458587912-32665-1-git-send-email-broonie@kernel.org> X-SA-Exim-Connect-IP: 2a01:348:6:8808:fab::3 X-SA-Exim-Mail-From: broonie@sirena.org.uk Subject: [PATCH 2/2] regulator: core: Ensure we are at least in bounds for our constraints X-SA-Exim-Version: 4.2.1 (built Mon, 26 Dec 2011 16:24:06 +0000) X-SA-Exim-Scanned: Yes (on mezzanine.sirena.org.uk) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2496 Lines: 71 Currently we only attempt to set the voltage during constraints application if an exact voltage is specified. Extend this so that if the currently set voltage for the regualtor is outside the bounds set in constraints we will move the voltage to the nearest constraint, raising to the minimum or lowering to the maximum as needed. This ensures that drivers can probe without the hardware being driven out of spec. Reported-by: Ivaylo Dimitrov Signed-off-by: Mark Brown --- Untested so far, will give it a spin later/tomorrow. drivers/regulator/core.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index fab065304fe2..f2acb6744c48 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -907,7 +907,8 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, /* do we need to apply the constraint voltage */ if (rdev->constraints->apply_uV && - rdev->constraints->min_uV == rdev->constraints->max_uV) { + rdev->constraints->min_uV && rdev->constraints->max_uV) { + int target_min, target_max; int current_uV = _regulator_get_voltage(rdev); if (current_uV < 0) { rdev_err(rdev, @@ -915,15 +916,32 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, current_uV); return current_uV; } - if (current_uV < rdev->constraints->min_uV || - current_uV > rdev->constraints->max_uV) { + + /* + * If we're below the minimum voltage move up to the + * minimum voltage, if we're above the maximum voltage + * then move down to the maximum. + */ + target_min = current_uV; + target_max = current_uV; + + if (current_uV < rdev->constraints->min_uV) { + target_min = rdev->constraints->min_uV; + target_max = rdev->constraints->min_uV; + } + + if (current_uV > rdev->constraints->max_uV) { + target_min = rdev->constraints->max_uV; + target_max = rdev->constraints->max_uV; + } + + if (target_min != current_uV || target_max != current_uV) { ret = _regulator_do_set_voltage( - rdev, rdev->constraints->min_uV, - rdev->constraints->max_uV); + rdev, target_min, target_max); if (ret < 0) { rdev_err(rdev, - "failed to apply %duV constraint(%d)\n", - rdev->constraints->min_uV, ret); + "failed to apply %d-%duV constraint(%d)\n", + target_min, target_max, ret); return ret; } } -- 2.7.0