Skip to content

Commit 795ddd1

Browse files
Srinivas-Kandagatlagregkh
authored andcommitted
nvmem: core: remove regmap dependency
nvmem uses regmap_raw_read/write apis to read/write data from providers, regmap raw apis stopped working with recent kernels which removed raw accessors on mmio bus. This resulted in broken nvmem for providers which are based on regmap mmio bus. This issue can be fixed temporarly by moving to other regmap apis, but we might hit same issue in future. Moving to interfaces based on read/write callbacks from providers would be more robust. This patch removes regmap dependency from nvmem and introduces read/write callbacks from the providers. Without this patch nvmem providers like qfprom based on regmap mmio bus would not work. Reported-by: Rajendra Nayak <rjendra@qti.qualcomm.com> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 326071b commit 795ddd1

3 files changed

Lines changed: 50 additions & 28 deletions

File tree

drivers/nvmem/Kconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
menuconfig NVMEM
22
tristate "NVMEM Support"
3-
select REGMAP
43
help
54
Support for NVMEM(Non Volatile Memory) devices like EEPROM, EFUSES...
65

drivers/nvmem/core.c

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,10 @@
2323
#include <linux/nvmem-consumer.h>
2424
#include <linux/nvmem-provider.h>
2525
#include <linux/of.h>
26-
#include <linux/regmap.h>
2726
#include <linux/slab.h>
2827

2928
struct nvmem_device {
3029
const char *name;
31-
struct regmap *regmap;
3230
struct module *owner;
3331
struct device dev;
3432
int stride;
@@ -41,6 +39,9 @@ struct nvmem_device {
4139
int flags;
4240
struct bin_attribute eeprom;
4341
struct device *base_dev;
42+
nvmem_reg_read_t reg_read;
43+
nvmem_reg_write_t reg_write;
44+
void *priv;
4445
};
4546

4647
#define FLAG_COMPAT BIT(0)
@@ -66,6 +67,23 @@ static struct lock_class_key eeprom_lock_key;
6667
#endif
6768

6869
#define to_nvmem_device(d) container_of(d, struct nvmem_device, dev)
70+
static int nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
71+
void *val, size_t bytes)
72+
{
73+
if (nvmem->reg_read)
74+
return nvmem->reg_read(nvmem->priv, offset, val, bytes);
75+
76+
return -EINVAL;
77+
}
78+
79+
static int nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
80+
void *val, size_t bytes)
81+
{
82+
if (nvmem->reg_write)
83+
return nvmem->reg_write(nvmem->priv, offset, val, bytes);
84+
85+
return -EINVAL;
86+
}
6987

7088
static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj,
7189
struct bin_attribute *attr,
@@ -93,7 +111,7 @@ static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj,
93111

94112
count = round_down(count, nvmem->word_size);
95113

96-
rc = regmap_raw_read(nvmem->regmap, pos, buf, count);
114+
rc = nvmem_reg_read(nvmem, pos, buf, count);
97115

98116
if (IS_ERR_VALUE(rc))
99117
return rc;
@@ -127,7 +145,7 @@ static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj,
127145

128146
count = round_down(count, nvmem->word_size);
129147

130-
rc = regmap_raw_write(nvmem->regmap, pos, buf, count);
148+
rc = nvmem_reg_write(nvmem, pos, buf, count);
131149

132150
if (IS_ERR_VALUE(rc))
133151
return rc;
@@ -421,18 +439,11 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
421439
{
422440
struct nvmem_device *nvmem;
423441
struct device_node *np;
424-
struct regmap *rm;
425442
int rval;
426443

427444
if (!config->dev)
428445
return ERR_PTR(-EINVAL);
429446

430-
rm = dev_get_regmap(config->dev, NULL);
431-
if (!rm) {
432-
dev_err(config->dev, "Regmap not found\n");
433-
return ERR_PTR(-EINVAL);
434-
}
435-
436447
nvmem = kzalloc(sizeof(*nvmem), GFP_KERNEL);
437448
if (!nvmem)
438449
return ERR_PTR(-ENOMEM);
@@ -444,14 +455,16 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
444455
}
445456

