nvmem: add ocotp support for i.MX23 and i.MX28
Subsystems (3)
v5 cover nvmem: add ocotp support for i.MX23 and i.MX28
This patch series brings read-only support for the On-Chip OTP cells in the i.MX23 and i.MX28 processor.
changes in V5:
- rebase to char-misc-next
- add nvmem prefix to module name
- set status in dtsi files
changes in V4:
- rename fsl_ocotp.c to mxs-ocotp.c
- adapt driver to use NVMEM framework V7
- take care of hbus clock
- increase too small timeout
- implement a wait function
- use defines from stmp_device.h
- remove owner init
- more code cleanup
changes in V3:
- drop write support
- take care of i.MX23 which has less registers
- drop unnecessary header file
- move static variables into driver data
- add devicetree probing
- fix missing bank closing in error case
- use kobj from platform device for sysfs
- add SYSFS to Kconfig
- add binding file
- code cleanup
Stefan Wahren (3):
DT: nvmem: add binding for mxs-ocotp
nvmem: add driver for ocotp in i.MX23 and i.MX28
ARM: mxs: enable ocotp for i.MX23 and i.MX28
.../devicetree/bindings/nvmem/mxs-ocotp.txt | 24 ++ arch/arm/boot/dts/imx23.dtsi | 7 +- arch/arm/boot/dts/imx28.dtsi | 7 +- drivers/nvmem/Kconfig | 11 + drivers/nvmem/Makefile | 2 + drivers/nvmem/mxs-ocotp.c | 252 ++++++++++++++++++++ 6 files changed, 299 insertions(+), 4 deletions(-) create mode 100644 Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt create mode 100644 drivers/nvmem/mxs-ocotp.c
Signature · 1 line
1.7.9.5
PATCH v5 1/3 DT: nvmem: add binding for mxs-ocotp
This patch adds the devicetree bindings for the Freescale MXS On Chip OTP driver.
--- .../devicetree/bindings/nvmem/mxs-ocotp.txt | 24 ++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt
Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt new file +24 -0
@@ -0,0 +1,24 @@ +On-Chip OTP Memory for Freescale i.MX23/i.MX28 + +Required properties: +- compatible: + - "fsl,imx23-ocotp" for i.MX23 + - "fsl,imx28-ocotp" for i.MX28 +- #address-cells : Should be 1 +- #size-cells : Should be 1 +- reg : Address and length of OTP controller registers +- clocks : Should contain a reference to the HBus clock + += Data cells = +Are child nodes of mxs-ocotp, bindings of which as described in +bindings/nvmem/nvmem.txt + +Example for i.MX28: + + ocotp: ocotp at 8002c000 { + compatible = "fsl,imx28-ocotp", "fsl,ocotp"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x8002c000 0x2000>; + clocks = <&clks 25>; + };
Signature · 1 line
1.7.9.5
PATCH v5 2/3 nvmem: add driver for ocotp in i.MX23 and i.MX28
In reply to Stefan WahrenThis patch brings read-only support for the On-Chip OTP cells in the i.MX23 and i.MX28 processor. The driver implements the new NVMEM provider API.
--- drivers/nvmem/Kconfig | 11 ++ drivers/nvmem/Makefile | 2 + drivers/nvmem/mxs-ocotp.c | 252 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 265 insertions(+) create mode 100644 drivers/nvmem/mxs-ocotp.c
drivers/nvmem/Kconfig +11 -0
@@ -36,4 +36,15 @@ config NVMEM_SUNXI_SID This driver can also be built as a module. If so, the module will be called nvmem_sunxi_sid. +config NVMEM_MXS_OCOTP + tristate "Freescale MXS On-Chip OTP Memory Support" + depends on ARCH_MXS + help + If you say Y here, you will get readonly access to the + One Time Programmable memory pages that are stored + on the Freescale i.MX23/i.MX28 processor. + + This driver can also be built as a module. If so, the module + will be called nvmem-mxs-ocotp. + endif
drivers/nvmem/Makefile +2 -0
@@ -10,3 +10,5 @@ obj-$(CONFIG_QCOM_QFPROM) += nvmem_qfprom.o nvmem_qfprom-y := qfprom.o obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o nvmem_sunxi_sid-y := sunxi_sid.o +obj-$(CONFIG_NVMEM_MXS_OCOTP) += nvmem-mxs-ocotp.o +nvmem-mxs-ocotp-y := mxs-ocotp.o
drivers/nvmem/mxs-ocotp.c new file +252 -0
252 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH v5 2/3 nvmem: add driver for ocotp in i.MX23 and i.MX28
Hi Stefan,
few nits.
Quoted 17 lines · Stefan Wahren
This patch brings read-only support for the On-Chip OTP cells in the i.MX23 and i.MX28 processor. The driver implements the new NVMEM provider API.
Signed-off-by Stefan Wahren <[email protected]>--- drivers/nvmem/Kconfig | 11 ++ drivers/nvmem/Makefile | 2 + drivers/nvmem/mxs-ocotp.c | 252 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 265 insertions(+)create mode 100644
drivers/nvmem/mxs-ocotp.cdrivers/nvmem/Kconfig +0
-0
drivers/nvmem/Kconfig config NVMEM_SUNXI_SID · line 41
Quoted 6 lines
drivers/nvmem/Kconfig +3
-0@@ -36,4 +36,15 @@ config NVMEM_SUNXI_SID This driver can also be built as a module. If so, the module will be called nvmem_sunxi_sid. +config NVMEM_MXS_OCOTP + tristate "Freescale MXS On-Chip OTP Memory Support" + depends on ARCH_MXS
Adding COMPILE_TEST here would enable the driver to be compile checked on buildrobots.
Quoted 40 lines
drivers/nvmem/Kconfig +8
-0+ help + If you say Y here, you will get readonly access to the + One Time Programmable memory pages that are stored + on the Freescale i.MX23/i.MX28 processor. + + This driver can also be built as a module. If so, the module + will be called nvmem-mxs-ocotp. + endifdrivers/nvmem/Makefile +2
-0@@ -10,3 +10,5 @@ obj-$(CONFIG_QCOM_QFPROM) += nvmem_qfprom.o nvmem_qfprom-y := qfprom.o obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o nvmem_sunxi_sid-y := sunxi_sid.o +obj-$(CONFIG_NVMEM_MXS_OCOTP) += nvmem-mxs-ocotp.o +nvmem-mxs-ocotp-y := mxs-ocotp.odrivers/nvmem/mxs-ocotp.c new file +15
-0@@ -0,0 +1,252 @@ +/* +* Freescale MXS On-Chip OTP driver +* +* Copyright (C) 2015 Stefan Wahren <[email protected]> +* +* Based on the driver from Huang Shijie and Christoph G. Baumann +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
drivers/nvmem/mxs-ocotp.c line 25
Quoted 10 lines
drivers/nvmem/mxs-ocotp.c new file +10
-0+* GNU General Public License for more details. +* +*/ +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/mutex.h>
??
drivers/nvmem/mxs-ocotp.c line 27
Quoted 2 lines
drivers/nvmem/mxs-ocotp.c new file +2
-0+#include <linux/nvmem-provider.h> +#include <linux/of_address.h>
??
Quoted 164 lines
drivers/nvmem/mxs-ocotp.c new file +164
-0+#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/slab.h> +#include <linux/stmp_device.h> + +/* OCOTP registers and bits */ + +#define BM_OCOTP_CTRL_RD_BANK_OPEN BIT(12) +#define BM_OCOTP_CTRL_ERROR BIT(9) +#define BM_OCOTP_CTRL_BUSY BIT(8) + +#define OCOTP_TIMEOUT 10000 +#define OCOTP_DATA_OFFSET 0x20 + +struct mxs_ocotp { +struct clk *clk; +void __iomem *base; +struct nvmem_device *nvmem; +}; + +static int mxs_ocotp_wait (struct mxs_ocotp *otp) +{ +int timeout =OCOTP_TIMEOUT ; +unsigned int status =0 ; + +while (timeout--) { + status =readl (otp->base); + +if (!(status & (BM_OCOTP_CTRL_BUSY |BM_OCOTP_CTRL_ERROR ))) +break ; + +cpu_relax (); + } + +if (status &BM_OCOTP_CTRL_BUSY ) +return -EBUSY ; +else if (status &BM_OCOTP_CTRL_ERROR ) +return -EIO ; + +return 0 ; +} + +static int mxs_ocotp_read (void *context,const void *reg,size_t reg_size, +void *val,size_t val_size) +{ +struct mxs_ocotp *otp = context; +unsigned int offset = *(u32 *)reg; +u32 *buf = val; +int ret =0 ; + +writel (BM_OCOTP_CTRL_ERROR , otp->base +STMP_OFFSET_REG_CLR ); + + ret =mxs_ocotp_wait (otp); +if (ret) +return ret; + +/* open OCOTP banks for read */ +writel (BM_OCOTP_CTRL_RD_BANK_OPEN , otp->base +STMP_OFFSET_REG_SET ); + +/* approximately wait 33 hclk cycles */ +udelay (1 ); + + ret =mxs_ocotp_wait (otp); +if (ret) + goto close_banks; + +while (val_size) { +if ((offset <OCOTP_DATA_OFFSET ) || (offset %16 )) { +/* fill up non-data register */ + *buf =0 ; + }else { + *buf =readl (otp->base + offset); + } + + buf++; + val_size--; + offset += reg_size; + } + +close_banks: +/* close banks for power saving */ +writel (BM_OCOTP_CTRL_RD_BANK_OPEN , otp->base +STMP_OFFSET_REG_CLR ); + +return ret; +} + +static int mxs_ocotp_write (void *context,const void *data,size_t count) +{ +/* We don't want to support writing */ +return 0 ; +} + +static bool mxs_ocotp_writeable_reg (struct device *dev,unsigned int reg) +{ +return false; +} + +static struct nvmem_config ocotp_config = { + .name ="mxs-ocotp" , + .owner =THIS_MODULE , +}; + +static const struct regmap_range imx23_ranges[] = { +regmap_reg_range (OCOTP_DATA_OFFSET ,0x210 ), +}; + +static const struct regmap_access_table imx23_access = { + .yes_ranges = imx23_ranges, + .n_yes_ranges =ARRAY_SIZE (imx23_ranges), +}; + +static const struct regmap_range imx28_ranges[] = { +regmap_reg_range (OCOTP_DATA_OFFSET ,0x290 ), +}; + +static const struct regmap_access_table imx28_access = { + .yes_ranges = imx28_ranges, + .n_yes_ranges =ARRAY_SIZE (imx28_ranges), +}; + +static struct regmap_bus mxs_ocotp_bus = { + .read = mxs_ocotp_read, + .write = mxs_ocotp_write,/* make regmap_init() happy */ + .reg_format_endian_default =REGMAP_ENDIAN_NATIVE , + .val_format_endian_default =REGMAP_ENDIAN_NATIVE , +}; + +static struct regmap_config mxs_ocotp_config = { + .reg_bits =32 , + .val_bits =32 , + .reg_stride =16 , + .writeable_reg = mxs_ocotp_writeable_reg, +}; + +static const struct of_device_id mxs_ocotp_match[] = { + { .compatible ="fsl,imx23-ocotp" , .data = &imx23_access }, + { .compatible ="fsl,imx28-ocotp" , .data = &imx28_access }, + {/* sentinel */ }, +}; +MODULE_DEVICE_TABLE (of, mxs_ocotp_match); + +static int mxs_ocotp_probe (struct platform_device *pdev) +{ +struct device *dev = &pdev->dev; +struct mxs_ocotp *otp; +struct resource *res; +const struct of_device_id *match; +struct regmap *regmap; +const struct regmap_access_table *access; +int ret; + + match =of_match_device (dev->driver->of_match_table, dev); +if (!match || !match->data) +return -EINVAL ; + + otp =devm_kzalloc (dev,sizeof (*otp),GFP_KERNEL ); +if (!otp) +return -ENOMEM ; + + res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); + otp->base =devm_ioremap_resource (dev, res); +if (IS_ERR (otp->base)) +return PTR_ERR (otp->base);
drivers/nvmem/mxs-ocotp.c line 201
Quoted 10 lines
drivers/nvmem/mxs-ocotp.c new file +10
-0+ + otp->clk =devm_clk_get (&pdev->dev,NULL ); +if (IS_ERR (otp->clk)) +return PTR_ERR (otp->clk); + + ret =clk_prepare (otp->clk); +if (ret <0 ) { +dev_err (dev,"failed to prepare clk: %d\n" , ret); +return ret; + }
Clk prepare will not really enable the clock, and I dont see a call to clk_enable() anywhere in this driver.
I dont see the point?
Quoted 41 lines
drivers/nvmem/mxs-ocotp.c new file +41
-0+ + access = match->data; + mxs_ocotp_config.rd_table = access; + mxs_ocotp_config.max_register = access->yes_ranges[0 ].range_max; + + regmap =devm_regmap_init (dev, &mxs_ocotp_bus, otp, &mxs_ocotp_config); +if (IS_ERR (regmap)) { +dev_err (dev,"regmap init failed\n" ); + ret =PTR_ERR (regmap); + goto err_clk; + } + + ocotp_config.dev = dev; + otp->nvmem =nvmem_register (&ocotp_config); +if (IS_ERR (otp->nvmem)) { + ret =PTR_ERR (otp->nvmem); + goto err_clk; + } + +platform_set_drvdata (pdev, otp); + +return 0 ; + +err_clk: +clk_unprepare (otp->clk); + +return ret; +} + +static int mxs_ocotp_remove (struct platform_device *pdev) +{ +struct mxs_ocotp *otp =platform_get_drvdata (pdev); + +clk_unprepare (otp->clk); + +return nvmem_unregister (otp->nvmem); +} + +static struct platform_driver mxs_ocotp_driver = { + .probe = mxs_ocotp_probe, + .remove = mxs_ocotp_remove,
drivers/nvmem/mxs-ocotp.c line 252
Quoted 10 lines
drivers/nvmem/mxs-ocotp.c new file +10
-0+ .driver = { + .name = "mxs-ocotp", + .of_match_table = mxs_ocotp_match, + }, +}; + +module_platform_driver (mxs_ocotp_driver); +MODULE_AUTHOR ("Stefan Wahren <[email protected]>" ); +MODULE_DESCRIPTION ("driver for OCOTP in i.MX23/i.MX28" ); +MODULE_LICENSE ("GPL" );
GPL v2??
Quoted 1 line
PATCH v5 3/3 ARM: mxs: enable ocotp for i.MX23 and i.MX28
In reply to Stefan WahrenThis patch enables On Chip OTP support for i.MX23 and i.MX28 SoCs, but keeps the old compatible string.
--- arch/arm/boot/dts/imx23.dtsi | 7 +++++-- arch/arm/boot/dts/imx28.dtsi | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-)
arch/arm/boot/dts/imx23.dtsi +5 -2
@@ -383,9 +383,12 @@ }; ocotp at 8002c000 { - compatible = "fsl,ocotp"; + compatible = "fsl,imx23-ocotp", "fsl,ocotp"; + #address-cells = <1>; + #size-cells = <1>; reg = <0x8002c000 0x2000>; - status = "disabled"; + clocks = <&clks 15>; + status = "okay"; }; axi-ahb at 8002e000 {
arch/arm/boot/dts/imx28.dtsi +5 -2
@@ -936,9 +936,12 @@ }; ocotp: ocotp at 8002c000 { - compatible = "fsl,ocotp"; + compatible = "fsl,imx28-ocotp", "fsl,ocotp"; + #address-cells = <1>; + #size-cells = <1>; reg = <0x8002c000 0x2000>; - status = "disabled"; + clocks = <&clks 25>; + status = "okay"; }; axi-ahb at 8002e000 {
Signature · 1 line
1.7.9.5
v5 cover nvmem: add ocotp support for i.MX23 and i.MX28
In reply to Stefan WahrenQuoted 35 lines · Stefan Wahren
This patch series brings read-only support for the On-Chip OTP cells in the i.MX23 and i.MX28 processor.
changes in V5:
- rebase to char-misc-next
- add nvmem prefix to module name
- set status in dtsi fileschanges in V4:
- renamefsl_ocotp.ctomxs-ocotp.c
- adapt driver to use NVMEM framework V7
- take care of hbus clock
- increase too small timeout
- implement a wait function
- use defines fromstmp_device.h
- remove owner init
- more code cleanupchanges in V3:
- drop write support
- take care of i.MX23 which has less registers
- drop unnecessary header file
- move static variables into driver data
- add devicetree probing
- fix missing bank closing in error case
- use kobj from platform device for sysfs
- add SYSFS toKconfig
- add binding file
- code cleanupStefan Wahren (3):
DT: nvmem: add binding for mxs-ocotp
nvmem: add driver for ocotp in i.MX23 and i.MX28
ARM: mxs: enable ocotp for i.MX23 and i.MX28
Quoted 9 lines
.../devicetree/bindings/nvmem/mxs-ocotp.txt | 24 ++ arch/arm/boot/dts/imx23.dtsi | 7 +- arch/arm/boot/dts/imx28.dtsi | 7 +- drivers/nvmem/Kconfig | 11 + drivers/nvmem/Makefile | 2 + drivers/nvmem/mxs-ocotp.c | 252 ++++++++++++++++++++ 6 files changed, 299 insertions(+), 4 deletions(-) create mode 100644 Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt create mode 100644 drivers/nvmem/mxs-ocotp.c
Very nice, other than the comments from Srinivas, you can add my
Best regards,
Marek Vasut