From patchwork Thu Apr 19 03:14:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 133689 Delivered-To: patch@linaro.org Received: by 10.46.66.142 with SMTP id h14csp155206ljf; Wed, 18 Apr 2018 20:18:40 -0700 (PDT) X-Google-Smtp-Source: AIpwx4/eKMOsxcE7L2fCbhoJfMMAC47nzL4bU9Orwi7PjQKt8p8vm9bJ0heWmo9o94X172tWsD2m X-Received: by 10.80.200.139 with SMTP id d11mr6243911edh.74.1524107920726; Wed, 18 Apr 2018 20:18:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524107920; cv=none; d=google.com; s=arc-20160816; b=pbcNHKdGLFrYLrjpXz79XUeajguqucwlYZFM1aorjQxwRE1nXnaLbqPBSA9AYRw6S/ H7Ro6NGs17i/oB3cdFHmVQ545nvxY1bKp26aIP+8HBMWlT8IQUh+DE7+Vhv6LL2ga2uV lELDNg2XrrRCvD/MDnQNNR2AWu4dzW5vfrRfRxzZe1MN8wDcfJ3/VPBV2DSP6mrByDk/ YGXs2cmDJAwTSRSPs7oYPWCzgrVxDH0O6dIMNHHmKTyJhlra2j7bULBPNfDhCBN3vG9U UNurqHJbAjzHNNV5ruq21AhX9XTZb+MxaHL+wVbMEeUUIjnI1iO+uUVSr3hgaAVZMvNa 3FIg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:cc:references:in-reply-to:message-id :date:to:from:dkim-signature:dkim-filter:arc-authentication-results; bh=1jrJ2egH1Hh7Rxrt92WcbQTUXryQVR84NXexpP+F7kA=; b=C75UnOLFK2lU2RdLL2fVF8WyuoXpcjUg1WBSuAHnLYQYcgKNLTS0EIL7X7gDzFqMit 3ty2zRh5KmSR4fjc4t0l1FLV6ulR6o7iJPM7RWzDkbJPBLCrDxECsgla/BVwTh9i8qld 3EyBXmfQaOLEUTf/w39r4nJww6UjeDRYSk69mz4xVJSG2JBh8exr05N8u2JgXdUtNL/G YXcMzkbse06RWNagyTusH3xTeZyA/vlb/pDMtTsmep4G7tuV4Q+ClmGezhSVHbTAxAyg knMHKGennz95O+TW3wWKS48SgB95uwm+ON5EMHZrhv0bed7WRFSVzLJx2EUatahxMEHj ijRw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@nifty.com header.s=dec2015msa header.b=IUDbpYKZ; spf=pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de Return-Path: Received: from lists.denx.de (dione.denx.de. [81.169.180.215]) by mx.google.com with ESMTP id j62si1489781edb.430.2018.04.18.20.18.40; Wed, 18 Apr 2018 20:18:40 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) client-ip=81.169.180.215; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@nifty.com header.s=dec2015msa header.b=IUDbpYKZ; spf=pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by lists.denx.de (Postfix, from userid 105) id 55B76C21F8F; Thu, 19 Apr 2018 03:17:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 2A7B5C21F91; Thu, 19 Apr 2018 03:16:21 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 1BFFBC21F3F; Thu, 19 Apr 2018 03:16:06 +0000 (UTC) Received: from conuserg-12.nifty.com (conuserg-12.nifty.com [210.131.2.79]) by lists.denx.de (Postfix) with ESMTPS id D651DC21EEF for ; Thu, 19 Apr 2018 03:16:05 +0000 (UTC) Received: from pug.e01.socionext.com (p14092-ipngnfx01kyoto.kyoto.ocn.ne.jp [153.142.97.92]) (authenticated) by conuserg-12.nifty.com with ESMTP id w3J3EwYt013098; Thu, 19 Apr 2018 12:15:03 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-12.nifty.com w3J3EwYt013098 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1524107703; bh=dmjEIBveWv78Q7bpILjOYutjmfS2saGXx0+VWH9bqMo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IUDbpYKZDiwyWS9mCv6orDO7ZBZFd8EYNcapSFGsGZn2kxmipa5fwPf3A4+xWf4Tr Eqy8VRbsj4iDHNabTxxeeuL7mYxHqmUhgs5N7ptbxKWsunLB4PjWfxzGiIvuQ1Ap8M Hw9ke10EvMF065CnmZiZzlGBW9U80TxipVXyE1KM17S8mRQVGWPaU2kBW2SKVQnB1W awd4oxv9AZne+hdRPBltyJpoSoca2wCcOO92D9QtKYL3UollLI1tpQ2nKHfpyRNDeU tcOKGSVQWIPaTCWLGbteL8FcqhOaDltJ1CxbYy3/+OpnYhRkazK+emnfdo3K31tGx+ gHRZzPlTPyn3w== X-Nifty-SrcIP: [153.142.97.92] From: Masahiro Yamada To: u-boot@lists.denx.de Date: Thu, 19 Apr 2018 12:14:04 +0900 Message-Id: <1524107644-28849-5-git-send-email-yamada.masahiro@socionext.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1524107644-28849-1-git-send-email-yamada.masahiro@socionext.com> References: <1524107644-28849-1-git-send-email-yamada.masahiro@socionext.com> Cc: Tom Rini , Jassi Brar , Masami Hiramatsu Subject: [U-Boot] [PATCH v2 4/4] syscon: add Linux-compatible syscon API X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" The syscon implementation in U-Boot is different from that in Linux. Thus, DT files imported from Linux do not work for U-Boot. In U-Boot driver model, each node is bound to a dedicated driver that is the most compatible to it. This design gets along with the concept of DT, and the syscon in Linux originally worked like that. However, Linux commit bdb0066df96e ("mfd: syscon: Decouple syscon interface from platform devices") changed the behavior because it is useful to let a device bind to another driver, but still work as a syscon provider. That change had happened before U-Boot initially supported the syscon driver by commit 6f98b7504f70 ("dm: Add support for generic system controllers (syscon)"). So, the U-Boot's syscon works differently from the beginning. I'd say this is mis-implementation given that DT is not oriented to a particular project, but Linux is the canon of DT in practice. The problem typically arises in the combination of "syscon" and "simple-mfd" compatibles. In Linux, they are orthogonal, i.e., the order between "syscon" and "simple-mfd" does not matter at all. Assume the following compatible. compatible = "foo,bar-syscon", "syscon", "simple-mfd"; In U-Boot, this device node is bound to the syscon driver (driver/core/syscon-uclass.c) since the "syscon" is found to be the most compatible. Then, syscon_get_regmap() succeeds. However, compatible = "foo,bar-syscon", "simple-mfd", "syscon"; does not work because this node is bound to the simple-bus driver (drivers/core/simple-bus.c) in favor of "simple-mfd" compatible. The compatible string "syscon" is just dismissed. Moreover, compatible = "foo,bar-syscon", "syscon"; works like the first case because the syscon driver populates the child devices. This is wrong because populating children is the job of "simple-mfd" (or "simple-bus"). This commit ports syscon_node_to_regmap() from Linux. This API does not require the given node to be bound to a driver in any way. Reported-by: Kunihiko Hayashi Signed-off-by: Masahiro Yamada --- Changes in v2: None drivers/core/syscon-uclass.c | 64 ++++++++++++++++++++++++++++++++++++++++++++ include/syscon.h | 8 ++++++ 2 files changed, 72 insertions(+) diff --git a/drivers/core/syscon-uclass.c b/drivers/core/syscon-uclass.c index c99409b..6f2c5e3 100644 --- a/drivers/core/syscon-uclass.c +++ b/drivers/core/syscon-uclass.c @@ -15,6 +15,15 @@ #include #include +/* + * Caution: + * This API requires the given device has alerady been bound to syscon driver. + * For example, + * compatible = "syscon", "simple-mfd"; + * works, but + * compatible = "simple-mfd", "syscon"; + * does not. The behavior is different from Linux. + */ struct regmap *syscon_get_regmap(struct udevice *dev) { struct syscon_uc_info *priv; @@ -109,3 +118,58 @@ U_BOOT_DRIVER(generic_syscon) = { #endif .of_match = generic_syscon_ids, }; + +/* + * Linux-compatible syscon-to-regmap + * The syscon node can be bound to another driver, but still works + * as a syscon provider. + */ +static LIST_HEAD(syscon_list); + +struct syscon { + ofnode node; + struct regmap *regmap; + struct list_head list; +}; + +static struct syscon *of_syscon_register(ofnode node) +{ + struct syscon *syscon; + int ret; + + if (!ofnode_device_is_compatible(node, "syscon")) + return ERR_PTR(-EINVAL); + + syscon = malloc(sizeof(*syscon)); + if (!syscon) + return ERR_PTR(-ENOMEM); + + ret = regmap_init_mem(node, &syscon->regmap); + if (ret) { + free(syscon); + return ERR_PTR(ret); + } + + list_add_tail(&syscon->list, &syscon_list); + + return syscon; +} + +struct regmap *syscon_node_to_regmap(ofnode node) +{ + struct syscon *entry, *syscon = NULL; + + list_for_each_entry(entry, &syscon_list, list) + if (ofnode_equal(entry->node, node)) { + syscon = entry; + break; + } + + if (!syscon) + syscon = of_syscon_register(node); + + if (IS_ERR(syscon)) + return ERR_CAST(syscon); + + return syscon->regmap; +} diff --git a/include/syscon.h b/include/syscon.h index 5d52b1c..f4b9cb0 100644 --- a/include/syscon.h +++ b/include/syscon.h @@ -8,6 +8,7 @@ #ifndef __SYSCON_H #define __SYSCON_H +#include #include /** @@ -82,4 +83,11 @@ struct regmap *syscon_get_regmap_by_driver_data(ulong driver_data); */ void *syscon_get_first_range(ulong driver_data); +/** + * syscon_node_to_regmap - get regmap from syscon + * + * @node: Device node of syscon + */ +struct regmap *syscon_node_to_regmap(ofnode node); + #endif