All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] misc: atmel-secumod: Driver for Atmel "security module".
@ 2016-01-21  3:57 David Mosberger-Tang
  2016-01-25 11:09 ` Alexandre Belloni
  2016-05-10 19:02 ` [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram David Mosberger-Tang
  0 siblings, 2 replies; 25+ messages in thread
From: David Mosberger-Tang @ 2016-01-21  3:57 UTC (permalink / raw)
  To: linux-arm-kernel

From: David Mosberger <davidm@egauge.net>

SAMA5D2 (and perhaps other SOCs) implements a secure module which
hosts a battery-backed SRAM with is sectioned into three different
areas with different properties: a 4KiB auto-erasable secure RAM, a
1KiB non-auto-eraseable secure RAM, and 32 bytes of (non-secure) RAM.

This driver provides (minimal) access to these RAM areas through
sysfs.  For example, adding this to the DTS:

	secumod at fc040000 {
		compatible = "atmel,sama5d2-secumod";
		reg = <0xfc040000 0x4000>;
		status = "okay";

		#address-cells = <1>;
		#size-cells = <1>;

		secram_auto_erasable at f8044000 {
			reg = <0xf8044000 0x1000>;
		};
		secram at f8045000 {
			reg = <0xf8045000 0x400>;
		};
		ram at f8045400 {
			reg = <0xf8045400 0x20>;
		};
	};

would provide binary files "ram", "secram", and "secram_auto_erasable"
in directory /sys/bus/platform/devices/fc040000.secumod.
This files can then be read or written with any user-level tool.

The driver is minimal in the sense that it doesn't provide (yet)
a way to manage scrambling keys etc.

Signed-off-by: David Mosberger <davidm@egauge.net>
---
 arch/arm/boot/dts/sama5d2.dtsi |  19 ++++
 drivers/misc/Kconfig           |   7 ++
 drivers/misc/Makefile          |   1 +
 drivers/misc/atmel-secumod.c   | 224 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 251 insertions(+)
 create mode 100644 drivers/misc/atmel-secumod.c

diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
index 89d4de8..d4bd3b6 100644
--- a/arch/arm/boot/dts/sama5d2.dtsi
+++ b/arch/arm/boot/dts/sama5d2.dtsi
@@ -1239,6 +1239,25 @@
 				clocks = <&pioA_clk>;
 			};
 
+			secumod at fc040000 {
+				compatible = "atmel,sama5d2-secumod";
+				reg = <0xfc040000 0x4000>;
+				status = "okay";
+
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				secram_auto_erasable at f8044000 {
+					reg = <0xf8044000 0x1000>;
+				};
+				secram at f8045000 {
+					reg = <0xf8045000 0x400>;
+				};
+				ram at f8045400 {
+					reg = <0xf8045400 0x20>;
+				};
+			};
+
 			tdes at fc044000 {
 				compatible = "atmel,at91sam9g46-tdes";
 				reg = <0xfc044000 0x100>;
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 006242c..74a8ee5 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -84,6 +84,13 @@ config ATMEL_TCB_CLKSRC_BLOCK
 	  TC can be used for other purposes, such as PWM generation and
 	  interval timing.
 
+config ATMEL_SECUMOD
+       tristate "Atmel Secure Module driver"
+       depends on ARCH_AT91
+       help
+         Select this to get support for the secure module (SECUMOD) built
+	 into the SAMA5D2 chips.
+
 config DUMMY_IRQ
 	tristate "Dummy IRQ handler"
 	default n
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 7d5c4cd..e1f661d 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_AD525X_DPOT_SPI)	+= ad525x_dpot-spi.o
 obj-$(CONFIG_INTEL_MID_PTI)	+= pti.o
 obj-$(CONFIG_ATMEL_SSC)		+= atmel-ssc.o
 obj-$(CONFIG_ATMEL_TCLIB)	+= atmel_tclib.o
+obj-$(CONFIG_ATMEL_SECUMOD)	+= atmel-secumod.o
 obj-$(CONFIG_BMP085)		+= bmp085.o
 obj-$(CONFIG_BMP085_I2C)	+= bmp085-i2c.o
 obj-$(CONFIG_BMP085_SPI)	+= bmp085-spi.o
