summaryrefslogtreecommitdiff
path: root/drivers/nvmem
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/nvmem')
-rw-r--r--drivers/nvmem/core.c17
-rw-r--r--drivers/nvmem/rockchip-efuse.c70
-rw-r--r--drivers/nvmem/uniphier-efuse.c10
3 files changed, 79 insertions, 18 deletions
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 5a5cefd12153..35a3dbeea324 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -444,7 +444,6 @@ static int nvmem_setup_compat(struct nvmem_device *nvmem,
struct nvmem_device *nvmem_register(const struct nvmem_config *config)
{
struct nvmem_device *nvmem;
- struct device_node *np;
int rval;
if (!config->dev)
@@ -464,8 +463,8 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
nvmem->owner = config->owner;
if (!nvmem->owner && config->dev->driver)
nvmem->owner = config->dev->driver->owner;
- nvmem->stride = config->stride;
- nvmem->word_size = config->word_size;
+ nvmem->stride = config->stride ?: 1;
+ nvmem->word_size = config->word_size ?: 1;
nvmem->size = config->size;
nvmem->dev.type = &nvmem_provider_type;
nvmem->dev.bus = &nvmem_bus_type;
@@ -473,13 +472,12 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
nvmem->priv = config->priv;
nvmem->reg_read = config->reg_read;
nvmem->reg_write = config->reg_write;
- np = config->dev->of_node;
- nvmem->dev.of_node = np;
+ nvmem->dev.of_node = config->dev->of_node;
dev_set_name(&nvmem->dev, "%s%d",
config->name ? : "nvmem",
config->name ? config->id : nvmem->id);
- nvmem->read_only = of_property_read_bool(np, "read-only") |
+ nvmem->read_only = device_property_present(config->dev, "read-only") |
config->read_only;
if (config->root_only)
@@ -600,16 +598,11 @@ static void __nvmem_device_put(struct nvmem_device *nvmem)
mutex_unlock(&nvmem_mutex);
}
-static int nvmem_match(struct device *dev, void *data)
-{
- return !strcmp(dev_name(dev), data);
-}
-
static struct nvmem_device *nvmem_find(const char *name)
{
struct device *d;
- d = bus_find_device(&nvmem_bus_type, NULL, (void *)name, nvmem_match);
+ d = bus_find_device_by_name(&nvmem_bus_type, NULL, name);
if (!d)
return NULL;
diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c
index 123de77ca5d6..f13a8335f364 100644
--- a/drivers/nvmem/rockchip-efuse.c
+++ b/drivers/nvmem/rockchip-efuse.c
@@ -32,6 +32,14 @@
#define RK3288_STROBE BIT(1)
#define RK3288_CSB BIT(0)
+#define RK3328_SECURE_SIZES 96
+#define RK3328_INT_STATUS 0x0018
+#define RK3328_DOUT 0x0020
+#define RK3328_AUTO_CTRL 0x0024
+#define RK3328_INT_FINISH BIT(0)
+#define RK3328_AUTO_ENB BIT(0)
+#define RK3328_AUTO_RD BIT(1)
+
#define RK3399_A_SHIFT 16
#define RK3399_A_MASK 0x3ff
#define RK3399_NBYTES 4
@@ -92,6 +100,60 @@ static int rockchip_rk3288_efuse_read(void *context, unsigned int offset,
return 0;
}
+static int rockchip_rk3328_efuse_read(void *context, unsigned int offset,
+ void *val, size_t bytes)
+{
+ struct rockchip_efuse_chip *efuse = context;
+ unsigned int addr_start, addr_end, addr_offset, addr_len;
+ u32 out_value, status;
+ u8 *buf;
+ int ret, i = 0;
+
+ ret = clk_prepare_enable(efuse->clk);
+ if (ret < 0) {
+ dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
+ return ret;
+ }
+
+ /* 128 Byte efuse, 96 Byte for secure, 32 Byte for non-secure */
+ offset += RK3328_SECURE_SIZES;
+ addr_start = rounddown(offset, RK3399_NBYTES) / RK3399_NBYTES;
+ addr_end = roundup(offset + bytes, RK3399_NBYTES) / RK3399_NBYTES;
+ addr_offset = offset % RK3399_NBYTES;
+ addr_len = addr_end - addr_start;
+
+ buf = kzalloc(sizeof(*buf) * addr_len * RK3399_NBYTES, GFP_KERNEL);
+ if (!buf) {
+ ret = -ENOMEM;
+ goto nomem;
+ }
+
+ while (addr_len--) {
+ writel(RK3328_AUTO_RD | RK3328_AUTO_ENB |
+ ((addr_start++ & RK3399_A_MASK) << RK3399_A_SHIFT),
+ efuse->base + RK3328_AUTO_CTRL);
+ udelay(4);
+ status = readl(efuse->base + RK3328_INT_STATUS);
+ if (!(status & RK3328_INT_FINISH)) {
+ ret = -EIO;
+ goto err;
+ }
+ out_value = readl(efuse->base + RK3328_DOUT);
+ writel(RK3328_INT_FINISH, efuse->base + RK3328_INT_STATUS);
+
+ memcpy(&buf[i], &out_value, RK3399_NBYTES);
+ i += RK3399_NBYTES;
+ }
+
+ memcpy(val, buf + addr_offset, bytes);
+err:
+ kfree(buf);
+nomem:
+ clk_disable_unprepare(efuse->clk);
+
+ return ret;
+}
+
static int rockchip_rk3399_efuse_read(void *context, unsigned int offset,
void *val, size_t bytes)
{
@@ -181,6 +243,10 @@ static const struct of_device_id rockchip_efuse_match[] = {
.data = (void *)&rockchip_rk3288_efuse_read,
},
{
+ .compatible = "rockchip,rk3328-efuse",
+ .data = (void *)&rockchip_rk3328_efuse_read,
+ },
+ {
.compatible = "rockchip,rk3399-efuse",
.data = (void *)&rockchip_rk3399_efuse_read,
},
@@ -217,7 +283,9 @@ static int rockchip_efuse_probe(struct platform_device *pdev)
return PTR_ERR(efuse->clk);
efuse->dev = &pdev->dev;
- econfig.size = resource_size(res);
+ if (of_property_read_u32(dev->of_node, "rockchip,efuse-size",
+ &econfig.size))
+ econfig.size = resource_size(res);
econfig.reg_read = match->data;
econfig.priv = efuse;
econfig.dev = efuse->dev;
diff --git a/drivers/nvmem/uniphier-efuse.c b/drivers/nvmem/uniphier-efuse.c
index 9d278b4e1dc7..be11880a1358 100644
--- a/drivers/nvmem/uniphier-efuse.c
+++ b/drivers/nvmem/uniphier-efuse.c
@@ -27,11 +27,11 @@ static int uniphier_reg_read(void *context,
unsigned int reg, void *_val, size_t bytes)
{
struct uniphier_efuse_priv *priv = context;
- u32 *val = _val;
+ u8 *val = _val;
int offs;
- for (offs = 0; offs < bytes; offs += sizeof(u32))
- *val++ = readl(priv->base + reg + offs);
+ for (offs = 0; offs < bytes; offs += sizeof(u8))
+ *val++ = readb(priv->base + reg + offs);
return 0;
}
@@ -53,8 +53,8 @@ static int uniphier_efuse_probe(struct platform_device *pdev)
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
- econfig.stride = 4;
- econfig.word_size = 4;
+ econfig.stride = 1;
+ econfig.word_size = 1;
econfig.read_only = true;
econfig.reg_read = uniphier_reg_read;
econfig.size = resource_size(res);