From patchwork Tue Oct 22 12:00:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Jacques Hiblot X-Patchwork-Id: 1181281 X-Patchwork-Delegate: lukma@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="D3mGajHI"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 46yBzx65bXz9sPk for ; Tue, 22 Oct 2019 23:06:05 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 89D99C21E39; Tue, 22 Oct 2019 12:04: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 42E1FC21DB6; Tue, 22 Oct 2019 12:02:19 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id B5E97C21DB6; Tue, 22 Oct 2019 12:02:17 +0000 (UTC) Received: from lelv0143.ext.ti.com (lelv0143.ext.ti.com [198.47.23.248]) by lists.denx.de (Postfix) with ESMTPS id D5B3AC21DFD for ; Tue, 22 Oct 2019 12:00:50 +0000 (UTC) Received: from lelv0266.itg.ti.com ([10.180.67.225]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id x9MC0huA043607; Tue, 22 Oct 2019 07:00:43 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1571745643; bh=J8hUrFwpxwS4CWiWoXT7ESTc8+UI6Q+aViKpQlRNQMg=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=D3mGajHIDEOBiJq/0w4ODHOpPgRVPMQ316nlJrP4h8Lq+40Rtucr749xTlE1xUW8J 3P71MTpbXFr2iiHHg+k3pVNdEu7ud0MsXKn+fB78aOsH5Jjb9g0gvO/D0RppNGTtL1 X5o529XsPyk4SNePfbB/UXWKyUAV8e+kj0N8bWVs= Received: from DLEE101.ent.ti.com (dlee101.ent.ti.com [157.170.170.31]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id x9MC0D1T055852 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 22 Oct 2019 07:00:13 -0500 Received: from DLEE101.ent.ti.com (157.170.170.31) by DLEE101.ent.ti.com (157.170.170.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5; Tue, 22 Oct 2019 07:00:03 -0500 Received: from lelv0326.itg.ti.com (10.180.67.84) by DLEE101.ent.ti.com (157.170.170.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5 via Frontend Transport; Tue, 22 Oct 2019 07:00:03 -0500 Received: from localhost (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id x9MC0C3l078585; Tue, 22 Oct 2019 07:00:12 -0500 From: Jean-Jacques Hiblot To: , Date: Tue, 22 Oct 2019 14:00:03 +0200 Message-ID: <20191022120007.23288-2-jjhiblot@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191022120007.23288-1-jjhiblot@ti.com> References: <20191022120007.23288-1-jjhiblot@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH v2 1/5] drivers: clk: Handle gracefully NULL pointers 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: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Prepare the way for a managed CLK API by handling NULL pointers without crashing nor failing. Signed-off-by: Jean-Jacques Hiblot --- Changes in v2: None drivers/clk/clk-uclass.c | 43 +++++++++++++++++++++++++++++++++------- include/clk.h | 2 +- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index 64c181f4ad..dff395fedb 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -349,9 +349,12 @@ int clk_release_all(struct clk *clk, int count) int clk_request(struct udevice *dev, struct clk *clk) { - const struct clk_ops *ops = clk_dev_ops(dev); + const struct clk_ops *ops; debug("%s(dev=%p, clk=%p)\n", __func__, dev, clk); + if (!clk) + return 0; + ops = clk_dev_ops(dev); clk->dev = dev; @@ -363,9 +366,12 @@ int clk_request(struct udevice *dev, struct clk *clk) int clk_free(struct clk *clk) { - const struct clk_ops *ops = clk_dev_ops(clk->dev); + const struct clk_ops *ops; debug("%s(clk=%p)\n", __func__, clk); + if (!clk) + return 0; + ops = clk_dev_ops(clk->dev); if (!ops->free) return 0; @@ -375,9 +381,12 @@ int clk_free(struct clk *clk) ulong clk_get_rate(struct clk *clk) { - const struct clk_ops *ops = clk_dev_ops(clk->dev); + const struct clk_ops *ops; debug("%s(clk=%p)\n", __func__, clk); + if (!clk) + return 0; + ops = clk_dev_ops(clk->dev); if (!ops->get_rate) return -ENOSYS; @@ -391,6 +400,8 @@ struct clk *clk_get_parent(struct clk *clk) struct clk *pclk; debug("%s(clk=%p)\n", __func__, clk); + if (!clk) + return NULL; pdev = dev_get_parent(clk->dev); pclk = dev_get_clk_ptr(pdev); @@ -406,6 +417,8 @@ long long clk_get_parent_rate(struct clk *clk) struct clk *pclk; debug("%s(clk=%p)\n", __func__, clk); + if (!clk) + return 0; pclk = clk_get_parent(clk); if (IS_ERR(pclk)) @@ -424,9 +437,12 @@ long long clk_get_parent_rate(struct clk *clk) ulong clk_set_rate(struct clk *clk, ulong rate) { - const struct clk_ops *ops = clk_dev_ops(clk->dev); + const struct clk_ops *ops; debug("%s(clk=%p, rate=%lu)\n", __func__, clk, rate); + if (!clk) + return 0; + ops = clk_dev_ops(clk->dev); if (!ops->set_rate) return -ENOSYS; @@ -436,9 +452,12 @@ ulong clk_set_rate(struct clk *clk, ulong rate) int clk_set_parent(struct clk *clk, struct clk *parent) { - const struct clk_ops *ops = clk_dev_ops(clk->dev); + const struct clk_ops *ops; debug("%s(clk=%p, parent=%p)\n", __func__, clk, parent); + if (!clk) + return 0; + ops = clk_dev_ops(clk->dev); if (!ops->set_parent) return -ENOSYS; @@ -448,11 +467,14 @@ int clk_set_parent(struct clk *clk, struct clk *parent) int clk_enable(struct clk *clk) { - const struct clk_ops *ops = clk_dev_ops(clk->dev); + const struct clk_ops *ops; struct clk *clkp = NULL; int ret; debug("%s(clk=%p)\n", __func__, clk); + if (!clk) + return 0; + ops = clk_dev_ops(clk->dev); if (CONFIG_IS_ENABLED(CLK_CCF)) { /* Take id 0 as a non-valid clk, such as dummy */ @@ -505,11 +527,14 @@ int clk_enable_bulk(struct clk_bulk *bulk) int clk_disable(struct clk *clk) { - const struct clk_ops *ops = clk_dev_ops(clk->dev); + const struct clk_ops *ops; struct clk *clkp = NULL; int ret; debug("%s(clk=%p)\n", __func__, clk); + if (!clk) + return 0; + ops = clk_dev_ops(clk->dev); if (CONFIG_IS_ENABLED(CLK_CCF)) { if (clk->id && !clk_get_by_id(clk->id, &clkp)) { @@ -589,6 +614,10 @@ bool clk_is_match(const struct clk *p, const struct clk *q) if (p == q) return true; + /* trivial case #2: on the clk pointer is NULL */ + if (!p || !q) + return false; + /* same device, id and data */ if (p->dev == q->dev && p->id == q->id && p->data == q->data) return true; diff --git a/include/clk.h b/include/clk.h index 18b2e3ca54..6568865d40 100644 --- a/include/clk.h +++ b/include/clk.h @@ -356,7 +356,7 @@ int soc_clk_dump(void); */ static inline bool clk_valid(struct clk *clk) { - return !!clk->dev; + return clk && !!clk->dev; } /** From patchwork Tue Oct 22 12:00:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Jacques Hiblot X-Patchwork-Id: 1181278 X-Patchwork-Delegate: lukma@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="DTGl9V2B"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 46yByM3Rdyz9s4Y for ; Tue, 22 Oct 2019 23:04:43 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 1C80DC21DA6; Tue, 22 Oct 2019 12:03:54 +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 5D997C21DD3; Tue, 22 Oct 2019 12:02:06 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 66E37C21E38; Tue, 22 Oct 2019 12:02:05 +0000 (UTC) Received: from lelv0142.ext.ti.com (lelv0142.ext.ti.com [198.47.23.249]) by lists.denx.de (Postfix) with ESMTPS id 6CACBC21BE5 for ; Tue, 22 Oct 2019 12:00:38 +0000 (UTC) Received: from lelv0266.itg.ti.com ([10.180.67.225]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id x9MC0TX7089263; Tue, 22 Oct 2019 07:00:29 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1571745629; bh=XzmT5d9A80QHsglqefJ0tqQUuqPq1wmTxjn5H1sXsbM=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=DTGl9V2BpziOKC4gZGciXbyzfsH7jZr+b/5hemz5N9o6GY5UHSzvSe1VgJJXIBjg0 41d6KSeFIwrbwq5KsBqNe5AwafUA1FcrIaUgTdIrFuwhP9AKknIN4B1YaXmvEh5d8P flad/Ms0pu5N4BwIne33HXji0zpjfbCerl3Gfj9I= Received: from DLEE104.ent.ti.com (dlee104.ent.ti.com [157.170.170.34]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id x9MC0E1A055885 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 22 Oct 2019 07:00:14 -0500 Received: from DLEE113.ent.ti.com (157.170.170.24) by DLEE104.ent.ti.com (157.170.170.34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5; Tue, 22 Oct 2019 07:00:04 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE113.ent.ti.com (157.170.170.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5 via Frontend Transport; Tue, 22 Oct 2019 07:00:04 -0500 Received: from localhost (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id x9MC0D6a018816; Tue, 22 Oct 2019 07:00:14 -0500 From: Jean-Jacques Hiblot To: , Date: Tue, 22 Oct 2019 14:00:04 +0200 Message-ID: <20191022120007.23288-3-jjhiblot@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191022120007.23288-1-jjhiblot@ti.com> References: <20191022120007.23288-1-jjhiblot@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH v2 2/5] drivers: clk: Add a managed API to get clocks from the device-tree 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: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Add devm_clk_get(), devm_clk_get_optional() to get clocks from the device-tree. The clocks is automatically released and the data structure freed when the device is unbound. Also add devm_clk_put() to release the clock and free the data structure manually. Signed-off-by: Jean-Jacques Hiblot --- Changes in v2: - Add clk_prepare_enable/clk_disable_unprepare - remove conflicting implmentations from brcmnand_compat.{c,h} drivers/clk/clk-uclass.c | 48 +++++++++++++++++++ .../mtd/nand/raw/brcmnand/brcmnand_compat.c | 30 ------------ .../mtd/nand/raw/brcmnand/brcmnand_compat.h | 4 -- include/clk.h | 47 ++++++++++++++++++ 4 files changed, 95 insertions(+), 34 deletions(-) diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index dff395fedb..e7ec6347de 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -625,6 +625,54 @@ bool clk_is_match(const struct clk *p, const struct clk *q) return false; } +static void devm_clk_release(struct udevice *dev, void *res) +{ + clk_free(res); +} + +static int devm_clk_match(struct udevice *dev, void *res, void *data) +{ + return res == data; +} + +struct clk *devm_clk_get(struct udevice *dev, const char *id) +{ + int rc; + struct clk *clk; + + clk = devres_alloc(devm_clk_release, sizeof(struct clk), __GFP_ZERO); + if (unlikely(!clk)) + return ERR_PTR(-ENOMEM); + + rc = clk_get_by_name(dev, id, clk); + if (rc) + return ERR_PTR(rc); + + devres_add(dev, clk); + return clk; +} + +struct clk *devm_clk_get_optional(struct udevice *dev, const char *id) +{ + struct clk *clk = devm_clk_get(dev, id); + + if (IS_ERR(clk)) + return NULL; + + return clk; +} + +void devm_clk_put(struct udevice *dev, struct clk *clk) +{ + int rc; + + if (!clk) + return; + + rc = devres_release(dev, devm_clk_release, devm_clk_match, clk); + WARN_ON(rc); +} + UCLASS_DRIVER(clk) = { .id = UCLASS_CLK, .name = "clk", diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand_compat.c b/drivers/mtd/nand/raw/brcmnand/brcmnand_compat.c index 96b27e6e5a..883948355c 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand_compat.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand_compat.c @@ -3,36 +3,6 @@ #include #include "brcmnand_compat.h" -struct clk *devm_clk_get(struct udevice *dev, const char *id) -{ - struct clk *clk; - int ret; - - clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL); - if (!clk) { - debug("%s: can't allocate clock\n", __func__); - return ERR_PTR(-ENOMEM); - } - - ret = clk_get_by_name(dev, id, clk); - if (ret < 0) { - debug("%s: can't get clock (ret = %d)!\n", __func__, ret); - return ERR_PTR(ret); - } - - return clk; -} - -int clk_prepare_enable(struct clk *clk) -{ - return clk_enable(clk); -} - -void clk_disable_unprepare(struct clk *clk) -{ - clk_disable(clk); -} - static char *devm_kvasprintf(struct udevice *dev, gfp_t gfp, const char *fmt, va_list ap) { diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand_compat.h b/drivers/mtd/nand/raw/brcmnand/brcmnand_compat.h index 02cab0f828..6f9bec7085 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand_compat.h +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand_compat.h @@ -6,10 +6,6 @@ #include #include -struct clk *devm_clk_get(struct udevice *dev, const char *id); -int clk_prepare_enable(struct clk *clk); -void clk_disable_unprepare(struct clk *clk); - char *devm_kasprintf(struct udevice *dev, gfp_t gfp, const char *fmt, ...); #endif /* __BRCMNAND_COMPAT_H */ diff --git a/include/clk.h b/include/clk.h index 6568865d40..9be3264113 100644 --- a/include/clk.h +++ b/include/clk.h @@ -154,6 +154,37 @@ int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk); */ int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk); +/** + * devm_clk_get - lookup and obtain a managed reference to a clock producer. + * @dev: device for clock "consumer" + * @id: clock consumer ID + * + * Returns a struct clk corresponding to the clock producer, or + * valid IS_ERR() condition containing errno. The implementation + * uses @dev and @id to determine the clock consumer, and thereby + * the clock producer. (IOW, @id may be identical strings, but + * clk_get may return different clock producers depending on @dev.) + * + * Drivers must assume that the clock source is not enabled. + * + * devm_clk_get should not be called from within interrupt context. + * + * The clock will automatically be freed when the device is unbound + * from the bus. + */ +struct clk *devm_clk_get(struct udevice *dev, const char *id); + +/** + * devm_clk_get_optional - lookup and obtain a managed reference to an optional + * clock producer. + * @dev: device for clock "consumer" + * @id: clock consumer ID + * + * Behaves the same as devm_clk_get() except where there is no clock producer. + * In this case, instead of returning -ENOENT, the function returns NULL. + */ +struct clk *devm_clk_get_optional(struct udevice *dev, const char *id); + /** * clk_release_all() - Disable (turn off)/Free an array of previously * requested clocks. @@ -168,6 +199,19 @@ int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk); */ int clk_release_all(struct clk *clk, int count); +/** + * devm_clk_put - "free" a managed clock source + * @dev: device used to acquire the clock + * @clk: clock source acquired with devm_clk_get() + * + * Note: drivers must ensure that all clk_enable calls made on this + * clock source are balanced by clk_disable calls prior to calling + * this function. + * + * clk_put should not be called from within interrupt context. + */ +void devm_clk_put(struct udevice *dev, struct clk *clk); + #else static inline int clk_get_by_index(struct udevice *dev, int index, struct clk *clk) @@ -379,3 +423,6 @@ int clk_get_by_id(ulong id, struct clk **clkp); */ bool clk_dev_binded(struct clk *clk); #endif + +#define clk_prepare_enable(clk) clk_enable(clk) +#define clk_disable_unprepare(clk) clk_disable(clk) From patchwork Tue Oct 22 12:00:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Jacques Hiblot X-Patchwork-Id: 1181277 X-Patchwork-Delegate: lukma@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="iOSe2gd6"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 46yBxF4F5Kz9s4Y for ; Tue, 22 Oct 2019 23:03:45 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 418D4C21DEC; Tue, 22 Oct 2019 12:03:33 +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 11FB7C21E31; Tue, 22 Oct 2019 12:02:04 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 65336C21E29; Tue, 22 Oct 2019 12:02:03 +0000 (UTC) Received: from lelv0142.ext.ti.com (lelv0142.ext.ti.com [198.47.23.249]) by lists.denx.de (Postfix) with ESMTPS id BF6D0C21C29 for ; Tue, 22 Oct 2019 12:00:34 +0000 (UTC) Received: from lelv0266.itg.ti.com ([10.180.67.225]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id x9MC0VCe089272; Tue, 22 Oct 2019 07:00:31 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1571745631; bh=vXu0kjjUw2aCRKY8nznPtjcYsXVQLrpIRszO+nlrf2Q=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=iOSe2gd6ravGKXhV1re/TH91gAeF85SsMk3A5LRZ05NxuDVngz+Mc/WYYOi0Q2vxc O+SZG28EDwBOlV1akoNuRKR09WAK4TlwPEK10kPM6ErlEtaakeKtTSMFqUSfsjfMmR FLicr0XpXLV4FXm/3lfUHqApmD5oS6b/d69agd2c= Received: from DLEE103.ent.ti.com (dlee103.ent.ti.com [157.170.170.33]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id x9MC0V1X056519 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 22 Oct 2019 07:00:31 -0500 Received: from DLEE104.ent.ti.com (157.170.170.34) by DLEE103.ent.ti.com (157.170.170.33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5; Tue, 22 Oct 2019 07:00:21 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE104.ent.ti.com (157.170.170.34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5 via Frontend Transport; Tue, 22 Oct 2019 07:00:21 -0500 Received: from localhost (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id x9MC0Et2018869; Tue, 22 Oct 2019 07:00:15 -0500 From: Jean-Jacques Hiblot To: , Date: Tue, 22 Oct 2019 14:00:05 +0200 Message-ID: <20191022120007.23288-4-jjhiblot@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191022120007.23288-1-jjhiblot@ti.com> References: <20191022120007.23288-1-jjhiblot@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH v2 3/5] test: clk: Update tests to also check the managed 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: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Add a few more clocks the clk_sandbox clock provider and get them using the managed API. Make sure they are released when the device is removed. Signed-off-by: Jean-Jacques Hiblot --- Changes in v2: None arch/sandbox/dts/test.dts | 6 ++-- arch/sandbox/include/asm/clk.h | 33 +++++++++++++++++ drivers/clk/clk_sandbox.c | 34 ++++++++++++++++++ drivers/clk/clk_sandbox_test.c | 66 +++++++++++++++++++++++++++++----- test/dm/clk.c | 36 ++++++++++++++++++- 5 files changed, 163 insertions(+), 12 deletions(-) diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 5d9ab3724f..0ee86a74ed 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -232,8 +232,10 @@ compatible = "sandbox,clk-test"; clocks = <&clk_fixed>, <&clk_sandbox 1>, - <&clk_sandbox 0>; - clock-names = "fixed", "i2c", "spi"; + <&clk_sandbox 0>, + <&clk_sandbox 3>, + <&clk_sandbox 2>; + clock-names = "fixed", "i2c", "spi", "uart2", "uart1"; }; ccf: clk-ccf { diff --git a/arch/sandbox/include/asm/clk.h b/arch/sandbox/include/asm/clk.h index 2b1c49f783..1573e4a134 100644 --- a/arch/sandbox/include/asm/clk.h +++ b/arch/sandbox/include/asm/clk.h @@ -19,6 +19,8 @@ struct udevice; enum sandbox_clk_id { SANDBOX_CLK_ID_SPI, SANDBOX_CLK_ID_I2C, + SANDBOX_CLK_ID_UART1, + SANDBOX_CLK_ID_UART2, SANDBOX_CLK_ID_COUNT, }; @@ -33,10 +35,15 @@ enum sandbox_clk_test_id { SANDBOX_CLK_TEST_ID_FIXED, SANDBOX_CLK_TEST_ID_SPI, SANDBOX_CLK_TEST_ID_I2C, + SANDBOX_CLK_TEST_ID_DEVM1, + SANDBOX_CLK_TEST_ID_DEVM2, + SANDBOX_CLK_TEST_ID_DEVM_NULL, SANDBOX_CLK_TEST_ID_COUNT, }; +#define SANDBOX_CLK_TEST_NON_DEVM_COUNT SANDBOX_CLK_TEST_ID_DEVM1 + /** * sandbox_clk_query_rate - Query the current rate of a sandbox clock. * @@ -53,6 +60,14 @@ ulong sandbox_clk_query_rate(struct udevice *dev, int id); * @return: The rate of the clock. */ int sandbox_clk_query_enable(struct udevice *dev, int id); +/** + * sandbox_clk_query_requested - Query the requested state of a sandbox clock. + * + * @dev: The sandbox clock provider device. + * @id: The clock to query. + * @return: The rate of the clock. + */ +int sandbox_clk_query_requested(struct udevice *dev, int id); /** * sandbox_clk_test_get - Ask the sandbox clock test device to request its @@ -62,6 +77,16 @@ int sandbox_clk_query_enable(struct udevice *dev, int id); * @return: 0 if OK, or a negative error code. */ int sandbox_clk_test_get(struct udevice *dev); + +/** + * sandbox_clk_test_devm_get - Ask the sandbox clock test device to request its + * clocks using the managed API. + * + * @dev: The sandbox clock test (client) devivce. + * @return: 0 if OK, or a negative error code. + */ +int sandbox_clk_test_devm_get(struct udevice *dev); + /** * sandbox_clk_test_get_bulk - Ask the sandbox clock test device to request its * clocks with the bulk clk API. @@ -146,5 +171,13 @@ int sandbox_clk_test_release_bulk(struct udevice *dev); * @return: 0 if OK, or a negative error code. */ int sandbox_clk_test_valid(struct udevice *dev); +/** + * sandbox_clk_test_valid - Ask the sandbox clock test device to check its + * clocks are valid. + * + * @dev: The sandbox clock test (client) devivce. + * @return: 0 if OK, or a negative error code. + */ +struct clk *sandbox_clk_test_get_devm_clk(struct udevice *dev, int id); #endif diff --git a/drivers/clk/clk_sandbox.c b/drivers/clk/clk_sandbox.c index 1d5cbb589a..d152fd7e5b 100644 --- a/drivers/clk/clk_sandbox.c +++ b/drivers/clk/clk_sandbox.c @@ -12,6 +12,7 @@ struct sandbox_clk_priv { ulong rate[SANDBOX_CLK_ID_COUNT]; bool enabled[SANDBOX_CLK_ID_COUNT]; + bool requested[SANDBOX_CLK_ID_COUNT]; }; static ulong sandbox_clk_get_rate(struct clk *clk) @@ -65,11 +66,35 @@ static int sandbox_clk_disable(struct clk *clk) return 0; } +static int sandbox_clk_request(struct clk *clk) +{ + struct sandbox_clk_priv *priv = dev_get_priv(clk->dev); + + if (clk->id >= SANDBOX_CLK_ID_COUNT) + return -EINVAL; + + priv->requested[clk->id] = true; + return 0; +} + +static int sandbox_clk_free(struct clk *clk) +{ + struct sandbox_clk_priv *priv = dev_get_priv(clk->dev); + + if (clk->id >= SANDBOX_CLK_ID_COUNT) + return -EINVAL; + + priv->requested[clk->id] = false; + return 0; +} + static struct clk_ops sandbox_clk_ops = { .get_rate = sandbox_clk_get_rate, .set_rate = sandbox_clk_set_rate, .enable = sandbox_clk_enable, .disable = sandbox_clk_disable, + .request = sandbox_clk_request, + .free = sandbox_clk_free, }; static const struct udevice_id sandbox_clk_ids[] = { @@ -104,3 +129,12 @@ int sandbox_clk_query_enable(struct udevice *dev, int id) return priv->enabled[id]; } + +int sandbox_clk_query_requested(struct udevice *dev, int id) +{ + struct sandbox_clk_priv *priv = dev_get_priv(dev); + + if (id < 0 || id >= SANDBOX_CLK_ID_COUNT) + return -EINVAL; + return priv->requested[id]; +} diff --git a/drivers/clk/clk_sandbox_test.c b/drivers/clk/clk_sandbox_test.c index e8465dbfad..41954660ea 100644 --- a/drivers/clk/clk_sandbox_test.c +++ b/drivers/clk/clk_sandbox_test.c @@ -9,7 +9,8 @@ #include struct sandbox_clk_test { - struct clk clks[SANDBOX_CLK_TEST_ID_COUNT]; + struct clk clks[SANDBOX_CLK_TEST_NON_DEVM_COUNT]; + struct clk *clkps[SANDBOX_CLK_TEST_ID_COUNT]; struct clk_bulk bulk; }; @@ -24,7 +25,7 @@ int sandbox_clk_test_get(struct udevice *dev) struct sandbox_clk_test *sbct = dev_get_priv(dev); int i, ret; - for (i = 0; i < SANDBOX_CLK_TEST_ID_COUNT; i++) { + for (i = 0; i < SANDBOX_CLK_TEST_NON_DEVM_COUNT; i++) { ret = clk_get_by_name(dev, sandbox_clk_test_names[i], &sbct->clks[i]); if (ret) @@ -34,6 +35,37 @@ int sandbox_clk_test_get(struct udevice *dev) return 0; } +int sandbox_clk_test_devm_get(struct udevice *dev) +{ + struct sandbox_clk_test *sbct = dev_get_priv(dev); + struct clk *clk; + + clk = devm_clk_get(dev, "no-an-existing-clock"); + if (!IS_ERR(clk)) { + dev_err(dev, "devm_clk_get() should have failed\n"); + return -EINVAL; + } + + clk = devm_clk_get(dev, "uart2"); + if (IS_ERR(clk)) + return PTR_ERR(clk); + sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM1] = clk; + + clk = devm_clk_get_optional(dev, "uart1"); + if (IS_ERR(clk)) + return PTR_ERR(clk); + sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM2] = clk; + + sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM_NULL] = NULL; + clk = devm_clk_get_optional(dev, "not_an_existing_clock"); + if (IS_ERR(clk)) + return PTR_ERR(clk); + if (clk) + return -EINVAL; + + return 0; +} + int sandbox_clk_test_get_bulk(struct udevice *dev) { struct sandbox_clk_test *sbct = dev_get_priv(dev); @@ -48,7 +80,7 @@ ulong sandbox_clk_test_get_rate(struct udevice *dev, int id) if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT) return -EINVAL; - return clk_get_rate(&sbct->clks[id]); + return clk_get_rate(sbct->clkps[id]); } ulong sandbox_clk_test_set_rate(struct udevice *dev, int id, ulong rate) @@ -58,7 +90,7 @@ ulong sandbox_clk_test_set_rate(struct udevice *dev, int id, ulong rate) if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT) return -EINVAL; - return clk_set_rate(&sbct->clks[id], rate); + return clk_set_rate(sbct->clkps[id], rate); } int sandbox_clk_test_enable(struct udevice *dev, int id) @@ -68,7 +100,7 @@ int sandbox_clk_test_enable(struct udevice *dev, int id) if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT) return -EINVAL; - return clk_enable(&sbct->clks[id]); + return clk_enable(sbct->clkps[id]); } int sandbox_clk_test_enable_bulk(struct udevice *dev) @@ -85,7 +117,7 @@ int sandbox_clk_test_disable(struct udevice *dev, int id) if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT) return -EINVAL; - return clk_disable(&sbct->clks[id]); + return clk_disable(sbct->clkps[id]); } int sandbox_clk_test_disable_bulk(struct udevice *dev) @@ -100,7 +132,8 @@ int sandbox_clk_test_free(struct udevice *dev) struct sandbox_clk_test *sbct = dev_get_priv(dev); int i, ret; - for (i = 0; i < SANDBOX_CLK_TEST_ID_COUNT; i++) { + devm_clk_put(dev, sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM1]); + for (i = 0; i < SANDBOX_CLK_TEST_NON_DEVM_COUNT; i++) { ret = clk_free(&sbct->clks[i]); if (ret) return ret; @@ -122,13 +155,27 @@ int sandbox_clk_test_valid(struct udevice *dev) int i; for (i = 0; i < SANDBOX_CLK_TEST_ID_COUNT; i++) { - if (!clk_valid(&sbct->clks[i])) - return -EINVAL; + if (!clk_valid(sbct->clkps[i])) + if (i != SANDBOX_CLK_TEST_ID_DEVM_NULL) + return -EINVAL; } return 0; } +static int sandbox_clk_test_probe(struct udevice *dev) +{ + struct sandbox_clk_test *sbct = dev_get_priv(dev); + int i; + + for (i = 0; i < SANDBOX_CLK_TEST_ID_DEVM1; i++) + sbct->clkps[i] = &sbct->clks[i]; + for (i = SANDBOX_CLK_TEST_ID_DEVM1; i < SANDBOX_CLK_TEST_ID_COUNT; i++) + sbct->clkps[i] = NULL; + + return 0; +} + static const struct udevice_id sandbox_clk_test_ids[] = { { .compatible = "sandbox,clk-test" }, { } @@ -138,5 +185,6 @@ U_BOOT_DRIVER(sandbox_clk_test) = { .name = "sandbox_clk_test", .id = UCLASS_MISC, .of_match = sandbox_clk_test_ids, + .probe = sandbox_clk_test_probe, .priv_auto_alloc_size = sizeof(struct sandbox_clk_test), }; diff --git a/test/dm/clk.c b/test/dm/clk.c index 676ef217f0..3ad0ad8ca3 100644 --- a/test/dm/clk.c +++ b/test/dm/clk.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -53,8 +54,19 @@ static int dm_test_clk(struct unit_test_state *uts) ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "clk-test", &dev_test)); ut_assertok(sandbox_clk_test_get(dev_test)); + ut_assertok(sandbox_clk_test_devm_get(dev_test)); ut_assertok(sandbox_clk_test_valid(dev_test)); + ut_asserteq(0, sandbox_clk_test_get_rate(dev_test, + SANDBOX_CLK_TEST_ID_DEVM_NULL)); + ut_asserteq(0, sandbox_clk_test_set_rate(dev_test, + SANDBOX_CLK_TEST_ID_DEVM_NULL, + 0)); + ut_asserteq(0, sandbox_clk_test_enable(dev_test, + SANDBOX_CLK_TEST_ID_DEVM_NULL)); + ut_asserteq(0, sandbox_clk_test_disable(dev_test, + SANDBOX_CLK_TEST_ID_DEVM_NULL)); + ut_asserteq(1234, sandbox_clk_test_get_rate(dev_test, SANDBOX_CLK_TEST_ID_FIXED)); @@ -62,6 +74,10 @@ static int dm_test_clk(struct unit_test_state *uts) SANDBOX_CLK_TEST_ID_SPI)); ut_asserteq(0, sandbox_clk_test_get_rate(dev_test, SANDBOX_CLK_TEST_ID_I2C)); + ut_asserteq(0, sandbox_clk_test_get_rate(dev_test, + SANDBOX_CLK_TEST_ID_DEVM1)); + ut_asserteq(0, sandbox_clk_test_get_rate(dev_test, + SANDBOX_CLK_TEST_ID_DEVM2)); rate = sandbox_clk_test_set_rate(dev_test, SANDBOX_CLK_TEST_ID_FIXED, 12345); @@ -121,8 +137,25 @@ static int dm_test_clk(struct unit_test_state *uts) ut_asserteq(0, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_SPI)); ut_asserteq(0, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_I2C)); + ut_asserteq(1, sandbox_clk_query_requested(dev_clk, + SANDBOX_CLK_ID_SPI)); + ut_asserteq(1, sandbox_clk_query_requested(dev_clk, + SANDBOX_CLK_ID_I2C)); + ut_asserteq(1, sandbox_clk_query_requested(dev_clk, + SANDBOX_CLK_ID_UART2)); ut_assertok(sandbox_clk_test_free(dev_test)); - + ut_asserteq(0, sandbox_clk_query_requested(dev_clk, + SANDBOX_CLK_ID_SPI)); + ut_asserteq(0, sandbox_clk_query_requested(dev_clk, + SANDBOX_CLK_ID_I2C)); + ut_asserteq(0, sandbox_clk_query_requested(dev_clk, + SANDBOX_CLK_ID_UART2)); + + ut_asserteq(1, sandbox_clk_query_requested(dev_clk, + SANDBOX_CLK_ID_UART1)); + ut_assertok(device_remove(dev_test, DM_REMOVE_NORMAL)); + ut_asserteq(0, sandbox_clk_query_requested(dev_clk, + SANDBOX_CLK_ID_UART1)); return 0; } DM_TEST(dm_test_clk, DM_TESTF_SCAN_FDT); @@ -159,6 +192,7 @@ static int dm_test_clk_bulk(struct unit_test_state *uts) ut_assertok(sandbox_clk_test_release_bulk(dev_test)); ut_asserteq(0, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_SPI)); ut_asserteq(0, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_I2C)); + ut_assertok(device_remove(dev_test, DM_REMOVE_NORMAL)); return 0; } From patchwork Tue Oct 22 12:00:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Jacques Hiblot X-Patchwork-Id: 1181279 X-Patchwork-Delegate: lukma@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="LippLQ/e"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 46yByR0xgRz9s4Y for ; Tue, 22 Oct 2019 23:04:47 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id CF7E3C21E38; Tue, 22 Oct 2019 12:04:09 +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 C6921C21E3E; Tue, 22 Oct 2019 12:02:06 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id BC225C21BE5; Tue, 22 Oct 2019 12:02:05 +0000 (UTC) Received: from lelv0143.ext.ti.com (lelv0143.ext.ti.com [198.47.23.248]) by lists.denx.de (Postfix) with ESMTPS id 8E1E1C21DD3 for ; Tue, 22 Oct 2019 12:00:38 +0000 (UTC) Received: from lelv0266.itg.ti.com ([10.180.67.225]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id x9MC0WnX043499; Tue, 22 Oct 2019 07:00:32 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1571745632; bh=7m0SE+dBT+6Cr8yu+WwxlVhbrTzguX0G1IbCPh8KPEo=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=LippLQ/eGcM/WlApMBm+70iUY57vf22kLgzY9Znr1fleiho5wHeYJJlc5USoMRi+W TB5oqpLGFlhQ+hGao4gQ9rRyC/nTLN5TlWfS1VECg4L6xXCMXrTyuWQW7Qou0HCUin sAcip0D8Qo+jJv1YC7Mr027gGugv67Q2qV+MCwCc= Received: from DLEE100.ent.ti.com (dlee100.ent.ti.com [157.170.170.30]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id x9MC0HTJ056004 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 22 Oct 2019 07:00:17 -0500 Received: from DLEE111.ent.ti.com (157.170.170.22) by DLEE100.ent.ti.com (157.170.170.30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5; Tue, 22 Oct 2019 07:00:16 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE111.ent.ti.com (157.170.170.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5 via Frontend Transport; Tue, 22 Oct 2019 07:00:07 -0500 Received: from localhost (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id x9MC0GmS018941; Tue, 22 Oct 2019 07:00:16 -0500 From: Jean-Jacques Hiblot To: , Date: Tue, 22 Oct 2019 14:00:06 +0200 Message-ID: <20191022120007.23288-5-jjhiblot@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191022120007.23288-1-jjhiblot@ti.com> References: <20191022120007.23288-1-jjhiblot@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH v2 4/5] drivers: clk: Fix using assigned-clocks in the node of the clock it sets up 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: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This fixes the case where assigned-clocks is used to define a clock defaults inside this same clock's node. This is used sometimes to setup a default parents and/or rate for a clock. example: muxed_clock: muxed_clock { clocks = <&clk_provider 0>, <&clk_provider 1>; #clock-cells = <0>; assigned-clocks = <&muxed_clock>; assigned-clock-parents = <&clk_provider 1>; }; It doesn't work in u-boot because the assigned-clocks are setup *before* the clock is probed. (clk_set_parent() will likely crash or fail if called before the device probe function) Making it work by handling "assigned-clocks" in 2 steps: first before the clk device is probed, and then after the clk device is probed. Signed-off-by: Jean-Jacques Hiblot --- Changes in v2: None drivers/clk/clk-uclass.c | 48 +++++++++++++++++++++++++++++++++++----- drivers/core/device.c | 2 +- include/clk.h | 7 ++++-- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index e7ec6347de..75d618a47b 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -178,7 +178,7 @@ bulk_get_err: return ret; } -static int clk_set_default_parents(struct udevice *dev) +static int clk_set_default_parents(struct udevice *dev, int stage) { struct clk clk, parent_clk; int index; @@ -214,8 +214,18 @@ static int clk_set_default_parents(struct udevice *dev) return ret; } - ret = clk_set_parent(&clk, &parent_clk); + /* This is clk provider device trying to reparent itself + * It cannot be done right now but need to wait after the + * device is probed + */ + if (stage == 0 && clk.dev == dev) + continue; + + if (stage > 0 && clk.dev != dev) + /* do not setup twice the parent clocks */ + continue; + ret = clk_set_parent(&clk, &parent_clk); /* * Not all drivers may support clock-reparenting (as of now). * Ignore errors due to this. @@ -233,7 +243,7 @@ static int clk_set_default_parents(struct udevice *dev) return 0; } -static int clk_set_default_rates(struct udevice *dev) +static int clk_set_default_rates(struct udevice *dev, int stage) { struct clk clk; int index; @@ -268,7 +278,19 @@ static int clk_set_default_rates(struct udevice *dev) continue; } + /* This is clk provider device trying to program itself + * It cannot be done right now but need to wait after the + * device is probed + */ + if (stage == 0 && clk.dev == dev) + continue; + + if (stage > 0 && clk.dev != dev) + /* do not setup twice the parent clocks */ + continue; + ret = clk_set_rate(&clk, rates[index]); + if (ret < 0) { debug("%s: failed to set rate on clock index %d (%ld) for %s\n", __func__, index, clk.id, dev_read_name(dev)); @@ -281,7 +303,7 @@ fail: return ret; } -int clk_set_defaults(struct udevice *dev) +int clk_set_defaults(struct udevice *dev, int stage) { int ret; @@ -294,11 +316,11 @@ int clk_set_defaults(struct udevice *dev) debug("%s(%s)\n", __func__, dev_read_name(dev)); - ret = clk_set_default_parents(dev); + ret = clk_set_default_parents(dev, stage); if (ret) return ret; - ret = clk_set_default_rates(dev); + ret = clk_set_default_rates(dev, stage); if (ret < 0) return ret; @@ -673,7 +695,21 @@ void devm_clk_put(struct udevice *dev, struct clk *clk) WARN_ON(rc); } +int clk_uclass_post_probe(struct udevice *dev) +{ + /* + * when a clock provider is probed. Call clk_set_defaults() + * also after the device is probed. This takes care of cases + * where the DT is used to setup default parents and rates + * using assigned-clocks + */ + clk_set_defaults(dev, 1); + + return 0; +} + UCLASS_DRIVER(clk) = { .id = UCLASS_CLK, .name = "clk", + .post_probe = clk_uclass_post_probe, }; diff --git a/drivers/core/device.c b/drivers/core/device.c index ce66c72e5e..854aa91bbf 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -417,7 +417,7 @@ int device_probe(struct udevice *dev) * Process 'assigned-{clocks/clock-parents/clock-rates}' * properties */ - ret = clk_set_defaults(dev); + ret = clk_set_defaults(dev, 0); if (ret) goto fail; } diff --git a/include/clk.h b/include/clk.h index 9be3264113..a5ee53d94a 100644 --- a/include/clk.h +++ b/include/clk.h @@ -244,10 +244,13 @@ static inline int clk_release_all(struct clk *clk, int count) * * @dev: A device to process (the ofnode associated with this device * will be processed). + * @stage: A integer. 0 indicates that this is called before the device + * is probed. 1 indicates that this is called just after the + * device has been probed */ -int clk_set_defaults(struct udevice *dev); +int clk_set_defaults(struct udevice *dev, int stage); #else -static inline int clk_set_defaults(struct udevice *dev) +static inline int clk_set_defaults(struct udevice *dev, int stage) { return 0; } From patchwork Tue Oct 22 12:00:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Jacques Hiblot X-Patchwork-Id: 1181276 X-Patchwork-Delegate: lukma@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="dIFCfruT"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 46yBwt1ylNz9s4Y for ; Tue, 22 Oct 2019 23:03:23 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 2CB78C21E68; Tue, 22 Oct 2019 12:03:18 +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 83B94C21E15; Tue, 22 Oct 2019 12:01:59 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 33AF3C21E12; Tue, 22 Oct 2019 12:01:58 +0000 (UTC) Received: from lelv0142.ext.ti.com (lelv0142.ext.ti.com [198.47.23.249]) by lists.denx.de (Postfix) with ESMTPS id 4F5F7C21CB1 for ; Tue, 22 Oct 2019 12:00:28 +0000 (UTC) Received: from lelv0266.itg.ti.com ([10.180.67.225]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id x9MC0Ilv089124; Tue, 22 Oct 2019 07:00:18 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1571745618; bh=uTEDSKvOTBARjcPB7Lb8nQFte/KzYuobl/JZOfgjPT8=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=dIFCfruTCi9e8zDdOuQKq3JAC+u/Bmsej1kaEgSx14IjU6itZKp01vGiv0Bi5y8bo CeyEPZje2frhKsm54BCH5HbdXGu51lkyzftHwBUY6W3qMh5Nem1esW9KDkKccCNTwu Eze8GeDcvFILv0v8orwbw2fHwMdCnO+44LVyZdNs= Received: from DLEE101.ent.ti.com (dlee101.ent.ti.com [157.170.170.31]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id x9MC0I0t056062 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 22 Oct 2019 07:00:18 -0500 Received: from DLEE112.ent.ti.com (157.170.170.23) by DLEE101.ent.ti.com (157.170.170.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5; Tue, 22 Oct 2019 07:00:08 -0500 Received: from lelv0326.itg.ti.com (10.180.67.84) by DLEE112.ent.ti.com (157.170.170.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5 via Frontend Transport; Tue, 22 Oct 2019 07:00:08 -0500 Received: from localhost (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id x9MC0HCS078788; Tue, 22 Oct 2019 07:00:17 -0500 From: Jean-Jacques Hiblot To: , Date: Tue, 22 Oct 2019 14:00:07 +0200 Message-ID: <20191022120007.23288-6-jjhiblot@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191022120007.23288-1-jjhiblot@ti.com> References: <20191022120007.23288-1-jjhiblot@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH v2 5/5] test: clk: test clock self assignment 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: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Make sure that the clock self-assignment works by having a clock of clk-sbox be configured automatically when clk-sbox is probed. Signed-off-by: Jean-Jacques Hiblot --- Changes in v2: None arch/sandbox/dts/test.dts | 2 ++ drivers/clk/clk_sandbox.c | 22 ++++++++++++++++++++++ test/dm/clk.c | 4 ++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 0ee86a74ed..c118125169 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -226,6 +226,8 @@ clk_sandbox: clk-sbox { compatible = "sandbox,clk"; #clock-cells = <1>; + assigned-clocks = <&clk_sandbox 3>; + assigned-clock-rates = <321>; }; clk-test { diff --git a/drivers/clk/clk_sandbox.c b/drivers/clk/clk_sandbox.c index d152fd7e5b..de6b2f7c82 100644 --- a/drivers/clk/clk_sandbox.c +++ b/drivers/clk/clk_sandbox.c @@ -10,6 +10,7 @@ #include struct sandbox_clk_priv { + bool probed; ulong rate[SANDBOX_CLK_ID_COUNT]; bool enabled[SANDBOX_CLK_ID_COUNT]; bool requested[SANDBOX_CLK_ID_COUNT]; @@ -19,6 +20,9 @@ static ulong sandbox_clk_get_rate(struct clk *clk) { struct sandbox_clk_priv *priv = dev_get_priv(clk->dev); + if (!priv->probed) + return -ENODEV; + if (clk->id >= SANDBOX_CLK_ID_COUNT) return -EINVAL; @@ -30,6 +34,9 @@ static ulong sandbox_clk_set_rate(struct clk *clk, ulong rate) struct sandbox_clk_priv *priv = dev_get_priv(clk->dev); ulong old_rate; + if (!priv->probed) + return -ENODEV; + if (clk->id >= SANDBOX_CLK_ID_COUNT) return -EINVAL; @@ -46,6 +53,9 @@ static int sandbox_clk_enable(struct clk *clk) { struct sandbox_clk_priv *priv = dev_get_priv(clk->dev); + if (!priv->probed) + return -ENODEV; + if (clk->id >= SANDBOX_CLK_ID_COUNT) return -EINVAL; @@ -58,6 +68,9 @@ static int sandbox_clk_disable(struct clk *clk) { struct sandbox_clk_priv *priv = dev_get_priv(clk->dev); + if (!priv->probed) + return -ENODEV; + if (clk->id >= SANDBOX_CLK_ID_COUNT) return -EINVAL; @@ -97,6 +110,14 @@ static struct clk_ops sandbox_clk_ops = { .free = sandbox_clk_free, }; +static int sandbox_clk_probe(struct udevice *dev) +{ + struct sandbox_clk_priv *priv = dev_get_priv(dev); + + priv->probed = true; + return 0; +} + static const struct udevice_id sandbox_clk_ids[] = { { .compatible = "sandbox,clk" }, { } @@ -107,6 +128,7 @@ U_BOOT_DRIVER(clk_sandbox) = { .id = UCLASS_CLK, .of_match = sandbox_clk_ids, .ops = &sandbox_clk_ops, + .probe = sandbox_clk_probe, .priv_auto_alloc_size = sizeof(struct sandbox_clk_priv), }; diff --git a/test/dm/clk.c b/test/dm/clk.c index 3ad0ad8ca3..31335a543f 100644 --- a/test/dm/clk.c +++ b/test/dm/clk.c @@ -74,8 +74,8 @@ static int dm_test_clk(struct unit_test_state *uts) SANDBOX_CLK_TEST_ID_SPI)); ut_asserteq(0, sandbox_clk_test_get_rate(dev_test, SANDBOX_CLK_TEST_ID_I2C)); - ut_asserteq(0, sandbox_clk_test_get_rate(dev_test, - SANDBOX_CLK_TEST_ID_DEVM1)); + ut_asserteq(321, sandbox_clk_test_get_rate(dev_test, + SANDBOX_CLK_TEST_ID_DEVM1)); ut_asserteq(0, sandbox_clk_test_get_rate(dev_test, SANDBOX_CLK_TEST_ID_DEVM2));