W1: add 2 default attributes "family" and "serial" to slave devices, every 1-Wire slave has them. Use attribute_group to handle. The rest of slave attributes are left as is - will be dealt with later. Signed-off-by: Dmitry Torokhov <dtor at mail.ru> --- w1.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++--------------------- w1.h | 1 2 files changed, 81 insertions(+), 35 deletions(-) Index: dtor/drivers/w1/w1.c =================================================================== --- dtor.orig/drivers/w1/w1.c +++ dtor/drivers/w1/w1.c @@ -81,40 +81,6 @@ static void w1_master_release(struct dev complete(&md->dev_released); } -static void w1_slave_release(struct device *dev) -{ - struct w1_slave *sl = container_of(dev, struct w1_slave, dev); - - complete(&sl->dev_released); -} - -static ssize_t w1_default_read_name(struct device *dev, char *buf) -{ - return sprintf(buf, "No family registered.\n"); -} - -static ssize_t w1_default_read_bin(struct kobject *kobj, char *buf, loff_t off, - size_t count) -{ - return sprintf(buf, "No family registered.\n"); -} - -static struct device_attribute w1_slave_attribute = - __ATTR(name, S_IRUGO, w1_default_read_name, NULL); - -static struct device_attribute w1_slave_attribute_val = - __ATTR(value, S_IRUGO, w1_default_read_name, NULL); - -static struct bin_attribute w1_slave_bin_attribute = { - .attr = { - .name = "w1_slave", - .mode = S_IRUGO, - .owner = THIS_MODULE, - }, - .size = W1_SLAVE_DATA_SIZE, - .read = &w1_default_read_bin, -}; - static struct bus_type w1_bus_type = { .name = "w1", @@ -279,6 +245,72 @@ void w1_destroy_master_attributes(struct sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group); } +static ssize_t w1_slave_attribute_show_family(struct device *dev, char *buf) +{ + struct w1_slave *slave = to_w1_slave(dev); + + return sprintf(buf, "%02X\n", slave->reg_num.family); +} + +static ssize_t w1_slave_attribute_show_serial(struct device *dev, char *buf) +{ + struct w1_slave *slave = to_w1_slave(dev); + + return sprintf(buf, "%llX\n", (unsigned long long)slave->reg_num.id); +} + +#define W1_SLAVE_ATTR_RO(_name, _mode) \ + struct device_attribute w1_slave_attribute_##_name = \ + __ATTR(_name, _mode, \ + w1_slave_attribute_show_##_name, NULL) + +static W1_SLAVE_ATTR_RO(family, S_IRUGO); +static W1_SLAVE_ATTR_RO(serial, S_IRUGO); + +static struct attribute *w1_slave_default_attrs[] = { + &w1_slave_attribute_family.attr, + &w1_slave_attribute_serial.attr, + NULL +}; + +static struct attribute_group w1_slave_defattr_group = { + .attrs = w1_slave_default_attrs, +}; + +static ssize_t w1_default_read_name(struct device *dev, char *buf) +{ + return sprintf(buf, "No family registered.\n"); +} + +static ssize_t w1_default_read_bin(struct kobject *kobj, char *buf, loff_t off, + size_t count) +{ + return sprintf(buf, "No family registered.\n"); +} + +static struct device_attribute w1_slave_attribute = + __ATTR(name, S_IRUGO, w1_default_read_name, NULL); + +static struct device_attribute w1_slave_attribute_val = + __ATTR(value, S_IRUGO, w1_default_read_name, NULL); + +static struct bin_attribute w1_slave_bin_attribute = { + .attr = { + .name = "w1_slave", + .mode = S_IRUGO, + .owner = THIS_MODULE, + }, + .size = W1_SLAVE_DATA_SIZE, + .read = &w1_default_read_bin, +}; + +static void w1_slave_release(struct device *dev) +{ + struct w1_slave *sl = container_of(dev, struct w1_slave, dev); + + complete(&sl->dev_released); +} + static int __w1_attach_slave_device(struct w1_slave *sl) { int err; @@ -347,6 +379,18 @@ static int __w1_attach_slave_device(stru return err; } + err = sysfs_create_group(&sl->dev.kobj, &w1_slave_defattr_group); + if (err < 0) { + dev_err(&sl->dev, + "sysfs group creation for [%s] failed. err=%d\n", + sl->dev.bus_id, err); + sysfs_remove_bin_file(&sl->dev.kobj, &sl->attr_bin); + device_remove_file(&sl->dev, &sl->attr_name); + device_remove_file(&sl->dev, &sl->attr_val); + device_unregister(&sl->dev); + return err; + } + list_add_tail(&sl->w1_slave_entry, &sl->master->slist); return 0; @@ -426,7 +470,8 @@ static void w1_slave_detach(struct w1_sl flush_signals(current); } - sysfs_remove_bin_file (&sl->dev.kobj, &sl->attr_bin); + sysfs_remove_group(&sl->dev.kobj, &w1_slave_defattr_group); + sysfs_remove_bin_file(&sl->dev.kobj, &sl->attr_bin); device_remove_file(&sl->dev, &sl->attr_name); device_remove_file(&sl->dev, &sl->attr_val); device_unregister(&sl->dev); Index: dtor/drivers/w1/w1.h =================================================================== --- dtor.orig/drivers/w1/w1.h +++ dtor/drivers/w1/w1.h @@ -81,6 +81,7 @@ struct w1_slave struct bin_attribute attr_bin; struct device_attribute attr_name, attr_val; }; +#define to_w1_slave(dev) container_of((dev), struct w1_slave, dev) typedef void (* w1_slave_found_callback)(unsigned long, u64);