Skip to content

Commit 668ba5e

Browse files
committed
Merge tag 'at24-updates-for-v5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux into i2c/for-5.10
at24 updates for v5.10 - add support for masking sensitive data in VAIO EEPROMs - set the nvmem TYPE to NVMEM_TYPE_EEPROM - add support for the new 'label' property - set the nvmem ID to NVMEM_DEVID_AUTO by default (for backward compatibility) or to NVMEM_DEVID_NONE if label is defined
2 parents 9b65b02 + 61f764c commit 668ba5e

File tree

2 files changed

+67
-7
lines changed

2 files changed

+67
-7
lines changed

Documentation/devicetree/bindings/eeprom/at24.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ properties:
114114
- const: renesas,r1ex24128
115115
- const: atmel,24c128
116116

117+
label:
118+
description: Descriptive name of the EEPROM.
119+
117120
reg:
118121
maxItems: 1
119122

drivers/misc/eeprom/at24.c

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <linux/acpi.h>
1010
#include <linux/bitops.h>
11+
#include <linux/capability.h>
1112
#include <linux/delay.h>
1213
#include <linux/i2c.h>
1314
#include <linux/init.h>
@@ -89,6 +90,7 @@ struct at24_data {
8990

9091
struct nvmem_device *nvmem;
9192
struct regulator *vcc_reg;
93+
void (*read_post)(unsigned int off, char *buf, size_t count);
9294

9395
/*
9496
* Some chips tie up multiple I2C addresses; dummy devices reserve
@@ -121,13 +123,40 @@ MODULE_PARM_DESC(at24_write_timeout, "Time (in ms) to try writes (default 25)");
121123
struct at24_chip_data {
122124
u32 byte_len;
123125
u8 flags;
126+
void (*read_post)(unsigned int off, char *buf, size_t count);
124127
};
125128

126129
#define AT24_CHIP_DATA(_name, _len, _flags) \
127130
static const struct at24_chip_data _name = { \
128131
.byte_len = _len, .flags = _flags, \
129132
}
130133

134+
#define AT24_CHIP_DATA_CB(_name, _len, _flags, _read_post) \
135+
static const struct at24_chip_data _name = { \
136+
.byte_len = _len, .flags = _flags, \
137+
.read_post = _read_post, \
138+
}
139+
140+
static void at24_read_post_vaio(unsigned int off, char *buf, size_t count)
141+
{
142+
int i;
143+
144+
if (capable(CAP_SYS_ADMIN))
145+
return;
146+
147+
/*
148+
* Hide VAIO private settings to regular users:
149+
* - BIOS passwords: bytes 0x00 to 0x0f
150+
* - UUID: bytes 0x10 to 0x1f
151+
* - Serial number: 0xc0 to 0xdf
152+
*/
153+
for (i = 0; i < count; i++) {
154+
if ((off + i <= 0x1f) ||
155+
(off + i >= 0xc0 && off + i <= 0xdf))
156+
buf[i] = 0;
157+
}
158+
}
159+
131160
/* needs 8 addresses as A0-A2 are ignored */
132161
AT24_CHIP_DATA(at24_data_24c00, 128 / 8, AT24_FLAG_TAKE8ADDR);
133162
/* old variants can't be handled with this generic entry! */
@@ -144,6 +173,10 @@ AT24_CHIP_DATA(at24_data_24mac602, 64 / 8,
144173
/* spd is a 24c02 in memory DIMMs */
145174
AT24_CHIP_DATA(at24_data_spd, 2048 / 8,
146175
AT24_FLAG_READONLY | AT24_FLAG_IRUGO);
176+
/* 24c02_vaio is a 24c02 on some Sony laptops */
177+
AT24_CHIP_DATA_CB(at24_data_24c02_vaio, 2048 / 8,
178+
AT24_FLAG_READONLY | AT24_FLAG_IRUGO,
179+
at24_read_post_vaio);
147180
AT24_CHIP_DATA(at24_data_24c04, 4096 / 8, 0);
148181
AT24_CHIP_DATA(at24_data_24cs04, 16,
149182
AT24_FLAG_SERIAL | AT24_FLAG_READONLY);
@@ -177,6 +210,7 @@ static const struct i2c_device_id at24_ids[] = {
177210
{ "24mac402", (kernel_ulong_t)&at24_data_24mac402 },
178211
{ "24mac602", (kernel_ulong_t)&at24_data_24mac602 },
179212
{ "spd", (kernel_ulong_t)&at24_data_spd },
213+
{ "24c02-vaio", (kernel_ulong_t)&at24_data_24c02_vaio },
180214
{ "24c04", (kernel_ulong_t)&at24_data_24c04 },
181215
{ "24cs04", (kernel_ulong_t)&at24_data_24cs04 },
182216
{ "24c08", (kernel_ulong_t)&at24_data_24c08 },
@@ -388,7 +422,7 @@ static int at24_read(void *priv, unsigned int off, void *val, size_t count)
388422
struct at24_data *at24;
389423
struct device *dev;
390424
char *buf = val;
391-
int ret;
425+
int i, ret;
392426

393427
at24 = priv;
394428
dev = at24_base_client_dev(at24);
@@ -411,22 +445,22 @@ static int at24_read(void *priv, unsigned int off, void *val, size_t count)
411445
*/
412446
mutex_lock(&at24->lock);
413447

414-
while (count) {
415-
ret = at24_regmap_read(at24, buf, off, count);
448+
for (i = 0; count; i += ret, count -= ret) {
449+
ret = at24_regmap_read(at24, buf + i, off + i, count);
416450
if (ret < 0) {
417451
mutex_unlock(&at24->lock);
418452
pm_runtime_put(dev);
419453
return ret;
420454
}
421-
buf += ret;
422-
off += ret;
423-
count -= ret;
424455
}
425456

426457
mutex_unlock(&at24->lock);
427458

428459
pm_runtime_put(dev);
429460

461+
if (unlikely(at24->read_post))
462+
at24->read_post(off, buf, i);
463+
430464
return 0;
431465
}
432466

@@ -654,6 +688,7 @@ static int at24_probe(struct i2c_client *client)
654688
at24->byte_len = byte_len;
655689
at24->page_size = page_size;
656690
at24->flags = flags;
691+
at24->read_post = cdata->read_post;
657692
at24->num_addresses = num_addresses;
658693
at24->offset_adj = at24_get_offset_adj(flags, byte_len);
659694
at24->client[0].client = client;
@@ -678,8 +713,30 @@ static int at24_probe(struct i2c_client *client)
678713
return err;
679714
}
680715

681-
nvmem_config.name = dev_name(dev);
716+
/*
717+
* If the 'label' property is not present for the AT24 EEPROM,
718+
* then nvmem_config.id is initialised to NVMEM_DEVID_AUTO,
719+
* and this will append the 'devid' to the name of the NVMEM
720+
* device. This is purely legacy and the AT24 driver has always
721+
* defaulted to this. However, if the 'label' property is
722+
* present then this means that the name is specified by the
723+
* firmware and this name should be used verbatim and so it is
724+
* not necessary to append the 'devid'.
725+
*/
726+
if (device_property_present(dev, "label")) {
727+
nvmem_config.id = NVMEM_DEVID_NONE;
728+
err = device_property_read_string(dev, "label",
729+
&nvmem_config.name);
730+
if (err)
731+
return err;
732+
} else {
733+
nvmem_config.id = NVMEM_DEVID_AUTO;
734+
nvmem_config.name = dev_name(dev);
735+
}
736+
737+
nvmem_config.type = NVMEM_TYPE_EEPROM;
682738
nvmem_config.dev = dev;
739+
nvmem_config.id = NVMEM_DEVID_AUTO;
683740
nvmem_config.read_only = !writable;
684741
nvmem_config.root_only = !(flags & AT24_FLAG_IRUGO);
685742
nvmem_config.owner = THIS_MODULE;

0 commit comments

Comments
 (0)