diff options
author | Fabrice Gasnier <fabrice.gasnier@st.com> | 2019-04-13 06:32:55 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-04-25 13:43:12 -0400 |
commit | ded1b7fc2cf5a4ae3b902b0e46f592ab724b7828 (patch) | |
tree | c3413efd2242839778f424cecf09700db833e839 | |
parent | 4f4cb173d811ba37aab3048b70583b6c73803d42 (diff) |
nvmem: Add driver for STM32 factory-programmed read only mem
Add a read only nvmem driver for STM32 factory-programmed memory area
(on-chip non-volatile storage).
Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/nvmem/Kconfig | 10 | ||||
-rw-r--r-- | drivers/nvmem/Makefile | 2 | ||||
-rw-r--r-- | drivers/nvmem/stm32-romem.c | 78 |
3 files changed, 90 insertions, 0 deletions
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig index 9e1d83643e9c..a90e9a1ebe55 100644 --- a/drivers/nvmem/Kconfig +++ b/drivers/nvmem/Kconfig | |||
@@ -113,6 +113,16 @@ config NVMEM_BCM_OCOTP | |||
113 | This driver can also be built as a module. If so, the module | 113 | This driver can also be built as a module. If so, the module |
114 | will be called nvmem-bcm-ocotp. | 114 | will be called nvmem-bcm-ocotp. |
115 | 115 | ||
116 | config NVMEM_STM32_ROMEM | ||
117 | tristate "STMicroelectronics STM32 factory-programmed memory support" | ||
118 | depends on ARCH_STM32 || COMPILE_TEST | ||
119 | help | ||
120 | Say y here to enable read-only access for STMicroelectronics STM32 | ||
121 | factory-programmed memory area. | ||
122 | |||
123 | This driver can also be built as a module. If so, the module | ||
124 | will be called nvmem-stm32-romem. | ||
125 | |||
116 | config NVMEM_SUNXI_SID | 126 | config NVMEM_SUNXI_SID |
117 | tristate "Allwinner SoCs SID support" | 127 | tristate "Allwinner SoCs SID support" |
118 | depends on ARCH_SUNXI | 128 | depends on ARCH_SUNXI |
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile index 2ece8ffffdda..4c7ba12a7005 100644 --- a/drivers/nvmem/Makefile +++ b/drivers/nvmem/Makefile | |||
@@ -26,6 +26,8 @@ nvmem_qfprom-y := qfprom.o | |||
26 | obj-$(CONFIG_ROCKCHIP_EFUSE) += nvmem_rockchip_efuse.o | 26 | obj-$(CONFIG_ROCKCHIP_EFUSE) += nvmem_rockchip_efuse.o |
27 | nvmem_rockchip_efuse-y := rockchip-efuse.o | 27 | nvmem_rockchip_efuse-y := rockchip-efuse.o |
28 | obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o | 28 | obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o |
29 | nvmem_stm32_romem-y := stm32-romem.o | ||
30 | obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o | ||
29 | nvmem_sunxi_sid-y := sunxi_sid.o | 31 | nvmem_sunxi_sid-y := sunxi_sid.o |
30 | obj-$(CONFIG_UNIPHIER_EFUSE) += nvmem-uniphier-efuse.o | 32 | obj-$(CONFIG_UNIPHIER_EFUSE) += nvmem-uniphier-efuse.o |
31 | nvmem-uniphier-efuse-y := uniphier-efuse.o | 33 | nvmem-uniphier-efuse-y := uniphier-efuse.o |
diff --git a/drivers/nvmem/stm32-romem.c b/drivers/nvmem/stm32-romem.c new file mode 100644 index 000000000000..07e98b53b391 --- /dev/null +++ b/drivers/nvmem/stm32-romem.c | |||
@@ -0,0 +1,78 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * STM32 Factory-programmed memory read access driver | ||
4 | * | ||
5 | * Copyright (C) 2017, STMicroelectronics - All Rights Reserved | ||
6 | * Author: Fabrice Gasnier <fabrice.gasnier@st.com> for STMicroelectronics. | ||
7 | */ | ||
8 | |||
9 | #include <linux/io.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/nvmem-provider.h> | ||
12 | #include <linux/of_device.h> | ||
13 | |||
14 | struct stm32_romem_priv { | ||
15 | void __iomem *base; | ||
16 | struct nvmem_config cfg; | ||
17 | }; | ||
18 | |||
19 | static int stm32_romem_read(void *context, unsigned int offset, void *buf, | ||
20 | size_t bytes) | ||
21 | { | ||
22 | struct stm32_romem_priv *priv = context; | ||
23 | u8 *buf8 = buf; | ||
24 | int i; | ||
25 | |||
26 | for (i = offset; i < offset + bytes; i++) | ||
27 | *buf8++ = readb_relaxed(priv->base + i); | ||
28 | |||
29 | return 0; | ||
30 | } | ||
31 | |||
32 | static int stm32_romem_probe(struct platform_device *pdev) | ||
33 | { | ||
34 | struct device *dev = &pdev->dev; | ||
35 | struct stm32_romem_priv *priv; | ||
36 | struct resource *res; | ||
37 | |||
38 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
39 | if (!priv) | ||
40 | return -ENOMEM; | ||
41 | |||
42 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
43 | priv->base = devm_ioremap_resource(dev, res); | ||
44 | if (IS_ERR(priv->base)) | ||
45 | return PTR_ERR(priv->base); | ||
46 | |||
47 | priv->cfg.name = "stm32-romem"; | ||
48 | priv->cfg.read_only = true; | ||
49 | priv->cfg.word_size = 1; | ||
50 | priv->cfg.stride = 1; | ||
51 | priv->cfg.size = resource_size(res); | ||
52 | priv->cfg.reg_read = stm32_romem_read; | ||
53 | priv->cfg.dev = dev; | ||
54 | priv->cfg.priv = priv; | ||
55 | priv->cfg.owner = THIS_MODULE; | ||
56 | |||
57 | return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg)); | ||
58 | } | ||
59 | |||
60 | static const struct of_device_id stm32_romem_of_match[] = { | ||
61 | { .compatible = "st,stm32f4-otp", }, | ||
62 | {}, | ||
63 | }; | ||
64 | MODULE_DEVICE_TABLE(of, stm32_romem_of_match); | ||
65 | |||
66 | static struct platform_driver stm32_romem_driver = { | ||
67 | .probe = stm32_romem_probe, | ||
68 | .driver = { | ||
69 | .name = "stm32-romem", | ||
70 | .of_match_table = of_match_ptr(stm32_romem_of_match), | ||
71 | }, | ||
72 | }; | ||
73 | module_platform_driver(stm32_romem_driver); | ||
74 | |||
75 | MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>"); | ||
76 | MODULE_DESCRIPTION("STMicroelectronics STM32 RO-MEM"); | ||
77 | MODULE_ALIAS("platform:nvmem-stm32-romem"); | ||
78 | MODULE_LICENSE("GPL v2"); | ||