Skip to content

Commit 79d0df3

Browse files
Wer-Wolfgregkh
authored andcommitted
eeprom: ee1004: Add nvmem support
Currently the driver does not register a nvmem provider, which means that userspace programs cannot access the ee1004 EEPROM through the standard nvmem sysfs API. Fix this by replacing the custom sysfs attribute with a standard nvmem interface, which also takes care of backwards compatibility. Tested on a Dell Inspiron 3505. Signed-off-by: Armin Wolf <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 55d57ef commit 79d0df3

File tree

2 files changed

+40
-20
lines changed

2 files changed

+40
-20
lines changed

drivers/misc/eeprom/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ config EEPROM_IDT_89HPESX
109109
config EEPROM_EE1004
110110
tristate "SPD EEPROMs on DDR4 memory modules"
111111
depends on I2C && SYSFS
112+
select NVMEM
113+
select NVMEM_SYSFS
112114
help
113115
Enable this driver to get read support to SPD EEPROMs following
114116
the JEDEC EE1004 standard. These are typically found on DDR4

drivers/misc/eeprom/ee1004.c

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/mod_devicetable.h>
1717
#include <linux/module.h>
1818
#include <linux/mutex.h>
19+
#include <linux/nvmem-provider.h>
1920

2021
/*
2122
* DDR4 memory modules use special EEPROMs following the Jedec EE1004
@@ -145,13 +146,17 @@ static ssize_t ee1004_eeprom_read(struct i2c_client *client, char *buf,
145146
return i2c_smbus_read_i2c_block_data_or_emulated(client, offset, count, buf);
146147
}
147148

148-
static ssize_t eeprom_read(struct file *filp, struct kobject *kobj,
149-
struct bin_attribute *bin_attr,
150-
char *buf, loff_t off, size_t count)
149+
static int ee1004_read(void *priv, unsigned int off, void *val, size_t count)
151150
{
152-
struct i2c_client *client = kobj_to_i2c_client(kobj);
153-
size_t requested = count;
154-
int ret = 0;
151+
struct i2c_client *client = priv;
152+
char *buf = val;
153+
int ret;
154+
155+
if (unlikely(!count))
156+
return count;
157+
158+
if (off + count > EE1004_EEPROM_SIZE)
159+
return -EINVAL;
155160

156161
/*
157162
* Read data from chip, protecting against concurrent access to
@@ -161,28 +166,21 @@ static ssize_t eeprom_read(struct file *filp, struct kobject *kobj,
161166

162167
while (count) {
163168
ret = ee1004_eeprom_read(client, buf, off, count);
164-
if (ret < 0)
165-
goto out;
169+
if (ret < 0) {
170+
mutex_unlock(&ee1004_bus_lock);
171+
return ret;
172+
}
166173

167174
buf += ret;
168175
off += ret;
169176
count -= ret;
170177
}
171-
out:
178+
172179
mutex_unlock(&ee1004_bus_lock);
173180

174-
return ret < 0 ? ret : requested;
181+
return 0;
175182
}
176183

177-
static BIN_ATTR_RO(eeprom, EE1004_EEPROM_SIZE);
178-
179-
static struct bin_attribute *ee1004_attrs[] = {
180-
&bin_attr_eeprom,
181-
NULL
182-
};
183-
184-
BIN_ATTRIBUTE_GROUPS(ee1004);
185-
186184
static void ee1004_probe_temp_sensor(struct i2c_client *client)
187185
{
188186
struct i2c_board_info info = { .type = "jc42" };
@@ -220,7 +218,24 @@ static void ee1004_cleanup_bus_data(void *data)
220218

221219
static int ee1004_probe(struct i2c_client *client)
222220
{
221+
struct nvmem_config config = {
222+
.dev = &client->dev,
223+
.name = dev_name(&client->dev),
224+
.id = NVMEM_DEVID_NONE,
225+
.owner = THIS_MODULE,
226+
.type = NVMEM_TYPE_EEPROM,
227+
.read_only = true,
228+
.root_only = false,
229+
.reg_read = ee1004_read,
230+
.size = EE1004_EEPROM_SIZE,
231+
.word_size = 1,
232+
.stride = 1,
233+
.priv = client,
234+
.compat = true,
235+
.base_dev = &client->dev,
236+
};
223237
struct ee1004_bus_data *bd;
238+
struct nvmem_device *ndev;
224239
int err, cnr = 0;
225240

226241
/* Make sure we can operate on this adapter */
@@ -272,6 +287,10 @@ static int ee1004_probe(struct i2c_client *client)
272287

273288
mutex_unlock(&ee1004_bus_lock);
274289

290+
ndev = devm_nvmem_register(&client->dev, &config);
291+
if (IS_ERR(ndev))
292+
return PTR_ERR(ndev);
293+
275294
dev_info(&client->dev,
276295
"%u byte EE1004-compliant SPD EEPROM, read-only\n",
277296
EE1004_EEPROM_SIZE);
@@ -284,7 +303,6 @@ static int ee1004_probe(struct i2c_client *client)
284303
static struct i2c_driver ee1004_driver = {
285304
.driver = {
286305
.name = "ee1004",
287-
.dev_groups = ee1004_groups,
288306
},
289307
.probe = ee1004_probe,
290308
.id_table = ee1004_ids,

0 commit comments

Comments
 (0)