Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp3509163imm; Thu, 17 May 2018 09:51:05 -0700 (PDT) X-Google-Smtp-Source: AB8JxZr3uQGWq0BNbKZy1yCRZELgIbpoTDa6RF1w7b7HXf13Pi2JSoSnQ0F61NbfVAAVwIesYiVp X-Received: by 2002:a17:902:265:: with SMTP id 92-v6mr5776914plc.368.1526575865809; Thu, 17 May 2018 09:51:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526575865; cv=none; d=google.com; s=arc-20160816; b=Ewlh3pPWCnYyVR/lZJ3J4MIqsm15lg/y6t9UA1SSrX1PqyriR1HaYbs+HIM5AtkQOT auKCnJbKa61HfrwHVRezfdgM0l1iKYO6NaAkC4i7GRgpyUCbAfT8pTmUOOT6Wh5Tflow EalUdE8vl62OTCeTgp8n9JnaqxQ9fOZHZ9cTyRDUPz8h2KEb+JKr+m3XUytNWLQ4eJdA mZmf0oOE/6IZkNCZNVJmezuDdH2u93zNE2mUmjMRBvJE4zjVmY1ZBgrLLpWtTKZH+HaS +gHoEETJl6H2GvmTn7wEVRHuU9CL93VlRz9o4pZmPtGIh30ja25UzAViOsJIsO6Bo4BD PJsQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:date:message-id:in-reply-to:subject:cc:to :from:dkim-signature:arc-authentication-results; bh=Hwr1RJ2zhW1+FOrZ6lQPmBUjewv5MncY8iGzq067EYw=; b=HXzVdEmBXo9QsLgW64Zfzv8B9QfcboiQD4GH/Mica10Cj+KBFmFpVJ97QghAZrFKWz UDQ6ACIimuSluN25thpxW65/4HF+eWYE6VbiP/R3cCDKFvUL5Sd3Dn19M9HkmjN7eCkc rdORE0V6azLhrM9vnJdL5PdONkFdczyEOm4PiUH8PDRrx6ipw53EdxMbGNIDKAvn70Q1 XjQX4OGqA/YgUdBzbnDAQG7El4clAYL4Um41A3OKBkJ/h8BiX4a+hlFBU2QjG+2ZtmBv WkyHZU4jjrjn63iSi3Vye9SUjE8GpX0d6mFsbAxDxVbrV8MP/Lkel+46e3IAwFQmiuPh 4zIw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@sirena.org.uk header.s=20170815-heliosphere header.b=FglL9oWf; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 206-v6si5499931pfw.130.2018.05.17.09.50.51; Thu, 17 May 2018 09:51:05 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@sirena.org.uk header.s=20170815-heliosphere header.b=FglL9oWf; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752678AbeEQQlh (ORCPT + 99 others); Thu, 17 May 2018 12:41:37 -0400 Received: from heliosphere.sirena.org.uk ([172.104.155.198]:53144 "EHLO heliosphere.sirena.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752655AbeEQQlf (ORCPT ); Thu, 17 May 2018 12:41:35 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sirena.org.uk; s=20170815-heliosphere; h=Date:Message-Id:In-Reply-To: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:References: List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner: List-Archive; bh=Hwr1RJ2zhW1+FOrZ6lQPmBUjewv5MncY8iGzq067EYw=; b=FglL9oWfqjdl J//oCjbfKxgc0lRPJzEQng1UzVkRBtt+WrZATKAAWqBppKVbvMzqO7zoI5O5kGaG+CXCCrC5K8V0i PODN72pBWvI7Ss3K4ZXNH8S7AYk3Ajow93Uk9Beg6XJoPV6D4udIKvbWLix0Oxq/+SUg9hdhrsEmi Q5YJ4=; Received: from [37.205.61.206] (helo=finisterre.ee.mobilebroadband) by heliosphere.sirena.org.uk with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1fJLy6-00013i-2Z; Thu, 17 May 2018 16:41:30 +0000 Received: by finisterre.ee.mobilebroadband (Postfix, from userid 1000) id 086B744007E; Thu, 17 May 2018 17:41:27 +0100 (BST) From: Mark Brown To: Maciej Purski Cc: Mark Brown , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Mark Brown , Fabio Estevam , Tony Lindgren , Liam Girdwood , Rob Herring , Mark Rutland , Marek Szyprowski , Doug Anderson , Bartlomiej Zolnierkiewicz , linux-kernel@vger.kernel.org Subject: Applied "regulator: core: Resolve coupled regulators" to the regulator tree In-Reply-To: <1524494022-22260-5-git-send-email-m.purski@samsung.com> Message-Id: <20180517164127.086B744007E@finisterre.ee.mobilebroadband> Date: Thu, 17 May 2018 17:41:26 +0100 (BST) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The patch regulator: core: Resolve coupled regulators has been applied to the regulator tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark From d3d64537c33956c94cfa2376b87d8917868a0f5e Mon Sep 17 00:00:00 2001 From: Maciej Purski Date: Mon, 23 Apr 2018 16:33:40 +0200 Subject: [PATCH] regulator: core: Resolve coupled regulators On Odroid XU3/4 and other Exynos5422 based boards there is a case, that different devices on the board are supplied by different regulators with non-fixed voltages. If one of these devices temporarily requires higher voltage, there might occur a situation that the spread between two devices' voltages is so high, that there is a risk of changing 'high' and 'low' states on the interconnection between devices powered by those regulators. Fill coupling descriptor with data obtained from DTS using previously defined of_functions. Fail to register a regulator, if some data inconsistency occurs. If some coupled regulators are not yet registered, don't fail to register, but try to resolve them in late init call. Signed-off-by: Maciej Purski Signed-off-by: Mark Brown --- drivers/regulator/core.c | 100 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 0ca941b53571..6ed568b96c0e 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -4129,6 +4129,96 @@ static int regulator_register_resolve_supply(struct device *dev, void *data) return 0; } +static int regulator_fill_coupling_array(struct regulator_dev *rdev) +{ + struct coupling_desc *c_desc = &rdev->coupling_desc; + int n_coupled = c_desc->n_coupled; + struct regulator_dev *c_rdev; + int i; + + for (i = 1; i < n_coupled; i++) { + /* already resolved */ + if (c_desc->coupled_rdevs[i]) + continue; + + c_rdev = of_parse_coupled_regulator(rdev, i - 1); + + if (c_rdev) { + c_desc->coupled_rdevs[i] = c_rdev; + c_desc->n_resolved++; + } + } + + if (rdev->coupling_desc.n_resolved < n_coupled) + return -1; + else + return 0; +} + +static int regulator_register_fill_coupling_array(struct device *dev, + void *data) +{ + struct regulator_dev *rdev = dev_to_rdev(dev); + + if (!IS_ENABLED(CONFIG_OF)) + return 0; + + if (regulator_fill_coupling_array(rdev)) + rdev_dbg(rdev, "unable to resolve coupling\n"); + + return 0; +} + +static int regulator_resolve_coupling(struct regulator_dev *rdev) +{ + int n_phandles; + + if (!IS_ENABLED(CONFIG_OF)) + n_phandles = 0; + else + n_phandles = of_get_n_coupled(rdev); + + if (n_phandles + 1 > MAX_COUPLED) { + rdev_err(rdev, "too many regulators coupled\n"); + return -EPERM; + } + + /* + * Every regulator should always have coupling descriptor filled with + * at least pointer to itself. + */ + rdev->coupling_desc.coupled_rdevs[0] = rdev; + rdev->coupling_desc.n_coupled = n_phandles + 1; + rdev->coupling_desc.n_resolved++; + + /* regulator isn't coupled */ + if (n_phandles == 0) + return 0; + + /* regulator, which can't change its voltage, can't be coupled */ + if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) { + rdev_err(rdev, "voltage operation not allowed\n"); + return -EPERM; + } + + if (rdev->constraints->max_spread <= 0) { + rdev_err(rdev, "wrong max_spread value\n"); + return -EPERM; + } + + if (!of_check_coupling_data(rdev)) + return -EPERM; + + /* + * After everything has been checked, try to fill rdevs array + * with pointers to regulators parsed from device tree. If some + * regulators are not registered yet, retry in late init call + */ + regulator_fill_coupling_array(rdev); + + return 0; +} + /** * regulator_register - register regulator * @regulator_desc: regulator to register @@ -4262,6 +4352,13 @@ regulator_register(const struct regulator_desc *regulator_desc, if (ret < 0) goto wash; + mutex_lock(®ulator_list_mutex); + ret = regulator_resolve_coupling(rdev); + mutex_unlock(®ulator_list_mutex); + + if (ret != 0) + goto wash; + /* add consumers devices */ if (init_data) { mutex_lock(®ulator_list_mutex); @@ -4756,6 +4853,9 @@ static int __init regulator_init_complete(void) class_for_each_device(®ulator_class, NULL, NULL, regulator_late_cleanup); + class_for_each_device(®ulator_class, NULL, NULL, + regulator_register_fill_coupling_array); + return 0; } late_initcall_sync(regulator_init_complete); -- 2.17.0