aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nvmem/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/nvmem/core.c')
-rw-r--r--drivers/nvmem/core.c89
1 files changed, 51 insertions, 38 deletions
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 0de3d878c439..965911d9b36a 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -23,12 +23,10 @@
#include <linux/nvmem-consumer.h>
#include <linux/nvmem-provider.h>
#include <linux/of.h>
-#include <linux/regmap.h>
#include <linux/slab.h>
struct nvmem_device {
const char *name;
- struct regmap *regmap;
struct module *owner;
struct device dev;
int stride;
@@ -41,6 +39,9 @@ struct nvmem_device {
int flags;
struct bin_attribute eeprom;
struct device *base_dev;
+ nvmem_reg_read_t reg_read;
+ nvmem_reg_write_t reg_write;
+ void *priv;
};
#define FLAG_COMPAT BIT(0)
@@ -66,6 +67,23 @@ static struct lock_class_key eeprom_lock_key;
#endif
#define to_nvmem_device(d) container_of(d, struct nvmem_device, dev)
+static int nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
+ void *val, size_t bytes)
+{
+ if (nvmem->reg_read)
+ return nvmem->reg_read(nvmem->priv, offset, val, bytes);
+
+ return -EINVAL;
+}
+
+static int nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
+ void *val, size_t bytes)
+{
+ if (nvmem->reg_write)
+ return nvmem->reg_write(nvmem->priv, offset, val, bytes);
+
+ return -EINVAL;
+}
static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr,
@@ -93,9 +111,9 @@ static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj,
count = round_down(count, nvmem->word_size);
- rc = regmap_raw_read(nvmem->regmap, pos, buf, count);
+ rc = nvmem_reg_read(nvmem, pos, buf, count);
- if (IS_ERR_VALUE(rc))
+ if (rc)
return rc;
return count;
@@ -127,9 +145,9 @@ static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj,
count = round_down(count, nvmem->word_size);
- rc = regmap_raw_write(nvmem->regmap, pos, buf, count);
+ rc = nvmem_reg_write(nvmem, pos, buf, count);
- if (IS_ERR_VALUE(rc))
+ if (rc)
return rc;
return count;
@@ -348,7 +366,7 @@ static int nvmem_add_cells(struct nvmem_device *nvmem,
}
rval = nvmem_cell_info_to_nvmem_cell(nvmem, &info[i], cells[i]);
- if (IS_ERR_VALUE(rval)) {
+ if (rval) {
kfree(cells[i]);
goto err;
}
@@ -421,18 +439,11 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
{
struct nvmem_device *nvmem;
struct device_node *np;
- struct regmap *rm;
int rval;
if (!config->dev)
return ERR_PTR(-EINVAL);
- rm = dev_get_regmap(config->dev, NULL);
- if (!rm) {
- dev_err(config->dev, "Regmap not found\n");
- return ERR_PTR(-EINVAL);
- }
-
nvmem = kzalloc(sizeof(*nvmem), GFP_KERNEL);
if (!nvmem)
return ERR_PTR(-ENOMEM);
@@ -444,14 +455,16 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
}
nvmem->id = rval;
- nvmem->regmap = rm;
nvmem->owner = config->owner;
- nvmem->stride = regmap_get_reg_stride(rm);
- nvmem->word_size = regmap_get_val_bytes(rm);
- nvmem->size = regmap_get_max_register(rm) + nvmem->stride;
+ nvmem->stride = config->stride;
+ nvmem->word_size = config->word_size;
+ nvmem->size = config->size;
nvmem->dev.type = &nvmem_provider_type;
nvmem->dev.bus = &nvmem_bus_type;
nvmem->dev.parent = config->dev;
+ 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;
dev_set_name(&nvmem->dev, "%s%d",
@@ -948,9 +961,9 @@ static int __nvmem_cell_read(struct nvmem_device *nvmem,
{
int rc;
- rc = regmap_raw_read(nvmem->regmap, cell->offset, buf, cell->bytes);
+ rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->bytes);
- if (IS_ERR_VALUE(rc))
+ if (rc)
return rc;
/* shift bits in-place */
@@ -977,7 +990,7 @@ void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len)
u8 *buf;
int rc;
- if (!nvmem || !nvmem->regmap)
+ if (!nvmem)
return ERR_PTR(-EINVAL);
buf = kzalloc(cell->bytes, GFP_KERNEL);
@@ -985,7 +998,7 @@ void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len)
return ERR_PTR(-ENOMEM);
rc = __nvmem_cell_read(nvmem, cell, buf, len);
- if (IS_ERR_VALUE(rc)) {
+ if (rc) {
kfree(buf);
return ERR_PTR(rc);
}
@@ -1014,7 +1027,7 @@ static inline void *nvmem_cell_prepare_write_buffer(struct nvmem_cell *cell,
*b <<= bit_offset;
/* setup the first byte with lsb bits from nvmem */
- rc = regmap_raw_read(nvmem->regmap, cell->offset, &v, 1);
+ rc = nvmem_reg_read(nvmem, cell->offset, &v, 1);
*b++ |= GENMASK(bit_offset - 1, 0) & v;
/* setup rest of the byte if any */
@@ -1031,7 +1044,7 @@ static inline void *nvmem_cell_prepare_write_buffer(struct nvmem_cell *cell,
/* if it's not end on byte boundary */
if ((nbits + bit_offset) % BITS_PER_BYTE) {
/* setup the last byte with msb bits from nvmem */
- rc = regmap_raw_read(nvmem->regmap,
+ rc = nvmem_reg_read(nvmem,
cell->offset + cell->bytes - 1, &v, 1);
*p |= GENMASK(7, (nbits + bit_offset) % BITS_PER_BYTE) & v;
@@ -1054,7 +1067,7 @@ int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len)
struct nvmem_device *nvmem = cell->nvmem;
int rc;
- if (!nvmem || !nvmem->regmap || nvmem->read_only ||
+ if (!nvmem || nvmem->read_only ||
(cell->bit_offset == 0 && len != cell->bytes))
return -EINVAL;
@@ -1064,13 +1077,13 @@ int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len)
return PTR_ERR(buf);
}
- rc = regmap_raw_write(nvmem->regmap, cell->offset, buf, cell->bytes);
+ rc = nvmem_reg_write(nvmem, cell->offset, buf, cell->bytes);
/* free the tmp buffer */
if (cell->bit_offset || cell->nbits)
kfree(buf);
- if (IS_ERR_VALUE(rc))
+ if (rc)
return rc;
return len;
@@ -1094,15 +1107,15 @@ ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem,
int rc;
ssize_t len;
- if (!nvmem || !nvmem->regmap)
+ if (!nvmem)
return -EINVAL;
rc = nvmem_cell_info_to_nvmem_cell(nvmem, info, &cell);
- if (IS_ERR_VALUE(rc))
+ if (rc)
return rc;
rc = __nvmem_cell_read(nvmem, &cell, buf, &len);
- if (IS_ERR_VALUE(rc))
+ if (rc)
return rc;
return len;
@@ -1124,11 +1137,11 @@ int nvmem_device_cell_write(struct nvmem_device *nvmem,
struct nvmem_cell cell;
int rc;
- if (!nvmem || !nvmem->regmap)
+ if (!nvmem)
return -EINVAL;
rc = nvmem_cell_info_to_nvmem_cell(nvmem, info, &cell);
- if (IS_ERR_VALUE(rc))
+ if (rc)
return rc;
return nvmem_cell_write(&cell, buf, cell.bytes);
@@ -1152,12 +1165,12 @@ int nvmem_device_read(struct nvmem_device *nvmem,
{
int rc;
- if (!nvmem || !nvmem->regmap)
+ if (!nvmem)
return -EINVAL;
- rc = regmap_raw_read(nvmem->regmap, offset, buf, bytes);
+ rc = nvmem_reg_read(nvmem, offset, buf, bytes);
- if (IS_ERR_VALUE(rc))
+ if (rc)
return rc;
return bytes;
@@ -1180,12 +1193,12 @@ int nvmem_device_write(struct nvmem_device *nvmem,
{
int rc;
- if (!nvmem || !nvmem->regmap)
+ if (!nvmem)
return -EINVAL;
- rc = regmap_raw_write(nvmem->regmap, offset, buf, bytes);
+ rc = nvmem_reg_write(nvmem, offset, buf, bytes);
- if (IS_ERR_VALUE(rc))
+ if (rc)
return rc;