hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/nvmem/core.c
....@@ -1,17 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * nvmem framework core.
34 *
45 * Copyright (C) 2015 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
56 * Copyright (C) 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License version 2 and
9
- * only version 2 as published by the Free Software Foundation.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
157 */
168
179 #include <linux/device.h>
....@@ -23,10 +15,34 @@
2315 #include <linux/module.h>
2416 #include <linux/nvmem-consumer.h>
2517 #include <linux/nvmem-provider.h>
18
+#include <linux/gpio/consumer.h>
2619 #include <linux/of.h>
2720 #include <linux/slab.h>
2821
29
-#include "nvmem.h"
22
+struct nvmem_device {
23
+ struct module *owner;
24
+ struct device dev;
25
+ int stride;
26
+ int word_size;
27
+ int id;
28
+ struct kref refcnt;
29
+ size_t size;
30
+ bool read_only;
31
+ bool root_only;
32
+ int flags;
33
+ enum nvmem_type type;
34
+ struct bin_attribute eeprom;
35
+ struct device *base_dev;
36
+ struct list_head cells;
37
+ nvmem_reg_read_t reg_read;
38
+ nvmem_reg_write_t reg_write;
39
+ struct gpio_desc *wp_gpio;
40
+ void *priv;
41
+};
42
+
43
+#define to_nvmem_device(d) container_of(d, struct nvmem_device, dev)
44
+
45
+#define FLAG_COMPAT BIT(0)
3046
3147 struct nvmem_cell {
3248 const char *name;
....@@ -45,6 +61,11 @@
4561 static DEFINE_MUTEX(nvmem_cell_mutex);
4662 static LIST_HEAD(nvmem_cell_tables);
4763
64
+static DEFINE_MUTEX(nvmem_lookup_mutex);
65
+static LIST_HEAD(nvmem_lookup_list);
66
+
67
+static BLOCKING_NOTIFIER_HEAD(nvmem_notifier);
68
+
4869 static int nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
4970 void *val, size_t bytes)
5071 {
....@@ -57,17 +78,253 @@
5778 static int nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
5879 void *val, size_t bytes)
5980 {
60
- if (nvmem->reg_write)
61
- return nvmem->reg_write(nvmem->priv, offset, val, bytes);
81
+ int ret;
82
+
83
+ if (nvmem->reg_write) {
84
+ gpiod_set_value_cansleep(nvmem->wp_gpio, 0);
85
+ ret = nvmem->reg_write(nvmem->priv, offset, val, bytes);
86
+ gpiod_set_value_cansleep(nvmem->wp_gpio, 1);
87
+ return ret;
88
+ }
6289
6390 return -EINVAL;
6491 }
92
+
93
+#ifdef CONFIG_NVMEM_SYSFS
94
+static const char * const nvmem_type_str[] = {
95
+ [NVMEM_TYPE_UNKNOWN] = "Unknown",
96
+ [NVMEM_TYPE_EEPROM] = "EEPROM",
97
+ [NVMEM_TYPE_OTP] = "OTP",
98
+ [NVMEM_TYPE_BATTERY_BACKED] = "Battery backed",
99
+};
100
+
101
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
102
+static struct lock_class_key eeprom_lock_key;
103
+#endif
104
+
105
+static ssize_t type_show(struct device *dev,
106
+ struct device_attribute *attr, char *buf)
107
+{
108
+ struct nvmem_device *nvmem = to_nvmem_device(dev);
109
+
110
+ return sprintf(buf, "%s\n", nvmem_type_str[nvmem->type]);
111
+}
112
+
113
+static DEVICE_ATTR_RO(type);
114
+
115
+static struct attribute *nvmem_attrs[] = {
116
+ &dev_attr_type.attr,
117
+ NULL,
118
+};
119
+
120
+static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj,
121
+ struct bin_attribute *attr, char *buf,
122
+ loff_t pos, size_t count)
123
+{
124
+ struct device *dev;
125
+ struct nvmem_device *nvmem;
126
+ int rc;
127
+
128
+ if (attr->private)
129
+ dev = attr->private;
130
+ else
131
+ dev = kobj_to_dev(kobj);
132
+ nvmem = to_nvmem_device(dev);
133
+
134
+ /* Stop the user from reading */
135
+ if (pos >= nvmem->size)
136
+ return 0;
137
+
138
+ if (!IS_ALIGNED(pos, nvmem->stride))
139
+ return -EINVAL;
140
+
141
+ if (count < nvmem->word_size)
142
+ return -EINVAL;
143
+
144
+ if (pos + count > nvmem->size)
145
+ count = nvmem->size - pos;
146
+
147
+ count = round_down(count, nvmem->word_size);
148
+
149
+ if (!nvmem->reg_read)
150
+ return -EPERM;
151
+
152
+ rc = nvmem_reg_read(nvmem, pos, buf, count);
153
+
154
+ if (rc)
155
+ return rc;
156
+
157
+ return count;
158
+}
159
+
160
+static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj,
161
+ struct bin_attribute *attr, char *buf,
162
+ loff_t pos, size_t count)
163
+{
164
+ struct device *dev;
165
+ struct nvmem_device *nvmem;
166
+ int rc;
167
+
168
+ if (attr->private)
169
+ dev = attr->private;
170
+ else
171
+ dev = kobj_to_dev(kobj);
172
+ nvmem = to_nvmem_device(dev);
173
+
174
+ /* Stop the user from writing */
175
+ if (pos >= nvmem->size)
176
+ return -EFBIG;
177
+
178
+ if (!IS_ALIGNED(pos, nvmem->stride))
179
+ return -EINVAL;
180
+
181
+ if (count < nvmem->word_size)
182
+ return -EINVAL;
183
+
184
+ if (pos + count > nvmem->size)
185
+ count = nvmem->size - pos;
186
+
187
+ count = round_down(count, nvmem->word_size);
188
+
189
+ if (!nvmem->reg_write)
190
+ return -EPERM;
191
+
192
+ rc = nvmem_reg_write(nvmem, pos, buf, count);
193
+
194
+ if (rc)
195
+ return rc;
196
+
197
+ return count;
198
+}
199
+
200
+static umode_t nvmem_bin_attr_get_umode(struct nvmem_device *nvmem)
201
+{
202
+ umode_t mode = 0400;
203
+
204
+ if (!nvmem->root_only)
205
+ mode |= 0044;
206
+
207
+ if (!nvmem->read_only)
208
+ mode |= 0200;
209
+
210
+ if (!nvmem->reg_write)
211
+ mode &= ~0200;
212
+
213
+ if (!nvmem->reg_read)
214
+ mode &= ~0444;
215
+
216
+ return mode;
217
+}
218
+
219
+static umode_t nvmem_bin_attr_is_visible(struct kobject *kobj,
220
+ struct bin_attribute *attr, int i)
221
+{
222
+ struct device *dev = kobj_to_dev(kobj);
223
+ struct nvmem_device *nvmem = to_nvmem_device(dev);
224
+
225
+ attr->size = nvmem->size;
226
+
227
+ return nvmem_bin_attr_get_umode(nvmem);
228
+}
229
+
230
+/* default read/write permissions */
231
+static struct bin_attribute bin_attr_rw_nvmem = {
232
+ .attr = {
233
+ .name = "nvmem",
234
+ .mode = 0644,
235
+ },
236
+ .read = bin_attr_nvmem_read,
237
+ .write = bin_attr_nvmem_write,
238
+};
239
+
240
+static struct bin_attribute *nvmem_bin_attributes[] = {
241
+ &bin_attr_rw_nvmem,
242
+ NULL,
243
+};
244
+
245
+static const struct attribute_group nvmem_bin_group = {
246
+ .bin_attrs = nvmem_bin_attributes,
247
+ .attrs = nvmem_attrs,
248
+ .is_bin_visible = nvmem_bin_attr_is_visible,
249
+};
250
+
251
+static const struct attribute_group *nvmem_dev_groups[] = {
252
+ &nvmem_bin_group,
253
+ NULL,
254
+};
255
+
256
+static struct bin_attribute bin_attr_nvmem_eeprom_compat = {
257
+ .attr = {
258
+ .name = "eeprom",
259
+ },
260
+ .read = bin_attr_nvmem_read,
261
+ .write = bin_attr_nvmem_write,
262
+};
263
+
264
+/*
265
+ * nvmem_setup_compat() - Create an additional binary entry in
266
+ * drivers sys directory, to be backwards compatible with the older
267
+ * drivers/misc/eeprom drivers.
268
+ */
269
+static int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem,
270
+ const struct nvmem_config *config)
271
+{
272
+ int rval;
273
+
274
+ if (!config->compat)
275
+ return 0;
276
+
277
+ if (!config->base_dev)
278
+ return -EINVAL;
279
+
280
+ nvmem->eeprom = bin_attr_nvmem_eeprom_compat;
281
+ nvmem->eeprom.attr.mode = nvmem_bin_attr_get_umode(nvmem);
282
+ nvmem->eeprom.size = nvmem->size;
283
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
284
+ nvmem->eeprom.attr.key = &eeprom_lock_key;
285
+#endif
286
+ nvmem->eeprom.private = &nvmem->dev;
287
+ nvmem->base_dev = config->base_dev;
288
+
289
+ rval = device_create_bin_file(nvmem->base_dev, &nvmem->eeprom);
290
+ if (rval) {
291
+ dev_err(&nvmem->dev,
292
+ "Failed to create eeprom binary file %d\n", rval);
293
+ return rval;
294
+ }
295
+
296
+ nvmem->flags |= FLAG_COMPAT;
297
+
298
+ return 0;
299
+}
300
+
301
+static void nvmem_sysfs_remove_compat(struct nvmem_device *nvmem,
302
+ const struct nvmem_config *config)
303
+{
304
+ if (config->compat)
305
+ device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
306
+}
307
+
308
+#else /* CONFIG_NVMEM_SYSFS */
309
+
310
+static int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem,
311
+ const struct nvmem_config *config)
312
+{
313
+ return -ENOSYS;
314
+}
315
+static void nvmem_sysfs_remove_compat(struct nvmem_device *nvmem,
316
+ const struct nvmem_config *config)
317
+{
318
+}
319
+
320
+#endif /* CONFIG_NVMEM_SYSFS */
65321
66322 static void nvmem_release(struct device *dev)
67323 {
68324 struct nvmem_device *nvmem = to_nvmem_device(dev);
69325
70
- ida_simple_remove(&nvmem_ida, nvmem->id);
326
+ ida_free(&nvmem_ida, nvmem->id);
327
+ gpiod_put(nvmem->wp_gpio);
71328 kfree(nvmem);
72329 }
73330
....@@ -79,32 +336,14 @@
79336 .name = "nvmem",
80337 };
81338
82
-static int of_nvmem_match(struct device *dev, void *nvmem_np)
83
-{
84
- return dev->of_node == nvmem_np;
85
-}
86
-
87
-static struct nvmem_device *of_nvmem_find(struct device_node *nvmem_np)
88
-{
89
- struct device *d;
90
-
91
- if (!nvmem_np)
92
- return NULL;
93
-
94
- d = bus_find_device(&nvmem_bus_type, NULL, nvmem_np, of_nvmem_match);
95
-
96
- if (!d)
97
- return NULL;
98
-
99
- return to_nvmem_device(d);
100
-}
101
-
102339 static void nvmem_cell_drop(struct nvmem_cell *cell)
103340 {
341
+ blocking_notifier_call_chain(&nvmem_notifier, NVMEM_CELL_REMOVE, cell);
104342 mutex_lock(&nvmem_mutex);
105343 list_del(&cell->node);
106344 mutex_unlock(&nvmem_mutex);
107345 of_node_put(cell->np);
346
+ kfree_const(cell->name);
108347 kfree(cell);
109348 }
110349
....@@ -121,11 +360,12 @@
121360 mutex_lock(&nvmem_mutex);
122361 list_add_tail(&cell->node, &cell->nvmem->cells);
123362 mutex_unlock(&nvmem_mutex);
363
+ blocking_notifier_call_chain(&nvmem_notifier, NVMEM_CELL_ADD, cell);
124364 }
125365
126
-static int nvmem_cell_info_to_nvmem_cell(struct nvmem_device *nvmem,
127
- const struct nvmem_cell_info *info,
128
- struct nvmem_cell *cell)
366
+static int nvmem_cell_info_to_nvmem_cell_nodup(struct nvmem_device *nvmem,
367
+ const struct nvmem_cell_info *info,
368
+ struct nvmem_cell *cell)
129369 {
130370 cell->nvmem = nvmem;
131371 cell->offset = info->offset;
....@@ -142,9 +382,26 @@
142382 if (!IS_ALIGNED(cell->offset, nvmem->stride)) {
143383 dev_err(&nvmem->dev,
144384 "cell %s unaligned to nvmem stride %d\n",
145
- cell->name, nvmem->stride);
385
+ cell->name ?: "<unknown>", nvmem->stride);
146386 return -EINVAL;
147387 }
388
+
389
+ return 0;
390
+}
391
+
392
+static int nvmem_cell_info_to_nvmem_cell(struct nvmem_device *nvmem,
393
+ const struct nvmem_cell_info *info,
394
+ struct nvmem_cell *cell)
395
+{
396
+ int err;
397
+
398
+ err = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, cell);
399
+ if (err)
400
+ return err;
401
+
402
+ cell->name = kstrdup_const(info->name, GFP_KERNEL);
403
+ if (!cell->name)
404
+ return -ENOMEM;
148405
149406 return 0;
150407 }
....@@ -158,7 +415,7 @@
158415 *
159416 * Return: 0 or negative error code on failure.
160417 */
161
-int nvmem_add_cells(struct nvmem_device *nvmem,
418
+static int nvmem_add_cells(struct nvmem_device *nvmem,
162419 const struct nvmem_cell_info *info,
163420 int ncells)
164421 {
....@@ -197,7 +454,32 @@
197454
198455 return rval;
199456 }
200
-EXPORT_SYMBOL_GPL(nvmem_add_cells);
457
+
458
+/**
459
+ * nvmem_register_notifier() - Register a notifier block for nvmem events.
460
+ *
461
+ * @nb: notifier block to be called on nvmem events.
462
+ *
463
+ * Return: 0 on success, negative error number on failure.
464
+ */
465
+int nvmem_register_notifier(struct notifier_block *nb)
466
+{
467
+ return blocking_notifier_chain_register(&nvmem_notifier, nb);
468
+}
469
+EXPORT_SYMBOL_GPL(nvmem_register_notifier);
470
+
471
+/**
472
+ * nvmem_unregister_notifier() - Unregister a notifier block for nvmem events.
473
+ *
474
+ * @nb: notifier block to be unregistered.
475
+ *
476
+ * Return: 0 on success, negative error number on failure.
477
+ */
478
+int nvmem_unregister_notifier(struct notifier_block *nb)
479
+{
480
+ return blocking_notifier_chain_unregister(&nvmem_notifier, nb);
481
+}
482
+EXPORT_SYMBOL_GPL(nvmem_unregister_notifier);
201483
202484 static int nvmem_add_cells_from_table(struct nvmem_device *nvmem)
203485 {
....@@ -236,6 +518,23 @@
236518 return rval;
237519 }
238520
521
+static struct nvmem_cell *
522
+nvmem_find_cell_by_name(struct nvmem_device *nvmem, const char *cell_id)
523
+{
524
+ struct nvmem_cell *iter, *cell = NULL;
525
+
526
+ mutex_lock(&nvmem_mutex);
527
+ list_for_each_entry(iter, &nvmem->cells, node) {
528
+ if (strcmp(cell_id, iter->name) == 0) {
529
+ cell = iter;
530
+ break;
531
+ }
532
+ }
533
+ mutex_unlock(&nvmem_mutex);
534
+
535
+ return cell;
536
+}
537
+
239538 static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
240539 {
241540 struct device_node *parent, *child;
....@@ -248,20 +547,24 @@
248547
249548 for_each_child_of_node(parent, child) {
250549 addr = of_get_property(child, "reg", &len);
251
- if (!addr || (len < 2 * sizeof(u32))) {
550
+ if (!addr)
551
+ continue;
552
+ if (len < 2 * sizeof(u32)) {
252553 dev_err(dev, "nvmem: invalid reg on %pOF\n", child);
554
+ of_node_put(child);
253555 return -EINVAL;
254556 }
255557
256558 cell = kzalloc(sizeof(*cell), GFP_KERNEL);
257
- if (!cell)
559
+ if (!cell) {
560
+ of_node_put(child);
258561 return -ENOMEM;
562
+ }
259563
260564 cell->nvmem = nvmem;
261
- cell->np = of_node_get(child);
262565 cell->offset = be32_to_cpup(addr++);
263566 cell->bytes = be32_to_cpup(addr);
264
- cell->name = child->name;
567
+ cell->name = kasprintf(GFP_KERNEL, "%pOFn", child);
265568
266569 addr = of_get_property(child, "bits", &len);
267570 if (addr && len == (2 * sizeof(u32))) {
....@@ -278,10 +581,13 @@
278581 dev_err(dev, "cell %s unaligned to nvmem stride %d\n",
279582 cell->name, nvmem->stride);
280583 /* Cells already added will be freed later. */
584
+ kfree_const(cell->name);
281585 kfree(cell);
586
+ of_node_put(child);
282587 return -EINVAL;
283588 }
284589
590
+ cell->np = of_node_get(child);
285591 nvmem_cell_add(cell);
286592 }
287593
....@@ -290,7 +596,7 @@
290596
291597 /**
292598 * nvmem_register() - Register a nvmem device for given nvmem_config.
293
- * Also creates an binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
599
+ * Also creates a binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
294600 *
295601 * @config: nvmem device configuration with which nvmem device is created.
296602 *
....@@ -306,12 +612,29 @@
306612 if (!config->dev)
307613 return ERR_PTR(-EINVAL);
308614
615
+ if (!config->reg_read && !config->reg_write)
616
+ return ERR_PTR(-EINVAL);
617
+
309618 nvmem = kzalloc(sizeof(*nvmem), GFP_KERNEL);
310619 if (!nvmem)
311620 return ERR_PTR(-ENOMEM);
312621
313
- rval = ida_simple_get(&nvmem_ida, 0, 0, GFP_KERNEL);
622
+ rval = ida_alloc(&nvmem_ida, GFP_KERNEL);
314623 if (rval < 0) {
624
+ kfree(nvmem);
625
+ return ERR_PTR(rval);
626
+ }
627
+
628
+ nvmem->id = rval;
629
+
630
+ if (config->wp_gpio)
631
+ nvmem->wp_gpio = config->wp_gpio;
632
+ else
633
+ nvmem->wp_gpio = gpiod_get_optional(config->dev, "wp",
634
+ GPIOD_OUT_HIGH);
635
+ if (IS_ERR(nvmem->wp_gpio)) {
636
+ ida_free(&nvmem_ida, nvmem->id);
637
+ rval = PTR_ERR(nvmem->wp_gpio);
315638 kfree(nvmem);
316639 return ERR_PTR(rval);
317640 }
....@@ -319,7 +642,6 @@
319642 kref_init(&nvmem->refcnt);
320643 INIT_LIST_HEAD(&nvmem->cells);
321644
322
- nvmem->id = rval;
323645 nvmem->owner = config->owner;
324646 if (!nvmem->owner && config->dev->driver)
325647 nvmem->owner = config->dev->driver->owner;
....@@ -329,29 +651,44 @@
329651 nvmem->dev.type = &nvmem_provider_type;
330652 nvmem->dev.bus = &nvmem_bus_type;
331653 nvmem->dev.parent = config->dev;
654
+ nvmem->root_only = config->root_only;
332655 nvmem->priv = config->priv;
656
+ nvmem->type = config->type;
333657 nvmem->reg_read = config->reg_read;
334658 nvmem->reg_write = config->reg_write;
335
- nvmem->dev.of_node = config->dev->of_node;
659
+ if (!config->no_of_node)
660
+ nvmem->dev.of_node = config->dev->of_node;
336661
337
- if (config->id == -1 && config->name) {
338
- dev_set_name(&nvmem->dev, "%s", config->name);
339
- } else {
340
- dev_set_name(&nvmem->dev, "%s%d",
662
+ switch (config->id) {
663
+ case NVMEM_DEVID_NONE:
664
+ rval = dev_set_name(&nvmem->dev, "%s", config->name);
665
+ break;
666
+ case NVMEM_DEVID_AUTO:
667
+ rval = dev_set_name(&nvmem->dev, "%s%d", config->name, nvmem->id);
668
+ break;
669
+ default:
670
+ rval = dev_set_name(&nvmem->dev, "%s%d",
341671 config->name ? : "nvmem",
342672 config->name ? config->id : nvmem->id);
673
+ break;
343674 }
344675
345
- nvmem->read_only = device_property_present(config->dev, "read-only") |
346
- config->read_only;
676
+ if (rval) {
677
+ ida_free(&nvmem_ida, nvmem->id);
678
+ kfree(nvmem);
679
+ return ERR_PTR(rval);
680
+ }
347681
348
- nvmem->dev.groups = nvmem_sysfs_get_groups(nvmem, config);
682
+ nvmem->read_only = device_property_present(config->dev, "read-only") ||
683
+ config->read_only || !nvmem->reg_write;
349684
350
- device_initialize(&nvmem->dev);
685
+#ifdef CONFIG_NVMEM_SYSFS
686
+ nvmem->dev.groups = nvmem_dev_groups;
687
+#endif
351688
352689 dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
353690
354
- rval = device_add(&nvmem->dev);
691
+ rval = device_register(&nvmem->dev);
355692 if (rval)
356693 goto err_put_device;
357694
....@@ -364,7 +701,7 @@
364701 if (config->cells) {
365702 rval = nvmem_add_cells(nvmem, config->cells, config->ncells);
366703 if (rval)
367
- goto err_teardown_compat;
704
+ goto err_remove_cells;
368705 }
369706
370707 rval = nvmem_add_cells_from_table(nvmem);
....@@ -375,11 +712,12 @@
375712 if (rval)
376713 goto err_remove_cells;
377714
715
+ blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
716
+
378717 return nvmem;
379718
380719 err_remove_cells:
381720 nvmem_device_remove_all_cells(nvmem);
382
-err_teardown_compat:
383721 if (config->compat)
384722 nvmem_sysfs_remove_compat(nvmem, config);
385723 err_device_del:
....@@ -397,38 +735,35 @@
397735
398736 nvmem = container_of(kref, struct nvmem_device, refcnt);
399737
738
+ blocking_notifier_call_chain(&nvmem_notifier, NVMEM_REMOVE, nvmem);
739
+
400740 if (nvmem->flags & FLAG_COMPAT)
401741 device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
402742
403743 nvmem_device_remove_all_cells(nvmem);
404
- device_del(&nvmem->dev);
405
- put_device(&nvmem->dev);
744
+ device_unregister(&nvmem->dev);
406745 }
407746
408747 /**
409748 * nvmem_unregister() - Unregister previously registered nvmem device
410749 *
411750 * @nvmem: Pointer to previously registered nvmem device.
412
- *
413
- * Return: Will be an negative on error or a zero on success.
414751 */
415
-int nvmem_unregister(struct nvmem_device *nvmem)
752
+void nvmem_unregister(struct nvmem_device *nvmem)
416753 {
417754 kref_put(&nvmem->refcnt, nvmem_device_release);
418
-
419
- return 0;
420755 }
421756 EXPORT_SYMBOL_GPL(nvmem_unregister);
422757
423758 static void devm_nvmem_release(struct device *dev, void *res)
424759 {
425
- WARN_ON(nvmem_unregister(*(struct nvmem_device **)res));
760
+ nvmem_unregister(*(struct nvmem_device **)res);
426761 }
427762
428763 /**
429764 * devm_nvmem_register() - Register a managed nvmem device for given
430765 * nvmem_config.
431
- * Also creates an binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
766
+ * Also creates a binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
432767 *
433768 * @dev: Device that uses the nvmem device.
434769 * @config: nvmem device configuration with which nvmem device is created.
....@@ -472,7 +807,7 @@
472807 * @dev: Device that uses the nvmem device.
473808 * @nvmem: Pointer to previously registered nvmem device.
474809 *
475
- * Return: Will be an negative on error or a zero on success.
810
+ * Return: Will be negative on error or zero on success.
476811 */
477812 int devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem)
478813 {
....@@ -480,18 +815,16 @@
480815 }
481816 EXPORT_SYMBOL(devm_nvmem_unregister);
482817
483
-
484
-static struct nvmem_device *__nvmem_device_get(struct device_node *np,
485
- struct nvmem_cell **cellp,
486
- const char *cell_id)
818
+static struct nvmem_device *__nvmem_device_get(void *data,
819
+ int (*match)(struct device *dev, const void *data))
487820 {
488821 struct nvmem_device *nvmem = NULL;
489
-
490
- if (!np)
491
- return ERR_PTR(-ENOENT);
822
+ struct device *dev;
492823
493824 mutex_lock(&nvmem_mutex);
494
- nvmem = of_nvmem_find(np);
825
+ dev = bus_find_device(&nvmem_bus_type, NULL, data, match);
826
+ if (dev)
827
+ nvmem = to_nvmem_device(dev);
495828 mutex_unlock(&nvmem_mutex);
496829 if (!nvmem)
497830 return ERR_PTR(-EPROBE_DEFER);
....@@ -499,8 +832,9 @@
499832 if (!try_module_get(nvmem->owner)) {
500833 dev_err(&nvmem->dev,
501834 "could not increase module refcount for cell %s\n",
502
- nvmem->name);
835
+ nvmem_dev_name(nvmem));
503836
837
+ put_device(&nvmem->dev);
504838 return ERR_PTR(-EINVAL);
505839 }
506840
....@@ -511,20 +845,9 @@
511845
512846 static void __nvmem_device_put(struct nvmem_device *nvmem)
513847 {
848
+ put_device(&nvmem->dev);
514849 module_put(nvmem->owner);
515850 kref_put(&nvmem->refcnt, nvmem_device_release);
516
-}
517
-
518
-static struct nvmem_device *nvmem_find(const char *name)
519
-{
520
- struct device *d;
521
-
522
- d = bus_find_device_by_name(&nvmem_bus_type, NULL, name);
523
-
524
- if (!d)
525
- return ERR_PTR(-ENOENT);
526
-
527
- return to_nvmem_device(d);
528851 }
529852
530853 #if IS_ENABLED(CONFIG_OF)
....@@ -541,15 +864,19 @@
541864 {
542865
543866 struct device_node *nvmem_np;
544
- int index;
867
+ struct nvmem_device *nvmem;
868
+ int index = 0;
545869
546
- index = of_property_match_string(np, "nvmem-names", id);
870
+ if (id)
871
+ index = of_property_match_string(np, "nvmem-names", id);
547872
548873 nvmem_np = of_parse_phandle(np, "nvmem", index);
549874 if (!nvmem_np)
550
- return ERR_PTR(-EINVAL);
875
+ return ERR_PTR(-ENOENT);
551876
552
- return __nvmem_device_get(nvmem_np, NULL, NULL);
877
+ nvmem = __nvmem_device_get(nvmem_np, device_match_of_node);
878
+ of_node_put(nvmem_np);
879
+ return nvmem;
553880 }
554881 EXPORT_SYMBOL_GPL(of_nvmem_device_get);
555882 #endif
....@@ -575,9 +902,25 @@
575902
576903 }
577904
578
- return nvmem_find(dev_name);
905
+ return __nvmem_device_get((void *)dev_name, device_match_name);
579906 }
580907 EXPORT_SYMBOL_GPL(nvmem_device_get);
908
+
909
+/**
910
+ * nvmem_device_find() - Find nvmem device with matching function
911
+ *
912
+ * @data: Data to pass to match function
913
+ * @match: Callback function to check device
914
+ *
915
+ * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_device
916
+ * on success.
917
+ */
918
+struct nvmem_device *nvmem_device_find(void *data,
919
+ int (*match)(struct device *dev, const void *data))
920
+{
921
+ return __nvmem_device_get(data, match);
922
+}
923
+EXPORT_SYMBOL_GPL(nvmem_device_find);
581924
582925 static int devm_nvmem_device_match(struct device *dev, void *res, void *data)
583926 {
....@@ -653,15 +996,44 @@
653996 }
654997 EXPORT_SYMBOL_GPL(devm_nvmem_device_get);
655998
656
-static struct nvmem_cell *nvmem_cell_get_from_list(const char *cell_id)
999
+static struct nvmem_cell *
1000
+nvmem_cell_get_from_lookup(struct device *dev, const char *con_id)
6571001 {
658
- struct nvmem_cell *cell = NULL;
1002
+ struct nvmem_cell *cell = ERR_PTR(-ENOENT);
1003
+ struct nvmem_cell_lookup *lookup;
6591004 struct nvmem_device *nvmem;
1005
+ const char *dev_id;
6601006
661
- nvmem = __nvmem_device_get(NULL, &cell, cell_id);
662
- if (IS_ERR(nvmem))
663
- return ERR_CAST(nvmem);
1007
+ if (!dev)
1008
+ return ERR_PTR(-EINVAL);
6641009
1010
+ dev_id = dev_name(dev);
1011
+
1012
+ mutex_lock(&nvmem_lookup_mutex);
1013
+
1014
+ list_for_each_entry(lookup, &nvmem_lookup_list, node) {
1015
+ if ((strcmp(lookup->dev_id, dev_id) == 0) &&
1016
+ (strcmp(lookup->con_id, con_id) == 0)) {
1017
+ /* This is the right entry. */
1018
+ nvmem = __nvmem_device_get((void *)lookup->nvmem_name,
1019
+ device_match_name);
1020
+ if (IS_ERR(nvmem)) {
1021
+ /* Provider may not be registered yet. */
1022
+ cell = ERR_CAST(nvmem);
1023
+ break;
1024
+ }
1025
+
1026
+ cell = nvmem_find_cell_by_name(nvmem,
1027
+ lookup->cell_name);
1028
+ if (!cell) {
1029
+ __nvmem_device_put(nvmem);
1030
+ cell = ERR_PTR(-ENOENT);
1031
+ }
1032
+ break;
1033
+ }
1034
+ }
1035
+
1036
+ mutex_unlock(&nvmem_lookup_mutex);
6651037 return cell;
6661038 }
6671039
....@@ -669,12 +1041,14 @@
6691041 static struct nvmem_cell *
6701042 nvmem_find_cell_by_node(struct nvmem_device *nvmem, struct device_node *np)
6711043 {
672
- struct nvmem_cell *cell = NULL;
1044
+ struct nvmem_cell *iter, *cell = NULL;
6731045
6741046 mutex_lock(&nvmem_mutex);
675
- list_for_each_entry(cell, &nvmem->cells, node) {
676
- if (np == cell->np)
1047
+ list_for_each_entry(iter, &nvmem->cells, node) {
1048
+ if (np == iter->np) {
1049
+ cell = iter;
6771050 break;
1051
+ }
6781052 }
6791053 mutex_unlock(&nvmem_mutex);
6801054
....@@ -685,16 +1059,15 @@
6851059 * of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id
6861060 *
6871061 * @np: Device tree node that uses the nvmem cell.
688
- * @name: nvmem cell name from nvmem-cell-names property, or NULL
689
- * for the cell at index 0 (the lone cell with no accompanying
690
- * nvmem-cell-names property).
1062
+ * @id: nvmem cell name from nvmem-cell-names property, or NULL
1063
+ * for the cell at index 0 (the lone cell with no accompanying
1064
+ * nvmem-cell-names property).
6911065 *
6921066 * Return: Will be an ERR_PTR() on error or a valid pointer
6931067 * to a struct nvmem_cell. The nvmem_cell will be freed by the
6941068 * nvmem_cell_put().
6951069 */
696
-struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
697
- const char *name)
1070
+struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, const char *id)
6981071 {
6991072 struct device_node *cell_np, *nvmem_np;
7001073 struct nvmem_device *nvmem;
....@@ -702,18 +1075,18 @@
7021075 int index = 0;
7031076
7041077 /* if cell name exists, find index to the name */
705
- if (name)
706
- index = of_property_match_string(np, "nvmem-cell-names", name);
1078
+ if (id)
1079
+ index = of_property_match_string(np, "nvmem-cell-names", id);
7071080
7081081 cell_np = of_parse_phandle(np, "nvmem-cells", index);
7091082 if (!cell_np)
710
- return ERR_PTR(-EINVAL);
1083
+ return ERR_PTR(-ENOENT);
7111084
7121085 nvmem_np = of_get_next_parent(cell_np);
7131086 if (!nvmem_np)
7141087 return ERR_PTR(-EINVAL);
7151088
716
- nvmem = __nvmem_device_get(nvmem_np, NULL, NULL);
1089
+ nvmem = __nvmem_device_get(nvmem_np, device_match_of_node);
7171090 of_node_put(nvmem_np);
7181091 if (IS_ERR(nvmem))
7191092 return ERR_CAST(nvmem);
....@@ -733,27 +1106,29 @@
7331106 * nvmem_cell_get() - Get nvmem cell of device form a given cell name
7341107 *
7351108 * @dev: Device that requests the nvmem cell.
736
- * @cell_id: nvmem cell name to get.
1109
+ * @id: nvmem cell name to get (this corresponds with the name from the
1110
+ * nvmem-cell-names property for DT systems and with the con_id from
1111
+ * the lookup entry for non-DT systems).
7371112 *
7381113 * Return: Will be an ERR_PTR() on error or a valid pointer
7391114 * to a struct nvmem_cell. The nvmem_cell will be freed by the
7401115 * nvmem_cell_put().
7411116 */
742
-struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *cell_id)
1117
+struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *id)
7431118 {
7441119 struct nvmem_cell *cell;
7451120
7461121 if (dev->of_node) { /* try dt first */
747
- cell = of_nvmem_cell_get(dev->of_node, cell_id);
1122
+ cell = of_nvmem_cell_get(dev->of_node, id);
7481123 if (!IS_ERR(cell) || PTR_ERR(cell) == -EPROBE_DEFER)
7491124 return cell;
7501125 }
7511126
752
- /* NULL cell_id only allowed for device tree; invalid otherwise */
753
- if (!cell_id)
1127
+ /* NULL cell id only allowed for device tree; invalid otherwise */
1128
+ if (!id)
7541129 return ERR_PTR(-EINVAL);
7551130
756
- return nvmem_cell_get_from_list(cell_id);
1131
+ return nvmem_cell_get_from_lookup(dev, id);
7571132 }
7581133 EXPORT_SYMBOL_GPL(nvmem_cell_get);
7591134
....@@ -1010,16 +1385,8 @@
10101385 }
10111386 EXPORT_SYMBOL_GPL(nvmem_cell_write);
10121387
1013
-/**
1014
- * nvmem_cell_read_u32() - Read a cell value as an u32
1015
- *
1016
- * @dev: Device that requests the nvmem cell.
1017
- * @cell_id: Name of nvmem cell to read.
1018
- * @val: pointer to output value.
1019
- *
1020
- * Return: 0 on success or negative errno.
1021
- */
1022
-int nvmem_cell_read_u32(struct device *dev, const char *cell_id, u32 *val)
1388
+static int nvmem_cell_read_common(struct device *dev, const char *cell_id,
1389
+ void *val, size_t count)
10231390 {
10241391 struct nvmem_cell *cell;
10251392 void *buf;
....@@ -1034,18 +1401,77 @@
10341401 nvmem_cell_put(cell);
10351402 return PTR_ERR(buf);
10361403 }
1037
- if (len != sizeof(*val)) {
1404
+ if (len != count) {
10381405 kfree(buf);
10391406 nvmem_cell_put(cell);
10401407 return -EINVAL;
10411408 }
1042
- memcpy(val, buf, sizeof(*val));
1043
-
1409
+ memcpy(val, buf, count);
10441410 kfree(buf);
10451411 nvmem_cell_put(cell);
1412
+
10461413 return 0;
10471414 }
1415
+
1416
+/**
1417
+ * nvmem_cell_read_u8() - Read a cell value as a u8
1418
+ *
1419
+ * @dev: Device that requests the nvmem cell.
1420
+ * @cell_id: Name of nvmem cell to read.
1421
+ * @val: pointer to output value.
1422
+ *
1423
+ * Return: 0 on success or negative errno.
1424
+ */
1425
+int nvmem_cell_read_u8(struct device *dev, const char *cell_id, u8 *val)
1426
+{
1427
+ return nvmem_cell_read_common(dev, cell_id, val, sizeof(*val));
1428
+}
1429
+EXPORT_SYMBOL_GPL(nvmem_cell_read_u8);
1430
+
1431
+/**
1432
+ * nvmem_cell_read_u16() - Read a cell value as a u16
1433
+ *
1434
+ * @dev: Device that requests the nvmem cell.
1435
+ * @cell_id: Name of nvmem cell to read.
1436
+ * @val: pointer to output value.
1437
+ *
1438
+ * Return: 0 on success or negative errno.
1439
+ */
1440
+int nvmem_cell_read_u16(struct device *dev, const char *cell_id, u16 *val)
1441
+{
1442
+ return nvmem_cell_read_common(dev, cell_id, val, sizeof(*val));
1443
+}
1444
+EXPORT_SYMBOL_GPL(nvmem_cell_read_u16);
1445
+
1446
+/**
1447
+ * nvmem_cell_read_u32() - Read a cell value as a u32
1448
+ *
1449
+ * @dev: Device that requests the nvmem cell.
1450
+ * @cell_id: Name of nvmem cell to read.
1451
+ * @val: pointer to output value.
1452
+ *
1453
+ * Return: 0 on success or negative errno.
1454
+ */
1455
+int nvmem_cell_read_u32(struct device *dev, const char *cell_id, u32 *val)
1456
+{
1457
+ return nvmem_cell_read_common(dev, cell_id, val, sizeof(*val));
1458
+}
10481459 EXPORT_SYMBOL_GPL(nvmem_cell_read_u32);
1460
+
1461
+/**
1462
+ * nvmem_cell_read_u64() - Read a cell value as a u64
1463
+ *
1464
+ * @dev: Device that requests the nvmem cell.
1465
+ * @cell_id: Name of nvmem cell to read.
1466
+ * @val: pointer to output value.
1467
+ *
1468
+ * Return: 0 on success or negative errno.
1469
+ */
1470
+int nvmem_cell_read_u64(struct device *dev, const char *cell_id, u64 *val)
1471
+{
1472
+ return nvmem_cell_read_common(dev, cell_id, val, sizeof(*val));
1473
+}
1474
+EXPORT_SYMBOL_GPL(nvmem_cell_read_u64);
10491475
10501476 /**
10511477 * nvmem_device_cell_read() - Read a given nvmem device and cell
....@@ -1067,7 +1493,7 @@
10671493 if (!nvmem)
10681494 return -EINVAL;
10691495
1070
- rc = nvmem_cell_info_to_nvmem_cell(nvmem, info, &cell);
1496
+ rc = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, &cell);
10711497 if (rc)
10721498 return rc;
10731499
....@@ -1087,7 +1513,7 @@
10871513 * @buf: buffer to be written to cell.
10881514 *
10891515 * Return: length of bytes written or negative error code on failure.
1090
- * */
1516
+ */
10911517 int nvmem_device_cell_write(struct nvmem_device *nvmem,
10921518 struct nvmem_cell_info *info, void *buf)
10931519 {
....@@ -1097,7 +1523,7 @@
10971523 if (!nvmem)
10981524 return -EINVAL;
10991525
1100
- rc = nvmem_cell_info_to_nvmem_cell(nvmem, info, &cell);
1526
+ rc = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, &cell);
11011527 if (rc)
11021528 return rc;
11031529
....@@ -1143,7 +1569,7 @@
11431569 * @buf: buffer to be written.
11441570 *
11451571 * Return: length of bytes written or negative error code on failure.
1146
- * */
1572
+ */
11471573 int nvmem_device_write(struct nvmem_device *nvmem,
11481574 unsigned int offset,
11491575 size_t bytes, void *buf)
....@@ -1190,6 +1616,41 @@
11901616 EXPORT_SYMBOL_GPL(nvmem_del_cell_table);
11911617
11921618 /**
1619
+ * nvmem_add_cell_lookups() - register a list of cell lookup entries
1620
+ *
1621
+ * @entries: array of cell lookup entries
1622
+ * @nentries: number of cell lookup entries in the array
1623
+ */
1624
+void nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries)
1625
+{
1626
+ int i;
1627
+
1628
+ mutex_lock(&nvmem_lookup_mutex);
1629
+ for (i = 0; i < nentries; i++)
1630
+ list_add_tail(&entries[i].node, &nvmem_lookup_list);
1631
+ mutex_unlock(&nvmem_lookup_mutex);
1632
+}
1633
+EXPORT_SYMBOL_GPL(nvmem_add_cell_lookups);
1634
+
1635
+/**
1636
+ * nvmem_del_cell_lookups() - remove a list of previously added cell lookup
1637
+ * entries
1638
+ *
1639
+ * @entries: array of cell lookup entries
1640
+ * @nentries: number of cell lookup entries in the array
1641
+ */
1642
+void nvmem_del_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries)
1643
+{
1644
+ int i;
1645
+
1646
+ mutex_lock(&nvmem_lookup_mutex);
1647
+ for (i = 0; i < nentries; i++)
1648
+ list_del(&entries[i].node);
1649
+ mutex_unlock(&nvmem_lookup_mutex);
1650
+}
1651
+EXPORT_SYMBOL_GPL(nvmem_del_cell_lookups);
1652
+
1653
+/**
11931654 * nvmem_dev_name() - Get the name of a given nvmem device.
11941655 *
11951656 * @nvmem: nvmem device.