[PATCH 1/1] drivers/rng: add Amlogic hardware RNG driver

Sughosh Ganu sughosh.ganu at linaro.org
Wed Feb 26 11:51:14 CET 2020


On Tue, 25 Feb 2020 at 03:56, Heinrich Schuchardt <xypron.glpk at gmx.de>
wrote:

> Add support for the hardware random number generator of Amlogic SOCs.
>
> Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
> ---
>  drivers/rng/Kconfig     |   8 +++
>  drivers/rng/Makefile    |   1 +
>  drivers/rng/meson-rng.c | 120 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 129 insertions(+)
>  create mode 100644 drivers/rng/meson-rng.c
>
> diff --git a/drivers/rng/Kconfig b/drivers/rng/Kconfig
> index c1aa43b823..edb6152bb9 100644
> --- a/drivers/rng/Kconfig
> +++ b/drivers/rng/Kconfig
> @@ -8,6 +8,14 @@ config DM_RNG
>
>  if DM_RNG
>
> +config RNG_MESON
> +       bool "Amlogic Meson Random Number Generator support"
> +       depends on ARCH_MESON
> +       default y
> +       help
> +         Enable support for hardware random number generator
> +         of Amlogic Meson SoCs.
> +
>  config RNG_SANDBOX
>         bool "Sandbox random number generator"
>         depends on SANDBOX
> diff --git a/drivers/rng/Makefile b/drivers/rng/Makefile
> index 3517005541..6a8a66779b 100644
> --- a/drivers/rng/Makefile
> +++ b/drivers/rng/Makefile
> @@ -4,5 +4,6 @@
>  #
>
>  obj-$(CONFIG_DM_RNG) += rng-uclass.o
> +obj-$(CONFIG_RNG_MESON) += meson-rng.o
>  obj-$(CONFIG_RNG_SANDBOX) += sandbox_rng.o
>  obj-$(CONFIG_RNG_STM32MP1) += stm32mp1_rng.o
> diff --git a/drivers/rng/meson-rng.c b/drivers/rng/meson-rng.c
> new file mode 100644
> index 0000000000..4b81a62353
> --- /dev/null
> +++ b/drivers/rng/meson-rng.c
> @@ -0,0 +1,120 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright 2020, Heinrich Schuchardt <xypron.glpk at gmx.de>
> + *
> + * Driver for Amlogic hardware random number generator
> + */
> +
> +#include <common.h>
> +#include <clk.h>
> +#include <dm.h>
> +#include <rng.h>
> +#include <asm/io.h>
> +
> +struct meson_rng_platdata {
> +       fdt_addr_t base;
> +       struct clk clk;
> +};
> +
> +/**
> + * meson_rng_read() - fill buffer with random bytes
> + *
> + * @buffer:    buffer to receive data
> + * @size:      size of buffer
> + *
> + * Return:     0
> + */
> +static int meson_rng_read(struct udevice *dev, void *data, size_t len)
> +{
> +       struct meson_rng_platdata *pdata = dev_get_platdata(dev);
> +       char *buffer = (char *)data;
> +
> +       while (len) {
> +               u32 rand = readl(pdata->base);
> +               size_t step;
>

I believe declaration of variables in the middle of the function is frowned
upon. Can be moved to the start of the function.

Other than that,
Reviewed-by: Sughosh Ganu <sughosh.ganu at linaro.org>

-sughosh



> +
> +               if (len >= 4)
> +                       step = 4;
> +               else
> +                       step = len;
> +               memcpy(buffer, &rand, step);
> +               buffer += step;
> +               len -= step;
> +       }
> +       return 0;
> +}
> +
> +/**
> + * meson_rng_probe() - probe rng device
> + *
> + * @dev:       device
> + * Return:     0 if ok
> + */
> +static int meson_rng_probe(struct udevice *dev)
> +{
> +       struct meson_rng_platdata *pdata = dev_get_platdata(dev);
> +       int err;
> +
> +       err = clk_enable(&pdata->clk);
> +       if (err)
> +               return err;
> +
> +       return 0;
> +}
> +
> +/**
> + * meson_rng_remove() - deinitialize rng device
> + *
> + * @dev:       device
> + * Return:     0 if ok
> + */
> +static int meson_rng_remove(struct udevice *dev)
> +{
> +       struct meson_rng_platdata *pdata = dev_get_platdata(dev);
> +
> +       return clk_disable(&pdata->clk);
> +}
> +
> +/**
> + * meson_rng_ofdata_to_platdata() - transfer device tree data to plaform
> data
> + *
> + * @dev:       device
> + * Return:     0 if ok
> + */
> +static int meson_rng_ofdata_to_platdata(struct udevice *dev)
> +{
> +       struct meson_rng_platdata *pdata = dev_get_platdata(dev);
> +       int err;
> +
> +       pdata->base = dev_read_addr(dev);
> +       if (!pdata->base)
> +               return -ENODEV;
> +
> +       err = clk_get_by_name(dev, "core", &pdata->clk);
> +       if (err)
> +               return err;
> +
> +       return 0;
> +}
> +
> +static const struct dm_rng_ops meson_rng_ops = {
> +       .read = meson_rng_read,
> +};
> +
> +static const struct udevice_id meson_rng_match[] = {
> +       {
> +               .compatible = "amlogic,meson-rng",
> +       },
> +       {},
> +};
> +
> +U_BOOT_DRIVER(meson_rng) = {
> +       .name = "meson-rng",
> +       .id = UCLASS_RNG,
> +       .of_match = meson_rng_match,
> +       .ops = &meson_rng_ops,
> +       .probe = meson_rng_probe,
> +       .remove = meson_rng_remove,
> +       .platdata_auto_alloc_size = sizeof(struct meson_rng_platdata),
> +       .ofdata_to_platdata = meson_rng_ofdata_to_platdata,
> +};
> --
> 2.20.1
>
>


More information about the U-Boot mailing list