From patchwork Fri Sep 11 20:08:28 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lee Jones X-Patchwork-Id: 53500 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f72.google.com (mail-la0-f72.google.com [209.85.215.72]) by patches.linaro.org (Postfix) with ESMTPS id AD07522B26 for ; Fri, 11 Sep 2015 20:11:38 +0000 (UTC) Received: by ladx5 with SMTP id x5sf13857054lad.1 for ; Fri, 11 Sep 2015 13:11:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=HNGWQlrHXC47rxo7BqPrfiwoT+CVxzh7e/+dejcwAZM=; b=JtV1ncwAdnDPBoQaJf5mtWAJP5xjmhAzBbbjizkL/Uc25W9AFOJMoPe1a4FBoIt+QH 0k9tnJ+f9TyndNs7oefelGDbwbyT0bnT0DRGC3l/lQSKt6bvt5toFKsJwVFLKgFH3uWe tUW3eNslyRnRDtn29vVP5IZSif7D+AnvAd5o8Opk906QHDcCABCyMKouh1vJE2xp/d+w BoOw3L5Ix4IBinCpfDgoeq9nNZqE1u4n2D02slWVGFKr/363ietpnbX/pN1JRvrKNRhw MyJMbMHA8U7AZpZ9hSXl0jjz7ihtKQqBz73SNxOu8ukz8IJlbauGW7xJqYolb9V99ejD e5LA== X-Gm-Message-State: ALoCoQmksmQ5P1SKoHkfCC7JotCSVetD9k2k4wc5yoE5yFPyi0eP4EMdzYBG4kAAjrM9bkPCRIhQ X-Received: by 10.112.138.2 with SMTP id qm2mr163913lbb.19.1442002297684; Fri, 11 Sep 2015 13:11:37 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.178.195 with SMTP id da3ls431356lac.79.gmail; Fri, 11 Sep 2015 13:11:37 -0700 (PDT) X-Received: by 10.112.234.199 with SMTP id ug7mr571996lbc.116.1442002297513; Fri, 11 Sep 2015 13:11:37 -0700 (PDT) Received: from mail-la0-f47.google.com (mail-la0-f47.google.com. [209.85.215.47]) by mx.google.com with ESMTPS id m1si1236475lag.69.2015.09.11.13.11.37 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 11 Sep 2015 13:11:37 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.47 as permitted sender) client-ip=209.85.215.47; Received: by lanb10 with SMTP id b10so54552083lan.3 for ; Fri, 11 Sep 2015 13:11:37 -0700 (PDT) X-Received: by 10.152.178.165 with SMTP id cz5mr558782lac.29.1442002297257; Fri, 11 Sep 2015 13:11:37 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.59.35 with SMTP id w3csp1813768lbq; Fri, 11 Sep 2015 13:11:36 -0700 (PDT) X-Received: by 10.107.10.14 with SMTP id u14mr6483691ioi.94.1442002296175; Fri, 11 Sep 2015 13:11:36 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b5si2623920pas.45.2015.09.11.13.11.35; Fri, 11 Sep 2015 13:11:36 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753825AbbIKULe (ORCPT + 7 others); Fri, 11 Sep 2015 16:11:34 -0400 Received: from mail-wi0-f178.google.com ([209.85.212.178]:37368 "EHLO mail-wi0-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753978AbbIKUKj (ORCPT ); Fri, 11 Sep 2015 16:10:39 -0400 Received: by wicfx3 with SMTP id fx3so70092779wic.0 for ; Fri, 11 Sep 2015 13:10:38 -0700 (PDT) X-Received: by 10.180.37.133 with SMTP id y5mr38749wij.15.1442002238679; Fri, 11 Sep 2015 13:10:38 -0700 (PDT) Received: from localhost.localdomain (host81-129-169-75.range81-129.btcentralplus.com. [81.129.169.75]) by smtp.gmail.com with ESMTPSA id fn8sm774193wib.2.2015.09.11.13.10.37 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 11 Sep 2015 13:10:38 -0700 (PDT) From: Lee Jones To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: kernel@stlinux.com, mpm@selenic.com, herbert@gondor.apana.org.au, linux-crypto@vger.kernel.org, devicetree@vger.kernel.org, Lee Jones , Pankaj Dev Subject: [PATCH 4/6] hwrng: st: Add support for ST's HW Random Number Generator Date: Fri, 11 Sep 2015 21:08:28 +0100 Message-Id: <1442002110-28733-5-git-send-email-lee.jones@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1442002110-28733-1-git-send-email-lee.jones@linaro.org> References: <1442002110-28733-1-git-send-email-lee.jones@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: devicetree@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: lee.jones@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.47 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Signed-off-by: Pankaj Dev Signed-off-by: Lee Jones --- drivers/char/hw_random/Kconfig | 10 +++ drivers/char/hw_random/Makefile | 1 + drivers/char/hw_random/st-rng.c | 142 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 drivers/char/hw_random/st-rng.c diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index f48cf11..bb6cb77 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -346,6 +346,16 @@ config HW_RANDOM_MSM If unsure, say Y. +config HW_RANDOM_ST + tristate "ST Microelectronics HW Random Number Generator support" + depends on HW_RANDOM && ARCH_STI + ---help--- + This driver provides kernel-side support for the Random Number + Generator hardware found on STi series of SoCs. + + To compile this driver as a module, choose M here: the + module will be called st-rng. + config HW_RANDOM_XGENE tristate "APM X-Gene True Random Number Generator (TRNG) support" depends on HW_RANDOM && ARCH_XGENE diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index 055bb01..8bcfb45 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile @@ -30,4 +30,5 @@ obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o +obj-$(CONFIG_HW_RANDOM_ST) += st-rng.o obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o diff --git a/drivers/char/hw_random/st-rng.c b/drivers/char/hw_random/st-rng.c new file mode 100644 index 0000000..717a831 --- /dev/null +++ b/drivers/char/hw_random/st-rng.c @@ -0,0 +1,142 @@ +/* + * ST Random Number Generator Driver ST's Platforms + * + * Author: Pankaj Dev: + * Lee Jones + * + * Copyright (C) 2015 STMicroelectronics (R&D) Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Registers */ +#define ST_RNG_STATUS_REG 0x20 +#define ST_RNG_DATA_REG 0x24 + +/* Registers fields */ +#define ST_RNG_STATUS_BAD_SEQUENCE BIT(0) +#define ST_RNG_STATUS_BAD_ALTERNANCE BIT(1) +#define ST_RNG_STATUS_FIFO_FULL BIT(5) + +#define ST_RNG_FIFO_SIZE 8 +#define ST_RNG_SAMPLE_SIZE 2 /* 2 Byte (16bit) samples */ + +/* Samples are available every 0.667us, which we round to 1us */ +#define ST_RNG_FILL_FIFO_TIMEOUT (1 * (ST_RNG_FIFO_SIZE / ST_RNG_SAMPLE_SIZE)) + +struct st_rng_data { + void __iomem *base; + struct clk *clk; + struct hwrng ops; +}; + +static int st_rng_read(struct hwrng *rng, void *data, size_t max, bool wait) +{ + struct st_rng_data *ddata = (struct st_rng_data *)rng->priv; + u32 status; + int i; + + if (max < sizeof(u16)) + return -EINVAL; + + /* Wait until FIFO is full - max 4uS*/ + for (i = 0; i < ST_RNG_FILL_FIFO_TIMEOUT; i++) { + status = readl_relaxed(ddata->base + ST_RNG_STATUS_REG); + if (status & ST_RNG_STATUS_FIFO_FULL) + break; + udelay(1); + } + + if (i == ST_RNG_FILL_FIFO_TIMEOUT) + return 0; + + for (i = 0; i < ST_RNG_FIFO_SIZE && i < max; i += 2) + *(u16 *)(data + i) = + readl_relaxed(ddata->base + ST_RNG_DATA_REG); + + return i - 2; /* No of bytes read */ +} + +static int st_rng_probe(struct platform_device *pdev) +{ + struct st_rng_data *ddata; + struct resource *res; + struct clk *clk; + void __iomem *base; + int ret; + + ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL); + if (!ddata) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + clk = devm_clk_get(&pdev->dev, NULL); + if (!clk) + return -EINVAL; + + clk_prepare_enable(clk); + + ddata->ops.priv = (unsigned long)ddata; + ddata->ops.read = st_rng_read; + ddata->ops.name = pdev->name; + ddata->base = base; + ddata->clk = clk; + + dev_set_drvdata(&pdev->dev, ddata); + + ret = hwrng_register(&ddata->ops); + if (ret) { + dev_err(&pdev->dev, "Failed to register HW RNG\n"); + return ret; + } + + dev_info(&pdev->dev, "Successfully registered HW RNG\n"); + + return 0; +} + +static int st_rng_remove(struct platform_device *pdev) +{ + struct st_rng_data *ddata = dev_get_drvdata(&pdev->dev); + + hwrng_unregister(&ddata->ops); + + clk_disable_unprepare(ddata->clk); + + return 0; +} + +static const struct of_device_id st_rng_match[] = { + { .compatible = "st,rng" }, + {}, +}; +MODULE_DEVICE_TABLE(of, st_rng_match); + +static struct platform_driver st_rng_driver = { + .driver = { + .name = "st-hwrandom", + .of_match_table = of_match_ptr(st_rng_match), + }, + .probe = st_rng_probe, + .remove = st_rng_remove +}; + +module_platform_driver(st_rng_driver); + +MODULE_AUTHOR("Pankaj Dev "); +MODULE_LICENSE("GPL v2");