446457
nvmem->id = rval;
447-
nvmem->regmap = rm;
448458
nvmem->owner = config->owner;
449-
nvmem->stride = regmap_get_reg_stride(rm);
450-
nvmem->word_size = regmap_get_val_bytes(rm);
451-
nvmem->size = regmap_get_max_register(rm) + nvmem->stride;
459+
nvmem->stride = config->stride;
460+
nvmem->word_size = config->word_size;
461+
nvmem->size = config->size;
452462
nvmem->dev.type = &nvmem_provider_type;
453463
nvmem->dev.bus = &nvmem_bus_type;
454464
nvmem->dev.parent = config->dev;
465+
nvmem->priv = config->priv;
466+
nvmem->reg_read = config->reg_read;
467+
nvmem->reg_write = config->reg_write;
455468
np = config->dev->of_node;
456469
nvmem->dev.of_node = np;
457470
dev_set_name(&nvmem->dev, "%s%d",
@@ -948,7 +961,7 @@ static int __nvmem_cell_read(struct nvmem_device *nvmem,
948961
{
949962
int rc;
950963

951-
rc = regmap_raw_read(nvmem->regmap, cell->offset, buf, cell->bytes);
964+
rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->bytes);
952965

953966
if (IS_ERR_VALUE(rc))
954967
return rc;
@@ -977,7 +990,7 @@ void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len)
977990
u8 *buf;
978991
int rc;
979992

980-
if (!nvmem || !nvmem->regmap)
993+
if (!nvmem)
981994
return ERR_PTR(-EINVAL);
982995

983996
buf = kzalloc(cell->bytes, GFP_KERNEL);
@@ -1014,7 +1027,7 @@ static inline void *nvmem_cell_prepare_write_buffer(struct nvmem_cell *cell,
10141027
*b <<= bit_offset;
10151028

10161029
/* setup the first byte with lsb bits from nvmem */
1017-
rc = regmap_raw_read(nvmem->regmap, cell->offset, &v, 1);
1030+
rc = nvmem_reg_read(nvmem, cell->offset, &v, 1);
10181031
*b++ |= GENMASK(bit_offset - 1, 0) & v;
10191032

10201033
/* setup rest of the byte if any */
@@ -1031,7 +1044,7 @@ static inline void *nvmem_cell_prepare_write_buffer(struct nvmem_cell *cell,
10311044
/* if it's not end on byte boundary */
10321045
if ((nbits + bit_offset) % BITS_PER_BYTE) {
10331046
/* setup the last byte with msb bits from nvmem */
1034-
rc = regmap_raw_read(nvmem->regmap,
1047+
rc = nvmem_reg_read(nvmem,
10351048
cell->offset + cell->bytes - 1, &v, 1);
10361049
*p |= GENMASK(7, (nbits + bit_offset) % BITS_PER_BYTE) & v;
10371050

@@ -1054,7 +1067,7 @@ int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len)
10541067
struct nvmem_device *nvmem = cell->nvmem;
10551068
int rc;
10561069

1057-
if (!nvmem || !nvmem->regmap || nvmem->read_only ||
1070+
if (!nvmem || nvmem->read_only ||
10581071
(cell->bit_offset == 0 && len != cell->bytes))
10591072
return -EINVAL;
10601073

@@ -1064,7 +1077,7 @@ int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len)
10641077
return PTR_ERR(buf);
10651078
}
10661079

1067-
rc = regmap_raw_write(nvmem->regmap, cell->offset, buf, cell->bytes);
1080+
rc = nvmem_reg_write(nvmem, cell->offset, buf, cell->bytes);
10681081

10691082
/* free the tmp buffer */
10701083
if (cell->bit_offset || cell->nbits)
@@ -1094,7 +1107,7 @@ ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem,
10941107
int rc;
10951108
ssize_t len;
10961109

1097-
if (!nvmem || !nvmem->regmap)
1110+
if (!nvmem)
10981111
return -EINVAL;
10991112

11001113
rc = nvmem_cell_info_to_nvmem_cell(nvmem, info, &cell);
@@ -1124,7 +1137,7 @@ int nvmem_device_cell_write(struct nvmem_device *nvmem,
11241137
struct nvmem_cell cell;
11251138
int rc;
11261139

1127-
if (!nvmem || !nvmem->regmap)
1140+
if (!nvmem)
11281141
return -EINVAL;
11291142

11301143
rc = nvmem_cell_info_to_nvmem_cell(nvmem, info, &cell);
@@ -1152,10 +1165,10 @@ int nvmem_device_read(struct nvmem_device *nvmem,
11521165
{
11531166
int rc;
11541167

1155-
if (!nvmem || !nvmem->regmap)
1168+
if (!nvmem)
11561169
return -EINVAL;
11571170

1158-
rc = regmap_raw_read(nvmem->regmap, offset, buf, bytes);
1171+
rc = nvmem_reg_read(nvmem, offset, buf, bytes);
11591172

11601173
if (IS_ERR_VALUE(rc))
11611174
return rc;
@@ -1180,10 +1193,10 @@ int nvmem_device_write(struct nvmem_device *nvmem,
11801193
{
11811194
int rc;
11821195

1183-
if (!nvmem || !nvmem->regmap)
1196+
if (!nvmem)
11841197
return -EINVAL;
11851198

1186-
rc = regmap_raw_write(nvmem->regmap, offset, buf, bytes);
1199+
rc = nvmem_reg_write(nvmem, offset, buf, bytes);
11871200

11881201
if (IS_ERR_VALUE(rc))
11891202
return rc;

include/linux/nvmem-provider.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414

1515
struct nvmem_device;
1616
struct nvmem_cell_info;
17+
typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset,
18+
void *val, size_t bytes);
19+
typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
20+
void *val, size_t bytes);
1721

1822
struct nvmem_config {
1923
struct device *dev;
@@ -24,6 +28,12 @@ struct nvmem_config {
2428
int ncells;
2529
bool read_only;
2630
bool root_only;
31+
nvmem_reg_read_t reg_read;
32+
nvmem_reg_write_t reg_write;
33+
int size;
34+
int word_size;
35+
int stride;
36+
void *priv;
2737
/* To be only used by old driver/misc/eeprom drivers */
2838
bool compat;
2939
struct device *base_dev;

0 commit comments

Comments
 (0)