diff --git a/drivers/misc/atmel-secumod.c b/drivers/misc/atmel-secumod.c
new file mode 100644
index 0000000..5ac1a18
--- /dev/null
+++ b/drivers/misc/atmel-secumod.c
@@ -0,0 +1,224 @@
+/*
+ * Driver for SAMA5D2 secure module (SECUMOD).
+ *
+ * Copyright (C) 2016 eGauge Systems LLC
+ *
+ * David Mosberger <davidm@egauge.net>
+ *
+ * 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 <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+
+/*
+ * Security-module register definitions:
+ */
+#define SECUMOD_RAMRDY	0x0014
+
+struct ram_area {
+	struct list_head next;
+	void *regs;	/* ioremapped RAM area */
+	size_t size;	/* size in bytes */
+	struct bin_attribute attr;
+};
+
+struct secumod_device {
+	struct spinlock lock;
+	void __iomem *regs;		/* ioremapped SECUMOD registers */
+	struct platform_device *pdev;
+	struct list_head ram_areas;
+};
+
+static ssize_t
+secumod_ram_write(struct file *filp, struct kobject *kobj,
+		  struct bin_attribute *attr,
+		  char *buf, loff_t off, size_t count)
+{
+	struct ram_area *ram = attr->private;
+	struct device *dev = kobj_to_dev(kobj);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct secumod_device *secumod = platform_get_drvdata(pdev);
+
+	if (off < 0 || off >= ram->size)
+		return -EINVAL;
+	if (off + count > ram->size)
+		count = ram->size = off;
+
+	if (count > 0) {
+		spin_lock(&secumod->lock);
+		memcpy_toio(ram->regs + off, buf, count);
+		spin_unlock(&secumod->lock);
+	}
+	return count;
+}
+
+static ssize_t
+secumod_ram_read(struct file *filp, struct kobject *kobj,
+		 struct bin_attribute *attr,
+		 char *buf, loff_t off, size_t count)
+{
+	struct ram_area *ram = attr->private;
+	struct device *dev = kobj_to_dev(kobj);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct secumod_device *secumod = platform_get_drvdata(pdev);
+
+	if (off < 0 || off >= ram->size)
+		return -EINVAL;
+	if (off + count > ram->size)
+		count = ram->size = off;
+
+	if (count > 0) {
+		spin_lock(&secumod->lock);
+		memcpy_fromio(buf, ram->regs + off, count);
+		spin_unlock(&secumod->lock);
+	}
+	return count;
+}
+
+static void
+secumod_register_ram(struct secumod_device *secumod,
+		     const char *name, unsigned long addr, size_t size)
+{
+	struct device *dev = &secumod->pdev->dev;
+	struct ram_area *ram;
+	int ret;
+
+	ram = devm_kzalloc(dev, sizeof(*ram), GFP_KERNEL);
+	if (!ram) {
+		dev_err(dev, "Out of memory for RAM area %s\n", name);
+		return;
+	}
+	INIT_LIST_HEAD(&ram->next);
+	ram->size = size;
+	ram->regs = ioremap_nocache(addr, size);
+	ram->attr.attr.name = name;
+	ram->attr.attr.mode = S_IRUGO | S_IWUSR;
+	ram->attr.private = ram;
+	ram->attr.size = size;
+	ram->attr.read = secumod_ram_read;
+	ram->attr.write = secumod_ram_write;
+	ret = device_create_bin_file(dev, &ram->attr);
+	if (ret) {
+		dev_err(dev, "Failed to register RAM area %s (%d)", name, ret);
+		return;
+	}
+	spin_lock(&secumod->lock);
+	list_add_tail(&ram->next, &secumod->ram_areas);
+	spin_unlock(&secumod->lock);
+	pr_info("atmel-secumod: RAM 0x%08lx-0x%08lx (%s)\n",
+		addr, addr + size - 1, name);
+}
+
+/*
+ * Since the secure module may need to automatically erase some of the
+ * RAM, it may take a while for it to be ready.  As far as I know,
+ * it's not documented how long this might take in the worst-case.
+ */
+static void
+secumod_wait_ready (struct secumod_device *secumod)
+{
+	unsigned long start, stop;
+
+	start = jiffies;
+	while (!(readl(secumod->regs + SECUMOD_RAMRDY) & 1))
+		msleep_interruptible(1);
+	stop = jiffies;
+	if (stop != start)
+		pr_info("atmel-secumod: it took %u msec for SECUMOD "
+			"to become ready...\n", jiffies_to_msecs(stop - start));
+}
+
+static int
+secumod_probe(struct platform_device *pdev)
+{
+	struct secumod_device *secumod;
+	struct device_node *child;
+	struct resource *regs;
+	u32 addr, size;
+	const void *pv;
+	int len;
+
+	secumod = devm_kzalloc(&pdev->dev, sizeof(*secumod), GFP_KERNEL);
+	if (!secumod) {
+		dev_err(&pdev->dev, "out of memory\n");
+		return -ENOMEM;
+	}
+	spin_lock_init(&secumod->lock);
+	INIT_LIST_HEAD(&secumod->ram_areas);
+
+	if (!pdev->dev.of_node) {
+		dev_err(&pdev->dev, "Missing of_node attribute\n");
+		return -ENODEV;
+	}
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!regs) {
+		dev_err(&pdev->dev, "Missing secumod resources.\n");
+		return -ENODEV;
+	}
+	secumod->pdev = pdev;
+	secumod->regs = devm_ioremap_resource(&pdev->dev, regs);
+
+	platform_set_drvdata(pdev, secumod);
+
+	for_each_child_of_node(pdev->dev.of_node, child) {
+		pv = of_get_property(child, "reg", &len);
+		if (!pv ||
+		    of_n_addr_cells(child) != 1 ||
+		    of_n_size_cells(child) != 1) {
+			dev_err(&pdev->dev, "Node %s missing \"reg\" property "
+				"or incorrect address/size count.",
+				child->name);
+			return -ENODEV;
+		}
+		addr = be32_to_cpup(pv);
+		size = be32_to_cpup(pv + 4);
+		secumod_register_ram(secumod, child->name, addr, size);
+	}
+	secumod_wait_ready(secumod);
+	return 0;
+}
+
+static int
+secumod_remove(struct platform_device *pdev)
+{
+	struct secumod_device *secumod = platform_get_drvdata(pdev);
+	struct ram_area *ram;
+
+	spin_lock(&secumod->lock);
+	list_for_each_entry(ram, &secumod->ram_areas, next)
+		device_remove_bin_file(&pdev->dev, &ram->attr);
+	spin_unlock(&secumod->lock);
+	return 0;
+}
+
+static const struct of_device_id secumod_dt_ids[] = {
+	{
+		.compatible = "atmel,sama5d2-secumod"
+	},
+	{
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, secumod_dt_ids);
+
+static struct platform_driver secumod_driver = {
+	.driver = {
+		.name = "atmel-secumod",
+		.of_match_table = of_match_ptr(secumod_dt_ids),
+	},
+	.probe		= secumod_probe,
+	.remove		= secumod_remove
+};
+module_platform_driver(secumod_driver);
+
+MODULE_AUTHOR("David Mosberger <davidm@egauge.net>");
+MODULE_DESCRIPTION("Atmel SAMA5D2 secure module driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH] misc: atmel-secumod: Driver for Atmel "security module".
  2016-01-21  3:57 [PATCH] misc: atmel-secumod: Driver for Atmel "security module" David Mosberger-Tang
@ 2016-01-25 11:09 ` Alexandre Belloni
  2016-01-25 16:24   ` David Mosberger
  2016-05-10 19:02 ` [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram David Mosberger-Tang
  1 sibling, 1 reply; 25+ messages in thread
From: Alexandre Belloni @ 2016-01-25 11:09 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 20/01/2016 at 20:57:35 -0700, David Mosberger-Tang wrote :
> From: David Mosberger <davidm@egauge.net>
> 
> SAMA5D2 (and perhaps other SOCs) implements a secure module which
> hosts a battery-backed SRAM with is sectioned into three different
> areas with different properties: a 4KiB auto-erasable secure RAM, a
> 1KiB non-auto-eraseable secure RAM, and 32 bytes of (non-secure) RAM.
> 
> This driver provides (minimal) access to these RAM areas through
> sysfs.  For example, adding this to the DTS:
> 
> 	secumod at fc040000 {
> 		compatible = "atmel,sama5d2-secumod";
> 		reg = <0xfc040000 0x4000>;
> 		status = "okay";
> 
> 		#address-cells = <1>;
> 		#size-cells = <1>;
> 
> 		secram_auto_erasable at f8044000 {
> 			reg = <0xf8044000 0x1000>;
> 		};
> 		secram at f8045000 {
> 			reg = <0xf8045000 0x400>;
> 		};
> 		ram at f8045400 {
> 			reg = <0xf8045400 0x20>;
> 		};
> 	};
> 
> would provide binary files "ram", "secram", and "secram_auto_erasable"
> in directory /sys/bus/platform/devices/fc040000.secumod.
> This files can then be read or written with any user-level tool.
> 
> The driver is minimal in the sense that it doesn't provide (yet)
> a way to manage scrambling keys etc.
> 

I know this does more than that but I think those thre sections should
be registered using the nvmem framework. The sysfs file creation and
accesses then comes for free.

Another idea is also to expose it using a genpool so it can be accessed
as sram from inside the kernel.

> Signed-off-by: David Mosberger <davidm@egauge.net>
> ---
>  arch/arm/boot/dts/sama5d2.dtsi |  19 ++++
>  drivers/misc/Kconfig           |   7 ++
>  drivers/misc/Makefile          |   1 +
>  drivers/misc/atmel-secumod.c   | 224 +++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 251 insertions(+)
>  create mode 100644 drivers/misc/atmel-secumod.c
> 
> diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
> index 89d4de8..d4bd3b6 100644
> --- a/arch/arm/boot/dts/sama5d2.dtsi
> +++ b/arch/arm/boot/dts/sama5d2.dtsi
> @@ -1239,6 +1239,25 @@
>  				clocks = <&pioA_clk>;
>  			};
>  
> +			secumod at fc040000 {
> +				compatible = "atmel,sama5d2-secumod";
> +				reg = <0xfc040000 0x4000>;
> +				status = "okay";
> +
> +				#address-cells = <1>;
> +				#size-cells = <1>;
> +
> +				secram_auto_erasable at f8044000 {
> +					reg = <0xf8044000 0x1000>;
> +				};
> +				secram at f8045000 {
> +					reg = <0xf8045000 0x400>;
> +				};
> +				ram at f8045400 {
> +					reg = <0xf8045400 0x20>;
> +				};
> +			};
> +
>  			tdes at fc044000 {
>  				compatible = "atmel,at91sam9g46-tdes";
>  				reg = <0xfc044000 0x100>;
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index 006242c..74a8ee5 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -84,6 +84,13 @@ config ATMEL_TCB_CLKSRC_BLOCK
>  	  TC can be used for other purposes, such as PWM generation and
>  	  interval timing.
>  
> +config ATMEL_SECUMOD
> +       tristate "Atmel Secure Module driver"
> +       depends on ARCH_AT91
> +       help
> +         Select this to get support for the secure module (SECUMOD) built
> +	 into the SAMA5D2 chips.
> +
>  config DUMMY_IRQ
>  	tristate "Dummy IRQ handler"
>  	default n
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index 7d5c4cd..e1f661d 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -9,6 +9,7 @@ obj-$(CONFIG_AD525X_DPOT_SPI)	+= ad525x_dpot-spi.o
>  obj-$(CONFIG_INTEL_MID_PTI)	+= pti.o
>  obj-$(CONFIG_ATMEL_SSC)		+= atmel-ssc.o
>  obj-$(CONFIG_ATMEL_TCLIB)	+= atmel_tclib.o
> +obj-$(CONFIG_ATMEL_SECUMOD)	+= atmel-secumod.o
>  obj-$(CONFIG_BMP085)		+= bmp085.o
>  obj-$(CONFIG_BMP085_I2C)	+= bmp085-i2c.o
>  obj-$(CONFIG_BMP085_SPI)	+= bmp085-spi.o
> diff --git a/drivers/misc/atmel-secumod.c b/drivers/misc/atmel-secumod.c
> new file mode 100644
> index 0000000..5ac1a18
> --- /dev/null
> +++ b/drivers/misc/atmel-secumod.c
> @@ -0,0 +1,224 @@
> +/*
> + * Driver for SAMA5D2 secure module (SECUMOD).
> + *
> + * Copyright (C) 2016 eGauge Systems LLC
> + *
> + * David Mosberger <davidm@egauge.net>
> + *
> + * 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 <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/delay.h>
> +
> +#include <asm/io.h>
> +
> +/*
> + * Security-module register definitions:
> + */
> +#define SECUMOD_RAMRDY	0x0014
> +
> +struct ram_area {
> +	struct list_head next;
> +	void *regs;	/* ioremapped RAM area */
> +	size_t size;	/* size in bytes */
> +	struct bin_attribute attr;
> +};
> +
> +struct secumod_device {
> +	struct spinlock lock;
> +	void __iomem *regs;		/* ioremapped SECUMOD registers */
> +	struct platform_device *pdev;
> +	struct list_head ram_areas;
> +};
> +
> +static ssize_t
> +secumod_ram_write(struct file *filp, struct kobject *kobj,
> +		  struct bin_attribute *attr,
> +		  char *buf, loff_t off, size_t count)
> +{
> +	struct ram_area *ram = attr->private;
> +	struct device *dev = kobj_to_dev(kobj);
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct secumod_device *secumod = platform_get_drvdata(pdev);
> +
> +	if (off < 0 || off >= ram->size)
> +		return -EINVAL;
> +	if (off + count > ram->size)
> +		count = ram->size = off;
> +
> +	if (count > 0) {
> +		spin_lock(&secumod->lock);
> +		memcpy_toio(ram->regs + off, buf, count);
> +		spin_unlock(&secumod->lock);
> +	}
> +	return count;
> +}
> +
> +static ssize_t
> +secumod_ram_read(struct file *filp, struct kobject *kobj,
> +		 struct bin_attribute *attr,
> +		 char *buf, loff_t off, size_t count)
> +{
> +	struct ram_area *ram = attr->private;
> +	struct device *dev = kobj_to_dev(kobj);
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct secumod_device *secumod = platform_get_drvdata(pdev);
> +
> +	if (off < 0 || off >= ram->size)
> +		return -EINVAL;
> +	if (off + count > ram->size)
> +		count = ram->size = off;
> +
> +	if (count > 0) {
> +		spin_lock(&secumod->lock);
> +		memcpy_fromio(buf, ram->regs + off, count);
> +		spin_unlock(&secumod->lock);
> +	}
> +	return count;
> +}
> +
> +static void
> +secumod_register_ram(struct secumod_device *secumod,
> +		     const char *name, unsigned long addr, size_t size)
> +{
> +	struct device *dev = &secumod->pdev->dev;
> +	struct ram_area *ram;
> +	int ret;
> +
> +	ram = devm_kzalloc(dev, sizeof(*ram), GFP_KERNEL);
> +	if (!ram) {
> +		dev_err(dev, "Out of memory for RAM area %s\n", name);
> +		return;
> +	}
> +	INIT_LIST_HEAD(&ram->next);
> +	ram->size = size;
> +	ram->regs = ioremap_nocache(addr, size);
> +	ram->attr.attr.name = name;
> +	ram->attr.attr.mode = S_IRUGO | S_IWUSR;
> +	ram->attr.private = ram;
> +	ram->attr.size = size;
> +	ram->attr.read = secumod_ram_read;
> +	ram->attr.write = secumod_ram_write;
> +	ret = device_create_bin_file(dev, &ram->attr);
> +	if (ret) {
> +		dev_err(dev, "Failed to register RAM area %s (%d)", name, ret);
> +		return;
> +	}
> +	spin_lock(&secumod->lock);
> +	list_add_tail(&ram->next, &secumod->ram_areas);
> +	spin_unlock(&secumod->lock);
> +	pr_info("atmel-secumod: RAM 0x%08lx-0x%08lx (%s)\n",
> +		addr, addr + size - 1, name);
> +}
> +
> +/*
> + * Since the secure module may need to automatically erase some of the
> + * RAM, it may take a while for it to be ready.  As far as I know,
> + * it's not documented how long this might take in the worst-case.
> + */
> +static void
> +secumod_wait_ready (struct secumod_device *secumod)
> +{
> +	unsigned long start, stop;
> +
> +	start = jiffies;
> +	while (!(readl(secumod->regs + SECUMOD_RAMRDY) & 1))
> +		msleep_interruptible(1);
> +	stop = jiffies;
> +	if (stop != start)
> +		pr_info("atmel-secumod: it took %u msec for SECUMOD "
> +			"to become ready...\n", jiffies_to_msecs(stop - start));
> +}
> +
> +static int
> +secumod_probe(struct platform_device *pdev)
> +{
> +	struct secumod_device *secumod;
> +	struct device_node *child;
> +	struct resource *regs;
> +	u32 addr, size;
> +	const void *pv;
> +	int len;
> +
> +	secumod = devm_kzalloc(&pdev->dev, sizeof(*secumod), GFP_KERNEL);
> +	if (!secumod) {
> +		dev_err(&pdev->dev, "out of memory\n");
> +		return -ENOMEM;
> +	}
> +	spin_lock_init(&secumod->lock);
> +	INIT_LIST_HEAD(&secumod->ram_areas);
> +
> +	if (!pdev->dev.of_node) {
> +		dev_err(&pdev->dev, "Missing of_node attribute\n");
> +		return -ENODEV;
> +	}
> +
> +	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!regs) {
> +		dev_err(&pdev->dev, "Missing secumod resources.\n");
> +		return -ENODEV;
> +	}
> +	secumod->pdev = pdev;
> +	secumod->regs = devm_ioremap_resource(&pdev->dev, regs);
> +
> +	platform_set_drvdata(pdev, secumod);
> +
> +	for_each_child_of_node(pdev->dev.of_node, child) {
> +		pv = of_get_property(child, "reg", &len);
> +		if (!pv ||
> +		    of_n_addr_cells(child) != 1 ||
> +		    of_n_size_cells(child) != 1) {
> +			dev_err(&pdev->dev, "Node %s missing \"reg\" property "
> +				"or incorrect address/size count.",
> +				child->name);
> +			return -ENODEV;
> +		}
> +		addr = be32_to_cpup(pv);
> +		size = be32_to_cpup(pv + 4);
> +		secumod_register_ram(secumod, child->name, addr, size);
> +	}
> +	secumod_wait_ready(secumod);
> +	return 0;
> +}
> +
> +static int
> +secumod_remove(struct platform_device *pdev)
> +{
> +	struct secumod_device *secumod = platform_get_drvdata(pdev);
> +	struct ram_area *ram;
> +
> +	spin_lock(&secumod->lock);
> +	list_for_each_entry(ram, &secumod->ram_areas, next)
> +		device_remove_bin_file(&pdev->dev, &ram->attr);
> +	spin_unlock(&secumod->lock);
> +	return 0;
> +}
> +
> +static const struct of_device_id secumod_dt_ids[] = {
> +	{
> +		.compatible = "atmel,sama5d2-secumod"
> +	},
> +	{
> +		/* sentinel */
> +	}
> +};
> +MODULE_DEVICE_TABLE(of, secumod_dt_ids);
> +
> +static struct platform_driver secumod_driver = {
> +	.driver = {
> +		.name = "atmel-secumod",
> +		.of_match_table = of_match_ptr(secumod_dt_ids),
> +	},
> +	.probe		= secumod_probe,
> +	.remove		= secumod_remove
> +};
> +module_platform_driver(secumod_driver);
> +
> +MODULE_AUTHOR("David Mosberger <davidm@egauge.net>");
> +MODULE_DESCRIPTION("Atmel SAMA5D2 secure module driver");
> +MODULE_LICENSE("GPL v2");
> -- 
> 1.9.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH] misc: atmel-secumod: Driver for Atmel "security module".
  2016-01-25 11:09 ` Alexandre Belloni
@ 2016-01-25 16:24   ` David Mosberger
  2016-01-29  0:13     ` Finn Thain
  0 siblings, 1 reply; 25+ messages in thread
From: David Mosberger @ 2016-01-25 16:24 UTC (permalink / raw)
  To: linux-arm-kernel

Alexandre,

On Mon, Jan 25, 2016 at 4:09 AM, Alexandre Belloni
<alexandre.belloni@free-electrons.com> wrote:

> I know this does more than that but I think those thre sections should
> be registered using the nvmem framework. The sysfs file creation and
> accesses then comes for free.

I think Finn's patches would have to go in for that first, since the
existing nvram code is a mess.
Even with Finn's patches in, I think it could go either way.  I'm not
exactly sure how some of the
features of the security module would be used: key management, auto
erasing, there is a strange
"backup mode" vs "normal mode" which is not well documented, etc.  So
I think it may well end up
being sufficiently different to warrant a separate driver.

> Another idea is also to expose it using a genpool so it can be accessed
> as sram from inside the kernel.

That may be a fine idea, but as far as our application is concerned,
we need user-level access
to the battery-backed RAM.

Best regards,

  --david
-- 
eGauge Systems LLC, http://egauge.net/, 1.877-EGAUGE1, fax 720.545.9768

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH] misc: atmel-secumod: Driver for Atmel "security module".
  2016-01-25 16:24   ` David Mosberger
@ 2016-01-29  0:13     ` Finn Thain
  2016-01-31 11:34       ` Alexandre Belloni
  0 siblings, 1 reply; 25+ messages in thread
From: Finn Thain @ 2016-01-29  0:13 UTC (permalink / raw)
  To: linux-arm-kernel


On Mon, 25 Jan 2016, David Mosberger wrote:

> On Mon, Jan 25, 2016 at 4:09 AM, Alexandre Belloni 
> <alexandre.belloni@free-electrons.com> wrote:
> 
> > I know this does more than that but I think those thre sections should 
> > be registered using the nvmem framework. The sysfs file creation and 
> > accesses then comes for free.
> 
> I think Finn's patches would have to go in for that first, since the 
> existing nvram code is a mess. Even with Finn's patches in, I think it 
> could go either way.

I think Alexandre is speaking of the nvmem subsystem (not nvram).
Documentation/devicetree/bindings/nvmem
Documentation/nvmem
drivers/nvmem

> I'm not exactly sure how some of the features of the security module 
> would be used: key management, auto erasing, there is a strange "backup 
> mode" vs "normal mode" which is not well documented, etc.  So I think it 
> may well end up being sufficiently different to warrant a separate 
> driver.

nvmem is not a subsystem I am familiar with, so it's not immediately clear 
to me what your driver would look like if re-written that way.

Maybe it would become simpler. But if you did end up needing a separate 
misc driver as well, maybe use of the nvmem framework would actually 
increase complexity.

It would depend on your requirements. But I would focus on the actual 
requirement rather than uncertain future possibilities.

> 
> > Another idea is also to expose it using a genpool so it can be 
> > accessed as sram from inside the kernel.
> 
> That may be a fine idea, but as far as our application is concerned, we 
> need user-level access to the battery-backed RAM.

Right. I don't see how adding a memory allocator would help either.

-- 

> 
> Best regards,
> 
>   --david
> 

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH] misc: atmel-secumod: Driver for Atmel "security module".
  2016-01-29  0:13     ` Finn Thain
@ 2016-01-31 11:34       ` Alexandre Belloni
  2016-05-23 12:04         ` Boris Brezillon
  0 siblings, 1 reply; 25+ messages in thread
From: Alexandre Belloni @ 2016-01-31 11:34 UTC (permalink / raw)
  To: linux-arm-kernel

On 29/01/2016 at 11:13:05 +1100, Finn Thain wrote :
> 
> On Mon, 25 Jan 2016, David Mosberger wrote:
> 
> > On Mon, Jan 25, 2016 at 4:09 AM, Alexandre Belloni 
> > <alexandre.belloni@free-electrons.com> wrote:
> > 
> > > I know this does more than that but I think those thre sections should 
> > > be registered using the nvmem framework. The sysfs file creation and 
> > > accesses then comes for free.
> > 
> > I think Finn's patches would have to go in for that first, since the 
> > existing nvram code is a mess. Even with Finn's patches in, I think it 
> > could go either way.
> 
> I think Alexandre is speaking of the nvmem subsystem (not nvram).
> Documentation/devicetree/bindings/nvmem
> Documentation/nvmem
> drivers/nvmem
> 

absolutely.

> > I'm not exactly sure how some of the features of the security module 
> > would be used: key management, auto erasing, there is a strange "backup 
> > mode" vs "normal mode" which is not well documented, etc.  So I think it 
> > may well end up being sufficiently different to warrant a separate 
> > driver.
> 
> nvmem is not a subsystem I am familiar with, so it's not immediately clear 
> to me what your driver would look like if re-written that way.
> 
> Maybe it would become simpler. But if you did end up needing a separate 
> misc driver as well, maybe use of the nvmem framework would actually 
> increase complexity.
> 
> It would depend on your requirements. But I would focus on the actual 
> requirement rather than uncertain future possibilities.
> 
> > 
> > > Another idea is also to expose it using a genpool so it can be 
> > > accessed as sram from inside the kernel.
> > 
> > That may be a fine idea, but as far as our application is concerned, we 
> > need user-level access to the battery-backed RAM.
> 
> Right. I don't see how adding a memory allocator would help either.
> 

While the immediate need is to use that sram from userspace, I think
this is valuable to already think that at some point we will need to be
able to partition and access that sram from the kernel.



-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram.
  2016-01-21  3:57 [PATCH] misc: atmel-secumod: Driver for Atmel "security module" David Mosberger-Tang
  2016-01-25 11:09 ` Alexandre Belloni
@ 2016-05-10 19:02 ` David Mosberger-Tang
  2016-05-12  5:06   ` Finn Thain
  1 sibling, 1 reply; 25+ messages in thread
From: David Mosberger-Tang @ 2016-05-10 19:02 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: David Mosberger <davidm@egauge.net>
---
 .../devicetree/bindings/nvmem/atmel-secumod.txt    |  46 ++++++++
 arch/arm/boot/dts/sama5d2.dtsi                     |  20 ++++
 drivers/nvmem/Kconfig                              |   7 ++
 drivers/nvmem/Makefile                             |   2 +
 drivers/nvmem/atmel-secumod.c                      | 122 +++++++++++++++++++++
 5 files changed, 197 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
 create mode 100644 drivers/nvmem/atmel-secumod.c

diff --git a/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
new file mode 100644
index 0000000..0bb7638
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
@@ -0,0 +1,46 @@
+= Atmel Secumod device tree bindings =
+
+This binding is intended to represent Atmel's Secumod which is found
+in SAMA5D2 and perhaps others.
+
+Required properties:
+- compatible: should be "atmel,sama5d2-secumod"
+- reg: Should contain registers location and length of the RAM, followed
+       by register location and length of the Secumod controller.
+
+= Data cells =
+Are child nodes of secumod, bindings of which as described in
+bindings/nvmem/nvmem.txt
+
+Example:
+
+    secumod at fc040000 {
+            compatible = "atmel,sama5d2-secumod";
+            reg = <0xf8044000 0x1420
+                   0xfc040000 0x4000>;
+            status = "okay";
+
+            #address-cells = <1>;
+            #size-cells = <1>;
+
+            secram_auto_erasable at 0000 {
+                    reg = <0x0000 0x1000>;
+            };
+            secram at 1000 {
+                    reg = <0x1000 0x400>;
+            };
+            ram at 1400 {
+                    reg = <0x1400 0x20>;
+            };
+    };
+
+= Data consumers =
+Are device nodes which consume nvmem data cells.
+
+For example:
+
+	ram {
+		...
+		nvmem-cells = <&ram>;
+		nvmem-cell-names = "calibration";
+	};
diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
index 78996bd..5856d6a 100644
--- a/arch/arm/boot/dts/sama5d2.dtsi
+++ b/arch/arm/boot/dts/sama5d2.dtsi
@@ -1178,6 +1178,26 @@
 				clocks = <&pioA_clk>;
 			};
 
+			secumod at fc040000 {
+				compatible = "atmel,sama5d2-secumod";
+				reg = <0xf8044000 0x1420
+				       0xfc040000 0x4000>;
+				status = "okay";
+
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				secram_auto_erasable at 0000 {
+					reg = <0x0000 0x1000>;
+				};
+				secram at 1000 {
+					reg = <0x1000 0x400>;
+				};
+				ram at 1400 {
+					reg = <0x1400 0x20>;
+				};
+			};
+
 			tdes at fc044000 {
 				compatible = "atmel,at91sam9g46-tdes";
 				reg = <0xfc044000 0x100>;
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index ca52952..3d34fbb 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -102,4 +102,11 @@ config NVMEM_VF610_OCOTP
 	  This driver can also be build as a module. If so, the module will
 	  be called nvmem-vf610-ocotp.
 
+config NVMEM_ATMEL_SECUMOD
+       tristate "Atmel Secure Module driver"
+       depends on ARCH_AT91
+       help
+         Select this to get support for the secure module (SECUMOD) built
+	 into the SAMA5D2 chips.
+
 endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 45ab1ae..9cbd950 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -22,3 +22,5 @@ obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
 nvmem_sunxi_sid-y		:= sunxi_sid.o
 obj-$(CONFIG_NVMEM_VF610_OCOTP)	+= nvmem-vf610-ocotp.o
 nvmem-vf610-ocotp-y		:= vf610-ocotp.o
+obj-$(CONFIG_NVMEM_ATMEL_SECUMOD)	+= nvmem-atmel-secumod.o
+nvmem-atmel-secumod-y		:= atmel-secumod.o
diff --git a/drivers/nvmem/atmel-secumod.c b/drivers/nvmem/atmel-secumod.c
new file mode 100644
index 0000000..a6b4574
--- /dev/null
+++ b/drivers/nvmem/atmel-secumod.c
@@ -0,0 +1,122 @@
+/*
+ * Driver for SAMA5D2 secure module (SECUMOD).
+ *
+ * Copyright (C) 2016 eGauge Systems LLC
+ *
+ * David Mosberger <davidm@egauge.net>
+ *
+ * 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 <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+static struct regmap_config secumod_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4
+};
+
+static struct nvmem_config econfig = {
+	.name = "secumod",
+	.owner = THIS_MODULE,
+};
+
+/*
+ * Security-module register definitions:
+ */
+#define SECUMOD_RAMRDY	0x0014
+
+/*
+ * Since the secure module may need to automatically erase some of the
+ * RAM, it may take a while for it to be ready.  As far as I know,
+ * it's not documented how long this might take in the worst-case.
+ */
+static void
+secumod_wait_ready (void *regs)
+{
+	unsigned long start, stop;
+
+	start = jiffies;
+	while (!(readl(regs + SECUMOD_RAMRDY) & 1))
+		msleep_interruptible(1);
+	stop = jiffies;
+	if (stop != start)
+		pr_info("nvmem-atmel-secumod: it took %u msec for SECUMOD "
+			"to become ready...\n", jiffies_to_msecs(stop - start));
+	else
+		pr_info("nvmem-atmel-secumod: ready\n");
+}
+
+static int secumod_remove(struct platform_device *pdev)
+{
+	struct nvmem_device *nvmem = platform_get_drvdata(pdev);
+
+	return nvmem_unregister(nvmem);
+}
+
+static int secumod_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct nvmem_device *nvmem;
+	struct regmap *regmap;
+	void __iomem *base;
+
+	/*
+	 * Map controller address temporarily so we can ensure that
+	 * the hardware is ready:
+	 */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	base = devm_ioremap_resource(dev, res);
+	secumod_wait_ready(base);
+	devm_iounmap(dev, base);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(dev, res);
+
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	secumod_regmap_config.max_register = resource_size(res) - 1;
+
+	regmap = devm_regmap_init_mmio(dev, base, &secumod_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(dev, "%s: regmap init failed\n", __func__);
+		return PTR_ERR(regmap);
+	}
+	econfig.dev = dev;
+	nvmem = nvmem_register(&econfig);
+	if (IS_ERR(nvmem))
+		return PTR_ERR(nvmem);
+
+	platform_set_drvdata(pdev, nvmem);
+
+	return 0;
+}
+
+static const struct of_device_id secumod_of_match[] = {
+	{ .compatible = "atmel,sama5d2-secumod",},
+	{/* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, secumod_of_match);
+
+static struct platform_driver secumod_driver = {
+	.probe = secumod_probe,
+	.remove = secumod_remove,
+	.driver = {
+		.name = "atmel,sama5d2-secumod",
+		.of_match_table = secumod_of_match,
+	},
+};
+module_platform_driver(secumod_driver);
+MODULE_AUTHOR("David Mosberger <davidm@egauge.net>");
+MODULE_DESCRIPTION("Atmel Secumod driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram.
  2016-05-10 19:02 ` [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram David Mosberger-Tang
@ 2016-05-12  5:06   ` Finn Thain
  2016-05-16 20:17       ` David Mosberger-Tang
  0 siblings, 1 reply; 25+ messages in thread
From: Finn Thain @ 2016-05-12  5:06 UTC (permalink / raw)
  To: linux-arm-kernel


On Tue, 10 May 2016, David Mosberger-Tang wrote:

> Signed-off-by: David Mosberger <davidm@egauge.net>
> ---
>  .../devicetree/bindings/nvmem/atmel-secumod.txt    |  46 ++++++++
>  arch/arm/boot/dts/sama5d2.dtsi                     |  20 ++++
>  drivers/nvmem/Kconfig                              |   7 ++
>  drivers/nvmem/Makefile                             |   2 +
>  drivers/nvmem/atmel-secumod.c                      | 122 +++++++++++++++++++++
>  5 files changed, 197 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
>  create mode 100644 drivers/nvmem/atmel-secumod.c
> 
> diff --git a/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
> new file mode 100644
> index 0000000..0bb7638
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
> @@ -0,0 +1,46 @@
> += Atmel Secumod device tree bindings =
> +
> +This binding is intended to represent Atmel's Secumod which is found
> +in SAMA5D2 and perhaps others.
> +
> +Required properties:
> +- compatible: should be "atmel,sama5d2-secumod"
> +- reg: Should contain registers location and length of the RAM, followed
> +       by register location and length of the Secumod controller.
> +
> += Data cells =
> +Are child nodes of secumod, bindings of which as described in
> +bindings/nvmem/nvmem.txt
> +
> +Example:
> +
> +    secumod at fc040000 {
> +            compatible = "atmel,sama5d2-secumod";
> +            reg = <0xf8044000 0x1420
> +                   0xfc040000 0x4000>;
> +            status = "okay";
> +
> +            #address-cells = <1>;
> +            #size-cells = <1>;
> +
> +            secram_auto_erasable at 0000 {
> +                    reg = <0x0000 0x1000>;
> +            };
> +            secram at 1000 {
> +                    reg = <0x1000 0x400>;
> +            };
> +            ram at 1400 {
> +                    reg = <0x1400 0x20>;
> +            };
> +    };
> +
> += Data consumers =
> +Are device nodes which consume nvmem data cells.
> +
> +For example:
> +
> +	ram {
> +		...
> +		nvmem-cells = <&ram>;
> +		nvmem-cell-names = "calibration";
> +	};
> diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
> index 78996bd..5856d6a 100644
> --- a/arch/arm/boot/dts/sama5d2.dtsi
> +++ b/arch/arm/boot/dts/sama5d2.dtsi
> @@ -1178,6 +1178,26 @@
>  				clocks = <&pioA_clk>;
>  			};
>  
> +			secumod at fc040000 {
> +				compatible = "atmel,sama5d2-secumod";
> +				reg = <0xf8044000 0x1420
> +				       0xfc040000 0x4000>;
> +				status = "okay";
> +
> +				#address-cells = <1>;
> +				#size-cells = <1>;
> +
> +				secram_auto_erasable at 0000 {
> +					reg = <0x0000 0x1000>;
> +				};
> +				secram at 1000 {
> +					reg = <0x1000 0x400>;
> +				};
> +				ram at 1400 {
> +					reg = <0x1400 0x20>;
> +				};
> +			};
> +
>  			tdes at fc044000 {
>  				compatible = "atmel,at91sam9g46-tdes";
>  				reg = <0xfc044000 0x100>;
> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
> index ca52952..3d34fbb 100644
> --- a/drivers/nvmem/Kconfig
> +++ b/drivers/nvmem/Kconfig
> @@ -102,4 +102,11 @@ config NVMEM_VF610_OCOTP
>  	  This driver can also be build as a module. If so, the module will
>  	  be called nvmem-vf610-ocotp.
>  
> +config NVMEM_ATMEL_SECUMOD
> +       tristate "Atmel Secure Module driver"
> +       depends on ARCH_AT91
> +       help
> +         Select this to get support for the secure module (SECUMOD) built
> +	 into the SAMA5D2 chips.
> +
>  endif
> diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
> index 45ab1ae..9cbd950 100644
> --- a/drivers/nvmem/Makefile
> +++ b/drivers/nvmem/Makefile
> @@ -22,3 +22,5 @@ obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
>  nvmem_sunxi_sid-y		:= sunxi_sid.o
>  obj-$(CONFIG_NVMEM_VF610_OCOTP)	+= nvmem-vf610-ocotp.o
>  nvmem-vf610-ocotp-y		:= vf610-ocotp.o
> +obj-$(CONFIG_NVMEM_ATMEL_SECUMOD)	+= nvmem-atmel-secumod.o
> +nvmem-atmel-secumod-y		:= atmel-secumod.o
> diff --git a/drivers/nvmem/atmel-secumod.c b/drivers/nvmem/atmel-secumod.c
> new file mode 100644
> index 0000000..a6b4574
> --- /dev/null
> +++ b/drivers/nvmem/atmel-secumod.c
> @@ -0,0 +1,122 @@
> +/*
> + * Driver for SAMA5D2 secure module (SECUMOD).
> + *
> + * Copyright (C) 2016 eGauge Systems LLC
> + *
> + * David Mosberger <davidm@egauge.net>
> + *
> + * 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 <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/nvmem-provider.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +static struct regmap_config secumod_regmap_config = {
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4
> +};
> +
> +static struct nvmem_config econfig = {
> +	.name = "secumod",
> +	.owner = THIS_MODULE,
> +};
> +
> +/*
> + * Security-module register definitions:
> + */
> +#define SECUMOD_RAMRDY	0x0014
> +
> +/*
> + * Since the secure module may need to automatically erase some of the
> + * RAM, it may take a while for it to be ready.  As far as I know,
> + * it's not documented how long this might take in the worst-case.
> + */
> +static void
> +secumod_wait_ready (void *regs)
> +{
> +	unsigned long start, stop;
> +
> +	start = jiffies;
> +	while (!(readl(regs + SECUMOD_RAMRDY) & 1))
> +		msleep_interruptible(1);
> +	stop = jiffies;
> +	if (stop != start)
> +		pr_info("nvmem-atmel-secumod: it took %u msec for SECUMOD "
> +			"to become ready...\n", jiffies_to_msecs(stop - start));
> +	else
> +		pr_info("nvmem-atmel-secumod: ready\n");
> +}
> +
> +static int secumod_remove(struct platform_device *pdev)
> +{
> +	struct nvmem_device *nvmem = platform_get_drvdata(pdev);
> +
> +	return nvmem_unregister(nvmem);
> +}
> +
> +static int secumod_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct resource *res;
> +	struct nvmem_device *nvmem;
> +	struct regmap *regmap;
> +	void __iomem *base;
> +
> +	/*
> +	 * Map controller address temporarily so we can ensure that
> +	 * the hardware is ready:
> +	 */
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> +	base = devm_ioremap_resource(dev, res);

I would check IS_ERR(base) here...

> +	secumod_wait_ready(base);
> +	devm_iounmap(dev, base);
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	base = devm_ioremap_resource(dev, res);
> +
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);

...just like you did here.

When you send v2, you should address it to all of the relevant maintainers 
and mailing lists in order to get the necessary Acked-by tags. My tags 
aren't useful here. Please see,

$ scripts/get_maintainer.pl this.patch

-- 

> +
> +	secumod_regmap_config.max_register = resource_size(res) - 1;
> +
> +	regmap = devm_regmap_init_mmio(dev, base, &secumod_regmap_config);
> +	if (IS_ERR(regmap)) {
> +		dev_err(dev, "%s: regmap init failed\n", __func__);
> +		return PTR_ERR(regmap);
> +	}
> +	econfig.dev = dev;
> +	nvmem = nvmem_register(&econfig);
> +	if (IS_ERR(nvmem))
> +		return PTR_ERR(nvmem);
> +
> +	platform_set_drvdata(pdev, nvmem);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id secumod_of_match[] = {
> +	{ .compatible = "atmel,sama5d2-secumod",},
> +	{/* sentinel */},
> +};
> +MODULE_DEVICE_TABLE(of, secumod_of_match);
> +
> +static struct platform_driver secumod_driver = {
> +	.probe = secumod_probe,
> +	.remove = secumod_remove,
> +	.driver = {
> +		.name = "atmel,sama5d2-secumod",
> +		.of_match_table = secumod_of_match,
> +	},
> +};
> +module_platform_driver(secumod_driver);
> +MODULE_AUTHOR("David Mosberger <davidm@egauge.net>");
> +MODULE_DESCRIPTION("Atmel Secumod driver");
> +MODULE_LICENSE("GPL v2");
> 

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram
  2016-05-12  5:06   ` Finn Thain
  2016-05-16 20:17       ` David Mosberger-Tang
@ 2016-05-16 20:17       ` David Mosberger-Tang
  0 siblings, 0 replies; 25+ messages in thread
From: David Mosberger-Tang @ 2016-05-16 20:17 UTC (permalink / raw)
  To: srinivas.kandagatla, maxime.ripard
  Cc: pawel.moll, mark.rutland, ijc+devicetree, galak, devicetree,
	linux-kernel, nicolas.ferre, linux-arm-kernel,
	David Mosberger-Tang

Signed-off-by: David Mosberger <davidm@egauge.net>
---
 .../devicetree/bindings/nvmem/atmel-secumod.txt    |  46 ++++++++
 drivers/nvmem/atmel-secumod.c                      | 125 +++++++++++++++++++++
 2 files changed, 171 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
 create mode 100644 drivers/nvmem/atmel-secumod.c

diff --git a/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
new file mode 100644
index 0000000..85db709
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
@@ -0,0 +1,46 @@
+= Atmel Secumod device tree bindings =
+
+This binding is intended to represent Atmel's Secumod which is found
+in SAMA5D2 and perhaps others.
+
+Required properties:
+- compatible: should be "atmel,sama5d2-secumod"
+- reg: Should contain registers location and length of the RAM, followed
+       by register location and length of the Secumod controller.
+
+= Data cells =
+Are child nodes of secumod, bindings of which as described in
+bindings/nvmem/nvmem.txt
+
+Example:
+
+    secumod@fc040000 {
+            compatible = "atmel,sama5d2-secumod";
+            reg = <0xf8044000 0x1420
+                   0xfc040000 0x4000>;
+            status = "okay";
+
+            #address-cells = <1>;
+            #size-cells = <1>;
+
+            secram_auto_erasable@0000 {
+                    reg = <0x0000 0x1000>;
+            };
+            secram@1000 {
+                    reg = <0x1000 0x400>;
+            };
+            ram@1400 {
+                    reg = <0x1400 0x20>;
+            };
+    };
+
+= Data consumers =
+Are device nodes which consume nvmem data cells.
+
+For example:
+
+	ram {
+		...
+		nvmem-cells = <&ram>;
+		nvmem-cell-names = "RAM";
+	};
diff --git a/drivers/nvmem/atmel-secumod.c b/drivers/nvmem/atmel-secumod.c
new file mode 100644
index 0000000..fda83c9
--- /dev/null
+++ b/drivers/nvmem/atmel-secumod.c
@@ -0,0 +1,125 @@
+/*
+ * Driver for SAMA5D2 secure module (SECUMOD).
+ *
+ * Copyright (C) 2016 eGauge Systems LLC
+ *
+ * David Mosberger <davidm@egauge.net>
+ *
+ * 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 <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+static struct regmap_config secumod_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4
+};
+
+static struct nvmem_config econfig = {
+	.name = "secumod",
+	.owner = THIS_MODULE,
+};
+
+/*
+ * Security-module register definitions:
+ */
+#define SECUMOD_RAMRDY	0x0014
+
+/*
+ * Since the secure module may need to automatically erase some of the
+ * RAM, it may take a while for it to be ready.  As far as I know,
+ * it's not documented how long this might take in the worst-case.
+ */
+static void
+secumod_wait_ready (void *regs)
+{
+	unsigned long start, stop;
+
+	start = jiffies;
+	while (!(readl(regs + SECUMOD_RAMRDY) & 1))
+		msleep_interruptible(1);
+	stop = jiffies;
+	if (stop != start)
+		pr_info("nvmem-atmel-secumod: it took %u msec for SECUMOD "
+			"to become ready...\n", jiffies_to_msecs(stop - start));
+	else
+		pr_info("nvmem-atmel-secumod: ready\n");
+}
+
+static int secumod_remove(struct platform_device *pdev)
+{
+	struct nvmem_device *nvmem = platform_get_drvdata(pdev);
+
+	return nvmem_unregister(nvmem);
+}
+
+static int secumod_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct nvmem_device *nvmem;
+	struct regmap *regmap;
+	void __iomem *base;
+
+	/*
+	 * Map controller address temporarily so we can ensure that
+	 * the hardware is ready:
+	 */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	secumod_wait_ready(base);
+	devm_iounmap(dev, base);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(dev, res);
+
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	secumod_regmap_config.max_register = resource_size(res) - 1;
+
+	regmap = devm_regmap_init_mmio(dev, base, &secumod_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(dev, "%s: regmap init failed\n", __func__);
+		return PTR_ERR(regmap);
+	}
+	econfig.dev = dev;
+	nvmem = nvmem_register(&econfig);
+	if (IS_ERR(nvmem))
+		return PTR_ERR(nvmem);
+
+	platform_set_drvdata(pdev, nvmem);
+
+	return 0;
+}
+
+static const struct of_device_id secumod_of_match[] = {
+	{ .compatible = "atmel,sama5d2-secumod",},
+	{/* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, secumod_of_match);
+
+static struct platform_driver secumod_driver = {
+	.probe = secumod_probe,
+	.remove = secumod_remove,
+	.driver = {
+		.name = "atmel,sama5d2-secumod",
+		.of_match_table = secumod_of_match,
+	},
+};
+module_platform_driver(secumod_driver);
+MODULE_AUTHOR("David Mosberger <davidm@egauge.net>");
+MODULE_DESCRIPTION("Atmel Secumod driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram
@ 2016-05-16 20:17       ` David Mosberger-Tang
  0 siblings, 0 replies; 25+ messages in thread
From: David Mosberger-Tang @ 2016-05-16 20:17 UTC (permalink / raw)
  To: srinivas.kandagatla, maxime.ripard
  Cc: mark.rutland, devicetree, pawel.moll, ijc+devicetree,
	David Mosberger-Tang, nicolas.ferre, linux-kernel, galak,
	linux-arm-kernel

Signed-off-by: David Mosberger <davidm@egauge.net>
---
 .../devicetree/bindings/nvmem/atmel-secumod.txt    |  46 ++++++++
 drivers/nvmem/atmel-secumod.c                      | 125 +++++++++++++++++++++
 2 files changed, 171 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
 create mode 100644 drivers/nvmem/atmel-secumod.c

diff --git a/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
new file mode 100644
index 0000000..85db709
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
@@ -0,0 +1,46 @@
+= Atmel Secumod device tree bindings =
+
+This binding is intended to represent Atmel's Secumod which is found
+in SAMA5D2 and perhaps others.
+
+Required properties:
+- compatible: should be "atmel,sama5d2-secumod"
+- reg: Should contain registers location and length of the RAM, followed
+       by register location and length of the Secumod controller.
+
+= Data cells =
+Are child nodes of secumod, bindings of which as described in
+bindings/nvmem/nvmem.txt
+
+Example:
+
+    secumod@fc040000 {
+            compatible = "atmel,sama5d2-secumod";
+            reg = <0xf8044000 0x1420
+                   0xfc040000 0x4000>;
+            status = "okay";
+
+            #address-cells = <1>;
+            #size-cells = <1>;
+
+            secram_auto_erasable@0000 {
+                    reg = <0x0000 0x1000>;
+            };
+            secram@1000 {
+                    reg = <0x1000 0x400>;
+            };
+            ram@1400 {
+                    reg = <0x1400 0x20>;
+            };
+    };
+
+= Data consumers =
+Are device nodes which consume nvmem data cells.
+
+For example:
+
+	ram {
+		...
+		nvmem-cells = <&ram>;
+		nvmem-cell-names = "RAM";
+	};
diff --git a/drivers/nvmem/atmel-secumod.c b/drivers/nvmem/atmel-secumod.c
new file mode 100644
index 0000000..fda83c9
--- /dev/null
+++ b/drivers/nvmem/atmel-secumod.c
@@ -0,0 +1,125 @@
+/*
+ * Driver for SAMA5D2 secure module (SECUMOD).
+ *
+ * Copyright (C) 2016 eGauge Systems LLC
+ *
+ * David Mosberger <davidm@egauge.net>
+ *
+ * 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 <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+static struct regmap_config secumod_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4
+};
+
+static struct nvmem_config econfig = {
+	.name = "secumod",
+	.owner = THIS_MODULE,
+};
+
+/*
+ * Security-module register definitions:
+ */
+#define SECUMOD_RAMRDY	0x0014
+
+/*
+ * Since the secure module may need to automatically erase some of the
+ * RAM, it may take a while for it to be ready.  As far as I know,
+ * it's not documented how long this might take in the worst-case.
+ */
+static void
+secumod_wait_ready (void *regs)
+{
+	unsigned long start, stop;
+
+	start = jiffies;
+	while (!(readl(regs + SECUMOD_RAMRDY) & 1))
+		msleep_interruptible(1);
+	stop = jiffies;
+	if (stop != start)
+		pr_info("nvmem-atmel-secumod: it took %u msec for SECUMOD "
+			"to become ready...\n", jiffies_to_msecs(stop - start));
+	else
+		pr_info("nvmem-atmel-secumod: ready\n");
+}
+
+static int secumod_remove(struct platform_device *pdev)
+{
+	struct nvmem_device *nvmem = platform_get_drvdata(pdev);
+
+	return nvmem_unregister(nvmem);
+}
+
+static int secumod_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct nvmem_device *nvmem;
+	struct regmap *regmap;
+	void __iomem *base;
+
+	/*
+	 * Map controller address temporarily so we can ensure that
+	 * the hardware is ready:
+	 */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	secumod_wait_ready(base);
+	devm_iounmap(dev, base);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(dev, res);
+
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	secumod_regmap_config.max_register = resource_size(res) - 1;
+
+	regmap = devm_regmap_init_mmio(dev, base, &secumod_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(dev, "%s: regmap init failed\n", __func__);
+		return PTR_ERR(regmap);
+	}
+	econfig.dev = dev;
+	nvmem = nvmem_register(&econfig);
+	if (IS_ERR(nvmem))
+		return PTR_ERR(nvmem);
+
+	platform_set_drvdata(pdev, nvmem);
+
+	return 0;
+}
+
+static const struct of_device_id secumod_of_match[] = {
+	{ .compatible = "atmel,sama5d2-secumod",},
+	{/* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, secumod_of_match);
+
+static struct platform_driver secumod_driver = {
+	.probe = secumod_probe,
+	.remove = secumod_remove,
+	.driver = {
+		.name = "atmel,sama5d2-secumod",
+		.of_match_table = secumod_of_match,
+	},
+};
+module_platform_driver(secumod_driver);
+MODULE_AUTHOR("David Mosberger <davidm@egauge.net>");
+MODULE_DESCRIPTION("Atmel Secumod driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram
@ 2016-05-16 20:17       ` David Mosberger-Tang
  0 siblings, 0 replies; 25+ messages in thread
From: David Mosberger-Tang @ 2016-05-16 20:17 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: David Mosberger <davidm@egauge.net>
---
 .../devicetree/bindings/nvmem/atmel-secumod.txt    |  46 ++++++++
 drivers/nvmem/atmel-secumod.c                      | 125 +++++++++++++++++++++
 2 files changed, 171 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
 create mode 100644 drivers/nvmem/atmel-secumod.c

diff --git a/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
new file mode 100644
index 0000000..85db709
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
@@ -0,0 +1,46 @@
+= Atmel Secumod device tree bindings =
+
+This binding is intended to represent Atmel's Secumod which is found
+in SAMA5D2 and perhaps others.
+
+Required properties:
+- compatible: should be "atmel,sama5d2-secumod"
+- reg: Should contain registers location and length of the RAM, followed
+       by register location and length of the Secumod controller.
+
+= Data cells =
+Are child nodes of secumod, bindings of which as described in
+bindings/nvmem/nvmem.txt
+
+Example:
+
+    secumod at fc040000 {
+            compatible = "atmel,sama5d2-secumod";
+            reg = <0xf8044000 0x1420
+                   0xfc040000 0x4000>;
+            status = "okay";
+
+            #address-cells = <1>;
+            #size-cells = <1>;
+
+            secram_auto_erasable at 0000 {
+                    reg = <0x0000 0x1000>;
+            };
+            secram at 1000 {
+                    reg = <0x1000 0x400>;
+            };
+            ram at 1400 {
+                    reg = <0x1400 0x20>;
+            };
+    };
+
+= Data consumers =
+Are device nodes which consume nvmem data cells.
+
+For example:
+
+	ram {
+		...
+		nvmem-cells = <&ram>;
+		nvmem-cell-names = "RAM";
+	};
diff --git a/drivers/nvmem/atmel-secumod.c b/drivers/nvmem/atmel-secumod.c
new file mode 100644
index 0000000..fda83c9
--- /dev/null
+++ b/drivers/nvmem/atmel-secumod.c
@@ -0,0 +1,125 @@
+/*
+ * Driver for SAMA5D2 secure module (SECUMOD).
+ *
+ * Copyright (C) 2016 eGauge Systems LLC
+ *
+ * David Mosberger <davidm@egauge.net>
+ *
+ * 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 <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+static struct regmap_config secumod_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4
+};
+
+static struct nvmem_config econfig = {
+	.name = "secumod",
+	.owner = THIS_MODULE,
+};
+
+/*
+ * Security-module register definitions:
+ */
+#define SECUMOD_RAMRDY	0x0014
+
+/*
+ * Since the secure module may need to automatically erase some of the
+ * RAM, it may take a while for it to be ready.  As far as I know,
+ * it's not documented how long this might take in the worst-case.
+ */
+static void
+secumod_wait_ready (void *regs)
+{
+	unsigned long start, stop;
+
+	start = jiffies;
+	while (!(readl(regs + SECUMOD_RAMRDY) & 1))
+		msleep_interruptible(1);
+	stop = jiffies;
+	if (stop != start)
+		pr_info("nvmem-atmel-secumod: it took %u msec for SECUMOD "
+			"to become ready...\n", jiffies_to_msecs(stop - start));
+	else
+		pr_info("nvmem-atmel-secumod: ready\n");
+}
+
+static int secumod_remove(struct platform_device *pdev)
+{
+	struct nvmem_device *nvmem = platform_get_drvdata(pdev);
+
+	return nvmem_unregister(nvmem);
+}
+
+static int secumod_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct nvmem_device *nvmem;
+	struct regmap *regmap;
+	void __iomem *base;
+
+	/*
+	 * Map controller address temporarily so we can ensure that
+	 * the hardware is ready:
+	 */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	secumod_wait_ready(base);
+	devm_iounmap(dev, base);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(dev, res);
+
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	secumod_regmap_config.max_register = resource_size(res) - 1;
+
+	regmap = devm_regmap_init_mmio(dev, base, &secumod_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(dev, "%s: regmap init failed\n", __func__);
+		return PTR_ERR(regmap);
+	}
+	econfig.dev = dev;
+	nvmem = nvmem_register(&econfig);
+	if (IS_ERR(nvmem))
+		return PTR_ERR(nvmem);
+
+	platform_set_drvdata(pdev, nvmem);
+
+	return 0;
+}
+
+static const struct of_device_id secumod_of_match[] = {
+	{ .compatible = "atmel,sama5d2-secumod",},
+	{/* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, secumod_of_match);
+
+static struct platform_driver secumod_driver = {
+	.probe = secumod_probe,
+	.remove = secumod_remove,
+	.driver = {
+		.name = "atmel,sama5d2-secumod",
+		.of_match_table = secumod_of_match,
+	},
+};
+module_platform_driver(secumod_driver);
+MODULE_AUTHOR("David Mosberger <davidm@egauge.net>");
+MODULE_DESCRIPTION("Atmel Secumod driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram
@ 2016-05-18 16:42         ` Rob Herring
  0 siblings, 0 replies; 25+ messages in thread
From: Rob Herring @ 2016-05-18 16:42 UTC (permalink / raw)
  To: David Mosberger-Tang
  Cc: srinivas.kandagatla, maxime.ripard, mark.rutland, devicetree,
	pawel.moll, ijc+devicetree, nicolas.ferre, linux-kernel, galak,
	linux-arm-kernel

On Mon, May 16, 2016 at 02:17:10PM -0600, David Mosberger-Tang wrote:
> Signed-off-by: David Mosberger <davidm@egauge.net>
> ---
>  .../devicetree/bindings/nvmem/atmel-secumod.txt    |  46 ++++++++
>  drivers/nvmem/atmel-secumod.c                      | 125 +++++++++++++++++++++
>  2 files changed, 171 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
>  create mode 100644 drivers/nvmem/atmel-secumod.c
> 
> diff --git a/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
> new file mode 100644
> index 0000000..85db709
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
> @@ -0,0 +1,46 @@
> += Atmel Secumod device tree bindings =
> +
> +This binding is intended to represent Atmel's Secumod which is found
> +in SAMA5D2 and perhaps others.
> +
> +Required properties:
> +- compatible: should be "atmel,sama5d2-secumod"
> +- reg: Should contain registers location and length of the RAM, followed

registers or RAM location?

"Should contain RAM location and length, ..."

> +       by register location and length of the Secumod controller.
> +
> += Data cells =
> +Are child nodes of secumod, bindings of which as described in
> +bindings/nvmem/nvmem.txt
> +
> +Example:
> +
> +    secumod@fc040000 {
> +            compatible = "atmel,sama5d2-secumod";
> +            reg = <0xf8044000 0x1420
> +                   0xfc040000 0x4000>;

You are missing ranges property.

> +            status = "okay";
> +
> +            #address-cells = <1>;
> +            #size-cells = <1>;
> +
> +            secram_auto_erasable@0000 {

Use '-' rather than '_' and drop leading 0s.

> +                    reg = <0x0000 0x1000>;
> +            };
> +            secram@1000 {
> +                    reg = <0x1000 0x400>;
> +            };
> +            ram@1400 {
> +                    reg = <0x1400 0x20>;
> +            };
> +    };
> +
> += Data consumers =
> +Are device nodes which consume nvmem data cells.
> +
> +For example:
> +
> +	ram {
> +		...
> +		nvmem-cells = <&ram>;
> +		nvmem-cell-names = "RAM";
> +	};

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram
@ 2016-05-18 16:42         ` Rob Herring
  0 siblings, 0 replies; 25+ messages in thread
From: Rob Herring @ 2016-05-18 16:42 UTC (permalink / raw)
  To: David Mosberger-Tang
  Cc: srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
	pawel.moll-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	nicolas.ferre-AIFe0yeh4nAAvxtiuMwx3w,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	galak-sgV2jX0FEOL9JmXXK+q4OQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Mon, May 16, 2016 at 02:17:10PM -0600, David Mosberger-Tang wrote:
> Signed-off-by: David Mosberger <davidm-haPfTeumbwasTnJN9+BGXg@public.gmane.org>
> ---
>  .../devicetree/bindings/nvmem/atmel-secumod.txt    |  46 ++++++++
>  drivers/nvmem/atmel-secumod.c                      | 125 +++++++++++++++++++++
>  2 files changed, 171 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
>  create mode 100644 drivers/nvmem/atmel-secumod.c
> 
> diff --git a/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
> new file mode 100644
> index 0000000..85db709
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
> @@ -0,0 +1,46 @@
> += Atmel Secumod device tree bindings =
> +
> +This binding is intended to represent Atmel's Secumod which is found
> +in SAMA5D2 and perhaps others.
> +
> +Required properties:
> +- compatible: should be "atmel,sama5d2-secumod"
> +- reg: Should contain registers location and length of the RAM, followed

registers or RAM location?

"Should contain RAM location and length, ..."

> +       by register location and length of the Secumod controller.
> +
> += Data cells =
> +Are child nodes of secumod, bindings of which as described in
> +bindings/nvmem/nvmem.txt
> +
> +Example:
> +
> +    secumod@fc040000 {
> +            compatible = "atmel,sama5d2-secumod";
> +            reg = <0xf8044000 0x1420
> +                   0xfc040000 0x4000>;

You are missing ranges property.

> +            status = "okay";
> +
> +            #address-cells = <1>;
> +            #size-cells = <1>;
> +
> +            secram_auto_erasable@0000 {

Use '-' rather than '_' and drop leading 0s.

> +                    reg = <0x0000 0x1000>;
> +            };
> +            secram@1000 {
> +                    reg = <0x1000 0x400>;
> +            };
> +            ram@1400 {
> +                    reg = <0x1400 0x20>;
> +            };
> +    };
> +
> += Data consumers =
> +Are device nodes which consume nvmem data cells.
> +
> +For example:
> +
> +	ram {
> +		...
> +		nvmem-cells = <&ram>;
> +		nvmem-cell-names = "RAM";
> +	};
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram
@ 2016-05-18 16:42         ` Rob Herring
  0 siblings, 0 replies; 25+ messages in thread
From: Rob Herring @ 2016-05-18 16:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 16, 2016 at 02:17:10PM -0600, David Mosberger-Tang wrote:
> Signed-off-by: David Mosberger <davidm@egauge.net>
> ---
>  .../devicetree/bindings/nvmem/atmel-secumod.txt    |  46 ++++++++
>  drivers/nvmem/atmel-secumod.c                      | 125 +++++++++++++++++++++
>  2 files changed, 171 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
>  create mode 100644 drivers/nvmem/atmel-secumod.c
> 
> diff --git a/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
> new file mode 100644
> index 0000000..85db709
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
> @@ -0,0 +1,46 @@
> += Atmel Secumod device tree bindings =
> +
> +This binding is intended to represent Atmel's Secumod which is found
> +in SAMA5D2 and perhaps others.
> +
> +Required properties:
> +- compatible: should be "atmel,sama5d2-secumod"
> +- reg: Should contain registers location and length of the RAM, followed

registers or RAM location?

"Should contain RAM location and length, ..."

> +       by register location and length of the Secumod controller.
> +
> += Data cells =
> +Are child nodes of secumod, bindings of which as described in
> +bindings/nvmem/nvmem.txt
> +
> +Example:
> +
> +    secumod at fc040000 {
> +            compatible = "atmel,sama5d2-secumod";
> +            reg = <0xf8044000 0x1420
> +                   0xfc040000 0x4000>;

You are missing ranges property.

> +            status = "okay";
> +
> +            #address-cells = <1>;
> +            #size-cells = <1>;
> +
> +            secram_auto_erasable at 0000 {

Use '-' rather than '_' and drop leading 0s.

> +                    reg = <0x0000 0x1000>;
> +            };
> +            secram at 1000 {
> +                    reg = <0x1000 0x400>;
> +            };
> +            ram at 1400 {
> +                    reg = <0x1400 0x20>;
> +            };
> +    };
> +
> += Data consumers =
> +Are device nodes which consume nvmem data cells.
> +
> +For example:
> +
> +	ram {
> +		...
> +		nvmem-cells = <&ram>;
> +		nvmem-cell-names = "RAM";
> +	};

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram
  2016-05-18 16:42         ` Rob Herring
@ 2016-05-18 20:46           ` David Mosberger
  -1 siblings, 0 replies; 25+ messages in thread
From: David Mosberger @ 2016-05-18 20:46 UTC (permalink / raw)
  To: Rob Herring
  Cc: srinivas.kandagatla, maxime.ripard, mark.rutland, devicetree,
	pawel.moll, ijc+devicetree, Nicolas Ferre, linux-kernel, galak,
	linux-arm-kernel

Thanks for the feedback. Rob!  I'll make the changes and resend the
patch (which has now also been updated to work with linux-next).

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram
@ 2016-05-18 20:46           ` David Mosberger
  0 siblings, 0 replies; 25+ messages in thread
From: David Mosberger @ 2016-05-18 20:46 UTC (permalink / raw)
  To: linux-arm-kernel

Thanks for the feedback. Rob!  I'll make the changes and resend the
patch (which has now also been updated to work with linux-next).

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram
  2016-05-18 16:42         ` Rob Herring
  (?)
@ 2016-05-18 21:06           ` David Mosberger-Tang
  -1 siblings, 0 replies; 25+ messages in thread
From: David Mosberger-Tang @ 2016-05-18 21:06 UTC (permalink / raw)
  To: srinivas.kandagatla, maxime.ripard
  Cc: pawel.moll, mark.rutland, ijc+devicetree, galak, devicetree,
	linux-kernel, nicolas.ferre, linux-arm-kernel,
	David Mosberger-Tang

Signed-off-by: David Mosberger <davidm@egauge.net>
---
 .../devicetree/bindings/nvmem/atmel-secumod.txt    |  47 +++++++
 drivers/nvmem/Kconfig                              |   7 +
 drivers/nvmem/Makefile                             |   2 +
 drivers/nvmem/atmel-secumod.c                      | 143 +++++++++++++++++++++
 4 files changed, 199 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
 create mode 100644 drivers/nvmem/atmel-secumod.c

diff --git a/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
new file mode 100644
index 0000000..d65cad5
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
@@ -0,0 +1,47 @@
+= Atmel Secumod device tree bindings =
+
+This binding is intended to represent Atmel's Secumod which is found
+in SAMA5D2 and perhaps others.
+
+Required properties:
+- compatible: should be "atmel,sama5d2-secumod"
+- reg: Should contain RAM location and length, followed
+       by register location and length of the Secumod controller.
+
+= Data cells =
+Are child nodes of secumod, bindings of which as described in
+bindings/nvmem/nvmem.txt
+
+Example:
+
+    secumod@fc040000 {
+            compatible = "atmel,sama5d2-secumod";
+            reg = <0xf8044000 0x1420>, <0xfc040000 0x4000>;
+            reg-names = "SECURAM", "SECUMOD";
+            status = "okay";
+
+            #address-cells = <1>;
+            #size-cells = <1>;
+            ranges;
+
+            secram-auto-erasable@0 {
+                    reg = <0x0000 0x1000>;
+            };
+            secram@1000 {
+                    reg = <0x1000 0x400>;
+            };
+            ram@1400 {
+                    reg = <0x1400 0x20>;
+            };
+    };
+
+= Data consumers =
+Are device nodes which consume nvmem data cells.
+
+For example:
+
+	ram {
+		...
+		nvmem-cells = <&ram>;
+		nvmem-cell-names = "RAM";
+	};
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 3041d48..88b21e3 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -101,4 +101,11 @@ config NVMEM_VF610_OCOTP
 	  This driver can also be build as a module. If so, the module will
 	  be called nvmem-vf610-ocotp.
 
+config NVMEM_ATMEL_SECUMOD
+       tristate "Atmel Secure Module driver"
+       depends on ARCH_AT91
+       help
+         Select this to get support for the secure module (SECUMOD) built
+	 into the SAMA5D2 chips.
+
 endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 45ab1ae..9cbd950 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -22,3 +22,5 @@ obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
 nvmem_sunxi_sid-y		:= sunxi_sid.o
 obj-$(CONFIG_NVMEM_VF610_OCOTP)	+= nvmem-vf610-ocotp.o
 nvmem-vf610-ocotp-y		:= vf610-ocotp.o
+obj-$(CONFIG_NVMEM_ATMEL_SECUMOD)	+= nvmem-atmel-secumod.o
+nvmem-atmel-secumod-y		:= atmel-secumod.o
diff --git a/drivers/nvmem/atmel-secumod.c b/drivers/nvmem/atmel-secumod.c
new file mode 100644
index 0000000..fc5a96b
--- /dev/null
+++ b/drivers/nvmem/atmel-secumod.c
@@ -0,0 +1,143 @@
+/*
+ * Driver for SAMA5D2 secure module (SECUMOD).
+ *
+ * Copyright (C) 2016 eGauge Systems LLC
+ *
+ * David Mosberger <davidm@egauge.net>
+ *
+ * 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 <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+static int
+secumod_reg_read(void *context, unsigned int reg, void *_val, size_t bytes)
+{
+	void __iomem *base = context;
+	u32 *val = _val;
+	int i = 0, words = bytes / 4;
+
+	while (words--)
+		*val++ = readl(base + reg + (i++ * 4));
+
+	return 0;
+}
+
+static int
+secumod_reg_write(void *context, unsigned int reg, void *_val, size_t bytes)
+{
+	void __iomem *base = context;
+	u32 *val = _val;
+	int i = 0, words = bytes / 4;
+
+	while (words--)
+		writel(*val++, base + reg + (i++ * 4));
+
+	return 0;
+}
+
+static struct nvmem_config econfig = {
+	.name = "secumod",
+	.owner = THIS_MODULE,
+	.stride = 4,
+	.word_size = 1,
+	.reg_read = secumod_reg_read,
+	.reg_write = secumod_reg_write,
+};
+
+/*
+ * Security-module register definitions:
+ */
+#define SECUMOD_RAMRDY	0x0014
+
+/*
+ * Since the secure module may need to automatically erase some of the
+ * RAM, it may take a while for it to be ready.  As far as I know,
+ * it's not documented how long this might take in the worst-case.
+ */
+static void
+secumod_wait_ready (void *regs)
+{
+	unsigned long start, stop;
+
+	start = jiffies;
+	while (!(readl(regs + SECUMOD_RAMRDY) & 1))
+		msleep_interruptible(1);
+	stop = jiffies;
+	if (stop != start)
+		pr_info("nvmem-atmel-secumod: it took %u msec for SECUMOD "
+			"to become ready...\n", jiffies_to_msecs(stop - start));
+	else
+		pr_info("nvmem-atmel-secumod: ready\n");
+}
+
+static int secumod_remove(struct platform_device *pdev)
+{
+	struct nvmem_device *nvmem = platform_get_drvdata(pdev);
+
+	return nvmem_unregister(nvmem);
+}
+
+static int secumod_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct nvmem_device *nvmem;
+	void __iomem *base;
+
+	/*
+	 * Map controller address temporarily so we can ensure that
+	 * the hardware is ready:
+	 */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	secumod_wait_ready(base);
+	devm_iounmap(dev, base);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(dev, res);
+
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	econfig.size = resource_size(res);
+	econfig.dev = dev;
+	econfig.priv = base;
+
+	nvmem = nvmem_register(&econfig);
+	if (IS_ERR(nvmem))
+		return PTR_ERR(nvmem);
+
+	platform_set_drvdata(pdev, nvmem);
+
+	return 0;
+}
+
+static const struct of_device_id secumod_of_match[] = {
+	{ .compatible = "atmel,sama5d2-secumod",},
+	{/* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, secumod_of_match);
+
+static struct platform_driver secumod_driver = {
+	.probe = secumod_probe,
+	.remove = secumod_remove,
+	.driver = {
+		.name = "atmel,sama5d2-secumod",
+		.of_match_table = secumod_of_match,
+	},
+};
+module_platform_driver(secumod_driver);
+MODULE_AUTHOR("David Mosberger <davidm@egauge.net>");
+MODULE_DESCRIPTION("Atmel Secumod driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram
@ 2016-05-18 21:06           ` David Mosberger-Tang
  0 siblings, 0 replies; 25+ messages in thread
From: David Mosberger-Tang @ 2016-05-18 21:06 UTC (permalink / raw)
  To: srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8
  Cc: pawel.moll-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	nicolas.ferre-AIFe0yeh4nAAvxtiuMwx3w,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	David Mosberger-Tang

Signed-off-by: David Mosberger <davidm-haPfTeumbwasTnJN9+BGXg@public.gmane.org>
---
 .../devicetree/bindings/nvmem/atmel-secumod.txt    |  47 +++++++
 drivers/nvmem/Kconfig                              |   7 +
 drivers/nvmem/Makefile                             |   2 +
 drivers/nvmem/atmel-secumod.c                      | 143 +++++++++++++++++++++
 4 files changed, 199 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
 create mode 100644 drivers/nvmem/atmel-secumod.c

diff --git a/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
new file mode 100644
index 0000000..d65cad5
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
@@ -0,0 +1,47 @@
+= Atmel Secumod device tree bindings =
+
+This binding is intended to represent Atmel's Secumod which is found
+in SAMA5D2 and perhaps others.
+
+Required properties:
+- compatible: should be "atmel,sama5d2-secumod"
+- reg: Should contain RAM location and length, followed
+       by register location and length of the Secumod controller.
+
+= Data cells =
+Are child nodes of secumod, bindings of which as described in
+bindings/nvmem/nvmem.txt
+
+Example:
+
+    secumod@fc040000 {
+            compatible = "atmel,sama5d2-secumod";
+            reg = <0xf8044000 0x1420>, <0xfc040000 0x4000>;
+            reg-names = "SECURAM", "SECUMOD";
+            status = "okay";
+
+            #address-cells = <1>;
+            #size-cells = <1>;
+            ranges;
+
+            secram-auto-erasable@0 {
+                    reg = <0x0000 0x1000>;
+            };
+            secram@1000 {
+                    reg = <0x1000 0x400>;
+            };
+            ram@1400 {
+                    reg = <0x1400 0x20>;
+            };
+    };
+
+= Data consumers =
+Are device nodes which consume nvmem data cells.
+
+For example:
+
+	ram {
+		...
+		nvmem-cells = <&ram>;
+		nvmem-cell-names = "RAM";
+	};
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 3041d48..88b21e3 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -101,4 +101,11 @@ config NVMEM_VF610_OCOTP
 	  This driver can also be build as a module. If so, the module will
 	  be called nvmem-vf610-ocotp.
 
+config NVMEM_ATMEL_SECUMOD
+       tristate "Atmel Secure Module driver"
+       depends on ARCH_AT91
+       help
+         Select this to get support for the secure module (SECUMOD) built
+	 into the SAMA5D2 chips.
+
 endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 45ab1ae..9cbd950 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -22,3 +22,5 @@ obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
 nvmem_sunxi_sid-y		:= sunxi_sid.o
 obj-$(CONFIG_NVMEM_VF610_OCOTP)	+= nvmem-vf610-ocotp.o
 nvmem-vf610-ocotp-y		:= vf610-ocotp.o
+obj-$(CONFIG_NVMEM_ATMEL_SECUMOD)	+= nvmem-atmel-secumod.o
+nvmem-atmel-secumod-y		:= atmel-secumod.o
diff --git a/drivers/nvmem/atmel-secumod.c b/drivers/nvmem/atmel-secumod.c
new file mode 100644
index 0000000..fc5a96b
--- /dev/null
+++ b/drivers/nvmem/atmel-secumod.c
@@ -0,0 +1,143 @@
+/*
+ * Driver for SAMA5D2 secure module (SECUMOD).
+ *
+ * Copyright (C) 2016 eGauge Systems LLC
+ *
+ * David Mosberger <davidm-haPfTeumbwasTnJN9+BGXg@public.gmane.org>
+ *
+ * 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 <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+static int
+secumod_reg_read(void *context, unsigned int reg, void *_val, size_t bytes)
+{
+	void __iomem *base = context;
+	u32 *val = _val;
+	int i = 0, words = bytes / 4;
+
+	while (words--)
+		*val++ = readl(base + reg + (i++ * 4));
+
+	return 0;
+}
+
+static int
+secumod_reg_write(void *context, unsigned int reg, void *_val, size_t bytes)
+{
+	void __iomem *base = context;
+	u32 *val = _val;
+	int i = 0, words = bytes / 4;
+
+	while (words--)
+		writel(*val++, base + reg + (i++ * 4));
+
+	return 0;
+}
+
+static struct nvmem_config econfig = {
+	.name = "secumod",
+	.owner = THIS_MODULE,
+	.stride = 4,
+	.word_size = 1,
+	.reg_read = secumod_reg_read,
+	.reg_write = secumod_reg_write,
+};
+
+/*
+ * Security-module register definitions:
+ */
+#define SECUMOD_RAMRDY	0x0014
+
+/*
+ * Since the secure module may need to automatically erase some of the
+ * RAM, it may take a while for it to be ready.  As far as I know,
+ * it's not documented how long this might take in the worst-case.
+ */
+static void
+secumod_wait_ready (void *regs)
+{
+	unsigned long start, stop;
+
+	start = jiffies;
+	while (!(readl(regs + SECUMOD_RAMRDY) & 1))
+		msleep_interruptible(1);
+	stop = jiffies;
+	if (stop != start)
+		pr_info("nvmem-atmel-secumod: it took %u msec for SECUMOD "
+			"to become ready...\n", jiffies_to_msecs(stop - start));
+	else
+		pr_info("nvmem-atmel-secumod: ready\n");
+}
+
+static int secumod_remove(struct platform_device *pdev)
+{
+	struct nvmem_device *nvmem = platform_get_drvdata(pdev);
+
+	return nvmem_unregister(nvmem);
+}
+
+static int secumod_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct nvmem_device *nvmem;
+	void __iomem *base;
+
+	/*
+	 * Map controller address temporarily so we can ensure that
+	 * the hardware is ready:
+	 */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	secumod_wait_ready(base);
+	devm_iounmap(dev, base);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(dev, res);
+
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	econfig.size = resource_size(res);
+	econfig.dev = dev;
+	econfig.priv = base;
+
+	nvmem = nvmem_register(&econfig);
+	if (IS_ERR(nvmem))
+		return PTR_ERR(nvmem);
+
+	platform_set_drvdata(pdev, nvmem);
+
+	return 0;
+}
+
+static const struct of_device_id secumod_of_match[] = {
+	{ .compatible = "atmel,sama5d2-secumod",},
+	{/* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, secumod_of_match);
+
+static struct platform_driver secumod_driver = {
+	.probe = secumod_probe,
+	.remove = secumod_remove,
+	.driver = {
+		.name = "atmel,sama5d2-secumod",
+		.of_match_table = secumod_of_match,
+	},
+};
+module_platform_driver(secumod_driver);
+MODULE_AUTHOR("David Mosberger <davidm-haPfTeumbwasTnJN9+BGXg@public.gmane.org>");
+MODULE_DESCRIPTION("Atmel Secumod driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram
@ 2016-05-18 21:06           ` David Mosberger-Tang
  0 siblings, 0 replies; 25+ messages in thread
From: David Mosberger-Tang @ 2016-05-18 21:06 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: David Mosberger <davidm@egauge.net>
---
 .../devicetree/bindings/nvmem/atmel-secumod.txt    |  47 +++++++
 drivers/nvmem/Kconfig                              |   7 +
 drivers/nvmem/Makefile                             |   2 +
 drivers/nvmem/atmel-secumod.c                      | 143 +++++++++++++++++++++
 4 files changed, 199 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
 create mode 100644 drivers/nvmem/atmel-secumod.c

diff --git a/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
new file mode 100644
index 0000000..d65cad5
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
@@ -0,0 +1,47 @@
+= Atmel Secumod device tree bindings =
+
+This binding is intended to represent Atmel's Secumod which is found
+in SAMA5D2 and perhaps others.
+
+Required properties:
+- compatible: should be "atmel,sama5d2-secumod"
+- reg: Should contain RAM location and length, followed
+       by register location and length of the Secumod controller.
+
+= Data cells =
+Are child nodes of secumod, bindings of which as described in
+bindings/nvmem/nvmem.txt
+
+Example:
+
+    secumod at fc040000 {
+            compatible = "atmel,sama5d2-secumod";
+            reg = <0xf8044000 0x1420>, <0xfc040000 0x4000>;
+            reg-names = "SECURAM", "SECUMOD";
+            status = "okay";
+
+            #address-cells = <1>;
+            #size-cells = <1>;
+            ranges;
+
+            secram-auto-erasable at 0 {
+                    reg = <0x0000 0x1000>;
+            };
+            secram at 1000 {
+                    reg = <0x1000 0x400>;
+            };
+            ram at 1400 {
+                    reg = <0x1400 0x20>;
+            };
+    };
+
+= Data consumers =
+Are device nodes which consume nvmem data cells.
+
+For example:
+
+	ram {
+		...
+		nvmem-cells = <&ram>;
+		nvmem-cell-names = "RAM";
+	};
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 3041d48..88b21e3 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -101,4 +101,11 @@ config NVMEM_VF610_OCOTP
 	  This driver can also be build as a module. If so, the module will
 	  be called nvmem-vf610-ocotp.
 
+config NVMEM_ATMEL_SECUMOD
+       tristate "Atmel Secure Module driver"
+       depends on ARCH_AT91
+       help
+         Select this to get support for the secure module (SECUMOD) built
+	 into the SAMA5D2 chips.
+
 endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 45ab1ae..9cbd950 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -22,3 +22,5 @@ obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
 nvmem_sunxi_sid-y		:= sunxi_sid.o
 obj-$(CONFIG_NVMEM_VF610_OCOTP)	+= nvmem-vf610-ocotp.o
 nvmem-vf610-ocotp-y		:= vf610-ocotp.o
+obj-$(CONFIG_NVMEM_ATMEL_SECUMOD)	+= nvmem-atmel-secumod.o
+nvmem-atmel-secumod-y		:= atmel-secumod.o
diff --git a/drivers/nvmem/atmel-secumod.c b/drivers/nvmem/atmel-secumod.c
new file mode 100644
index 0000000..fc5a96b
--- /dev/null
+++ b/drivers/nvmem/atmel-secumod.c
@@ -0,0 +1,143 @@
+/*
+ * Driver for SAMA5D2 secure module (SECUMOD).
+ *
+ * Copyright (C) 2016 eGauge Systems LLC
+ *
+ * David Mosberger <davidm@egauge.net>
+ *
+ * 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 <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+static int
+secumod_reg_read(void *context, unsigned int reg, void *_val, size_t bytes)
+{
+	void __iomem *base = context;
+	u32 *val = _val;
+	int i = 0, words = bytes / 4;
+
+	while (words--)
+		*val++ = readl(base + reg + (i++ * 4));
+
+	return 0;
+}
+
+static int
+secumod_reg_write(void *context, unsigned int reg, void *_val, size_t bytes)
+{
+	void __iomem *base = context;
+	u32 *val = _val;
+	int i = 0, words = bytes / 4;
+
+	while (words--)
+		writel(*val++, base + reg + (i++ * 4));
+
+	return 0;
+}
+
+static struct nvmem_config econfig = {
+	.name = "secumod",
+	.owner = THIS_MODULE,
+	.stride = 4,
+	.word_size = 1,
+	.reg_read = secumod_reg_read,
+	.reg_write = secumod_reg_write,
+};
+
+/*
+ * Security-module register definitions:
+ */
+#define SECUMOD_RAMRDY	0x0014
+
+/*
+ * Since the secure module may need to automatically erase some of the
+ * RAM, it may take a while for it to be ready.  As far as I know,
+ * it's not documented how long this might take in the worst-case.
+ */
+static void
+secumod_wait_ready (void *regs)
+{
+	unsigned long start, stop;
+
+	start = jiffies;
+	while (!(readl(regs + SECUMOD_RAMRDY) & 1))
+		msleep_interruptible(1);
+	stop = jiffies;
+	if (stop != start)
+		pr_info("nvmem-atmel-secumod: it took %u msec for SECUMOD "
+			"to become ready...\n", jiffies_to_msecs(stop - start));
+	else
+		pr_info("nvmem-atmel-secumod: ready\n");
+}
+
+static int secumod_remove(struct platform_device *pdev)
+{
+	struct nvmem_device *nvmem = platform_get_drvdata(pdev);
+
+	return nvmem_unregister(nvmem);
+}
+
+static int secumod_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct nvmem_device *nvmem;
+	void __iomem *base;
+
+	/*
+	 * Map controller address temporarily so we can ensure that
+	 * the hardware is ready:
+	 */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	secumod_wait_ready(base);
+	devm_iounmap(dev, base);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(dev, res);
+
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	econfig.size = resource_size(res);
+	econfig.dev = dev;
+	econfig.priv = base;
+
+	nvmem = nvmem_register(&econfig);
+	if (IS_ERR(nvmem))
+		return PTR_ERR(nvmem);
+
+	platform_set_drvdata(pdev, nvmem);
+
+	return 0;
+}
+
+static const struct of_device_id secumod_of_match[] = {
+	{ .compatible = "atmel,sama5d2-secumod",},
+	{/* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, secumod_of_match);
+
+static struct platform_driver secumod_driver = {
+	.probe = secumod_probe,
+	.remove = secumod_remove,
+	.driver = {
+		.name = "atmel,sama5d2-secumod",
+		.of_match_table = secumod_of_match,
+	},
+};
+module_platform_driver(secumod_driver);
+MODULE_AUTHOR("David Mosberger <davidm@egauge.net>");
+MODULE_DESCRIPTION("Atmel Secumod driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram
  2016-05-18 21:06           ` David Mosberger-Tang
@ 2016-05-20 19:21             ` Rob Herring
  -1 siblings, 0 replies; 25+ messages in thread
From: Rob Herring @ 2016-05-20 19:21 UTC (permalink / raw)
  To: David Mosberger-Tang
  Cc: srinivas.kandagatla, maxime.ripard, pawel.moll, mark.rutland,
	ijc+devicetree, galak, devicetree, linux-kernel, nicolas.ferre,
	linux-arm-kernel

On Wed, May 18, 2016 at 03:06:04PM -0600, David Mosberger-Tang wrote:
> Signed-off-by: David Mosberger <davidm@egauge.net>
> ---
>  .../devicetree/bindings/nvmem/atmel-secumod.txt    |  47 +++++++
>  drivers/nvmem/Kconfig                              |   7 +
>  drivers/nvmem/Makefile                             |   2 +
>  drivers/nvmem/atmel-secumod.c                      | 143 +++++++++++++++++++++
>  4 files changed, 199 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
>  create mode 100644 drivers/nvmem/atmel-secumod.c
> 
> diff --git a/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
> new file mode 100644
> index 0000000..d65cad5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
> @@ -0,0 +1,47 @@
> += Atmel Secumod device tree bindings =
> +
> +This binding is intended to represent Atmel's Secumod which is found
> +in SAMA5D2 and perhaps others.
> +
> +Required properties:
> +- compatible: should be "atmel,sama5d2-secumod"
> +- reg: Should contain RAM location and length, followed
> +       by register location and length of the Secumod controller.
> +
> += Data cells =
> +Are child nodes of secumod, bindings of which as described in
> +bindings/nvmem/nvmem.txt
> +
> +Example:
> +
> +    secumod@fc040000 {

This unit-address should match the first reg address.

> +            compatible = "atmel,sama5d2-secumod";
> +            reg = <0xf8044000 0x1420>, <0xfc040000 0x4000>;
> +            reg-names = "SECURAM", "SECUMOD";
> +            status = "okay";
> +
> +            #address-cells = <1>;
> +            #size-cells = <1>;
> +            ranges;

Sorry, to be clear, you need values here too.

> +
> +            secram-auto-erasable@0 {
> +                    reg = <0x0000 0x1000>;

The 0 here is address 0xf8044000, right? So ranges is what is used to 
translate from child address of 0 to the parent address.

> +            };
> +            secram@1000 {
> +                    reg = <0x1000 0x400>;
> +            };
> +            ram@1400 {
> +                    reg = <0x1400 0x20>;
> +            };
> +    };
> +
> += Data consumers =
> +Are device nodes which consume nvmem data cells.
> +
> +For example:
> +
> +	ram {
> +		...
> +		nvmem-cells = <&ram>;
> +		nvmem-cell-names = "RAM";
> +	};

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram
@ 2016-05-20 19:21             ` Rob Herring
  0 siblings, 0 replies; 25+ messages in thread
From: Rob Herring @ 2016-05-20 19:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 18, 2016 at 03:06:04PM -0600, David Mosberger-Tang wrote:
> Signed-off-by: David Mosberger <davidm@egauge.net>
> ---
>  .../devicetree/bindings/nvmem/atmel-secumod.txt    |  47 +++++++
>  drivers/nvmem/Kconfig                              |   7 +
>  drivers/nvmem/Makefile                             |   2 +
>  drivers/nvmem/atmel-secumod.c                      | 143 +++++++++++++++++++++
>  4 files changed, 199 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
>  create mode 100644 drivers/nvmem/atmel-secumod.c
> 
> diff --git a/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
> new file mode 100644
> index 0000000..d65cad5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
> @@ -0,0 +1,47 @@
> += Atmel Secumod device tree bindings =
> +
> +This binding is intended to represent Atmel's Secumod which is found
> +in SAMA5D2 and perhaps others.
> +
> +Required properties:
> +- compatible: should be "atmel,sama5d2-secumod"
> +- reg: Should contain RAM location and length, followed
> +       by register location and length of the Secumod controller.
> +
> += Data cells =
> +Are child nodes of secumod, bindings of which as described in
> +bindings/nvmem/nvmem.txt
> +
> +Example:
> +
> +    secumod at fc040000 {

This unit-address should match the first reg address.

> +            compatible = "atmel,sama5d2-secumod";
> +            reg = <0xf8044000 0x1420>, <0xfc040000 0x4000>;
> +            reg-names = "SECURAM", "SECUMOD";
> +            status = "okay";
> +
> +            #address-cells = <1>;
> +            #size-cells = <1>;
> +            ranges;

Sorry, to be clear, you need values here too.

> +
> +            secram-auto-erasable at 0 {
> +                    reg = <0x0000 0x1000>;

The 0 here is address 0xf8044000, right? So ranges is what is used to 
translate from child address of 0 to the parent address.

> +            };
> +            secram at 1000 {
> +                    reg = <0x1000 0x400>;
> +            };
> +            ram at 1400 {
> +                    reg = <0x1400 0x20>;
> +            };
> +    };
> +
> += Data consumers =
> +Are device nodes which consume nvmem data cells.
> +
> +For example:
> +
> +	ram {
> +		...
> +		nvmem-cells = <&ram>;
> +		nvmem-cell-names = "RAM";
> +	};

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram
  2016-05-18 21:06           ` David Mosberger-Tang
@ 2016-05-23  8:50             ` Srinivas Kandagatla
  -1 siblings, 0 replies; 25+ messages in thread
From: Srinivas Kandagatla @ 2016-05-23  8:50 UTC (permalink / raw)
  To: David Mosberger-Tang, maxime.ripard
  Cc: mark.rutland, devicetree, pawel.moll, ijc+devicetree,
	nicolas.ferre, linux-kernel, galak, linux-arm-kernel

Thanks for the patch,
Few minors comments below.

On 18/05/16 22:06, David Mosberger-Tang wrote:
> Signed-off-by: David Mosberger <davidm@egauge.net>
> ---
>   .../devicetree/bindings/nvmem/atmel-secumod.txt    |  47 +++++++
>   drivers/nvmem/Kconfig                              |   7 +
>   drivers/nvmem/Makefile                             |   2 +
>   drivers/nvmem/atmel-secumod.c                      | 143 +++++++++++++++++++++
>   4 files changed, 199 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
>   create mode 100644 drivers/nvmem/atmel-secumod.c
>
> diff --git a/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
> new file mode 100644
> index 0000000..d65cad5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
> @@ -0,0 +1,47 @@
> += Atmel Secumod device tree bindings =
> +

Can you split the dt-bindings into separate patch.

> +This binding is intended to represent Atmel's Secumod which is found
> +in SAMA5D2 and perhaps others.
> +
> +Required properties:
> +- compatible: should be "atmel,sama5d2-secumod"
> +- reg: Should contain RAM location and length, followed
> +       by register location and length of the Secumod controller.
> +
> += Data cells =
> +Are child nodes of secumod, bindings of which as described in
> +bindings/nvmem/nvmem.txt
> +
> +Example:
> +
> +    secumod@fc040000 {
> +            compatible = "atmel,sama5d2-secumod";
> +            reg = <0xf8044000 0x1420>, <0xfc040000 0x4000>;
> +            reg-names = "SECURAM", "SECUMOD";
> +            status = "okay";
> +
> +            #address-cells = <1>;
> +            #size-cells = <1>;
> +            ranges;
> +
> +            secram-auto-erasable@0 {
> +                    reg = <0x0000 0x1000>;
> +            };
> +            secram@1000 {
> +                    reg = <0x1000 0x400>;
> +            };
> +            ram@1400 {
> +                    reg = <0x1400 0x20>;
> +            };
> +    };
> +
> += Data consumers =
> +Are device nodes which consume nvmem data cells.
> +
> +For example:
> +
> +	ram {
> +		...
> +		nvmem-cells = <&ram>;
> +		nvmem-cell-names = "RAM";
> +	};
> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
> index 3041d48..88b21e3 100644
> --- a/drivers/nvmem/Kconfig
> +++ b/drivers/nvmem/Kconfig
> @@ -101,4 +101,11 @@ config NVMEM_VF610_OCOTP
>   	  This driver can also be build as a module. If so, the module will
>   	  be called nvmem-vf610-ocotp.
>
> +config NVMEM_ATMEL_SECUMOD
> +       tristate "Atmel Secure Module driver"
> +       depends on ARCH_AT91

COMPILE_TEST ?
Also please add
depends on HAS_IOMEM

> +       help
> +         Select this to get support for the secure module (SECUMOD) built
> +	 into the SAMA5D2 chips.
> +
>   endif
...

> index 0000000..fc5a96b
> --- /dev/null
> +++ b/drivers/nvmem/atmel-secumod.c

...
> +
> +/*
> + * Security-module register definitions:
> + */
> +#define SECUMOD_RAMRDY	0x0014
> +
> +/*
> + * Since the secure module may need to automatically erase some of the
> + * RAM, it may take a while for it to be ready.  As far as I know,
> + * it's not documented how long this might take in the worst-case.
> + */
> +static void
> +secumod_wait_ready (void *regs)
> +{
> +	unsigned long start, stop;
> +
> +	start = jiffies;
> +	while (!(readl(regs + SECUMOD_RAMRDY) & 1))
> +		msleep_interruptible(1);

Worst case would be the system loop here forever, Can we add worst case 
timeout for this, and get out of this loop.

> +	stop = jiffies;
> +	if (stop != start)
> +		pr_info("nvmem-atmel-secumod: it took %u msec for SECUMOD "
> +			"to become ready...\n", jiffies_to_msecs(stop - start));
> +	else
> +		pr_info("nvmem-atmel-secumod: ready\n");
I dont see any use of this prints, We should probably remove these and 
add just a one dev_dbg.

> +}
> +
...
thanks,
srini

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram
@ 2016-05-23  8:50             ` Srinivas Kandagatla
  0 siblings, 0 replies; 25+ messages in thread
From: Srinivas Kandagatla @ 2016-05-23  8:50 UTC (permalink / raw)
  To: linux-arm-kernel

Thanks for the patch,
Few minors comments below.

On 18/05/16 22:06, David Mosberger-Tang wrote:
> Signed-off-by: David Mosberger <davidm@egauge.net>
> ---
>   .../devicetree/bindings/nvmem/atmel-secumod.txt    |  47 +++++++
>   drivers/nvmem/Kconfig                              |   7 +
>   drivers/nvmem/Makefile                             |   2 +
>   drivers/nvmem/atmel-secumod.c                      | 143 +++++++++++++++++++++
>   4 files changed, 199 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
>   create mode 100644 drivers/nvmem/atmel-secumod.c
>
> diff --git a/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
> new file mode 100644
> index 0000000..d65cad5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/nvmem/atmel-secumod.txt
> @@ -0,0 +1,47 @@
> += Atmel Secumod device tree bindings =
> +

Can you split the dt-bindings into separate patch.

> +This binding is intended to represent Atmel's Secumod which is found
> +in SAMA5D2 and perhaps others.
> +
> +Required properties:
> +- compatible: should be "atmel,sama5d2-secumod"
> +- reg: Should contain RAM location and length, followed
> +       by register location and length of the Secumod controller.
> +
> += Data cells =
> +Are child nodes of secumod, bindings of which as described in
> +bindings/nvmem/nvmem.txt
> +
> +Example:
> +
> +    secumod at fc040000 {
> +            compatible = "atmel,sama5d2-secumod";
> +            reg = <0xf8044000 0x1420>, <0xfc040000 0x4000>;
> +            reg-names = "SECURAM", "SECUMOD";
> +            status = "okay";
> +
> +            #address-cells = <1>;
> +            #size-cells = <1>;
> +            ranges;
> +
> +            secram-auto-erasable at 0 {
> +                    reg = <0x0000 0x1000>;
> +            };
> +            secram at 1000 {
> +                    reg = <0x1000 0x400>;
> +            };
> +            ram at 1400 {
> +                    reg = <0x1400 0x20>;
> +            };
> +    };
> +
> += Data consumers =
> +Are device nodes which consume nvmem data cells.
> +
> +For example:
> +
> +	ram {
> +		...
> +		nvmem-cells = <&ram>;
> +		nvmem-cell-names = "RAM";
> +	};
> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
> index 3041d48..88b21e3 100644
> --- a/drivers/nvmem/Kconfig
> +++ b/drivers/nvmem/Kconfig
> @@ -101,4 +101,11 @@ config NVMEM_VF610_OCOTP
>   	  This driver can also be build as a module. If so, the module will
>   	  be called nvmem-vf610-ocotp.
>
> +config NVMEM_ATMEL_SECUMOD
> +       tristate "Atmel Secure Module driver"
> +       depends on ARCH_AT91

COMPILE_TEST ?
Also please add
depends on HAS_IOMEM

> +       help
> +         Select this to get support for the secure module (SECUMOD) built
> +	 into the SAMA5D2 chips.
> +
>   endif
...

> index 0000000..fc5a96b
> --- /dev/null
> +++ b/drivers/nvmem/atmel-secumod.c

...
> +
> +/*
> + * Security-module register definitions:
> + */
> +#define SECUMOD_RAMRDY	0x0014
> +
> +/*
> + * Since the secure module may need to automatically erase some of the
> + * RAM, it may take a while for it to be ready.  As far as I know,
> + * it's not documented how long this might take in the worst-case.
> + */
> +static void
> +secumod_wait_ready (void *regs)
> +{
> +	unsigned long start, stop;
> +
> +	start = jiffies;
> +	while (!(readl(regs + SECUMOD_RAMRDY) & 1))
> +		msleep_interruptible(1);

Worst case would be the system loop here forever, Can we add worst case 
timeout for this, and get out of this loop.

> +	stop = jiffies;
> +	if (stop != start)
> +		pr_info("nvmem-atmel-secumod: it took %u msec for SECUMOD "
> +			"to become ready...\n", jiffies_to_msecs(stop - start));
> +	else
> +		pr_info("nvmem-atmel-secumod: ready\n");
I dont see any use of this prints, We should probably remove these and 
add just a one dev_dbg.

> +}
> +
...
thanks,
srini

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH] misc: atmel-secumod: Driver for Atmel "security module".
  2016-01-31 11:34       ` Alexandre Belloni
@ 2016-05-23 12:04         ` Boris Brezillon
  2016-05-23 12:53           ` Boris Brezillon
  0 siblings, 1 reply; 25+ messages in thread
From: Boris Brezillon @ 2016-05-23 12:04 UTC (permalink / raw)
  To: linux-arm-kernel

Hi David,

Sorry for the late review (I know you've posted new versions but I want
to comment on this one).

On Sun, 31 Jan 2016 12:34:09 +0100
Alexandre Belloni <alexandre.belloni@free-electrons.com> wrote:

> On 29/01/2016 at 11:13:05 +1100, Finn Thain wrote :
> > 
> > On Mon, 25 Jan 2016, David Mosberger wrote:
> >   
> > > On Mon, Jan 25, 2016 at 4:09 AM, Alexandre Belloni 
> > > <alexandre.belloni@free-electrons.com> wrote:
> > >   
> > > > I know this does more than that but I think those thre sections should 
> > > > be registered using the nvmem framework. The sysfs file creation and 
> > > > accesses then comes for free.  
> > > 
> > > I think Finn's patches would have to go in for that first, since the 
> > > existing nvram code is a mess. Even with Finn's patches in, I think it 
> > > could go either way.  
> > 
> > I think Alexandre is speaking of the nvmem subsystem (not nvram).
> > Documentation/devicetree/bindings/nvmem
> > Documentation/nvmem
> > drivers/nvmem
> >   
> 
> absolutely.
> 
> > > I'm not exactly sure how some of the features of the security module 
> > > would be used: key management, auto erasing, there is a strange "backup 
> > > mode" vs "normal mode" which is not well documented, etc.  So I think it 
> > > may well end up being sufficiently different to warrant a separate 
> > > driver.  
> > 
> > nvmem is not a subsystem I am familiar with, so it's not immediately clear 
> > to me what your driver would look like if re-written that way.
> > 
> > Maybe it would become simpler. But if you did end up needing a separate 
> > misc driver as well, maybe use of the nvmem framework would actually 
> > increase complexity.
> > 
> > It would depend on your requirements. But I would focus on the actual 
> > requirement rather than uncertain future possibilities.
> >   
> > >   
> > > > Another idea is also to expose it using a genpool so it can be 
> > > > accessed as sram from inside the kernel.  
> > > 
> > > That may be a fine idea, but as far as our application is concerned, we 
> > > need user-level access to the battery-backed RAM.  
> > 
> > Right. I don't see how adding a memory allocator would help either.
> >   
> 
> While the immediate need is to use that sram from userspace, I think
> this is valuable to already think that at some point we will need to be
> able to partition and access that sram from the kernel.
> 
> 
> 

Well, I think we're reaching this point right now: I have to implement
"freeze" mode (entering a deep sleep mode by cutting all power domains
except VDDBU), and in order to do that I need to access BUREGs which
are part of the secu-sram you're trying to expose here.

Two comments on the nvmem approach:
1/ first of all it's not really a non-volative memory: if you loose
VDDBU you also loose the whole SRAM content.
2/ I need to be able to reserve the BUREG region (at least part of it)
for in kernel usage (need to store the SDRAM address I should jump to
when exiting freeze mode).

For those reason I think using the SRAM driver (drivers/misc/sram.c) is
a better approach. This driver both provides a sysfs interface (just
add the "export" property on the SRAM region you want to export to
user-space through sysfs), and a genpool provider (which I need to
reserve part of the SRAM for my "freeze" mode implementation).

Best Regards,

Boris

-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH] misc: atmel-secumod: Driver for Atmel "security module".
  2016-05-23 12:04         ` Boris Brezillon
@ 2016-05-23 12:53           ` Boris Brezillon
  2016-05-23 13:59             ` Alexandre Belloni
  0 siblings, 1 reply; 25+ messages in thread
From: Boris Brezillon @ 2016-05-23 12:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 23 May 2016 14:04:24 +0200
Boris Brezillon <boris.brezillon@free-electrons.com> wrote:

> Hi David,
> 
> Sorry for the late review (I know you've posted new versions but I want
> to comment on this one).
> 
> On Sun, 31 Jan 2016 12:34:09 +0100
> Alexandre Belloni <alexandre.belloni@free-electrons.com> wrote:
> 
> > On 29/01/2016 at 11:13:05 +1100, Finn Thain wrote :  
> > > 
> > > On Mon, 25 Jan 2016, David Mosberger wrote:
> > >     
> > > > On Mon, Jan 25, 2016 at 4:09 AM, Alexandre Belloni 
> > > > <alexandre.belloni@free-electrons.com> wrote:
> > > >     
> > > > > I know this does more than that but I think those thre sections should 
> > > > > be registered using the nvmem framework. The sysfs file creation and 
> > > > > accesses then comes for free.    
> > > > 
> > > > I think Finn's patches would have to go in for that first, since the 
> > > > existing nvram code is a mess. Even with Finn's patches in, I think it 
> > > > could go either way.    
> > > 
> > > I think Alexandre is speaking of the nvmem subsystem (not nvram).
> > > Documentation/devicetree/bindings/nvmem
> > > Documentation/nvmem
> > > drivers/nvmem
> > >     
> > 
> > absolutely.
> >   
> > > > I'm not exactly sure how some of the features of the security module 
> > > > would be used: key management, auto erasing, there is a strange "backup 
> > > > mode" vs "normal mode" which is not well documented, etc.  So I think it 
> > > > may well end up being sufficiently different to warrant a separate 
> > > > driver.    
> > > 
> > > nvmem is not a subsystem I am familiar with, so it's not immediately clear 
> > > to me what your driver would look like if re-written that way.
> > > 
> > > Maybe it would become simpler. But if you did end up needing a separate 
> > > misc driver as well, maybe use of the nvmem framework would actually 
> > > increase complexity.
> > > 
> > > It would depend on your requirements. But I would focus on the actual 
> > > requirement rather than uncertain future possibilities.
> > >     
> > > >     
> > > > > Another idea is also to expose it using a genpool so it can be 
> > > > > accessed as sram from inside the kernel.    
> > > > 
> > > > That may be a fine idea, but as far as our application is concerned, we 
> > > > need user-level access to the battery-backed RAM.    
> > > 
> > > Right. I don't see how adding a memory allocator would help either.
> > >     
> > 
> > While the immediate need is to use that sram from userspace, I think
> > this is valuable to already think that at some point we will need to be
> > able to partition and access that sram from the kernel.
> > 
> > 
> >   
> 
> Well, I think we're reaching this point right now: I have to implement
> "freeze" mode (entering a deep sleep mode by cutting all power domains
> except VDDBU), and in order to do that I need to access BUREGs which
> are part of the secu-sram you're trying to expose here.
> 
> Two comments on the nvmem approach:
> 1/ first of all it's not really a non-volative memory: if you loose
> VDDBU you also loose the whole SRAM content.
> 2/ I need to be able to reserve the BUREG region (at least part of it)
> for in kernel usage (need to store the SDRAM address I should jump to
> when exiting freeze mode).

Forget this aspect. As Alexandre pointed out, the nvmem framework
provides an in-kernel API, so reserving space for the "freeze" mode
implementation is doable. But need to use the securam for advanced
stuff (like executing code from there) then the SRAM driver approach is
more future-proof IMO.


-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH] misc: atmel-secumod: Driver for Atmel "security module".
  2016-05-23 12:53           ` Boris Brezillon
@ 2016-05-23 13:59             ` Alexandre Belloni
  0 siblings, 0 replies; 25+ messages in thread
From: Alexandre Belloni @ 2016-05-23 13:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 23/05/2016 at 14:53:15 +0200, Boris Brezillon wrote :
> > Well, I think we're reaching this point right now: I have to implement
> > "freeze" mode (entering a deep sleep mode by cutting all power domains
> > except VDDBU), and in order to do that I need to access BUREGs which
> > are part of the secu-sram you're trying to expose here.
> > 
> > Two comments on the nvmem approach:
> > 1/ first of all it's not really a non-volative memory: if you loose
> > VDDBU you also loose the whole SRAM content.
> > 2/ I need to be able to reserve the BUREG region (at least part of it)
> > for in kernel usage (need to store the SDRAM address I should jump to
> > when exiting freeze mode).
> 
> Forget this aspect. As Alexandre pointed out, the nvmem framework
> provides an in-kernel API, so reserving space for the "freeze" mode
> implementation is doable. But need to use the securam for advanced
> stuff (like executing code from there) then the SRAM driver approach is
> more future-proof IMO.
> 

Yeah, in case we want to use the SRAM to actually run some code, we will
need the sram driver.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2016-05-23 13:59 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-21  3:57 [PATCH] misc: atmel-secumod: Driver for Atmel "security module" David Mosberger-Tang
2016-01-25 11:09 ` Alexandre Belloni
2016-01-25 16:24   ` David Mosberger
2016-01-29  0:13     ` Finn Thain
2016-01-31 11:34       ` Alexandre Belloni
2016-05-23 12:04         ` Boris Brezillon
2016-05-23 12:53           ` Boris Brezillon
2016-05-23 13:59             ` Alexandre Belloni
2016-05-10 19:02 ` [PATCH] drivers: nvmem: atmel-secumod: New driver for Atmel Secumod nvram David Mosberger-Tang
2016-05-12  5:06   ` Finn Thain
2016-05-16 20:17     ` David Mosberger-Tang
2016-05-16 20:17       ` David Mosberger-Tang
2016-05-16 20:17       ` David Mosberger-Tang
2016-05-18 16:42       ` Rob Herring
2016-05-18 16:42         ` Rob Herring
2016-05-18 16:42         ` Rob Herring
2016-05-18 20:46         ` David Mosberger
2016-05-18 20:46           ` David Mosberger
2016-05-18 21:06         ` David Mosberger-Tang
2016-05-18 21:06           ` David Mosberger-Tang
2016-05-18 21:06           ` David Mosberger-Tang
2016-05-20 19:21           ` Rob Herring
2016-05-20 19:21             ` Rob Herring
2016-05-23  8:50           ` Srinivas Kandagatla
2016-05-23  8:50             ` Srinivas Kandagatla

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.