From patchwork Fri Jul 27 16:47:52 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabio Estevam X-Patchwork-Id: 1250271 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 4E55A3FDD9 for ; Fri, 27 Jul 2012 16:54:37 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1Sunjh-0005wt-37; Fri, 27 Jul 2012 16:49:57 +0000 Received: from co1ehsobe003.messaging.microsoft.com ([216.32.180.186] helo=co1outboundpool.messaging.microsoft.com) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1SuniP-0005uq-PF for linux-arm-kernel@lists.infradead.org; Fri, 27 Jul 2012 16:48:38 +0000 Received: from mail69-co1-R.bigfish.com (10.243.78.237) by CO1EHSOBE010.bigfish.com (10.243.66.73) with Microsoft SMTP Server id 14.1.225.23; Fri, 27 Jul 2012 16:47:59 +0000 Received: from mail69-co1 (localhost [127.0.0.1]) by mail69-co1-R.bigfish.com (Postfix) with ESMTP id 931CEC602B9; Fri, 27 Jul 2012 16:47:59 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 5 X-BigFish: VS5(zz78fbmzz1202hzz8275bh8275dh84d07hz2dh2a8h668h839hd24he5bhf0ah107ah) Received: from mail69-co1 (localhost.localdomain [127.0.0.1]) by mail69-co1 (MessageSwitch) id 1343407677104253_14764; Fri, 27 Jul 2012 16:47:57 +0000 (UTC) Received: from CO1EHSMHS030.bigfish.com (unknown [10.243.78.247]) by mail69-co1.bigfish.com (Postfix) with ESMTP id 1775868003F; Fri, 27 Jul 2012 16:47:57 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by CO1EHSMHS030.bigfish.com (10.243.66.40) with Microsoft SMTP Server (TLS) id 14.1.225.23; Fri, 27 Jul 2012 16:47:56 +0000 Received: from tx30smr01.am.freescale.net (10.81.153.31) by 039-SN1MMR1-001.039d.mgd.msft.net (10.84.1.13) with Microsoft SMTP Server (TLS) id 14.2.298.5; Fri, 27 Jul 2012 11:47:55 -0500 Received: from fabio-Latitude-E6410.am.freescale.net ([10.29.240.146]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id q6RGlpws019421; Fri, 27 Jul 2012 09:47:53 -0700 From: Fabio Estevam To: Subject: [PATCH v2 2/2] hw_random: mxc-rnga: Access data via structure Date: Fri, 27 Jul 2012 13:47:52 -0300 Message-ID: <1343407672-27185-2-git-send-email-fabio.estevam@freescale.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1343407672-27185-1-git-send-email-fabio.estevam@freescale.com> References: <1343407672-27185-1-git-send-email-fabio.estevam@freescale.com> MIME-Version: 1.0 X-OriginatorOrg: freescale.com X-Spam-Note: CRM114 invocation failed X-Spam-Note: SpamAssassin invocation failed Cc: Fabio Estevam , Theodore Ts'o , linux-kernel@vger.kernel.org, kernel@pengutronix.de X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org In current driver, everytime we need to access the rng clock (,ie to enable or disable it) a call to clk_get is done. This is not correct and the preferred way is to provide a rng data structure that could be used for accessing rng resources. Cc: Theodore Ts'o Cc: Herbert Xu Cc: Signed-off-by: Fabio Estevam --- Changes since v1: - No changes. Newly introduced in this version drivers/char/hw_random/mxc-rnga.c | 108 +++++++++++++++++------------------- 1 files changed, 51 insertions(+), 57 deletions(-) diff --git a/drivers/char/hw_random/mxc-rnga.c b/drivers/char/hw_random/mxc-rnga.c index 62c7efe..f05d857 100644 --- a/drivers/char/hw_random/mxc-rnga.c +++ b/drivers/char/hw_random/mxc-rnga.c @@ -59,16 +59,21 @@ #define RNGA_STATUS_LAST_READ_STATUS 0x00000002 #define RNGA_STATUS_SECURITY_VIOLATION 0x00000001 -static struct platform_device *rng_dev; +struct mxc_rng { + struct device *dev; + struct hwrng rng; + void __iomem *mem; + struct clk *clk; +}; static int mxc_rnga_data_present(struct hwrng *rng, int wait) { - void __iomem *rng_base = (void __iomem *)rng->priv; int i; + struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng); for (i = 0; i < 20; i++) { /* how many random numbers are in FIFO? [0-16] */ - int level = (__raw_readl(rng_base + RNGA_STATUS) & + int level = (__raw_readl(mxc_rng->mem + RNGA_STATUS) & RNGA_STATUS_LEVEL_MASK) >> 8; if (level || !wait) return !!level; @@ -81,20 +86,20 @@ static int mxc_rnga_data_read(struct hwrng *rng, u32 * data) { int err; u32 ctrl; - void __iomem *rng_base = (void __iomem *)rng->priv; + struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng); /* retrieve a random number from FIFO */ - *data = __raw_readl(rng_base + RNGA_OUTPUT_FIFO); + *data = __raw_readl(mxc_rng->mem + RNGA_OUTPUT_FIFO); /* some error while reading this random number? */ - err = __raw_readl(rng_base + RNGA_STATUS) & RNGA_STATUS_ERROR_INT; + err = __raw_readl(mxc_rng->mem + RNGA_STATUS) & RNGA_STATUS_ERROR_INT; /* if error: clear error interrupt, but doesn't return random number */ if (err) { - dev_dbg(&rng_dev->dev, "Error while reading random number!\n"); - ctrl = __raw_readl(rng_base + RNGA_CONTROL); + dev_dbg(mxc_rng->dev, "Error while reading random number!\n"); + ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL); __raw_writel(ctrl | RNGA_CONTROL_CLEAR_INT, - rng_base + RNGA_CONTROL); + mxc_rng->mem + RNGA_CONTROL); return 0; } else return 4; @@ -103,22 +108,22 @@ static int mxc_rnga_data_read(struct hwrng *rng, u32 * data) static int mxc_rnga_init(struct hwrng *rng) { u32 ctrl, osc; - void __iomem *rng_base = (void __iomem *)rng->priv; + struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng); /* wake up */ - ctrl = __raw_readl(rng_base + RNGA_CONTROL); - __raw_writel(ctrl & ~RNGA_CONTROL_SLEEP, rng_base + RNGA_CONTROL); + ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL); + __raw_writel(ctrl & ~RNGA_CONTROL_SLEEP, mxc_rng->mem + RNGA_CONTROL); /* verify if oscillator is working */ - osc = __raw_readl(rng_base + RNGA_STATUS); + osc = __raw_readl(mxc_rng->mem + RNGA_STATUS); if (osc & RNGA_STATUS_OSC_DEAD) { - dev_err(&rng_dev->dev, "RNGA Oscillator is dead!\n"); + dev_err(mxc_rng->dev, "RNGA Oscillator is dead!\n"); return -ENODEV; } /* go running */ - ctrl = __raw_readl(rng_base + RNGA_CONTROL); - __raw_writel(ctrl | RNGA_CONTROL_GO, rng_base + RNGA_CONTROL); + ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL); + __raw_writel(ctrl | RNGA_CONTROL_GO, mxc_rng->mem + RNGA_CONTROL); return 0; } @@ -126,40 +131,40 @@ static int mxc_rnga_init(struct hwrng *rng) static void mxc_rnga_cleanup(struct hwrng *rng) { u32 ctrl; - void __iomem *rng_base = (void __iomem *)rng->priv; + struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng); - ctrl = __raw_readl(rng_base + RNGA_CONTROL); + ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL); /* stop rnga */ - __raw_writel(ctrl & ~RNGA_CONTROL_GO, rng_base + RNGA_CONTROL); + __raw_writel(ctrl & ~RNGA_CONTROL_GO, mxc_rng->mem + RNGA_CONTROL); } -static struct hwrng mxc_rnga = { - .name = "mxc-rnga", - .init = mxc_rnga_init, - .cleanup = mxc_rnga_cleanup, - .data_present = mxc_rnga_data_present, - .data_read = mxc_rnga_data_read -}; - static int __init mxc_rnga_probe(struct platform_device *pdev) { int err = -ENODEV; - struct clk *clk; struct resource *res, *mem; - void __iomem *rng_base = NULL; - - if (rng_dev) - return -EBUSY; - - clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) { + struct mxc_rng *mxc_rng; + + mxc_rng = devm_kzalloc(&pdev->dev, sizeof(struct mxc_rng), + GFP_KERNEL); + if (!mxc_rng) + return -ENOMEM; + + mxc_rng->dev = &pdev->dev; + mxc_rng->rng.name = "mxc-rnga"; + mxc_rng->rng.init = mxc_rnga_init; + mxc_rng->rng.cleanup = mxc_rnga_cleanup, + mxc_rng->rng.data_present = mxc_rnga_data_present, + mxc_rng->rng.data_read = mxc_rnga_data_read, + + mxc_rng->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(mxc_rng->clk)) { dev_err(&pdev->dev, "Could not get rng_clk!\n"); - err = PTR_ERR(clk); + err = PTR_ERR(mxc_rng->clk); goto out; } - clk_prepare_enable(clk); + clk_prepare_enable(mxc_rng->clk); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { @@ -173,36 +178,27 @@ static int __init mxc_rnga_probe(struct platform_device *pdev) goto err_region; } - rng_base = ioremap(res->start, resource_size(res)); - if (!rng_base) { + mxc_rng->mem = ioremap(res->start, resource_size(res)); + if (!mxc_rng->mem) { err = -ENOMEM; goto err_ioremap; } - mxc_rnga.priv = (unsigned long)rng_base; - - err = hwrng_register(&mxc_rnga); + err = hwrng_register(&mxc_rng->rng); if (err) { dev_err(&pdev->dev, "MXC RNGA registering failed (%d)\n", err); - goto err_register; + goto err_ioremap; } - rng_dev = pdev; - dev_info(&pdev->dev, "MXC RNGA Registered.\n"); return 0; -err_register: - iounmap(rng_base); - rng_base = NULL; - err_ioremap: release_mem_region(res->start, resource_size(res)); err_region: - clk_disable_unprepare(clk); - clk_put(clk); + clk_disable_unprepare(mxc_rng->clk); out: return err; @@ -211,17 +207,15 @@ out: static int __exit mxc_rnga_remove(struct platform_device *pdev) { struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - void __iomem *rng_base = (void __iomem *)mxc_rnga.priv; - struct clk *clk = clk_get(&pdev->dev, NULL); + struct mxc_rng *mxc_rng = platform_get_drvdata(pdev); - hwrng_unregister(&mxc_rnga); + hwrng_unregister(&mxc_rng->rng); - iounmap(rng_base); + iounmap(mxc_rng->mem); release_mem_region(res->start, resource_size(res)); - clk_disable_unprepare(clk); - clk_put(clk); + clk_disable_unprepare(mxc_rng->clk); return 0; }