summaryrefslogtreecommitdiff
path: root/drivers/nvmem
diff options
context:
space:
mode:
authorPeng Fan <peng.fan@nxp.com>2017-10-27 18:02:45 +0800
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:28:55 +0800
commite336f4f6e686716680eb46778a91eec45630e1c5 (patch)
treecbb4ba70adae1ca5a987119ba5b509a16dc363ba /drivers/nvmem
parentb6eeceeeed62de34f0e53f3e5707b8c28af8e30a (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.c41
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);