From patchwork Wed Apr 18 02:38:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 133591 Delivered-To: patch@linaro.org Received: by 10.46.84.18 with SMTP id i18csp5390692ljb; Tue, 17 Apr 2018 19:40:13 -0700 (PDT) X-Google-Smtp-Source: AIpwx4/kFfzLa8XpZBhV7eK6gdIQ+vrSadglXIYYziMq0Ggv6HV0tWxBz29bkgHqGCq+bykha0ej X-Received: by 10.80.179.92 with SMTP id r28mr776294edd.145.1524019213365; Tue, 17 Apr 2018 19:40:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524019213; cv=none; d=google.com; s=arc-20160816; b=j02Fk6D5YmxKk823+2963xgwHL5vZMMNRGrnJCEEPSvZ0s2JNORtppO4m0SRNiG87Z 89Pky9N5DZEl6kQ7FPyqbIDOdQQwUec5DPqbQ9kk4nCK9G39mGIBVe5v7aM7n2z4gBrd UdauxvdyKRzFuEACqbIyzt6jG99aT35mACpnygXlQlyW8t/L6siYdnhf/q3s6S8ZO+CH V00w0csjos+MVeWTYgvp0gyVmwQ90cOBA099iGiqAYUKWSB0hPdaarJR2f50m0Uka+cj YUxBFhCC2CdNUKtApCUr17EKb2MBNi//8RkXXZ9Kwj0l4bTQa+44Ct8sSSRDVCa5iP4E d/wQ== 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:references:in-reply-to:message-id:date :to:from:dkim-signature:dkim-filter:arc-authentication-results; bh=pSZlg7H8I8Vtgamg4XKPRLqvNlDkG1S2wJpoJidgMFQ=; b=ZgagWpzMXmC740fsj2wShTkBla1jHm4FQI/tzZHKbW/LrOgIIdmYqnosy0iP0FjCA1 fM/yeJO+153xxPYstfnCs0hihMhFpF3vSAWm4Lmkqjq7xZth541afftHRbJXC2bS84J3 3SsEBFp6sQn/wDqhZ+JIPFg6fUJP55Dzj9I3GHX0RFg5FY7/oW6V2tGmJ4AINE7PdIjL kj7gzJeDAk0h69XOBB9Gp6qYhEmjX9fx6yBx7PUQQ4aHoZEb9fCmw29UWBUpyi/QRWwU PaLIrhT6wl/165Vky3sh7r+eWQxqieAuYcMHJW4dRxti/xiIhSKevImfe5yGc2ENEK0Y dFYQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@nifty.com header.s=dec2015msa header.b=YWt0lc86; 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 o2si345756edf.305.2018.04.17.19.40.13; Tue, 17 Apr 2018 19:40:13 -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=YWt0lc86; 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 E3775C21E70; Wed, 18 Apr 2018 02:39:45 +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 110A8C21E68; Wed, 18 Apr 2018 02:39:28 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id A1BFCC21C27; Wed, 18 Apr 2018 02:39:24 +0000 (UTC) Received: from conuserg-08.nifty.com (conuserg-08.nifty.com [210.131.2.75]) by lists.denx.de (Postfix) with ESMTPS id AA504C21C29 for ; Wed, 18 Apr 2018 02:39:23 +0000 (UTC) Received: from pug.e01.socionext.com (p14092-ipngnfx01kyoto.kyoto.ocn.ne.jp [153.142.97.92]) (authenticated) by conuserg-08.nifty.com with ESMTP id w3I2culG028728; Wed, 18 Apr 2018 11:38:59 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-08.nifty.com w3I2culG028728 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1524019140; bh=GfNL4XrKT+ma3+l4z+n5IcK+wqYQg/KGgCBHJDi8bB0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YWt0lc86Gw0Q6H3S9u2QawurxFgK23QIy+GDJIgZf79Ox4cNTEj9QBugemcFvPnx4 qUY2Mar6ZEIbWRajucJNq2LOGsByTas2uj67dq+YP3kkmE2S3vIXVRtjqw9mGWEQ9S 4nfiO1m/OMFYK4hO7O2oRW1HMb7ghLmBLTfKu8C7wke6PpdhK4SpwRQXLrCr+72EAs FU4EJmIKIffU73of5y0bbtjoag0sVeScfRqeElICxr2/dXjNhsyN8IqUS5MU69C1JE EfnGWKqhr2On9MEQ+8Y8/Wnd/YKFIVsZ8AnUZ4bfgYwIhAPBBb1khaVK8U5+1HvasV u02tEfBcvw8BA== X-Nifty-SrcIP: [153.142.97.92] From: Masahiro Yamada To: u-boot@lists.denx.de Date: Wed, 18 Apr 2018 11:38:45 +0900 Message-Id: <1524019125-26287-5-git-send-email-yamada.masahiro@socionext.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1524019125-26287-1-git-send-email-yamada.masahiro@socionext.com> References: <1524019125-26287-1-git-send-email-yamada.masahiro@socionext.com> Subject: [U-Boot] [PATCH 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 works 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 the 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 --- drivers/core/syscon-uclass.c | 63 ++++++++++++++++++++++++++++++++++++++++++++ include/syscon.h | 8 ++++++ 2 files changed, 71 insertions(+) diff --git a/drivers/core/syscon-uclass.c b/drivers/core/syscon-uclass.c index c99409b..bd2f681 100644 --- a/drivers/core/syscon-uclass.c +++ b/drivers/core/syscon-uclass.c @@ -15,6 +15,14 @@ #include #include +/* + * Caution: + * This API requires the given node has already been bound to "syscon". + * compatible = "syscon", "simple-mfd"; + * works, but + * compatible = "simple-mfd", "syscon"; + * does not. This behavior is different from Linux. + */ struct regmap *syscon_get_regmap(struct udevice *dev) { struct syscon_uc_info *priv; @@ -109,3 +117,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..a019345 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 - Linux-compat syscon lookup + * + * @node: Device node of syscon + */ +struct regmap *syscon_node_to_regmap(ofnode node); + #endif