123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 |
- From 5343e674f32fb82b7a80a24b5a84eee62d3fe624 Mon Sep 17 00:00:00 2001
- From: Christian Lamparter <chunkeey@googlemail.com>
- Date: Mon, 18 Apr 2016 12:57:41 +0200
- Subject: [PATCH] crypto4xx: integrate ppc4xx-rng into crypto4xx
- This patch integrates the ppc4xx-rng driver into the existing
- crypto4xx. This is because the true random number generator
- is controlled and part of the security core.
- Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
- Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
- ---
- drivers/char/hw_random/Kconfig | 13 ---
- drivers/char/hw_random/Makefile | 1 -
- drivers/char/hw_random/ppc4xx-rng.c | 147 --------------------------------
- drivers/crypto/Kconfig | 8 ++
- drivers/crypto/amcc/Makefile | 1 +
- drivers/crypto/amcc/crypto4xx_core.c | 7 +-
- drivers/crypto/amcc/crypto4xx_core.h | 4 +
- drivers/crypto/amcc/crypto4xx_reg_def.h | 1 +
- drivers/crypto/amcc/crypto4xx_trng.c | 131 ++++++++++++++++++++++++++++
- drivers/crypto/amcc/crypto4xx_trng.h | 34 ++++++++
- 10 files changed, 184 insertions(+), 163 deletions(-)
- delete mode 100644 drivers/char/hw_random/ppc4xx-rng.c
- create mode 100644 drivers/crypto/amcc/crypto4xx_trng.c
- create mode 100644 drivers/crypto/amcc/crypto4xx_trng.h
- --- a/drivers/char/hw_random/Kconfig
- +++ b/drivers/char/hw_random/Kconfig
- @@ -268,19 +268,6 @@ config HW_RANDOM_NOMADIK
-
- If unsure, say Y.
-
- -config HW_RANDOM_PPC4XX
- - tristate "PowerPC 4xx generic true random number generator support"
- - depends on PPC && 4xx
- - default HW_RANDOM
- - ---help---
- - This driver provides the kernel-side support for the TRNG hardware
- - found in the security function of some PowerPC 4xx SoCs.
- -
- - To compile this driver as a module, choose M here: the
- - module will be called ppc4xx-rng.
- -
- - If unsure, say N.
- -
- config HW_RANDOM_PSERIES
- tristate "pSeries HW Random Number Generator support"
- depends on PPC64 && IBMVIO
- --- a/drivers/char/hw_random/Makefile
- +++ b/drivers/char/hw_random/Makefile
- @@ -22,7 +22,6 @@ obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939
- obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o
- obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o
- obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
- -obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o
- obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
- obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o
- obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o
- --- a/drivers/char/hw_random/ppc4xx-rng.c
- +++ /dev/null
- @@ -1,147 +0,0 @@
- -/*
- - * Generic PowerPC 44x RNG driver
- - *
- - * Copyright 2011 IBM Corporation
- - *
- - * This program is free software; you can redistribute it and/or modify it
- - * under the terms of the GNU General Public License as published by the
- - * Free Software Foundation; version 2 of the License.
- - */
- -
- -#include <linux/module.h>
- -#include <linux/kernel.h>
- -#include <linux/platform_device.h>
- -#include <linux/hw_random.h>
- -#include <linux/delay.h>
- -#include <linux/of_address.h>
- -#include <linux/of_platform.h>
- -#include <asm/io.h>
- -
- -#define PPC4XX_TRNG_DEV_CTRL 0x60080
- -
- -#define PPC4XX_TRNGE 0x00020000
- -#define PPC4XX_TRNG_CTRL 0x0008
- -#define PPC4XX_TRNG_CTRL_DALM 0x20
- -#define PPC4XX_TRNG_STAT 0x0004
- -#define PPC4XX_TRNG_STAT_B 0x1
- -#define PPC4XX_TRNG_DATA 0x0000
- -
- -#define MODULE_NAME "ppc4xx_rng"
- -
- -static int ppc4xx_rng_data_present(struct hwrng *rng, int wait)
- -{
- - void __iomem *rng_regs = (void __iomem *) rng->priv;
- - int busy, i, present = 0;
- -
- - for (i = 0; i < 20; i++) {
- - busy = (in_le32(rng_regs + PPC4XX_TRNG_STAT) & PPC4XX_TRNG_STAT_B);
- - if (!busy || !wait) {
- - present = 1;
- - break;
- - }
- - udelay(10);
- - }
- - return present;
- -}
- -
- -static int ppc4xx_rng_data_read(struct hwrng *rng, u32 *data)
- -{
- - void __iomem *rng_regs = (void __iomem *) rng->priv;
- - *data = in_le32(rng_regs + PPC4XX_TRNG_DATA);
- - return 4;
- -}
- -
- -static int ppc4xx_rng_enable(int enable)
- -{
- - struct device_node *ctrl;
- - void __iomem *ctrl_reg;
- - int err = 0;
- - u32 val;
- -
- - /* Find the main crypto device node and map it to turn the TRNG on */
- - ctrl = of_find_compatible_node(NULL, NULL, "amcc,ppc4xx-crypto");
- - if (!ctrl)
- - return -ENODEV;
- -
- - ctrl_reg = of_iomap(ctrl, 0);
- - if (!ctrl_reg) {
- - err = -ENODEV;
- - goto out;
- - }
- -
- - val = in_le32(ctrl_reg + PPC4XX_TRNG_DEV_CTRL);
- -
- - if (enable)
- - val |= PPC4XX_TRNGE;
- - else
- - val = val & ~PPC4XX_TRNGE;
- -
- - out_le32(ctrl_reg + PPC4XX_TRNG_DEV_CTRL, val);
- - iounmap(ctrl_reg);
- -
- -out:
- - of_node_put(ctrl);
- -
- - return err;
- -}
- -
- -static struct hwrng ppc4xx_rng = {
- - .name = MODULE_NAME,
- - .data_present = ppc4xx_rng_data_present,
- - .data_read = ppc4xx_rng_data_read,
- -};
- -
- -static int ppc4xx_rng_probe(struct platform_device *dev)
- -{
- - void __iomem *rng_regs;
- - int err = 0;
- -
- - rng_regs = of_iomap(dev->dev.of_node, 0);
- - if (!rng_regs)
- - return -ENODEV;
- -
- - err = ppc4xx_rng_enable(1);
- - if (err)
- - return err;
- -
- - out_le32(rng_regs + PPC4XX_TRNG_CTRL, PPC4XX_TRNG_CTRL_DALM);
- - ppc4xx_rng.priv = (unsigned long) rng_regs;
- -
- - err = hwrng_register(&ppc4xx_rng);
- -
- - return err;
- -}
- -
- -static int ppc4xx_rng_remove(struct platform_device *dev)
- -{
- - void __iomem *rng_regs = (void __iomem *) ppc4xx_rng.priv;
- -
- - hwrng_unregister(&ppc4xx_rng);
- - ppc4xx_rng_enable(0);
- - iounmap(rng_regs);
- -
- - return 0;
- -}
- -
- -static const struct of_device_id ppc4xx_rng_match[] = {
- - { .compatible = "ppc4xx-rng", },
- - { .compatible = "amcc,ppc460ex-rng", },
- - { .compatible = "amcc,ppc440epx-rng", },
- - {},
- -};
- -MODULE_DEVICE_TABLE(of, ppc4xx_rng_match);
- -
- -static struct platform_driver ppc4xx_rng_driver = {
- - .driver = {
- - .name = MODULE_NAME,
- - .of_match_table = ppc4xx_rng_match,
- - },
- - .probe = ppc4xx_rng_probe,
- - .remove = ppc4xx_rng_remove,
- -};
- -
- -module_platform_driver(ppc4xx_rng_driver);
- -
- -MODULE_LICENSE("GPL");
- -MODULE_AUTHOR("Josh Boyer <jwboyer@linux.vnet.ibm.com>");
- -MODULE_DESCRIPTION("HW RNG driver for PPC 4xx processors");
- --- a/drivers/crypto/Kconfig
- +++ b/drivers/crypto/Kconfig
- @@ -277,6 +277,14 @@ config CRYPTO_DEV_PPC4XX
- help
- This option allows you to have support for AMCC crypto acceleration.
-
- +config HW_RANDOM_PPC4XX
- + bool "PowerPC 4xx generic true random number generator support"
- + depends on CRYPTO_DEV_PPC4XX && HW_RANDOM
- + default y
- + ---help---
- + This option provides the kernel-side support for the TRNG hardware
- + found in the security function of some PowerPC 4xx SoCs.
- +
- config CRYPTO_DEV_OMAP_SHAM
- tristate "Support for OMAP MD5/SHA1/SHA2 hw accelerator"
- depends on ARCH_OMAP2PLUS
- --- a/drivers/crypto/amcc/Makefile
- +++ b/drivers/crypto/amcc/Makefile
- @@ -1,2 +1,3 @@
- obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += crypto4xx.o
- crypto4xx-y := crypto4xx_core.o crypto4xx_alg.o crypto4xx_sa.o
- +crypto4xx-$(CONFIG_HW_RANDOM_PPC4XX) += crypto4xx_trng.o
- --- a/drivers/crypto/amcc/crypto4xx_core.c
- +++ b/drivers/crypto/amcc/crypto4xx_core.c
- @@ -40,6 +40,7 @@
- #include "crypto4xx_reg_def.h"
- #include "crypto4xx_core.h"
- #include "crypto4xx_sa.h"
- +#include "crypto4xx_trng.h"
-
- #define PPC4XX_SEC_VERSION_STR "0.5"
-
- @@ -1221,6 +1222,7 @@ static int crypto4xx_probe(struct platfo
- if (rc)
- goto err_start_dev;
-
- + ppc4xx_trng_probe(core_dev);
- return 0;
-
- err_start_dev:
- @@ -1247,6 +1249,8 @@ static int crypto4xx_remove(struct platf
- struct device *dev = &ofdev->dev;
- struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev);
-
- + ppc4xx_trng_remove(core_dev);
- +
- free_irq(core_dev->irq, dev);
- irq_dispose_mapping(core_dev->irq);
-
- @@ -1267,7 +1271,7 @@ MODULE_DEVICE_TABLE(of, crypto4xx_match)
-
- static struct platform_driver crypto4xx_driver = {
- .driver = {
- - .name = "crypto4xx",
- + .name = MODULE_NAME,
- .of_match_table = crypto4xx_match,
- },
- .probe = crypto4xx_probe,
- @@ -1279,4 +1283,3 @@ module_platform_driver(crypto4xx_driver)
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("James Hsiao <jhsiao@amcc.com>");
- MODULE_DESCRIPTION("Driver for AMCC PPC4xx crypto accelerator");
- -
- --- a/drivers/crypto/amcc/crypto4xx_core.h
- +++ b/drivers/crypto/amcc/crypto4xx_core.h
- @@ -24,6 +24,8 @@
-
- #include <crypto/internal/hash.h>
-
- +#define MODULE_NAME "crypto4xx"
- +
- #define PPC460SX_SDR0_SRST 0x201
- #define PPC405EX_SDR0_SRST 0x200
- #define PPC460EX_SDR0_SRST 0x201
- @@ -72,6 +74,7 @@ struct crypto4xx_device {
- char *name;
- u64 ce_phy_address;
- void __iomem *ce_base;
- + void __iomem *trng_base;
-
- void *pdr; /* base address of packet
- descriptor ring */
- @@ -106,6 +109,7 @@ struct crypto4xx_core_device {
- struct device *device;
- struct platform_device *ofdev;
- struct crypto4xx_device *dev;
- + struct hwrng *trng;
- u32 int_status;
- u32 irq;
- struct tasklet_struct tasklet;
- --- a/drivers/crypto/amcc/crypto4xx_reg_def.h
- +++ b/drivers/crypto/amcc/crypto4xx_reg_def.h
- @@ -125,6 +125,7 @@
- #define PPC4XX_INTERRUPT_CLR 0x3ffff
- #define PPC4XX_PRNG_CTRL_AUTO_EN 0x3
- #define PPC4XX_DC_3DES_EN 1
- +#define PPC4XX_TRNG_EN 0x00020000
- #define PPC4XX_INT_DESCR_CNT 4
- #define PPC4XX_INT_TIMEOUT_CNT 0
- #define PPC4XX_INT_CFG 1
- --- /dev/null
- +++ b/drivers/crypto/amcc/crypto4xx_trng.c
- @@ -0,0 +1,131 @@
- +/*
- + * Generic PowerPC 44x RNG driver
- + *
- + * Copyright 2011 IBM Corporation
- + *
- + * This program is free software; you can redistribute it and/or modify it
- + * under the terms of the GNU General Public License as published by the
- + * Free Software Foundation; version 2 of the License.
- + */
- +
- +#include <linux/module.h>
- +#include <linux/kernel.h>
- +#include <linux/interrupt.h>
- +#include <linux/platform_device.h>
- +#include <linux/hw_random.h>
- +#include <linux/delay.h>
- +#include <linux/of_address.h>
- +#include <linux/of_platform.h>
- +#include <linux/io.h>
- +
- +#include "crypto4xx_core.h"
- +#include "crypto4xx_trng.h"
- +#include "crypto4xx_reg_def.h"
- +
- +#define PPC4XX_TRNG_CTRL 0x0008
- +#define PPC4XX_TRNG_CTRL_DALM 0x20
- +#define PPC4XX_TRNG_STAT 0x0004
- +#define PPC4XX_TRNG_STAT_B 0x1
- +#define PPC4XX_TRNG_DATA 0x0000
- +
- +static int ppc4xx_trng_data_present(struct hwrng *rng, int wait)
- +{
- + struct crypto4xx_device *dev = (void *)rng->priv;
- + int busy, i, present = 0;
- +
- + for (i = 0; i < 20; i++) {
- + busy = (in_le32(dev->trng_base + PPC4XX_TRNG_STAT) &
- + PPC4XX_TRNG_STAT_B);
- + if (!busy || !wait) {
- + present = 1;
- + break;
- + }
- + udelay(10);
- + }
- + return present;
- +}
- +
- +static int ppc4xx_trng_data_read(struct hwrng *rng, u32 *data)
- +{
- + struct crypto4xx_device *dev = (void *)rng->priv;
- + *data = in_le32(dev->trng_base + PPC4XX_TRNG_DATA);
- + return 4;
- +}
- +
- +static void ppc4xx_trng_enable(struct crypto4xx_device *dev, bool enable)
- +{
- + u32 device_ctrl;
- +
- + device_ctrl = readl(dev->ce_base + CRYPTO4XX_DEVICE_CTRL);
- + if (enable)
- + device_ctrl |= PPC4XX_TRNG_EN;
- + else
- + device_ctrl &= ~PPC4XX_TRNG_EN;
- + writel(device_ctrl, dev->ce_base + CRYPTO4XX_DEVICE_CTRL);
- +}
- +
- +static const struct of_device_id ppc4xx_trng_match[] = {
- + { .compatible = "ppc4xx-rng", },
- + { .compatible = "amcc,ppc460ex-rng", },
- + { .compatible = "amcc,ppc440epx-rng", },
- + {},
- +};
- +
- +void ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev)
- +{
- + struct crypto4xx_device *dev = core_dev->dev;
- + struct device_node *trng = NULL;
- + struct hwrng *rng = NULL;
- + int err;
- +
- + /* Find the TRNG device node and map it */
- + trng = of_find_matching_node(NULL, ppc4xx_trng_match);
- + if (!trng || !of_device_is_available(trng))
- + return;
- +
- + dev->trng_base = of_iomap(trng, 0);
- + of_node_put(trng);
- + if (!dev->trng_base)
- + goto err_out;
- +
- + rng = kzalloc(sizeof(*rng), GFP_KERNEL);
- + if (!rng)
- + goto err_out;
- +
- + rng->name = MODULE_NAME;
- + rng->data_present = ppc4xx_trng_data_present;
- + rng->data_read = ppc4xx_trng_data_read;
- + rng->priv = (unsigned long) dev;
- + core_dev->trng = rng;
- + ppc4xx_trng_enable(dev, true);
- + out_le32(dev->trng_base + PPC4XX_TRNG_CTRL, PPC4XX_TRNG_CTRL_DALM);
- + err = devm_hwrng_register(core_dev->device, core_dev->trng);
- + if (err) {
- + ppc4xx_trng_enable(dev, false);
- + dev_err(core_dev->device, "failed to register hwrng (%d).\n",
- + err);
- + goto err_out;
- + }
- + return;
- +
- +err_out:
- + of_node_put(trng);
- + iounmap(dev->trng_base);
- + kfree(rng);
- + dev->trng_base = NULL;
- + core_dev->trng = NULL;
- +}
- +
- +void ppc4xx_trng_remove(struct crypto4xx_core_device *core_dev)
- +{
- + if (core_dev && core_dev->trng) {
- + struct crypto4xx_device *dev = core_dev->dev;
- +
- + devm_hwrng_unregister(core_dev->device, core_dev->trng);
- + ppc4xx_trng_enable(dev, false);
- + iounmap(dev->trng_base);
- + kfree(core_dev->trng);
- + }
- +}
- +
- +MODULE_ALIAS("ppc4xx_rng");
- --- /dev/null
- +++ b/drivers/crypto/amcc/crypto4xx_trng.h
- @@ -0,0 +1,34 @@
- +/**
- + * AMCC SoC PPC4xx Crypto Driver
- + *
- + * Copyright (c) 2008 Applied Micro Circuits Corporation.
- + * All rights reserved. James Hsiao <jhsiao@amcc.com>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + *
- + * This program is distributed in the hope that it will be useful,
- + * but WITHOUT ANY WARRANTY; without even the implied warranty of
- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + * GNU General Public License for more details.
- + *
- + * This file defines the security context
- + * associate format.
- + */
- +
- +#ifndef __CRYPTO4XX_TRNG_H__
- +#define __CRYPTO4XX_TRNG_H__
- +
- +#ifdef CONFIG_HW_RANDOM_PPC4XX
- +void ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev);
- +void ppc4xx_trng_remove(struct crypto4xx_core_device *core_dev);
- +#else
- +static inline void ppc4xx_trng_probe(
- + struct crypto4xx_device *dev __maybe_unused) { }
- +static inline void ppc4xx_trng_remove(
- + struct crypto4xx_device *dev __maybe_unused) { }
- +#endif
- +
- +#endif
|