[PATCH v1 2/2] nvmem: add simple nvstore driver
Sascha Hauer
s.hauer at pengutronix.de
Tue Mar 14 00:36:53 PDT 2017
On Mon, Mar 13, 2017 at 11:22:07AM +0100, Oleksij Rempel wrote:
> From: Steffen Trumtrar <s.trumtrar at pengutronix.de>
>
> Signed-off-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>
> Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
> ---
> drivers/nvmem/Kconfig | 8 +++
> drivers/nvmem/Makefile | 4 ++
> drivers/nvmem/nvstore.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 154 insertions(+)
> create mode 100644 drivers/nvmem/nvstore.c
>
> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
> index 218be05b2..23ebc1ea7 100644
> --- a/drivers/nvmem/Kconfig
> +++ b/drivers/nvmem/Kconfig
> @@ -6,3 +6,11 @@ menuconfig NVMEM
> This framework is designed to provide a generic interface to NVMEM
>
> If unsure, say no.
> +
> +if NVMEM
> +
> +config NVMEM_STORE
> + tristate "NVMEM storage"
> + help
What is a nvstore?
> +
> +endif
> diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
> index 6df2c6952..34a59c316 100644
> --- a/drivers/nvmem/Makefile
> +++ b/drivers/nvmem/Makefile
> @@ -4,3 +4,7 @@
>
> obj-$(CONFIG_NVMEM) += nvmem_core.o
> nvmem_core-y := core.o
> +
> +# Devices
> +obj-$(CONFIG_NVMEM_STORE) += nvmem_nvstore.o
> +nvmem_nvstore-y := nvstore.o
> diff --git a/drivers/nvmem/nvstore.c b/drivers/nvmem/nvstore.c
> new file mode 100644
> index 000000000..c1b256d92
> --- /dev/null
> +++ b/drivers/nvmem/nvstore.c
> @@ -0,0 +1,142 @@
> +/*
> + * Copyright (c) 2015 Pengutronix, Steffen Trumtrar <kernel at pengutronix.de>
> + *
> + * 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.
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +#include <common.h>
> +#include <driver.h>
> +#include <init.h>
> +#include <io.h>
> +#include <of.h>
> +#include <malloc.h>
> +#include <linux/nvmem-provider.h>
> +
> +struct nvstore_priv {
> + struct device_d *dev;
> + void __iomem *base;
> +};
> +
> +static int nvstore_write(struct device_d *dev, const int reg, const void *val,
> + int val_size)
> +{
> + struct nvstore_priv *priv = dev->parent->priv;
> + unsigned int offset;
> +
> + offset = reg;
> + while (val_size > 0) {
Here val_size looks like it's the number of words (bytes?) to write.
> + switch (val_size) {
> + case 1:
> + writeb(*(u8 *)val, priv->base + offset);
> + break;
> + case 2:
> + writew(*(u16 *)val, priv->base + offset);
> + break;
> + case 4:
> + writel(*(u32 *)val, priv->base + offset);
> + break;
> + }
This instead suggests val_size is the width of a single word.
> + val_size -= 4;
> + val += 4;
> + offset += 4;
And this looks like a word width of 4 bytes is the only supported.
This looks wrong. Same for the read function.
> +
> +static struct nvmem_bus nvstore_nvmem_bus = {
> + .write = nvstore_write,
> + .read = nvstore_read,
> +};
> +
> +static struct nvmem_config nvstore_nvmem_config = {
> + .name = "nvstore",
> + .stride = 4,
> + .word_size = 4,
> +};
> +
> +static int nvstore_probe(struct device_d *dev)
> +{
> + struct nvstore_priv *priv;
> + struct nvmem_device *nvmem;
> + struct resource *res;
> +
> + priv = kzalloc(sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + res = dev_get_resource(dev, IORESOURCE_MEM, 0);
> + if (IS_ERR(res)) {
> + res = dev_get_resource(dev->parent, IORESOURCE_MEM, 0);
> + if (IS_ERR(res)) {
> + free(priv);
> + return PTR_ERR(res);
> + }
> + }
> +
> + res = request_iomem_region(dev_name(dev), res->start, res->end);
> + if (IS_ERR(res)) {
> + free(priv);
> + return PTR_ERR(res);
> + }
dev_request_mem_resource() should do instead of
dev_get_resource()/request_iomem_region()
> +
> + priv->base = (void __iomem *)res->start;
> +
> + nvstore_nvmem_config.size = 1;
> + nvstore_nvmem_config.dev = dev;
> + nvstore_nvmem_config.bus = &nvstore_nvmem_bus;
Gnagna. This is what happens when the initial driver writer decides that
his device is single instance only. Everyone copies the template and now
we find it in a generic driver which clearly is not necessarily single
instance.
> +
> + nvmem = nvmem_register(&nvstore_nvmem_config);
> + if (IS_ERR(nvmem)) {
> + free(priv);
> + return PTR_ERR(nvmem);
> + }
> +
> + dev->priv = priv;
This should be set before nvmem_register() is called.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
More information about the barebox
mailing list