Received: by 10.192.165.148 with SMTP id m20csp3501481imm; Mon, 23 Apr 2018 07:37:19 -0700 (PDT) X-Google-Smtp-Source: AIpwx4+K9RdzqoDriK0ePxbYjA+zqNgKY+iHOv1rPKI47Yp4MkMhTTlAwL3wWt/p+Ww9pxuUw81u X-Received: by 2002:a17:902:3181:: with SMTP id x1-v6mr21262105plb.198.1524494239268; Mon, 23 Apr 2018 07:37:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524494239; cv=none; d=google.com; s=arc-20160816; b=eW96YjKGcqXqtEOxAT8JcKUeisqF+DUGAVEmYZr+oV283HGm9IMS3992sFRj6Bu9E2 X1YTo1+AWyWyGozXr3UWw0A71jK2YxAFKLIXpz/X5jM4fX7S2wtRUIFtridHdHSdCJAi HbXnandEP3bmnGScH48c0qHWYh8Awdfl/qt5+keNbUi60nTntg1tyOudpsM12Pv7QaQf 4tz4HooJasOFamNY0ewefKYgAZjZtXhte98psXl9VOFTFntO7pqJ7+yOnyxwNgiVkAdL vfWO/SBlQqnwSHVPk/nX8belGCQpu/+JnUlLF3PD/IZE97e6pKxbF0nqGBO0pcFD6Plg hogA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:cms-type:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature:dkim-filter :arc-authentication-results; bh=8jz+UwW/GxrvUGHdKPgTQ7+UgFx3oQKQ7/1FiUe0lpk=; b=JaFBXAFyRAR5iSxoq//HQdEvL1ugxdE8yrgS8yYXuAi6aUn82HYAx0ncHQDumuakqg pjiHqvP9eJd3Qp6DNk9ojMTjkbVBM4XL+2iFt94pf1fqc3sKcqbnyLKsppcRx18D/q9y hpCBVMUKJVeCuyIMr6TwNAlvn3vYkED6Nrk7a+P8KvUVCnZWAp+fDWxBEZCbVjnFspcd uUCQn6TrJqZBTOOpsnh3UqfmoxKCjsDhWs5D0JGSryNYl69VTkx9fja9qJCc188NvB0R jdgrT0D2MAIypOl8zp+HW1jh7XQWZiQ+AdKAoJcrtzSj77mJ9dnWLC+GssKd5c0oQD91 kILw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@samsung.com header.s=mail20170921 header.b=tsB6OpEP; 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=pass (p=NONE sp=NONE dis=NONE) header.from=samsung.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m1-v6si214983plk.219.2018.04.23.07.37.05; Mon, 23 Apr 2018 07:37:19 -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=pass header.i=@samsung.com header.s=mail20170921 header.b=tsB6OpEP; 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=pass (p=NONE sp=NONE dis=NONE) header.from=samsung.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755593AbeDWOfY (ORCPT + 99 others); Mon, 23 Apr 2018 10:35:24 -0400 Received: from mailout2.w1.samsung.com ([210.118.77.12]:36828 "EHLO mailout2.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754962AbeDWOeJ (ORCPT ); Mon, 23 Apr 2018 10:34:09 -0400 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20180423143405euoutp0236fe69e346435c028b467c63105ccf65~oF0H33Qhg2198521985euoutp021; Mon, 23 Apr 2018 14:34:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20180423143405euoutp0236fe69e346435c028b467c63105ccf65~oF0H33Qhg2198521985euoutp021 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1524494046; bh=8jz+UwW/GxrvUGHdKPgTQ7+UgFx3oQKQ7/1FiUe0lpk=; h=From:To:Cc:Subject:Date:In-reply-to:References:From; b=tsB6OpEP2EfQqXmwVIrt4MpJzMYqN+JAC5reko8+O6UZo1wjPESBR2FLfkyrxwL81 GiK2RzJxzAnTBA2E3NiNnDVxE0k1MbF60QIG3mcRyK1sGZyAT+sTpmzdyfyAvNmK40 cPN8xBb91ExY5MpJKv/I1hX3UKvYClRI4TSA6hcE= Received: from eusmges3new.samsung.com (unknown [203.254.199.245]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20180423143404eucas1p11b8db098d02cfa1f4800b4fd35167eba~oF0GUZBzE0201602016eucas1p10; Mon, 23 Apr 2018 14:34:04 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges3new.samsung.com (EUCPMTA) with SMTP id C8.95.10409.BDEEDDA5; Mon, 23 Apr 2018 15:34:03 +0100 (BST) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20180423143401eucas1p1cfe9b2c807cf88b3f3b68b7b2f580e83~oF0EB_TD02715727157eucas1p1U; Mon, 23 Apr 2018 14:34:01 +0000 (GMT) X-AuditID: cbfec7f5-f95739c0000028a9-56-5addeedbd617 Received: from eusync1.samsung.com ( [203.254.199.211]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id 53.12.04183.9DEEDDA5; Mon, 23 Apr 2018 15:34:01 +0100 (BST) Received: from AMDC2075.DIGITAL.local ([106.120.51.25]) by eusync1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0P7N006C1748LC60@eusync1.samsung.com>; Mon, 23 Apr 2018 15:34:01 +0100 (BST) From: Maciej Purski To: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: Mark Brown , Fabio Estevam , Tony Lindgren , Liam Girdwood , Rob Herring , Mark Rutland , Marek Szyprowski , Doug Anderson , Bartlomiej Zolnierkiewicz , Maciej Purski Subject: [PATCH v7 4/6] regulator: core: Resolve coupled regulators Date: Mon, 23 Apr 2018 16:33:40 +0200 Message-id: <1524494022-22260-5-git-send-email-m.purski@samsung.com> X-Mailer: git-send-email 2.7.4 In-reply-to: <1524494022-22260-1-git-send-email-m.purski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrCIsWRmVeSWpSXmKPExsWy7djP87q3392NMpi1l8ti44z1rBZTHz5h s5h/5ByrxdllB9ksHl71t/h2pYPJ4vKuOWwWC17eYrFYe+Quu8XS6xeZLFr3HmG32H/Fy4HH Y828NYwe375OYvGY3XCRxWPnrLvsHptWdbJ59G1ZxejxeZNcAHsUl01Kak5mWWqRvl0CV8aZ w69ZC5oUK/6uOszcwPhWqouRk0NCwERi5/ztjF2MXBxCAisYJbbde8MG4XxmlNi1aiszTNW5 H7+ZQGwhgWWMEs+eJUAU/WeUeD31AHsXIwcHm4CWxJr2eJAaEQEbibc3DoBNZRboZ5aY3NTK ApIQFnCWOHbpIpjNIqAqcXX1Z1YQm1fAReL5jbeMEMvkJG6e6wRbzCngKrGk+QE7yCAJgR1s EtNnbWGFKHKR2HV3JVSDsMSr41vYIWwZicuTu1kg7GqJi193sUHYNRKNtzdA1VhLfJ60BWwB swCfxKRt05lBHpAQ4JXoaBOCKPGQOLuqFWqMo8SOzz+YIZ6fwSix8I7wBEapBYwMqxjFU0uL c9NTi43zUsv1ihNzi0vz0vWS83M3MQLj+vS/4193MO77k3SIUYCDUYmHd4fu3Sgh1sSy4src Q4wSHMxKIrwP3wCFeFMSK6tSi/Lji0pzUosPMUpzsCiJ88Zp1EUJCaQnlqRmp6YWpBbBZJk4 OKUaGNdc9nPNdRb7sPHKlHVenJ+D3Q5tuuX6Tfxp7eVf8io1J15kT5lU+WiOyxJJiXu2s/7L cm6dGtngbyQdarzq5PR3fi+fdt7TtFb7FjP7yPNGOfcLLcd6f33iWOO0dtuporzIs//iVDbe SLisdNz15bIqrt5fZtt9DnZ7pe98ILN9V3WartLDI9FKLMUZiYZazEXFiQCIgtba5wIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrBLMWRmVeSWpSXmKPExsVy+t/xy7o3392NMvg8Vc9i44z1rBZTHz5h s5h/5ByrxdllB9ksHl71t/h2pYPJ4vKuOWwWC17eYrFYe+Quu8XS6xeZLFr3HmG32H/Fy4HH Y828NYwe375OYvGY3XCRxWPnrLvsHptWdbJ59G1ZxejxeZNcAHsUl01Kak5mWWqRvl0CV8aZ w69ZC5oUK/6uOszcwPhWqouRk0NCwETi3I/fTF2MXBxCAksYJSat+80C4TQySSw7u46ti5GD g01AS2JNezxIg4iAjcTbGwcYQWqYBSYySyxcfIUVJCEs4Cxx7NJFFhCbRUBV4urqz2BxXgEX iec33jJCbJOTuHmukxnE5hRwlVjS/IAdxBYCqtm3bxfzBEaeBYwMqxhFUkuLc9Nzi430ihNz i0vz0vWS83M3MQLDb9uxn1t2MHa9Cz7EKMDBqMTDu0P3bpQQa2JZcWXuIUYJDmYlEd6Hb4BC vCmJlVWpRfnxRaU5qcWHGKU5WJTEec8bVEYJCaQnlqRmp6YWpBbBZJk4OKUaGDsuuIbPVbn3 2PaXycwLTy++aVJys7Z2K+MqVMi5f6m52dPlS3CVybPiPXZF94VKDiYtubC16s3Vl5fYV2wR 5XO3cPh9cn7tci+G3no+uf7YVd3h2Xc+b9gtvHOL+3qX/kOJPE97bmf/TGcru5A6gUdzy62S NylNSXP/50ecP2E2mUXqhZbdKyWW4oxEQy3mouJEAMsnpqw7AgAA X-CMS-MailID: 20180423143401eucas1p1cfe9b2c807cf88b3f3b68b7b2f580e83 X-Msg-Generator: CA CMS-TYPE: 201P X-CMS-RootMailID: 20180423143401eucas1p1cfe9b2c807cf88b3f3b68b7b2f580e83 X-RootMTR: 20180423143401eucas1p1cfe9b2c807cf88b3f3b68b7b2f580e83 References: <1524494022-22260-1-git-send-email-m.purski@samsung.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- drivers/regulator/core.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index acca5de..82b002e 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -4117,6 +4117,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 @@ -4250,6 +4340,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); @@ -4744,6 +4841,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.7.4