diff options
author | Peng Fan <peng.fan@nxp.com> | 2017-10-27 18:02:45 +0800 |
---|---|---|
committer | Jason Liu <jason.hui.liu@nxp.com> | 2019-02-12 10:28:55 +0800 |
commit | e336f4f6e686716680eb46778a91eec45630e1c5 (patch) | |
tree | cbb4ba70adae1ca5a987119ba5b509a16dc363ba /drivers/nvmem | |
parent | b6eeceeeed62de34f0e53f3e5707b8c28af8e30a (diff) |
MLK-16716 nvmem: imx-scu-ocotp do not read invalid address
Fix: hexdump: /sys/bus/nvmem/devices/imx-ocotp0/nvmem: Input/output error
Address space [272,543] is invalid address space on 8QXP, reading from SCU
will get SC_ERR_PARAM. So ignore these words when reading fuse.
BuildInfo:
- SCFW 8dcff26, IMX-MKIMAGE ea027c4b, ATF
- U-Boot 2017.03-imx_v2017.03_4.9.51_imx8_beta1+g6dc7b0f
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Diffstat (limited to 'drivers/nvmem')
-rw-r--r-- | drivers/nvmem/imx-scu-ocotp.c | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/drivers/nvmem/imx-scu-ocotp.c b/drivers/nvmem/imx-scu-ocotp.c index 8c622df1ca54..ee2d0bdc81fb 100644 --- a/drivers/nvmem/imx-scu-ocotp.c +++ b/drivers/nvmem/imx-scu-ocotp.c @@ -26,12 +26,32 @@ #include <linux/slab.h> #include <soc/imx8/sc/sci.h> +enum ocotp_devtype { + IMX8QM, + IMX8QXP, +}; + +struct ocotp_devtype_data { + int devtype; + int nregs; +}; + struct ocotp_priv { struct device *dev; - unsigned int nregs; + struct ocotp_devtype_data *data; sc_ipc_t nvmem_ipc; }; +static struct ocotp_devtype_data imx8qm_data = { + .devtype = IMX8QM, + .nregs = 800, +}; + +static struct ocotp_devtype_data imx8qxp_data = { + .devtype = IMX8QXP, + .nregs = 800, +}; + static int imx_scu_ocotp_read(void *context, unsigned int offset, void *val, size_t bytes) { @@ -47,8 +67,8 @@ static int imx_scu_ocotp_read(void *context, unsigned int offset, num_bytes = round_up((offset % 4) + bytes, 4); count = num_bytes >> 2; - if (count > (priv->nregs - index)) - count = priv->nregs - index; + if (count > (priv->data->nregs - index)) + count = priv->data->nregs - index; p = kzalloc(num_bytes, GFP_KERNEL); if (!p) @@ -57,6 +77,14 @@ static int imx_scu_ocotp_read(void *context, unsigned int offset, buf = p; for (i = index; i < (index + count); i++) { + if (priv->data->devtype == IMX8QXP) { + if ((i > 271) && (i < 544)) { + *(u32 *)buf = 0; + buf += 4; + continue; + } + } + sciErr = sc_misc_otp_fuse_read(priv->nvmem_ipc, i, (u32 *)buf); if (sciErr != SC_ERR_NONE) { kfree(p); @@ -83,7 +111,8 @@ static struct nvmem_config imx_scu_ocotp_nvmem_config = { }; static const struct of_device_id imx_scu_ocotp_dt_ids[] = { - { .compatible = "fsl,imx8qm-ocotp", (void *)800 }, + { .compatible = "fsl,imx8qm-ocotp", (void *)&imx8qm_data }, + { .compatible = "fsl,imx8qxp-ocotp", (void *)&imx8qxp_data }, { }, }; MODULE_DEVICE_TABLE(of, imx_scu_ocotp_dt_ids); @@ -115,9 +144,9 @@ static int imx_scu_ocotp_probe(struct platform_device *pdev) }; of_id = of_match_device(imx_scu_ocotp_dt_ids, dev); - priv->nregs = (unsigned long)of_id->data; + priv->data = (struct ocotp_devtype_data *)of_id->data; priv->dev = dev; - imx_scu_ocotp_nvmem_config.size = 4 * priv->nregs; + imx_scu_ocotp_nvmem_config.size = 4 * priv->data->nregs; imx_scu_ocotp_nvmem_config.dev = dev; imx_scu_ocotp_nvmem_config.priv = priv; nvmem = nvmem_register(&imx_scu_ocotp_nvmem_config); |