Received: by 10.223.185.116 with SMTP id b49csp115513wrg; Fri, 2 Mar 2018 14:50:26 -0800 (PST) X-Google-Smtp-Source: AG47ELtlDaBXltQ+yqRLkax8bei9WA/wzDvyGEOeRM37TD7YnKbsurVkMagGc6vrfoPAD8Bh5rEc X-Received: by 10.98.156.148 with SMTP id u20mr7065387pfk.167.1520031025967; Fri, 02 Mar 2018 14:50:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520031025; cv=none; d=google.com; s=arc-20160816; b=vy9UcTy7RB7WknUH2tb2ZZXZIfar4uPb8nUF+kDQj6smfXiyQ6jstcCNLc2szEGdgC SeU5hUXHiZZ5L8Eop36wUvSwp6j+fbEcpE1zp7jPrwioJQX9e+rqm1awQ7twddBFiTlF u3wFmuwtqiE27GWXBU7wfq4pbEcFCfY9wJYk8qaskuVV3o643iAVcpUuDTvgIRwcDPg9 SgSo6+xlKNhJbiCChT6MlwjFlbe6uOwbhvSNxFx03TFz5EjeLJC3Z/ZvwtwvRJLpnwvW /LZqotDOWSqp6Qi7PhVm9k13MxJkqn5LcHun4hnYK7Ez9N3592v0KR6cKyeLDtbG69Qv pEcg== 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=6dO3RdvLpuk1T4Bp4YzZ68DUcqoG2dcnJK6yyBwB3ls=; b=ydGQs61o0p+tPZBHUF1dbAs6BUCQ6qsjo9ph6VlGBnG/rvN7Ix7Dj7ge13UFJhK2Su wB8lxC8kvXyqxAyyWcwxHMnwBuniP47egxaVvlwMVg+CfWE/3b4dkUKRp1tvlfz6QSSm KflbsBAV+4quuE6Nfoax+fDXcKyu/MEQt8GLgd9gWUMII8oLGJDCBDLAZzXpxUEmw9I4 DWLx+nHp3Is0CXoXLpyxIG7RhIihQ0qajIMLQoCDoYf3OnXd21rQU7ZJ+qygJ1VeuQOC jZGIsQO2Voocz6TGDsmxmLa95rZssME+LFlwUWxpw4VxLSHc8t9DDLlSevXR5U1RBFdX dDpQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@sirena.org.uk header.s=20170815-heliosphere header.b=rWcU5QHw; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e91-v6si5476576plb.177.2018.03.02.14.50.11; Fri, 02 Mar 2018 14:50:25 -0800 (PST) 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=rWcU5QHw; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1427930AbeCBMz3 (ORCPT + 99 others); Fri, 2 Mar 2018 07:55:29 -0500 Received: from heliosphere.sirena.org.uk ([172.104.155.198]:57168 "EHLO heliosphere.sirena.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1427916AbeCBMzY (ORCPT ); Fri, 2 Mar 2018 07:55:24 -0500 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=6dO3RdvLpuk1T4Bp4YzZ68DUcqoG2dcnJK6yyBwB3ls=; b=rWcU5QHw79iV FZbQ/4gbWyCD34C163e4Ko9CeTuOnVaKtiYoPi798DFFNnkxFR36q3fvntAW4ywXmcqWOCLKuxc0H EK+T6VQsuw57LyZGk5//03c/4tuKoyHbYl4c/RXEgpc+XhmCbgkc54HAWnAWGPN003o08Z7X/Xbh/ Txzuw=; Received: from debutante.sirena.org.uk ([2001:470:1f1d:6b5::3] helo=debutante) by heliosphere.sirena.org.uk with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1erkDZ-0008QC-Pe; Fri, 02 Mar 2018 12:55:21 +0000 Received: from broonie by debutante with local (Exim 4.90_1) (envelope-from ) id 1erkDZ-0004X0-Ab; Fri, 02 Mar 2018 12:55:21 +0000 From: Mark Brown To: Maciej Purski Cc: Mark Brown , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Mark Brown , 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: <1516631412-17542-6-git-send-email-m.purski@samsung.com> Message-Id: Date: Fri, 02 Mar 2018 12:55:21 +0000 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 cf6fc8064766f405fa895eb823685154f9ec9266 Mon Sep 17 00:00:00 2001 From: Maciej Purski Date: Fri, 2 Mar 2018 09:42:47 +0100 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 | 92 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index dd4708c58480..82568cadc37e 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -4061,6 +4061,88 @@ 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 (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 = 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 @@ -4193,6 +4275,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); @@ -4686,6 +4775,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.16.2