Received: by 2002:a25:c593:0:0:0:0:0 with SMTP id v141csp2496527ybe; Sat, 14 Sep 2019 16:38:03 -0700 (PDT) X-Google-Smtp-Source: APXvYqxHB9HJuW4wSZszEyW4t2FwMRXK7pZruO9cWBtCnl1fs6rwvtZ8BS120B0qF2eWxNH6MgdB X-Received: by 2002:a17:906:a954:: with SMTP id hh20mr45678193ejb.196.1568504282953; Sat, 14 Sep 2019 16:38:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1568504282; cv=none; d=google.com; s=arc-20160816; b=p2/zdP7+Q9m+3z9HV6dMaipJ0da7VRXOud1b8LJ0FFeuDjIzh4B+HDCEqq4d+OCOX3 6R/x1Tt8Wf23gv5tRKR06brNjvnTLHcnySNQ3s5n46u70hLHcXE+sQEaL+/4cl1yqwb1 Po2A2rBRS1Ym/qdIdEtwyFWx7HABLKbVD7hgIqiqc8v09k1chwTZgb5RLxCZ1yiI7uvi xcgUlFoRx2XzLILV8IkOYHWWzRWfhJyVxRSTLLXA0QpR4maV7qF3ULp0RrhF+ztWs6zk pMapl1J8VYIs0x/PioB0RCUTP7dmcJVQl9rrT0mp5h9KwhfOZtHCEswXYRWdtUrkPoS+ lvUA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=le7NygfwECXHI29Aa1HMyjTxRhJsGRJaaspEZV21iFA=; b=FOCJgq/AsV48qjJt5pcReq9TWpmw6kl8RKmED4weGjl6ql9Ob51ofxMhEBnKJXX78/ w26MF2Wn6dBZm1ccc+l9OXty8sOLn9T+W3TS7ZCJ4DnX8FtRdwSIBTDdIe93hBah85i2 nfw2ZfSReYlQT/RSIOp/ly6GAIqXVq01HbJ6yrdqD1QObcV07lTTlArDpiUn35TiTb8W hisZMeBbf4mxNQHZHO20qMkuA3ewZPc9ob7zDd3cBGOf4oEe6REE1wSbrpI3IXlUxcqG WvxPMw86OjqYy2f9p7UUDNY617krIMeBzUL67gV4E2ZAoKHQONfQNczuTK0LbLJMWUQg bG0Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-crypto-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x2si712989ejd.126.2019.09.14.16.37.38; Sat, 14 Sep 2019 16:38:02 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-crypto-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-crypto-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731353AbfINVDS (ORCPT + 99 others); Sat, 14 Sep 2019 17:03:18 -0400 Received: from muru.com ([72.249.23.125]:32950 "EHLO muru.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731336AbfINVDR (ORCPT ); Sat, 14 Sep 2019 17:03:17 -0400 Received: from hillo.muru.com (localhost [127.0.0.1]) by muru.com (Postfix) with ESMTP id 31CE18105; Sat, 14 Sep 2019 21:03:46 +0000 (UTC) From: Tony Lindgren To: Matt Mackall , Herbert Xu , linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org Cc: linux-crypto@vger.kernel.org, Aaro Koskinen , Adam Ford , =?UTF-8?q?Pali=20Roh=C3=A1r?= , Sebastian Reichel , Tero Kristo , Rob Herring , devicetree@vger.kernel.org Subject: [PATCH 6/7] hwrng: omap3-rom - Use runtime PM instead of custom functions Date: Sat, 14 Sep 2019 14:02:59 -0700 Message-Id: <20190914210300.15836-7-tony@atomide.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190914210300.15836-1-tony@atomide.com> References: <20190914210300.15836-1-tony@atomide.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org Nowadays we have runtime PM, and we can use it with autosuspend_timeout to idle things automatically. This allows us to get rid of the custom PM implementation. We enable clocks and init RNG in runtime_resume, and reset RNG and disable clocks in runtime_suspend. And then omap3_rom_rng_read() becomes very simple and we don't need the old functions for omap3_rom_rng_idle() and omap3_rom_rng_get_random(). We can now also get rid of pr_fmt as we're using dev_err instead. Cc: Aaro Koskinen Cc: Adam Ford Cc: Pali Rohár Cc: Sebastian Reichel Cc: Tero Kristo Signed-off-by: Tony Lindgren --- drivers/char/hw_random/omap3-rom-rng.c | 126 ++++++++++++++----------- 1 file changed, 73 insertions(+), 53 deletions(-) diff --git a/drivers/char/hw_random/omap3-rom-rng.c b/drivers/char/hw_random/omap3-rom-rng.c --- a/drivers/char/hw_random/omap3-rom-rng.c +++ b/drivers/char/hw_random/omap3-rom-rng.c @@ -11,8 +11,6 @@ * warranty of any kind, whether express or implied. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -23,73 +21,83 @@ #include #include #include +#include #define RNG_RESET 0x01 #define RNG_GEN_PRNG_HW_INIT 0x02 #define RNG_GEN_HW 0x08 -/* param1: ptr, param2: count, param3: flag */ -static u32 (*omap3_rom_rng_call)(u32, u32, u32); - struct omap_rom_rng { struct clk *clk; struct device *dev; struct hwrng ops; + u32 (*rom_rng_call)(u32 ptr, u32 count, u32 flag); }; -static struct delayed_work idle_work; -static int rng_idle; -static struct clk *rng_clk; - -static void omap3_rom_rng_idle(struct work_struct *work) +static int omap3_rom_rng_read(struct hwrng *rng, void *data, size_t max, bool w) { + struct omap_rom_rng *ddata; + u32 ptr; int r; - r = omap3_rom_rng_call(0, 0, RNG_RESET); - if (r != 0) { - pr_err("reset failed: %d\n", r); - return; + ddata = (struct omap_rom_rng *)rng->priv; + + r = pm_runtime_get_sync(ddata->dev); + if (r < 0) { + pm_runtime_put_noidle(ddata->dev); + + return r; } - clk_disable_unprepare(rng_clk); - rng_idle = 1; + + ptr = virt_to_phys(data); + r = ddata->rom_rng_call(ptr, 4, RNG_GEN_HW); + if (r != 0) + r = -EINVAL; + else + r = 4; + + pm_runtime_mark_last_busy(ddata->dev); + pm_runtime_put_autosuspend(ddata->dev); + + return r; } -static int omap3_rom_rng_get_random(void *buf, unsigned int count) +static int omap_rom_rng_runtime_suspend(struct device *dev) { - u32 r; - u32 ptr; + struct omap_rom_rng *ddata; + int r; - cancel_delayed_work_sync(&idle_work); - if (rng_idle) { - r = clk_prepare_enable(rng_clk); - if (r) - return r; - - r = omap3_rom_rng_call(0, 0, RNG_GEN_PRNG_HW_INIT); - if (r != 0) { - clk_disable_unprepare(rng_clk); - pr_err("HW init failed: %d\n", r); - return -EIO; - } - rng_idle = 0; - } + ddata = dev_get_drvdata(dev); - ptr = virt_to_phys(buf); - r = omap3_rom_rng_call(ptr, count, RNG_GEN_HW); - schedule_delayed_work(&idle_work, msecs_to_jiffies(500)); + r = ddata->rom_rng_call(0, 0, RNG_RESET); if (r != 0) - return -EINVAL; + dev_err(dev, "reset failed: %d\n", r); + + clk_disable_unprepare(ddata->clk); + return 0; } -static int omap3_rom_rng_read(struct hwrng *rng, void *data, size_t max, bool w) +static int omap_rom_rng_runtime_resume(struct device *dev) { + struct omap_rom_rng *ddata; int r; - r = omap3_rom_rng_get_random(data, 4); + ddata = dev_get_drvdata(dev); + + r = clk_prepare_enable(ddata->clk); if (r < 0) return r; - return 4; + + r = ddata->rom_rng_call(0, 0, RNG_GEN_PRNG_HW_INIT); + if (r != 0) { + clk_disable(ddata->clk); + dev_err(dev, "HW init failed: %d\n", r); + + return -EIO; + } + + return 0; } static int omap3_rom_rng_probe(struct platform_device *pdev) @@ -113,27 +121,33 @@ static int omap3_rom_rng_probe(struct platform_device *pdev) } dev_set_drvdata(ddata->dev, ddata); - omap3_rom_rng_call = pdev->dev.platform_data; - if (!omap3_rom_rng_call) { + ddata->rom_rng_call = pdev->dev.platform_data; + if (!ddata->rom_rng_call) { dev_err(ddata->dev, "rom_rng_call is NULL\n"); return -EINVAL; } - INIT_DELAYED_WORK(&idle_work, omap3_rom_rng_idle); ddata->clk = devm_clk_get(ddata->dev, "ick"); if (IS_ERR(ddata->clk)) { dev_err(ddata->dev, "unable to get RNG clock\n"); return PTR_ERR(ddata->clk); } - rng_clk = ddata->clk; - /* Leave the RNG in reset state. */ - ret = clk_prepare_enable(ddata->clk); - if (ret) - return ret; - omap3_rom_rng_idle(0); + pm_runtime_enable(ddata->dev); + + ret = hwrng_register(&ddata->ops); + if (!ret) + goto err_disable; + + pm_runtime_set_autosuspend_delay(ddata->dev, 500); + pm_runtime_use_autosuspend(ddata->dev); + + return 0; - return hwrng_register(&ddata->ops); +err_disable: + pm_runtime_disable(ddata->dev); + + return ret; } static int omap3_rom_rng_remove(struct platform_device *pdev) @@ -141,10 +155,10 @@ static int omap3_rom_rng_remove(struct platform_device *pdev) struct omap_rom_rng *ddata; ddata = dev_get_drvdata(&pdev->dev); - cancel_delayed_work_sync(&idle_work); hwrng_unregister(&ddata->ops); - if (!rng_idle) - clk_disable_unprepare(rng_clk); + pm_runtime_dont_use_autosuspend(ddata->dev); + pm_runtime_disable(ddata->dev); + return 0; } @@ -154,10 +168,16 @@ static const struct of_device_id omap_rom_rng_match[] = { }; MODULE_DEVICE_TABLE(of, omap_rom_rng_match); +static const struct dev_pm_ops omap_rom_rng_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(omap_rom_rng_runtime_suspend, + omap_rom_rng_runtime_resume) +}; + static struct platform_driver omap3_rom_rng_driver = { .driver = { .name = "omap3-rom-rng", .of_match_table = omap_rom_rng_match, + .pm = &omap_rom_rng_pm_ops, }, .probe = omap3_rom_rng_probe, .remove = omap3_rom_rng_remove, -- 2.23.0