Received: by 10.223.185.111 with SMTP id b44csp246209wrg; Fri, 9 Mar 2018 04:25:23 -0800 (PST) X-Google-Smtp-Source: AG47ELvnMGemRSvbNovV9qmahyKI23rAu1mCKFSOODDNFay4VLrCGQBHOimG96CRsWL33CFYFju3 X-Received: by 2002:a17:902:51a9:: with SMTP id y38-v6mr18306970plh.120.1520598323341; Fri, 09 Mar 2018 04:25:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520598323; cv=none; d=google.com; s=arc-20160816; b=erUZUF3jx+ImGs6Nmzuxhd6EiFpIWIJNYfe0kCK0FivzTOF2BLMdmJXZ3pGz5rxNmH Ms3X22WDF7k1u9zmNQOGunm0CG1WKzl61pqoatRu22sJfNU8FY0zviBTuJ11vsp6IcE+ 2/3gDtnfDm2NQHJZLperHNHEaHEQZYNUPikGaZpvxysZdoX1jHcDzeu4BaRtRfOn8UUF XzgaNZxuxAQmHq4VPqPISE2wVF3hLknMMdFc7CBOaFXbFcxjtOgzl01ESkat7Apq2R1C Jpm1Dmic4Ykmyy8j03F5j/Ld72kWSJqgDRkAoMC6BfR8Ll4V75TJWpb5UvZFwfMDpj9q uXHA== 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=21G7OyOYsi6afR1KN4WGyhNyGcZaefwQ9XB1Rz/s6ks=; b=Gw1vPy4ZUsHY5u3crDifi8e/Jb79e9+G+gC0SFeAdwVhWODkAXVPDx+oN31yOw9bZy h/AX1dP2RbYTXiZdGWECtT2pFsYPZ5+nhIA7djOKASUBmnGRV2fMW/dx0WmaIeSgtFPU JJP5w+e1MrF4d4ATbwKh+4gV5az2p5ZXP1fjhk7091GfqbpqcViMUxbQ1tJMUGcleE2d 61vaMVP5NeYN5JeL0FTrXF/Z86v5kcKbUbupupEqv/jb1+81ZvRzG3lLnt8hWyEXP5JI pXniCnP9hcCIlV8eMNvzB0i9xJE+Tvn+z+q74APbeY4mUCxskzogQzxUPVhWK2BYAlPU 7ICQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@samsung.com header.s=mail20170921 header.b=XuAEeVQT; 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 36-v6si791078pla.511.2018.03.09.04.25.08; Fri, 09 Mar 2018 04:25:23 -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=pass header.i=@samsung.com header.s=mail20170921 header.b=XuAEeVQT; 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 S1751318AbeCIMXp (ORCPT + 99 others); Fri, 9 Mar 2018 07:23:45 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:46456 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751178AbeCIMWh (ORCPT ); Fri, 9 Mar 2018 07:22:37 -0500 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20180309122235euoutp014a4b49d97ff56ab108a192d91177d0e7~aP-dXzXni1671716717euoutp01C; Fri, 9 Mar 2018 12:22:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20180309122235euoutp014a4b49d97ff56ab108a192d91177d0e7~aP-dXzXni1671716717euoutp01C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1520598155; bh=21G7OyOYsi6afR1KN4WGyhNyGcZaefwQ9XB1Rz/s6ks=; h=From:To:Cc:Subject:Date:In-reply-to:References:From; b=XuAEeVQTC7fz7xRkpZJLQeUh6W+sLTGXXot/RmSQxmjqoWlCQQ+s8EBu4DUfKZLKp nflY8E4ED/vb3trYCTpvBxUL/OYdgJEDTrbH2sYRxPro/ApIQS82O15ibWmkShh8ow NjveG+pbyKiYBd5Sw2ufoupbqmuzw/AEQcndB5NA= Received: from eusmges2new.samsung.com (unknown [203.254.199.244]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20180309122234eucas1p15a24a2ab8f1d0a34e05ecd0424e071d4~aP-cfLb2V0128101281eucas1p1b; Fri, 9 Mar 2018 12:22:34 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges2new.samsung.com (EUCPMTA) with SMTP id 82.28.17380.A8C72AA5; Fri, 9 Mar 2018 12:22:34 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20180309122234eucas1p1a5c9e939848191de36a9daa06e785ae7~aP-bxcdDo0128101281eucas1p1a; Fri, 9 Mar 2018 12:22:34 +0000 (GMT) X-AuditID: cbfec7f4-6f9ff700000043e4-36-5aa27c8a2386 Received: from eusync1.samsung.com ( [203.254.199.211]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id A7.F8.04183.98C72AA5; Fri, 9 Mar 2018 12:22:33 +0000 (GMT) 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 <0P5B00JEWP1FM310@eusync1.samsung.com>; Fri, 09 Mar 2018 12:22:33 +0000 (GMT) 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 v6 4/6] regulator: core: Resolve coupled regulators Date: Fri, 09 Mar 2018 13:22:06 +0100 Message-id: <1520598128-11768-5-git-send-email-m.purski@samsung.com> X-Mailer: git-send-email 2.7.4 In-reply-to: <1520598128-11768-1-git-send-email-m.purski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrMIsWRmVeSWpSXmKPExsWy7djP87pdNYuiDH5sUrDYOGM9q8XUh0/Y LOYfOcdqcXbZQTaLh1f9Lb5d6WCyuLxrDpvFgpe3WCzWHrnLbrH0+kUmi9a9R9gt9l/xcuDx WDNvDaPHt6+TWDxmN1xk8dg56y67x6ZVnWwefVtWMXp83iQXwB7FZZOSmpNZllqkb5fAlbFm 3zT2gm8KFc9mbmNpYHwi1cXIySEhYCLx9MMDxi5GLg4hgRWMEle/b2SBcD4zSsyfupwNpmrn k1nsEIlljBKLXi9lB0kICfxnlNh2UK6LkYODTUBLYk17PEhYRMBG4u2NA2BTmQX6mSUmN7Wy gCSEBZwl1rXOABvKIqAqsa25lQ2kl1fAReLFr1yIXXISN891MoPYnAKuEueuv2GEiO9gk7h3 vADCdpG4OaEB6jZhiVfHt7BD2DISlyd3s0DY1RIXv+6CqqmRaLy9AarGWuLzpC1g85kF+CQm bZvODHKChACvREebEESJh8Tftd+hxjhKvDnxkhXi9RmMEm82fGGawCi1gJFhFaN4amlxbnpq sVFearlecWJucWleul5yfu4mRmBUn/53/MsOxl1/kg4xCnAwKvHwPnBcGCXEmlhWXJl7iFGC g1lJhLeqYlGUEG9KYmVValF+fFFpTmrxIUZpDhYlcd44jbooIYH0xJLU7NTUgtQimCwTB6dU AyOrlcJetogpzMcvdX1bceAzs9+Lxa/YnI7FBs8PWrzmE/+F+4nF/+9HccqUt337/Oy7VpkN b/2jkHOfb2fOXPlClE+9aM+B5rf/9IVPXf00vfaw52eBfQfu9cy8s3XpFCWlmRKrGPV/hwUL rNDSf35yXUVp3MLzH0TuLd3tV2Jgn6mbed7eosBGiaU4I9FQi7moOBEAt2eLAOYCAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrOLMWRmVeSWpSXmKPExsVy+t/xy7qdNYuiDHp/2VhsnLGe1WLqwyds FvOPnGO1OLvsIJvFw6v+Ft+udDBZXN41h81iwctbLBZrj9xlt1h6/SKTReveI+wW+694OfB4 rJm3htHj29dJLB6zGy6yeOycdZfdY9OqTjaPvi2rGD0+b5ILYI/isklJzcksSy3St0vgyliz bxp7wTeFimczt7E0MD6R6mLk5JAQMJHY+WQWexcjF4eQwBJGiTPnv0I5jUwSO7bvAXI4ONgE tCTWtMeDNIgI2Ei8vXGAEaSGWWAis8TCxVdYQRLCAs4S61pnsIHYLAKqEtuaW9lAenkFXCRe /MqFWCYncfNcJzOIzSngKnHu+htGEFsIqKRjxnP2CYw8CxgZVjGKpJYW56bnFhvpFSfmFpfm pesl5+duYgQG37ZjP7fsYOx6F3yIUYCDUYmH94Hjwigh1sSy4srcQ4wSHMxKIrxVFYuihHhT EiurUovy44tKc1KLDzFKc7AoifOeN6iMEhJITyxJzU5NLUgtgskycXBKNTByvC5o8K+o/Zr2 PuTh+at9m58o8179zeskf3yJs/mOLOa3j/+fCtBS+8x0/LDLpMUZtprLY15JP35Q+EXWqO1E yXW7Gyt1nts3WiVotfZYz332QD00dp9f2/sbEaU3t3tK1Iu8ckiJq4mZYTjn2UO+20GWXHc9 A9he/zx/PvHw8w6dvMj+RhUlluKMREMt5qLiRABQDBVMOgIAAA== X-CMS-MailID: 20180309122234eucas1p1a5c9e939848191de36a9daa06e785ae7 X-Msg-Generator: CA CMS-TYPE: 201P X-CMS-RootMailID: 20180309122234eucas1p1a5c9e939848191de36a9daa06e785ae7 X-RootMTR: 20180309122234eucas1p1a5c9e939848191de36a9daa06e785ae7 References: <1520598128-11768-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 f6e784c..60fb05d 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)) + return 0; + + 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); @@ -4743,6 +4840,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