diff options
Diffstat (limited to 'drivers/w1')
-rw-r--r-- | drivers/w1/slaves/w1_ds2408.c | 174 | ||||
-rw-r--r-- | drivers/w1/slaves/w1_ds2413.c | 72 | ||||
-rw-r--r-- | drivers/w1/slaves/w1_ds2423.c | 27 | ||||
-rw-r--r-- | drivers/w1/slaves/w1_ds2431.c | 43 | ||||
-rw-r--r-- | drivers/w1/slaves/w1_ds2433.c | 47 | ||||
-rw-r--r-- | drivers/w1/slaves/w1_ds2760.c | 35 | ||||
-rw-r--r-- | drivers/w1/slaves/w1_ds2780.c | 36 | ||||
-rw-r--r-- | drivers/w1/slaves/w1_ds2781.c | 36 | ||||
-rw-r--r-- | drivers/w1/slaves/w1_ds28e04.c | 112 | ||||
-rw-r--r-- | drivers/w1/slaves/w1_therm.c | 24 | ||||
-rw-r--r-- | drivers/w1/w1.c | 164 | ||||
-rw-r--r-- | drivers/w1/w1_family.h | 1 |
12 files changed, 326 insertions, 445 deletions
diff --git a/drivers/w1/slaves/w1_ds2408.c b/drivers/w1/slaves/w1_ds2408.c index cb8a8e5d9573..7dfa0e11688a 100644 --- a/drivers/w1/slaves/w1_ds2408.c +++ b/drivers/w1/slaves/w1_ds2408.c @@ -72,10 +72,9 @@ static int _read_reg(struct w1_slave *sl, u8 address, unsigned char* buf) return 1; } -static ssize_t w1_f29_read_state( - struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t state_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, + size_t count) { dev_dbg(&kobj_to_w1_slave(kobj)->dev, "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", @@ -85,10 +84,9 @@ static ssize_t w1_f29_read_state( return _read_reg(kobj_to_w1_slave(kobj), W1_F29_REG_LOGIG_STATE, buf); } -static ssize_t w1_f29_read_output( - struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t output_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { dev_dbg(&kobj_to_w1_slave(kobj)->dev, "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", @@ -99,10 +97,9 @@ static ssize_t w1_f29_read_output( W1_F29_REG_OUTPUT_LATCH_STATE, buf); } -static ssize_t w1_f29_read_activity( - struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t activity_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { dev_dbg(&kobj_to_w1_slave(kobj)->dev, "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", @@ -113,10 +110,9 @@ static ssize_t w1_f29_read_activity( W1_F29_REG_ACTIVITY_LATCH_STATE, buf); } -static ssize_t w1_f29_read_cond_search_mask( - struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t cond_search_mask_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { dev_dbg(&kobj_to_w1_slave(kobj)->dev, "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", @@ -127,10 +123,10 @@ static ssize_t w1_f29_read_cond_search_mask( W1_F29_REG_COND_SEARCH_SELECT_MASK, buf); } -static ssize_t w1_f29_read_cond_search_polarity( - struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t cond_search_polarity_read(struct file *filp, + struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) { if (count != 1 || off != 0) return -EFAULT; @@ -138,10 +134,9 @@ static ssize_t w1_f29_read_cond_search_polarity( W1_F29_REG_COND_SEARCH_POL_SELECT, buf); } -static ssize_t w1_f29_read_status_control( - struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t status_control_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { if (count != 1 || off != 0) return -EFAULT; @@ -149,13 +144,9 @@ static ssize_t w1_f29_read_status_control( W1_F29_REG_CONTROL_AND_STATUS, buf); } - - - -static ssize_t w1_f29_write_output( - struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t output_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); u8 w1_buf[3]; @@ -224,10 +215,9 @@ error: /** * Writing to the activity file resets the activity latches. */ -static ssize_t w1_f29_write_activity( - struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t activity_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); unsigned int retries = W1_F29_RETRIES; @@ -255,13 +245,9 @@ error: return -EIO; } -static ssize_t w1_f29_write_status_control( - struct file *filp, - struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, - loff_t off, - size_t count) +static ssize_t status_control_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); u8 w1_buf[4]; @@ -330,91 +316,35 @@ out: return res; } -static struct bin_attribute w1_f29_sysfs_bin_files[] = { - { - .attr = { - .name = "state", - .mode = S_IRUGO, - }, - .size = 1, - .read = w1_f29_read_state, - }, - { - .attr = { - .name = "output", - .mode = S_IRUGO | S_IWUSR | S_IWGRP, - }, - .size = 1, - .read = w1_f29_read_output, - .write = w1_f29_write_output, - }, - { - .attr = { - .name = "activity", - .mode = S_IRUGO, - }, - .size = 1, - .read = w1_f29_read_activity, - .write = w1_f29_write_activity, - }, - { - .attr = { - .name = "cond_search_mask", - .mode = S_IRUGO, - }, - .size = 1, - .read = w1_f29_read_cond_search_mask, - }, - { - .attr = { - .name = "cond_search_polarity", - .mode = S_IRUGO, - }, - .size = 1, - .read = w1_f29_read_cond_search_polarity, - }, - { - .attr = { - .name = "status_control", - .mode = S_IRUGO | S_IWUSR | S_IWGRP, - }, - .size = 1, - .read = w1_f29_read_status_control, - .write = w1_f29_write_status_control, - } +static BIN_ATTR_RO(state, 1); +static BIN_ATTR_RW(output, 1); +static BIN_ATTR_RW(activity, 1); +static BIN_ATTR_RO(cond_search_mask, 1); +static BIN_ATTR_RO(cond_search_polarity, 1); +static BIN_ATTR_RW(status_control, 1); + +static struct bin_attribute *w1_f29_bin_attrs[] = { + &bin_attr_state, + &bin_attr_output, + &bin_attr_activity, + &bin_attr_cond_search_mask, + &bin_attr_cond_search_polarity, + &bin_attr_status_control, + NULL, }; -static int w1_f29_add_slave(struct w1_slave *sl) -{ - int err = 0; - int i; - - err = w1_f29_disable_test_mode(sl); - if (err) - return err; - - for (i = 0; i < ARRAY_SIZE(w1_f29_sysfs_bin_files) && !err; ++i) - err = sysfs_create_bin_file( - &sl->dev.kobj, - &(w1_f29_sysfs_bin_files[i])); - if (err) - while (--i >= 0) - sysfs_remove_bin_file(&sl->dev.kobj, - &(w1_f29_sysfs_bin_files[i])); - return err; -} +static const struct attribute_group w1_f29_group = { + .bin_attrs = w1_f29_bin_attrs, +}; -static void w1_f29_remove_slave(struct w1_slave *sl) -{ - int i; - for (i = ARRAY_SIZE(w1_f29_sysfs_bin_files) - 1; i >= 0; --i) - sysfs_remove_bin_file(&sl->dev.kobj, - &(w1_f29_sysfs_bin_files[i])); -} +static const struct attribute_group *w1_f29_groups[] = { + &w1_f29_group, + NULL, +}; static struct w1_family_ops w1_f29_fops = { - .add_slave = w1_f29_add_slave, - .remove_slave = w1_f29_remove_slave, + .add_slave = w1_f29_disable_test_mode, + .groups = w1_f29_groups, }; static struct w1_family w1_family_29 = { diff --git a/drivers/w1/slaves/w1_ds2413.c b/drivers/w1/slaves/w1_ds2413.c index 85937773a96a..ee28fc1ff390 100644 --- a/drivers/w1/slaves/w1_ds2413.c +++ b/drivers/w1/slaves/w1_ds2413.c @@ -30,10 +30,9 @@ MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2413)); #define W1_F3A_FUNC_PIO_ACCESS_WRITE 0x5A #define W1_F3A_SUCCESS_CONFIRM_BYTE 0xAA -static ssize_t w1_f3a_read_state( - struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t state_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, + size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); dev_dbg(&sl->dev, @@ -66,10 +65,11 @@ static ssize_t w1_f3a_read_state( return 1; } -static ssize_t w1_f3a_write_output( - struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static BIN_ATTR_RO(state, 1); + +static ssize_t output_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); u8 w1_buf[3]; @@ -110,53 +110,25 @@ error: return -EIO; } -#define NB_SYSFS_BIN_FILES 2 -static struct bin_attribute w1_f3a_sysfs_bin_files[NB_SYSFS_BIN_FILES] = { - { - .attr = { - .name = "state", - .mode = S_IRUGO, - }, - .size = 1, - .read = w1_f3a_read_state, - }, - { - .attr = { - .name = "output", - .mode = S_IRUGO | S_IWUSR | S_IWGRP, - }, - .size = 1, - .write = w1_f3a_write_output, - } +static BIN_ATTR(output, S_IRUGO | S_IWUSR | S_IWGRP, NULL, output_write, 1); + +static struct bin_attribute *w1_f3a_bin_attrs[] = { + &bin_attr_state, + &bin_attr_output, + NULL, }; -static int w1_f3a_add_slave(struct w1_slave *sl) -{ - int err = 0; - int i; - - for (i = 0; i < NB_SYSFS_BIN_FILES && !err; ++i) - err = sysfs_create_bin_file( - &sl->dev.kobj, - &(w1_f3a_sysfs_bin_files[i])); - if (err) - while (--i >= 0) - sysfs_remove_bin_file(&sl->dev.kobj, - &(w1_f3a_sysfs_bin_files[i])); - return err; -} +static const struct attribute_group w1_f3a_group = { + .bin_attrs = w1_f3a_bin_attrs, +}; -static void w1_f3a_remove_slave(struct w1_slave *sl) -{ - int i; - for (i = NB_SYSFS_BIN_FILES - 1; i >= 0; --i) - sysfs_remove_bin_file(&sl->dev.kobj, - &(w1_f3a_sysfs_bin_files[i])); -} +static const struct attribute_group *w1_f3a_groups[] = { + &w1_f3a_group, + NULL, +}; static struct w1_family_ops w1_f3a_fops = { - .add_slave = w1_f3a_add_slave, - .remove_slave = w1_f3a_remove_slave, + .groups = w1_f3a_groups, }; static struct w1_family w1_family_3a = { diff --git a/drivers/w1/slaves/w1_ds2423.c b/drivers/w1/slaves/w1_ds2423.c index 7f86aec74088..7e41b7d91fb5 100644 --- a/drivers/w1/slaves/w1_ds2423.c +++ b/drivers/w1/slaves/w1_ds2423.c @@ -40,14 +40,8 @@ #define COUNTER_COUNT 4 #define READ_BYTE_COUNT 42 -static ssize_t w1_counter_read(struct device *device, - struct device_attribute *attr, char *buf); - -static struct device_attribute w1_counter_attr = - __ATTR(w1_slave, S_IRUGO, w1_counter_read, NULL); - -static ssize_t w1_counter_read(struct device *device, - struct device_attribute *attr, char *out_buf) +static ssize_t w1_slave_show(struct device *device, + struct device_attribute *attr, char *out_buf) { struct w1_slave *sl = dev_to_w1_slave(device); struct w1_master *dev = sl->master; @@ -128,19 +122,16 @@ static ssize_t w1_counter_read(struct device *device, return PAGE_SIZE - c; } -static int w1_f1d_add_slave(struct w1_slave *sl) -{ - return device_create_file(&sl->dev, &w1_counter_attr); -} +static DEVICE_ATTR_RO(w1_slave); -static void w1_f1d_remove_slave(struct w1_slave *sl) -{ - device_remove_file(&sl->dev, &w1_counter_attr); -} +static struct attribute *w1_f1d_attrs[] = { + &dev_attr_w1_slave.attr, + NULL, +}; +ATTRIBUTE_GROUPS(w1_f1d); static struct w1_family_ops w1_f1d_fops = { - .add_slave = w1_f1d_add_slave, - .remove_slave = w1_f1d_remove_slave, + .groups = w1_f1d_groups, }; static struct w1_family w1_family_1d = { diff --git a/drivers/w1/slaves/w1_ds2431.c b/drivers/w1/slaves/w1_ds2431.c index cef8605e43ec..9c4ff9d28adc 100644 --- a/drivers/w1/slaves/w1_ds2431.c +++ b/drivers/w1/slaves/w1_ds2431.c @@ -96,9 +96,9 @@ static int w1_f2d_readblock(struct w1_slave *sl, int off, int count, char *buf) return -1; } -static ssize_t w1_f2d_read_bin(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); int todo = count; @@ -202,9 +202,9 @@ retry: return 0; } -static ssize_t w1_f2d_write_bin(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t eeprom_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); int addr, len; @@ -264,29 +264,24 @@ out_up: return count; } -static struct bin_attribute w1_f2d_bin_attr = { - .attr = { - .name = "eeprom", - .mode = S_IRUGO | S_IWUSR, - }, - .size = W1_F2D_EEPROM_SIZE, - .read = w1_f2d_read_bin, - .write = w1_f2d_write_bin, +static BIN_ATTR_RW(eeprom, W1_F2D_EEPROM_SIZE); + +static struct bin_attribute *w1_f2d_bin_attrs[] = { + &bin_attr_eeprom, + NULL, }; -static int w1_f2d_add_slave(struct w1_slave *sl) -{ - return sysfs_create_bin_file(&sl->dev.kobj, &w1_f2d_bin_attr); -} +static const struct attribute_group w1_f2d_group = { + .bin_attrs = w1_f2d_bin_attrs, +}; -static void w1_f2d_remove_slave(struct w1_slave *sl) -{ - sysfs_remove_bin_file(&sl->dev.kobj, &w1_f2d_bin_attr); -} +static const struct attribute_group *w1_f2d_groups[] = { + &w1_f2d_group, + NULL, +}; static struct w1_family_ops w1_f2d_fops = { - .add_slave = w1_f2d_add_slave, - .remove_slave = w1_f2d_remove_slave, + .groups = w1_f2d_groups, }; static struct w1_family w1_family_2d = { diff --git a/drivers/w1/slaves/w1_ds2433.c b/drivers/w1/slaves/w1_ds2433.c index 10cc1b6176e6..72319a968a9e 100644 --- a/drivers/w1/slaves/w1_ds2433.c +++ b/drivers/w1/slaves/w1_ds2433.c @@ -93,9 +93,9 @@ static int w1_f23_refresh_block(struct w1_slave *sl, struct w1_f23_data *data, } #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ -static ssize_t w1_f23_read_bin(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); #ifdef CONFIG_W1_SLAVE_DS2433_CRC @@ -207,9 +207,9 @@ static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data) return 0; } -static ssize_t w1_f23_write_bin(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t eeprom_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); int addr, len, idx; @@ -257,19 +257,24 @@ out_up: return count; } -static struct bin_attribute w1_f23_bin_attr = { - .attr = { - .name = "eeprom", - .mode = S_IRUGO | S_IWUSR, - }, - .size = W1_EEPROM_SIZE, - .read = w1_f23_read_bin, - .write = w1_f23_write_bin, +static BIN_ATTR_RW(eeprom, W1_EEPROM_SIZE); + +static struct bin_attribute *w1_f23_bin_attributes[] = { + &bin_attr_eeprom, + NULL, +}; + +static const struct attribute_group w1_f23_group = { + .bin_attrs = w1_f23_bin_attributes, +}; + +static const struct attribute_group *w1_f23_groups[] = { + &w1_f23_group, + NULL, }; static int w1_f23_add_slave(struct w1_slave *sl) { - int err; #ifdef CONFIG_W1_SLAVE_DS2433_CRC struct w1_f23_data *data; @@ -279,15 +284,7 @@ static int w1_f23_add_slave(struct w1_slave *sl) sl->family_data = data; #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ - - err = sysfs_create_bin_file(&sl->dev.kobj, &w1_f23_bin_attr); - -#ifdef CONFIG_W1_SLAVE_DS2433_CRC - if (err) - kfree(data); -#endif /* CONFIG_W1_SLAVE_DS2433_CRC */ - - return err; + return 0; } static void w1_f23_remove_slave(struct w1_slave *sl) @@ -296,12 +293,12 @@ static void w1_f23_remove_slave(struct w1_slave *sl) kfree(sl->family_data); sl->family_data = NULL; #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ - sysfs_remove_bin_file(&sl->dev.kobj, &w1_f23_bin_attr); } static struct w1_family_ops w1_f23_fops = { .add_slave = w1_f23_add_slave, .remove_slave = w1_f23_remove_slave, + .groups = w1_f23_groups, }; static struct w1_family w1_family_23 = { diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c index 93719d25d849..65f90dccd60e 100644 --- a/drivers/w1/slaves/w1_ds2760.c +++ b/drivers/w1/slaves/w1_ds2760.c @@ -97,21 +97,28 @@ int w1_ds2760_recall_eeprom(struct device *dev, int addr) return w1_ds2760_eeprom_cmd(dev, addr, W1_DS2760_RECALL_DATA); } -static ssize_t w1_ds2760_read_bin(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); return w1_ds2760_read(dev, buf, off, count); } -static struct bin_attribute w1_ds2760_bin_attr = { - .attr = { - .name = "w1_slave", - .mode = S_IRUGO, - }, - .size = DS2760_DATA_SIZE, - .read = w1_ds2760_read_bin, +static BIN_ATTR_RO(w1_slave, DS2760_DATA_SIZE); + +static struct bin_attribute *w1_ds2760_bin_attrs[] = { + &bin_attr_w1_slave, + NULL, +}; + +static const struct attribute_group w1_ds2760_group = { + .bin_attrs = w1_ds2760_bin_attrs, +}; + +static const struct attribute_group *w1_ds2760_groups[] = { + &w1_ds2760_group, + NULL, }; static DEFINE_IDA(bat_ida); @@ -139,16 +146,10 @@ static int w1_ds2760_add_slave(struct w1_slave *sl) if (ret) goto pdev_add_failed; - ret = sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr); - if (ret) - goto bin_attr_failed; - dev_set_drvdata(&sl->dev, pdev); goto success; -bin_attr_failed: - platform_device_del(pdev); pdev_add_failed: platform_device_put(pdev); pdev_alloc_failed: @@ -165,12 +166,12 @@ static void w1_ds2760_remove_slave(struct w1_slave *sl) platform_device_unregister(pdev); ida_simple_remove(&bat_ida, id); - sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr); } static struct w1_family_ops w1_ds2760_fops = { .add_slave = w1_ds2760_add_slave, .remove_slave = w1_ds2760_remove_slave, + .groups = w1_ds2760_groups, }; static struct w1_family w1_ds2760_family = { diff --git a/drivers/w1/slaves/w1_ds2780.c b/drivers/w1/slaves/w1_ds2780.c index 0cd7a27b5d6b..50e85f7929d4 100644 --- a/drivers/w1/slaves/w1_ds2780.c +++ b/drivers/w1/slaves/w1_ds2780.c @@ -89,22 +89,28 @@ int w1_ds2780_eeprom_cmd(struct device *dev, int addr, int cmd) } EXPORT_SYMBOL(w1_ds2780_eeprom_cmd); -static ssize_t w1_ds2780_read_bin(struct file *filp, - struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); return w1_ds2780_io(dev, buf, off, count, 0); } -static struct bin_attribute w1_ds2780_bin_attr = { - .attr = { - .name = "w1_slave", - .mode = S_IRUGO, - }, - .size = DS2780_DATA_SIZE, - .read = w1_ds2780_read_bin, +static BIN_ATTR_RO(w1_slave, DS2780_DATA_SIZE); + +static struct bin_attribute *w1_ds2780_bin_attrs[] = { + &bin_attr_w1_slave, + NULL, +}; + +static const struct attribute_group w1_ds2780_group = { + .bin_attrs = w1_ds2780_bin_attrs, +}; + +static const struct attribute_group *w1_ds2780_groups[] = { + &w1_ds2780_group, + NULL, }; static DEFINE_IDA(bat_ida); @@ -132,16 +138,10 @@ static int w1_ds2780_add_slave(struct w1_slave *sl) if (ret) goto pdev_add_failed; - ret = sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2780_bin_attr); - if (ret) - goto bin_attr_failed; - dev_set_drvdata(&sl->dev, pdev); return 0; -bin_attr_failed: - platform_device_del(pdev); pdev_add_failed: platform_device_put(pdev); pdev_alloc_failed: @@ -157,12 +157,12 @@ static void w1_ds2780_remove_slave(struct w1_slave *sl) platform_device_unregister(pdev); ida_simple_remove(&bat_ida, id); - sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2780_bin_attr); } static struct w1_family_ops w1_ds2780_fops = { .add_slave = w1_ds2780_add_slave, .remove_slave = w1_ds2780_remove_slave, + .groups = w1_ds2780_groups, }; static struct w1_family w1_ds2780_family = { diff --git a/drivers/w1/slaves/w1_ds2781.c b/drivers/w1/slaves/w1_ds2781.c index 1aba8e41ad46..1eb98fb1688d 100644 --- a/drivers/w1/slaves/w1_ds2781.c +++ b/drivers/w1/slaves/w1_ds2781.c @@ -87,22 +87,28 @@ int w1_ds2781_eeprom_cmd(struct device *dev, int addr, int cmd) } EXPORT_SYMBOL(w1_ds2781_eeprom_cmd); -static ssize_t w1_ds2781_read_bin(struct file *filp, - struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); return w1_ds2781_io(dev, buf, off, count, 0); } -static struct bin_attribute w1_ds2781_bin_attr = { - .attr = { - .name = "w1_slave", - .mode = S_IRUGO, - }, - .size = DS2781_DATA_SIZE, - .read = w1_ds2781_read_bin, +static BIN_ATTR_RO(w1_slave, DS2781_DATA_SIZE); + +static struct bin_attribute *w1_ds2781_bin_attrs[] = { + &bin_attr_w1_slave, + NULL, +}; + +static const struct attribute_group w1_ds2781_group = { + .bin_attrs = w1_ds2781_bin_attrs, +}; + +static const struct attribute_group *w1_ds2781_groups[] = { + &w1_ds2781_group, + NULL, }; static DEFINE_IDA(bat_ida); @@ -130,16 +136,10 @@ static int w1_ds2781_add_slave(struct w1_slave *sl) if (ret) goto pdev_add_failed; - ret = sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2781_bin_attr); - if (ret) - goto bin_attr_failed; - dev_set_drvdata(&sl->dev, pdev); return 0; -bin_attr_failed: - platform_device_del(pdev); pdev_add_failed: platform_device_put(pdev); pdev_alloc_failed: @@ -155,12 +155,12 @@ static void w1_ds2781_remove_slave(struct w1_slave *sl) platform_device_unregister(pdev); ida_simple_remove(&bat_ida, id); - sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2781_bin_attr); } static struct w1_family_ops w1_ds2781_fops = { .add_slave = w1_ds2781_add_slave, .remove_slave = w1_ds2781_remove_slave, + .groups = w1_ds2781_groups, }; static struct w1_family w1_ds2781_family = { diff --git a/drivers/w1/slaves/w1_ds28e04.c b/drivers/w1/slaves/w1_ds28e04.c index cd30a6d95ea5..365d6dff21de 100644 --- a/drivers/w1/slaves/w1_ds28e04.c +++ b/drivers/w1/slaves/w1_ds28e04.c @@ -118,9 +118,9 @@ static int w1_f1C_read(struct w1_slave *sl, int addr, int len, char *data) return w1_read_block(sl->master, data, len); } -static ssize_t w1_f1C_read_bin(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); struct w1_f1C_data *data = sl->family_data; @@ -226,9 +226,9 @@ static int w1_f1C_write(struct w1_slave *sl, int addr, int len, const u8 *data) return 0; } -static ssize_t w1_f1C_write_bin(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t eeprom_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); @@ -280,9 +280,11 @@ out_up: return count; } -static ssize_t w1_f1C_read_pio(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static BIN_ATTR_RW(eeprom, W1_EEPROM_SIZE); + +static ssize_t pio_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, + size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); @@ -299,9 +301,9 @@ static ssize_t w1_f1C_read_pio(struct file *filp, struct kobject *kobj, return ret; } -static ssize_t w1_f1C_write_pio(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t pio_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, + size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); @@ -339,8 +341,10 @@ static ssize_t w1_f1C_write_pio(struct file *filp, struct kobject *kobj, return count; } -static ssize_t w1_f1C_show_crccheck(struct device *dev, - struct device_attribute *attr, char *buf) +static BIN_ATTR_RW(pio, 1); + +static ssize_t crccheck_show(struct device *dev, struct device_attribute *attr, + char *buf) { if (put_user(w1_enable_crccheck + 0x30, buf)) return -EFAULT; @@ -348,9 +352,8 @@ static ssize_t w1_f1C_show_crccheck(struct device *dev, return sizeof(w1_enable_crccheck); } -static ssize_t w1_f1C_store_crccheck(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t crccheck_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { char val; @@ -371,35 +374,31 @@ static ssize_t w1_f1C_store_crccheck(struct device *dev, return sizeof(w1_enable_crccheck); } -#define NB_SYSFS_BIN_FILES 2 -static struct bin_attribute w1_f1C_bin_attr[NB_SYSFS_BIN_FILES] = { - { - .attr = { - .name = "eeprom", - .mode = S_IRUGO | S_IWUSR, - }, - .size = W1_EEPROM_SIZE, - .read = w1_f1C_read_bin, - .write = w1_f1C_write_bin, - }, - { - .attr = { - .name = "pio", - .mode = S_IRUGO | S_IWUSR, - }, - .size = 1, - .read = w1_f1C_read_pio, - .write = w1_f1C_write_pio, - } +static DEVICE_ATTR_RW(crccheck); + +static struct attribute *w1_f1C_attrs[] = { + &dev_attr_crccheck.attr, + NULL, }; -static DEVICE_ATTR(crccheck, S_IWUSR | S_IRUGO, - w1_f1C_show_crccheck, w1_f1C_store_crccheck); +static struct bin_attribute *w1_f1C_bin_attrs[] = { + &bin_attr_eeprom, + &bin_attr_pio, + NULL, +}; + +static const struct attribute_group w1_f1C_group = { + .attrs = w1_f1C_attrs, + .bin_attrs = w1_f1C_bin_attrs, +}; + +static const struct attribute_group *w1_f1C_groups[] = { + &w1_f1C_group, + NULL, +}; static int w1_f1C_add_slave(struct w1_slave *sl) { - int err = 0; - int i; struct w1_f1C_data *data = NULL; if (w1_enable_crccheck) { @@ -409,46 +408,19 @@ static int w1_f1C_add_slave(struct w1_slave *sl) sl->family_data = data; } - /* create binary sysfs attributes */ - for (i = 0; i < NB_SYSFS_BIN_FILES && !err; ++i) - err = sysfs_create_bin_file( - &sl->dev.kobj, &(w1_f1C_bin_attr[i])); - - if (!err) { - /* create device attributes */ - err = device_create_file(&sl->dev, &dev_attr_crccheck); - } - - if (err) { - /* remove binary sysfs attributes */ - for (i = 0; i < NB_SYSFS_BIN_FILES; ++i) - sysfs_remove_bin_file( - &sl->dev.kobj, &(w1_f1C_bin_attr[i])); - - kfree(data); - } - - return err; + return 0; } static void w1_f1C_remove_slave(struct w1_slave *sl) { - int i; - kfree(sl->family_data); sl->family_data = NULL; - - /* remove device attributes */ - device_remove_file(&sl->dev, &dev_attr_crccheck); - - /* remove binary sysfs attributes */ - for (i = 0; i < NB_SYSFS_BIN_FILES; ++i) - sysfs_remove_bin_file(&sl->dev.kobj, &(w1_f1C_bin_attr[i])); } static struct w1_family_ops w1_f1C_fops = { .add_slave = w1_f1C_add_slave, .remove_slave = w1_f1C_remove_slave, + .groups = w1_f1C_groups, }; static struct w1_family w1_family_1C = { diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index 8978360bd387..8b5ff33f72cf 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c @@ -59,25 +59,19 @@ static int w1_strong_pullup = 1; module_param_named(strong_pullup, w1_strong_pullup, int, 0); -static ssize_t w1_therm_read(struct device *device, +static ssize_t w1_slave_show(struct device *device, struct device_attribute *attr, char *buf); -static struct device_attribute w1_therm_attr = - __ATTR(w1_slave, S_IRUGO, w1_therm_read, NULL); +static DEVICE_ATTR_RO(w1_slave); -static int w1_therm_add_slave(struct w1_slave *sl) -{ - return device_create_file(&sl->dev, &w1_therm_attr); -} - -static void w1_therm_remove_slave(struct w1_slave *sl) -{ - device_remove_file(&sl->dev, &w1_therm_attr); -} +static struct attribute *w1_therm_attrs[] = { + &dev_attr_w1_slave.attr, + NULL, +}; +ATTRIBUTE_GROUPS(w1_therm); static struct w1_family_ops w1_therm_fops = { - .add_slave = w1_therm_add_slave, - .remove_slave = w1_therm_remove_slave, + .groups = w1_therm_groups, }; static struct w1_family w1_therm_family_DS18S20 = { @@ -178,7 +172,7 @@ static inline int w1_convert_temp(u8 rom[9], u8 fid) } -static ssize_t w1_therm_read(struct device *device, +static ssize_t w1_slave_show(struct device *device, struct device_attribute *attr, char *buf) { struct w1_slave *sl = dev_to_w1_slave(device); diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 0459df843c58..22013ca2119c 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -96,14 +96,15 @@ static void w1_slave_release(struct device *dev) complete(&sl->released); } -static ssize_t w1_slave_read_name(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t name_show(struct device *dev, struct device_attribute *attr, char *buf) { struct w1_slave *sl = dev_to_w1_slave(dev); return sprintf(buf, "%s\n", sl->name); } +static DEVICE_ATTR_RO(name); -static ssize_t w1_slave_read_id(struct device *dev, +static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf) { struct w1_slave *sl = dev_to_w1_slave(dev); @@ -112,17 +113,20 @@ static ssize_t w1_slave_read_id(struct device *dev, memcpy(buf, (u8 *)&sl->reg_num, count); return count; } +static DEVICE_ATTR_RO(id); -static struct device_attribute w1_slave_attr_name = - __ATTR(name, S_IRUGO, w1_slave_read_name, NULL); -static struct device_attribute w1_slave_attr_id = - __ATTR(id, S_IRUGO, w1_slave_read_id, NULL); +static struct attribute *w1_slave_attrs[] = { + &dev_attr_name.attr, + &dev_attr_id.attr, + NULL, +}; +ATTRIBUTE_GROUPS(w1_slave); /* Default family */ -static ssize_t w1_default_write(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t rw_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, + size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); @@ -139,9 +143,9 @@ out_up: return count; } -static ssize_t w1_default_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t rw_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, + size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); @@ -151,29 +155,24 @@ static ssize_t w1_default_read(struct file *filp, struct kobject *kobj, return count; } -static struct bin_attribute w1_default_attr = { - .attr = { - .name = "rw", - .mode = S_IRUGO | S_IWUSR, - }, - .size = PAGE_SIZE, - .read = w1_default_read, - .write = w1_default_write, +static BIN_ATTR_RW(rw, PAGE_SIZE); + +static struct bin_attribute *w1_slave_bin_attrs[] = { + &bin_attr_rw, + NULL, }; -static int w1_default_add_slave(struct w1_slave *sl) -{ - return sysfs_create_bin_file(&sl->dev.kobj, &w1_default_attr); -} +static const struct attribute_group w1_slave_default_group = { + .bin_attrs = w1_slave_bin_attrs, +}; -static void w1_default_remove_slave(struct w1_slave *sl) -{ - sysfs_remove_bin_file(&sl->dev.kobj, &w1_default_attr); -} +static const struct attribute_group *w1_slave_default_groups[] = { + &w1_slave_default_group, + NULL, +}; static struct w1_family_ops w1_default_fops = { - .add_slave = w1_default_add_slave, - .remove_slave = w1_default_remove_slave, + .groups = w1_slave_default_groups, }; static struct w1_family w1_default_family = { @@ -587,6 +586,66 @@ end: return err; } +/* + * Handle sysfs file creation and removal here, before userspace is told that + * the device is added / removed from the system + */ +static int w1_bus_notify(struct notifier_block *nb, unsigned long action, + void *data) +{ + struct device *dev = data; + struct w1_slave *sl; + struct w1_family_ops *fops; + int err; + + /* + * Only care about slave devices at the moment. Yes, we should use a + * separate "type" for this, but for now, look at the release function + * to know which type it is... + */ + if (dev->release != w1_slave_release) + return 0; + + sl = dev_to_w1_slave(dev); + fops = sl->family->fops; + + switch (action) { + case BUS_NOTIFY_ADD_DEVICE: + /* if the family driver needs to initialize something... */ + if (fops->add_slave) { + err = fops->add_slave(sl); + if (err < 0) { + dev_err(&sl->dev, + "add_slave() call failed. err=%d\n", + err); + return err; + } + } + if (fops->groups) { + err = sysfs_create_groups(&sl->dev.kobj, fops->groups); + if (err) { + dev_err(&sl->dev, + "sysfs group creation failed. err=%d\n", + err); + return err; + } + } + + break; + case BUS_NOTIFY_DEL_DEVICE: + if (fops->remove_slave) + sl->family->fops->remove_slave(sl); + if (fops->groups) + sysfs_remove_groups(&sl->dev.kobj, fops->groups); + break; + } + return 0; +} + +static struct notifier_block w1_bus_nb = { + .notifier_call = w1_bus_notify, +}; + static int __w1_attach_slave_device(struct w1_slave *sl) { int err; @@ -595,6 +654,7 @@ static int __w1_attach_slave_device(struct w1_slave *sl) sl->dev.driver = &w1_slave_driver; sl->dev.bus = &w1_bus_type; sl->dev.release = &w1_slave_release; + sl->dev.groups = w1_slave_groups; dev_set_name(&sl->dev, "%02x-%012llx", (unsigned int) sl->reg_num.family, @@ -615,44 +675,13 @@ static int __w1_attach_slave_device(struct w1_slave *sl) return err; } - /* Create "name" entry */ - err = device_create_file(&sl->dev, &w1_slave_attr_name); - if (err < 0) { - dev_err(&sl->dev, - "sysfs file creation for [%s] failed. err=%d\n", - dev_name(&sl->dev), err); - goto out_unreg; - } - - /* Create "id" entry */ - err = device_create_file(&sl->dev, &w1_slave_attr_id); - if (err < 0) { - dev_err(&sl->dev, - "sysfs file creation for [%s] failed. err=%d\n", - dev_name(&sl->dev), err); - goto out_rem1; - } - /* if the family driver needs to initialize something... */ - if (sl->family->fops && sl->family->fops->add_slave && - ((err = sl->family->fops->add_slave(sl)) < 0)) { - dev_err(&sl->dev, - "sysfs file creation for [%s] failed. err=%d\n", - dev_name(&sl->dev), err); - goto out_rem2; - } + dev_set_uevent_suppress(&sl->dev, false); + kobject_uevent(&sl->dev.kobj, KOBJ_ADD); list_add_tail(&sl->w1_slave_entry, &sl->master->slist); return 0; - -out_rem2: - device_remove_file(&sl->dev, &w1_slave_attr_id); -out_rem1: - device_remove_file(&sl->dev, &w1_slave_attr_name); -out_unreg: - device_unregister(&sl->dev); - return err; } static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) @@ -723,16 +752,11 @@ void w1_slave_detach(struct w1_slave *sl) list_del(&sl->w1_slave_entry); - if (sl->family->fops && sl->family->fops->remove_slave) - sl->family->fops->remove_slave(sl); - memset(&msg, 0, sizeof(msg)); memcpy(msg.id.id, &sl->reg_num, sizeof(msg.id)); msg.type = W1_SLAVE_REMOVE; w1_netlink_send(sl->master, &msg); - device_remove_file(&sl->dev, &w1_slave_attr_id); - device_remove_file(&sl->dev, &w1_slave_attr_name); device_unregister(&sl->dev); wait_for_completion(&sl->released); @@ -1017,6 +1041,10 @@ static int __init w1_init(void) goto err_out_exit_init; } + retval = bus_register_notifier(&w1_bus_type, &w1_bus_nb); + if (retval) + goto err_out_bus_unregister; + retval = driver_register(&w1_master_driver); if (retval) { printk(KERN_ERR diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h index 625dd08f775f..4ad0e81b6404 100644 --- a/drivers/w1/w1_family.h +++ b/drivers/w1/w1_family.h @@ -52,6 +52,7 @@ struct w1_family_ops { int (* add_slave)(struct w1_slave *); void (* remove_slave)(struct w1_slave *); + const struct attribute_group **groups; }; struct w1_family |