Commit abc925f7 authored by Alexandre Belloni's avatar Alexandre Belloni

rtc: ds1307: use generic nvmem

Instead of adding a binary sysfs attribute from the driver (which suffers
from a race condition as the attribute appears after the device), use the
core to register an nvmem device.
Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@free-electrons.com>
parent 69b119a6
...@@ -118,7 +118,7 @@ struct ds1307 { ...@@ -118,7 +118,7 @@ struct ds1307 {
u8 offset; /* register's offset */ u8 offset; /* register's offset */
u8 regs[11]; u8 regs[11];
u16 nvram_offset; u16 nvram_offset;
struct bin_attribute *nvram; struct nvmem_config nvmem_cfg;
enum ds_type type; enum ds_type type;
unsigned long flags; unsigned long flags;
#define HAS_NVRAM 0 /* bit 0 == sysfs file active */ #define HAS_NVRAM 0 /* bit 0 == sysfs file active */
...@@ -895,43 +895,24 @@ static const struct rtc_class_ops mcp794xx_rtc_ops = { ...@@ -895,43 +895,24 @@ static const struct rtc_class_ops mcp794xx_rtc_ops = {
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
static ssize_t static int ds1307_nvram_read(void *priv, unsigned int offset, void *val,
ds1307_nvram_read(struct file *filp, struct kobject *kobj, size_t bytes)
struct bin_attribute *attr,
char *buf, loff_t off, size_t count)
{ {
struct ds1307 *ds1307; struct ds1307 *ds1307 = priv;
int result;
ds1307 = dev_get_drvdata(kobj_to_dev(kobj));
result = regmap_bulk_read(ds1307->regmap, ds1307->nvram_offset + off, return regmap_bulk_read(ds1307->regmap, ds1307->nvram_offset + offset,
buf, count); val, bytes);
if (result)
dev_err(ds1307->dev, "%s error %d\n", "nvram read", result);
return result;
} }
static ssize_t static int ds1307_nvram_write(void *priv, unsigned int offset, void *val,
ds1307_nvram_write(struct file *filp, struct kobject *kobj, size_t bytes)
struct bin_attribute *attr,
char *buf, loff_t off, size_t count)
{ {
struct ds1307 *ds1307; struct ds1307 *ds1307 = priv;
int result;
ds1307 = dev_get_drvdata(kobj_to_dev(kobj)); return regmap_bulk_write(ds1307->regmap, ds1307->nvram_offset + offset,
val, bytes);
result = regmap_bulk_write(ds1307->regmap, ds1307->nvram_offset + off,
buf, count);
if (result) {
dev_err(ds1307->dev, "%s error %d\n", "nvram write", result);
return result;
}
return count;
} }
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
static u8 do_trickle_setup_ds1339(struct ds1307 *ds1307, static u8 do_trickle_setup_ds1339(struct ds1307 *ds1307,
...@@ -1704,37 +1685,17 @@ static int ds1307_probe(struct i2c_client *client, ...@@ -1704,37 +1685,17 @@ static int ds1307_probe(struct i2c_client *client,
} }
if (chip->nvram_size) { if (chip->nvram_size) {
ds1307->nvmem_cfg.name = "ds1307_nvram";
ds1307->nvram = devm_kzalloc(ds1307->dev, ds1307->nvmem_cfg.word_size = 1;
sizeof(struct bin_attribute), ds1307->nvmem_cfg.stride = 1;
GFP_KERNEL); ds1307->nvmem_cfg.size = chip->nvram_size;
if (!ds1307->nvram) { ds1307->nvmem_cfg.reg_read = ds1307_nvram_read;
dev_err(ds1307->dev, ds1307->nvmem_cfg.reg_write = ds1307_nvram_write;
"cannot allocate memory for nvram sysfs\n"); ds1307->nvmem_cfg.priv = ds1307;
} else {
ds1307->nvram->attr.name = "nvram";
ds1307->nvram->attr.mode = S_IRUGO | S_IWUSR;
sysfs_bin_attr_init(ds1307->nvram);
ds1307->nvram->read = ds1307_nvram_read;
ds1307->nvram->write = ds1307_nvram_write;
ds1307->nvram->size = chip->nvram_size;
ds1307->nvram_offset = chip->nvram_offset; ds1307->nvram_offset = chip->nvram_offset;
err = sysfs_create_bin_file(&ds1307->dev->kobj, ds1307->rtc->nvmem_config = &ds1307->nvmem_cfg;
ds1307->nvram); ds1307->rtc->nvram_old_abi = true;
if (err) {
dev_err(ds1307->dev,
"unable to create sysfs file: %s\n",
ds1307->nvram->attr.name);
} else {
set_bit(HAS_NVRAM, &ds1307->flags);
dev_info(ds1307->dev, "%zu bytes nvram\n",
ds1307->nvram->size);
}
}
} }
ds1307->rtc->ops = rtc_ops; ds1307->rtc->ops = rtc_ops;
...@@ -1753,11 +1714,6 @@ static int ds1307_probe(struct i2c_client *client, ...@@ -1753,11 +1714,6 @@ static int ds1307_probe(struct i2c_client *client,
static int ds1307_remove(struct i2c_client *client) static int ds1307_remove(struct i2c_client *client)
{ {
struct ds1307 *ds1307 = i2c_get_clientdata(client);
if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags))
sysfs_remove_bin_file(&ds1307->dev->kobj, ds1307->nvram);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment