diff mbox series

[v2,2/2] hwmon: Add "label" attribute

Message ID 20220105151551.20285-3-paul@crapouillou.net (mailing list archive)
State Changes Requested
Headers show
Series hwmon: Add "label" attribute v2 | expand

Commit Message

Paul Cercueil Jan. 5, 2022, 3:15 p.m. UTC
If a label is defined in the device tree for this device add that
to the device specific attributes. This is useful for userspace to
be able to identify an individual device when multiple identical
chips are present in the system.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Tested-by: Cosmin Tanislav <cosmin.tanislav@analog.com>
---

Notes:
    v2: - Cache label into hwmon_device
        - Rename hwmon_dev_name_is_visible() to hwmon_dev_attr_is_visible()
	- Add missing <linux/property.h> include

 drivers/hwmon/hwmon.c | 34 +++++++++++++++++++++++++++++++---
 1 file changed, 31 insertions(+), 3 deletions(-)

Comments

kernel test robot Jan. 5, 2022, 10:27 p.m. UTC | #1
Hi Paul,

I love your patch! Perhaps something to improve:

[auto build test WARNING on groeck-staging/hwmon-next]
[also build test WARNING on v5.16-rc8 next-20220105]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Paul-Cercueil/hwmon-Add-label-attribute-v2/20220105-231930
base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
config: arm64-randconfig-r026-20220105 (https://download.01.org/0day-ci/archive/20220106/202201060630.vsp02mfB-lkp@intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project d5b6e30ed3acad794dd0aec400e617daffc6cc3d)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm64 cross compiling tool for clang build
        # apt-get install binutils-aarch64-linux-gnu
        # https://github.com/0day-ci/linux/commit/57dab49995d01d638d9fa9aaddb5fa48e17b3c48
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Paul-Cercueil/hwmon-Add-label-attribute-v2/20220105-231930
        git checkout 57dab49995d01d638d9fa9aaddb5fa48e17b3c48
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm64 SHELL=/bin/bash drivers/hwmon/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/hwmon/hwmon.c:777:7: warning: variable 'hdev' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
                   if (hwdev->label == NULL) {
                       ^~~~~~~~~~~~~~~~~~~~
   drivers/hwmon/hwmon.c:851:20: note: uninitialized use occurs here
           hwmon_dev_release(hdev);
                             ^~~~
   drivers/hwmon/hwmon.c:777:3: note: remove the 'if' if its condition is always false
                   if (hwdev->label == NULL) {
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/hwmon/hwmon.c:773:7: warning: variable 'hdev' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
                   if (err < 0)
                       ^~~~~~~
   drivers/hwmon/hwmon.c:851:20: note: uninitialized use occurs here
           hwmon_dev_release(hdev);
                             ^~~~
   drivers/hwmon/hwmon.c:773:3: note: remove the 'if' if its condition is always false
                   if (err < 0)
                   ^~~~~~~~~~~~
   drivers/hwmon/hwmon.c:752:21: note: initialize the variable 'hdev' to silence this warning
           struct device *hdev;
                              ^
                               = NULL
   2 warnings generated.


vim +777 drivers/hwmon/hwmon.c

   744	
   745	static struct device *
   746	__hwmon_device_register(struct device *dev, const char *name, void *drvdata,
   747				const struct hwmon_chip_info *chip,
   748				const struct attribute_group **groups)
   749	{
   750		struct hwmon_device *hwdev;
   751		const char *label;
   752		struct device *hdev;
   753		int i, err, id;
   754	
   755		/* Complain about invalid characters in hwmon name attribute */
   756		if (name && (!strlen(name) || strpbrk(name, "-* \t\n")))
   757			dev_warn(dev,
   758				 "hwmon: '%s' is not a valid name attribute, please fix\n",
   759				 name);
   760	
   761		id = ida_simple_get(&hwmon_ida, 0, 0, GFP_KERNEL);
   762		if (id < 0)
   763			return ERR_PTR(id);
   764	
   765		hwdev = kzalloc(sizeof(*hwdev), GFP_KERNEL);
   766		if (hwdev == NULL) {
   767			err = -ENOMEM;
   768			goto ida_remove;
   769		}
   770	
   771		if (device_property_present(dev, "label")) {
   772			err = device_property_read_string(dev, "label", &label);
   773			if (err < 0)
   774				goto free_hwmon;
   775	
   776			hwdev->label = kstrdup(label, GFP_KERNEL);
 > 777			if (hwdev->label == NULL) {
   778				err = -ENOMEM;
   779				goto free_hwmon;
   780			}
   781		}
   782	
   783		hdev = &hwdev->dev;
   784	
   785		if (chip) {
   786			struct attribute **attrs;
   787			int ngroups = 2; /* terminating NULL plus &hwdev->groups */
   788	
   789			if (groups)
   790				for (i = 0; groups[i]; i++)
   791					ngroups++;
   792	
   793			hwdev->groups = kcalloc(ngroups, sizeof(*groups), GFP_KERNEL);
   794			if (!hwdev->groups) {
   795				err = -ENOMEM;
   796				goto free_hwmon;
   797			}
   798	
   799			attrs = __hwmon_create_attrs(drvdata, chip);
   800			if (IS_ERR(attrs)) {
   801				err = PTR_ERR(attrs);
   802				goto free_hwmon;
   803			}
   804	
   805			hwdev->group.attrs = attrs;
   806			ngroups = 0;
   807			hwdev->groups[ngroups++] = &hwdev->group;
   808	
   809			if (groups) {
   810				for (i = 0; groups[i]; i++)
   811					hwdev->groups[ngroups++] = groups[i];
   812			}
   813	
   814			hdev->groups = hwdev->groups;
   815		} else {
   816			hdev->groups = groups;
   817		}
   818	
   819		hwdev->name = name;
   820		hdev->class = &hwmon_class;
   821		hdev->parent = dev;
   822		hdev->of_node = dev ? dev->of_node : NULL;
   823		hwdev->chip = chip;
   824		dev_set_drvdata(hdev, drvdata);
   825		dev_set_name(hdev, HWMON_ID_FORMAT, id);
   826		err = device_register(hdev);
   827		if (err) {
   828			put_device(hdev);
   829			goto ida_remove;
   830		}
   831	
   832		INIT_LIST_HEAD(&hwdev->tzdata);
   833	
   834		if (dev && dev->of_node && chip && chip->ops->read &&
   835		    chip->info[0]->type == hwmon_chip &&
   836		    (chip->info[0]->config[0] & HWMON_C_REGISTER_TZ)) {
   837			err = hwmon_thermal_register_sensors(hdev);
   838			if (err) {
   839				device_unregister(hdev);
   840				/*
   841				 * Don't worry about hwdev; hwmon_dev_release(), called
   842				 * from device_unregister(), will free it.
   843				 */
   844				goto ida_remove;
   845			}
   846		}
   847	
   848		return hdev;
   849	
   850	free_hwmon:
   851		hwmon_dev_release(hdev);
   852	ida_remove:
   853		ida_simple_remove(&hwmon_ida, id);
   854		return ERR_PTR(err);
   855	}
   856	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Guenter Roeck Jan. 10, 2022, 1:29 a.m. UTC | #2
On Wed, Jan 05, 2022 at 03:15:51PM +0000, Paul Cercueil wrote:
> If a label is defined in the device tree for this device add that
> to the device specific attributes. This is useful for userspace to
> be able to identify an individual device when multiple identical
> chips are present in the system.
> 
> Signed-off-by: Paul Cercueil <paul@crapouillou.net>
> Tested-by: Cosmin Tanislav <cosmin.tanislav@analog.com>
> Reported-by: kernel test robot <lkp@intel.com>
> ---
> 
> Notes:
>     v2: - Cache label into hwmon_device
>         - Rename hwmon_dev_name_is_visible() to hwmon_dev_attr_is_visible()
> 	- Add missing <linux/property.h> include
> 
>  drivers/hwmon/hwmon.c | 34 +++++++++++++++++++++++++++++++---
>  1 file changed, 31 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c
> index 3501a3ead4ba..22e1b47c09fc 100644
> --- a/drivers/hwmon/hwmon.c
> +++ b/drivers/hwmon/hwmon.c
> @@ -18,6 +18,7 @@
>  #include <linux/list.h>
>  #include <linux/module.h>
>  #include <linux/pci.h>
> +#include <linux/property.h>
>  #include <linux/slab.h>
>  #include <linux/string.h>
>  #include <linux/thermal.h>
> @@ -30,6 +31,7 @@
>  
>  struct hwmon_device {
>  	const char *name;
> +	const char *label;
>  	struct device dev;
>  	const struct hwmon_chip_info *chip;
>  	struct list_head tzdata;
> @@ -71,17 +73,29 @@ name_show(struct device *dev, struct device_attribute *attr, char *buf)
>  }
>  static DEVICE_ATTR_RO(name);
>  
> +static ssize_t
> +label_show(struct device *dev, struct device_attribute *attr, char *buf)
> +{
> +	return sysfs_emit(buf, "%s\n", to_hwmon_device(dev)->label);
> +}
> +static DEVICE_ATTR_RO(label);
> +
>  static struct attribute *hwmon_dev_attrs[] = {
>  	&dev_attr_name.attr,
> +	&dev_attr_label.attr,
>  	NULL
>  };
>  
> -static umode_t hwmon_dev_name_is_visible(struct kobject *kobj,
> +static umode_t hwmon_dev_attr_is_visible(struct kobject *kobj,
>  					 struct attribute *attr, int n)
>  {
>  	struct device *dev = kobj_to_dev(kobj);
> +	struct hwmon_device *hdev = to_hwmon_device(dev);
>  
> -	if (to_hwmon_device(dev)->name == NULL)
> +	if (attr == &dev_attr_name.attr && hdev->name == NULL)
> +		return 0;
> +
> +	if (attr == &dev_attr_label.attr && hdev->label == NULL)
>  		return 0;
>  
>  	return attr->mode;
> @@ -89,7 +103,7 @@ static umode_t hwmon_dev_name_is_visible(struct kobject *kobj,
>  
>  static const struct attribute_group hwmon_dev_attr_group = {
>  	.attrs		= hwmon_dev_attrs,
> -	.is_visible	= hwmon_dev_name_is_visible,
> +	.is_visible	= hwmon_dev_attr_is_visible,
>  };
>  
>  static const struct attribute_group *hwmon_dev_attr_groups[] = {
> @@ -117,6 +131,7 @@ static void hwmon_dev_release(struct device *dev)
>  	if (hwdev->group.attrs)
>  		hwmon_free_attrs(hwdev->group.attrs);
>  	kfree(hwdev->groups);
> +	kfree(hwdev->label);
>  	kfree(hwdev);
>  }
>  
> @@ -733,6 +748,7 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata,
>  			const struct attribute_group **groups)
>  {
>  	struct hwmon_device *hwdev;
> +	const char *label;
>  	struct device *hdev;
>  	int i, err, id;
>  
> @@ -752,6 +768,18 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata,
>  		goto ida_remove;
>  	}
>  
> +	if (device_property_present(dev, "label")) {
> +		err = device_property_read_string(dev, "label", &label);
> +		if (err < 0)
> +			goto free_hwmon;
> +
> +		hwdev->label = kstrdup(label, GFP_KERNEL);
> +		if (hwdev->label == NULL) {
> +			err = -ENOMEM;
> +			goto free_hwmon;

The code after free_hwmon: uses hdev, so 0-day has a point. Please fix.

Guenter

> +		}
> +	}
> +
>  	hdev = &hwdev->dev;
>  
>  	if (chip) {
Dan Carpenter Jan. 10, 2022, 6:44 a.m. UTC | #3
Hi Paul,

url:    https://github.com/0day-ci/linux/commits/Paul-Cercueil/hwmon-Add-label-attribute-v2/20220105-231930
base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
config: i386-randconfig-m021-20220105 (https://download.01.org/0day-ci/archive/20220108/202201081730.TlHZabuC-lkp@intel.com/config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

smatch warnings:
drivers/hwmon/hwmon.c:851 __hwmon_device_register() error: uninitialized symbol 'hdev'.
drivers/hwmon/hwmon.c:854 __hwmon_device_register() warn: possible memory leak of 'hwdev'

vim +/hdev +851 drivers/hwmon/hwmon.c

d560168b5d0fb4 Guenter Roeck    2015-08-26  745  static struct device *
d560168b5d0fb4 Guenter Roeck    2015-08-26  746  __hwmon_device_register(struct device *dev, const char *name, void *drvdata,
d560168b5d0fb4 Guenter Roeck    2015-08-26  747  			const struct hwmon_chip_info *chip,
bab2243ce18978 Guenter Roeck    2013-07-06  748  			const struct attribute_group **groups)
1236441f38b6a9 Mark M. Hoffman  2005-07-15  749  {
bab2243ce18978 Guenter Roeck    2013-07-06  750  	struct hwmon_device *hwdev;
57dab49995d01d Paul Cercueil    2022-01-05  751  	const char *label;
d560168b5d0fb4 Guenter Roeck    2015-08-26  752  	struct device *hdev;
44e3ad882bb268 Akinobu Mita     2020-05-04  753  	int i, err, id;
ded2b666156130 Mark M. Hoffman  2006-03-05  754  
74d3b6419772e4 Guenter Roeck    2017-01-27  755  	/* Complain about invalid characters in hwmon name attribute */
648cd48c9e566f Guenter Roeck    2014-02-28  756  	if (name && (!strlen(name) || strpbrk(name, "-* \t\n")))
74d3b6419772e4 Guenter Roeck    2017-01-27  757  		dev_warn(dev,
74d3b6419772e4 Guenter Roeck    2017-01-27  758  			 "hwmon: '%s' is not a valid name attribute, please fix\n",
74d3b6419772e4 Guenter Roeck    2017-01-27  759  			 name);
648cd48c9e566f Guenter Roeck    2014-02-28  760  
4ca5f468cc2a0b Jonathan Cameron 2011-10-31  761  	id = ida_simple_get(&hwmon_ida, 0, 0, GFP_KERNEL);
4ca5f468cc2a0b Jonathan Cameron 2011-10-31  762  	if (id < 0)
4ca5f468cc2a0b Jonathan Cameron 2011-10-31  763  		return ERR_PTR(id);
1236441f38b6a9 Mark M. Hoffman  2005-07-15  764  
bab2243ce18978 Guenter Roeck    2013-07-06  765  	hwdev = kzalloc(sizeof(*hwdev), GFP_KERNEL);
bab2243ce18978 Guenter Roeck    2013-07-06  766  	if (hwdev == NULL) {
bab2243ce18978 Guenter Roeck    2013-07-06  767  		err = -ENOMEM;
bab2243ce18978 Guenter Roeck    2013-07-06  768  		goto ida_remove;
bab2243ce18978 Guenter Roeck    2013-07-06  769  	}
1236441f38b6a9 Mark M. Hoffman  2005-07-15  770  
57dab49995d01d Paul Cercueil    2022-01-05  771  	if (device_property_present(dev, "label")) {
57dab49995d01d Paul Cercueil    2022-01-05  772  		err = device_property_read_string(dev, "label", &label);
57dab49995d01d Paul Cercueil    2022-01-05  773  		if (err < 0)
57dab49995d01d Paul Cercueil    2022-01-05  774  			goto free_hwmon;

"hwdev" not freed on this goto path and "hdev" is uninitialized.  Sort
of related bugs.

57dab49995d01d Paul Cercueil    2022-01-05  775  
57dab49995d01d Paul Cercueil    2022-01-05  776  		hwdev->label = kstrdup(label, GFP_KERNEL);
57dab49995d01d Paul Cercueil    2022-01-05  777  		if (hwdev->label == NULL) {
57dab49995d01d Paul Cercueil    2022-01-05  778  			err = -ENOMEM;
57dab49995d01d Paul Cercueil    2022-01-05  779  			goto free_hwmon;
57dab49995d01d Paul Cercueil    2022-01-05  780  		}
57dab49995d01d Paul Cercueil    2022-01-05  781  	}
57dab49995d01d Paul Cercueil    2022-01-05  782  
d560168b5d0fb4 Guenter Roeck    2015-08-26  783  	hdev = &hwdev->dev;
d560168b5d0fb4 Guenter Roeck    2015-08-26  784  
239552f495b91f Guenter Roeck    2016-10-16  785  	if (chip) {
d560168b5d0fb4 Guenter Roeck    2015-08-26  786  		struct attribute **attrs;
b2a4cc3a060da0 Guenter Roeck    2016-10-16  787  		int ngroups = 2; /* terminating NULL plus &hwdev->groups */
d560168b5d0fb4 Guenter Roeck    2015-08-26  788  
d560168b5d0fb4 Guenter Roeck    2015-08-26  789  		if (groups)
d560168b5d0fb4 Guenter Roeck    2015-08-26  790  			for (i = 0; groups[i]; i++)
d560168b5d0fb4 Guenter Roeck    2015-08-26  791  				ngroups++;
d560168b5d0fb4 Guenter Roeck    2015-08-26  792  
3bf8bdcf3bada7 Guenter Roeck    2020-01-16  793  		hwdev->groups = kcalloc(ngroups, sizeof(*groups), GFP_KERNEL);
38d8ed65092ed2 Colin Ian King   2016-10-23  794  		if (!hwdev->groups) {
38d8ed65092ed2 Colin Ian King   2016-10-23  795  			err = -ENOMEM;
38d8ed65092ed2 Colin Ian King   2016-10-23  796  			goto free_hwmon;
38d8ed65092ed2 Colin Ian King   2016-10-23  797  		}
d560168b5d0fb4 Guenter Roeck    2015-08-26  798  
3bf8bdcf3bada7 Guenter Roeck    2020-01-16  799  		attrs = __hwmon_create_attrs(drvdata, chip);
d560168b5d0fb4 Guenter Roeck    2015-08-26  800  		if (IS_ERR(attrs)) {
d560168b5d0fb4 Guenter Roeck    2015-08-26  801  			err = PTR_ERR(attrs);
d560168b5d0fb4 Guenter Roeck    2015-08-26  802  			goto free_hwmon;
d560168b5d0fb4 Guenter Roeck    2015-08-26  803  		}
d560168b5d0fb4 Guenter Roeck    2015-08-26  804  
d560168b5d0fb4 Guenter Roeck    2015-08-26  805  		hwdev->group.attrs = attrs;
d560168b5d0fb4 Guenter Roeck    2015-08-26  806  		ngroups = 0;
d560168b5d0fb4 Guenter Roeck    2015-08-26  807  		hwdev->groups[ngroups++] = &hwdev->group;
d560168b5d0fb4 Guenter Roeck    2015-08-26  808  
d560168b5d0fb4 Guenter Roeck    2015-08-26  809  		if (groups) {
d560168b5d0fb4 Guenter Roeck    2015-08-26  810  			for (i = 0; groups[i]; i++)
d560168b5d0fb4 Guenter Roeck    2015-08-26  811  				hwdev->groups[ngroups++] = groups[i];
d560168b5d0fb4 Guenter Roeck    2015-08-26  812  		}
d560168b5d0fb4 Guenter Roeck    2015-08-26  813  
d560168b5d0fb4 Guenter Roeck    2015-08-26  814  		hdev->groups = hwdev->groups;
d560168b5d0fb4 Guenter Roeck    2015-08-26  815  	} else {
d560168b5d0fb4 Guenter Roeck    2015-08-26  816  		hdev->groups = groups;
d560168b5d0fb4 Guenter Roeck    2015-08-26  817  	}
d560168b5d0fb4 Guenter Roeck    2015-08-26  818  
bab2243ce18978 Guenter Roeck    2013-07-06  819  	hwdev->name = name;
d560168b5d0fb4 Guenter Roeck    2015-08-26  820  	hdev->class = &hwmon_class;
d560168b5d0fb4 Guenter Roeck    2015-08-26  821  	hdev->parent = dev;
d560168b5d0fb4 Guenter Roeck    2015-08-26  822  	hdev->of_node = dev ? dev->of_node : NULL;
d560168b5d0fb4 Guenter Roeck    2015-08-26  823  	hwdev->chip = chip;
d560168b5d0fb4 Guenter Roeck    2015-08-26  824  	dev_set_drvdata(hdev, drvdata);
d560168b5d0fb4 Guenter Roeck    2015-08-26  825  	dev_set_name(hdev, HWMON_ID_FORMAT, id);
d560168b5d0fb4 Guenter Roeck    2015-08-26  826  	err = device_register(hdev);
ada61aa0b1184a Yang Yingliang   2021-10-12  827  	if (err) {
ada61aa0b1184a Yang Yingliang   2021-10-12  828  		put_device(hdev);
ada61aa0b1184a Yang Yingliang   2021-10-12  829  		goto ida_remove;
ada61aa0b1184a Yang Yingliang   2021-10-12  830  	}
d560168b5d0fb4 Guenter Roeck    2015-08-26  831  
1597b374af2226 Guenter Roeck    2020-05-28  832  	INIT_LIST_HEAD(&hwdev->tzdata);
1597b374af2226 Guenter Roeck    2020-05-28  833  
c41dd48e21fae3 Eduardo Valentin 2019-05-29  834  	if (dev && dev->of_node && chip && chip->ops->read &&
d560168b5d0fb4 Guenter Roeck    2015-08-26  835  	    chip->info[0]->type == hwmon_chip &&
d560168b5d0fb4 Guenter Roeck    2015-08-26  836  	    (chip->info[0]->config[0] & HWMON_C_REGISTER_TZ)) {
44e3ad882bb268 Akinobu Mita     2020-05-04  837  		err = hwmon_thermal_register_sensors(hdev);
74e3512731bd5c Dmitry Osipenko  2018-10-24  838  		if (err) {
74e3512731bd5c Dmitry Osipenko  2018-10-24  839  			device_unregister(hdev);
792eac18431967 Guenter Roeck    2019-06-06  840  			/*
44e3ad882bb268 Akinobu Mita     2020-05-04  841  			 * Don't worry about hwdev; hwmon_dev_release(), called
44e3ad882bb268 Akinobu Mita     2020-05-04  842  			 * from device_unregister(), will free it.
792eac18431967 Guenter Roeck    2019-06-06  843  			 */
74e3512731bd5c Dmitry Osipenko  2018-10-24  844  			goto ida_remove;
74e3512731bd5c Dmitry Osipenko  2018-10-24  845  		}
47c332deb8e89f Linus Walleij    2017-12-05  846  	}
bab2243ce18978 Guenter Roeck    2013-07-06  847  
d560168b5d0fb4 Guenter Roeck    2015-08-26  848  	return hdev;
bab2243ce18978 Guenter Roeck    2013-07-06  849  
d560168b5d0fb4 Guenter Roeck    2015-08-26  850  free_hwmon:
3bf8bdcf3bada7 Guenter Roeck    2020-01-16 @851  	hwmon_dev_release(hdev);
bab2243ce18978 Guenter Roeck    2013-07-06  852  ida_remove:
4ca5f468cc2a0b Jonathan Cameron 2011-10-31  853  	ida_simple_remove(&hwmon_ida, id);
bab2243ce18978 Guenter Roeck    2013-07-06 @854  	return ERR_PTR(err);
bab2243ce18978 Guenter Roeck    2013-07-06  855  }

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Paul Cercueil Jan. 10, 2022, 10:48 a.m. UTC | #4
Hi,

Le dim., janv. 9 2022 at 17:29:24 -0800, Guenter Roeck 
<linux@roeck-us.net> a écrit :
> On Wed, Jan 05, 2022 at 03:15:51PM +0000, Paul Cercueil wrote:
>>  If a label is defined in the device tree for this device add that
>>  to the device specific attributes. This is useful for userspace to
>>  be able to identify an individual device when multiple identical
>>  chips are present in the system.
>> 
>>  Signed-off-by: Paul Cercueil <paul@crapouillou.net>
>>  Tested-by: Cosmin Tanislav <cosmin.tanislav@analog.com>
>>  Reported-by: kernel test robot <lkp@intel.com>
>>  ---
>> 
>>  Notes:
>>      v2: - Cache label into hwmon_device
>>          - Rename hwmon_dev_name_is_visible() to 
>> hwmon_dev_attr_is_visible()
>>  	- Add missing <linux/property.h> include
>> 
>>   drivers/hwmon/hwmon.c | 34 +++++++++++++++++++++++++++++++---
>>   1 file changed, 31 insertions(+), 3 deletions(-)
>> 
>>  diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c
>>  index 3501a3ead4ba..22e1b47c09fc 100644
>>  --- a/drivers/hwmon/hwmon.c
>>  +++ b/drivers/hwmon/hwmon.c
>>  @@ -18,6 +18,7 @@
>>   #include <linux/list.h>
>>   #include <linux/module.h>
>>   #include <linux/pci.h>
>>  +#include <linux/property.h>
>>   #include <linux/slab.h>
>>   #include <linux/string.h>
>>   #include <linux/thermal.h>
>>  @@ -30,6 +31,7 @@
>> 
>>   struct hwmon_device {
>>   	const char *name;
>>  +	const char *label;
>>   	struct device dev;
>>   	const struct hwmon_chip_info *chip;
>>   	struct list_head tzdata;
>>  @@ -71,17 +73,29 @@ name_show(struct device *dev, struct 
>> device_attribute *attr, char *buf)
>>   }
>>   static DEVICE_ATTR_RO(name);
>> 
>>  +static ssize_t
>>  +label_show(struct device *dev, struct device_attribute *attr, char 
>> *buf)
>>  +{
>>  +	return sysfs_emit(buf, "%s\n", to_hwmon_device(dev)->label);
>>  +}
>>  +static DEVICE_ATTR_RO(label);
>>  +
>>   static struct attribute *hwmon_dev_attrs[] = {
>>   	&dev_attr_name.attr,
>>  +	&dev_attr_label.attr,
>>   	NULL
>>   };
>> 
>>  -static umode_t hwmon_dev_name_is_visible(struct kobject *kobj,
>>  +static umode_t hwmon_dev_attr_is_visible(struct kobject *kobj,
>>   					 struct attribute *attr, int n)
>>   {
>>   	struct device *dev = kobj_to_dev(kobj);
>>  +	struct hwmon_device *hdev = to_hwmon_device(dev);
>> 
>>  -	if (to_hwmon_device(dev)->name == NULL)
>>  +	if (attr == &dev_attr_name.attr && hdev->name == NULL)
>>  +		return 0;
>>  +
>>  +	if (attr == &dev_attr_label.attr && hdev->label == NULL)
>>   		return 0;
>> 
>>   	return attr->mode;
>>  @@ -89,7 +103,7 @@ static umode_t hwmon_dev_name_is_visible(struct 
>> kobject *kobj,
>> 
>>   static const struct attribute_group hwmon_dev_attr_group = {
>>   	.attrs		= hwmon_dev_attrs,
>>  -	.is_visible	= hwmon_dev_name_is_visible,
>>  +	.is_visible	= hwmon_dev_attr_is_visible,
>>   };
>> 
>>   static const struct attribute_group *hwmon_dev_attr_groups[] = {
>>  @@ -117,6 +131,7 @@ static void hwmon_dev_release(struct device 
>> *dev)
>>   	if (hwdev->group.attrs)
>>   		hwmon_free_attrs(hwdev->group.attrs);
>>   	kfree(hwdev->groups);
>>  +	kfree(hwdev->label);
>>   	kfree(hwdev);
>>   }
>> 
>>  @@ -733,6 +748,7 @@ __hwmon_device_register(struct device *dev, 
>> const char *name, void *drvdata,
>>   			const struct attribute_group **groups)
>>   {
>>   	struct hwmon_device *hwdev;
>>  +	const char *label;
>>   	struct device *hdev;
>>   	int i, err, id;
>> 
>>  @@ -752,6 +768,18 @@ __hwmon_device_register(struct device *dev, 
>> const char *name, void *drvdata,
>>   		goto ida_remove;
>>   	}
>> 
>>  +	if (device_property_present(dev, "label")) {
>>  +		err = device_property_read_string(dev, "label", &label);
>>  +		if (err < 0)
>>  +			goto free_hwmon;
>>  +
>>  +		hwdev->label = kstrdup(label, GFP_KERNEL);
>>  +		if (hwdev->label == NULL) {
>>  +			err = -ENOMEM;
>>  +			goto free_hwmon;
> 
> The code after free_hwmon: uses hdev, so 0-day has a point. Please 
> fix.

Yes indeed. I was going to send a v3.

-Paul

> 
>>  +		}
>>  +	}
>>  +
>>   	hdev = &hwdev->dev;
>> 
>>   	if (chip) {
diff mbox series

Patch

diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c
index 3501a3ead4ba..22e1b47c09fc 100644
--- a/drivers/hwmon/hwmon.c
+++ b/drivers/hwmon/hwmon.c
@@ -18,6 +18,7 @@ 
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/property.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/thermal.h>
@@ -30,6 +31,7 @@ 
 
 struct hwmon_device {
 	const char *name;
+	const char *label;
 	struct device dev;
 	const struct hwmon_chip_info *chip;
 	struct list_head tzdata;
@@ -71,17 +73,29 @@  name_show(struct device *dev, struct device_attribute *attr, char *buf)
 }
 static DEVICE_ATTR_RO(name);
 
+static ssize_t
+label_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return sysfs_emit(buf, "%s\n", to_hwmon_device(dev)->label);
+}
+static DEVICE_ATTR_RO(label);
+
 static struct attribute *hwmon_dev_attrs[] = {
 	&dev_attr_name.attr,
+	&dev_attr_label.attr,
 	NULL
 };
 
-static umode_t hwmon_dev_name_is_visible(struct kobject *kobj,
+static umode_t hwmon_dev_attr_is_visible(struct kobject *kobj,
 					 struct attribute *attr, int n)
 {
 	struct device *dev = kobj_to_dev(kobj);
+	struct hwmon_device *hdev = to_hwmon_device(dev);
 
-	if (to_hwmon_device(dev)->name == NULL)
+	if (attr == &dev_attr_name.attr && hdev->name == NULL)
+		return 0;
+
+	if (attr == &dev_attr_label.attr && hdev->label == NULL)
 		return 0;
 
 	return attr->mode;
@@ -89,7 +103,7 @@  static umode_t hwmon_dev_name_is_visible(struct kobject *kobj,
 
 static const struct attribute_group hwmon_dev_attr_group = {
 	.attrs		= hwmon_dev_attrs,
-	.is_visible	= hwmon_dev_name_is_visible,
+	.is_visible	= hwmon_dev_attr_is_visible,
 };
 
 static const struct attribute_group *hwmon_dev_attr_groups[] = {
@@ -117,6 +131,7 @@  static void hwmon_dev_release(struct device *dev)
 	if (hwdev->group.attrs)
 		hwmon_free_attrs(hwdev->group.attrs);
 	kfree(hwdev->groups);
+	kfree(hwdev->label);
 	kfree(hwdev);
 }
 
@@ -733,6 +748,7 @@  __hwmon_device_register(struct device *dev, const char *name, void *drvdata,
 			const struct attribute_group **groups)
 {
 	struct hwmon_device *hwdev;
+	const char *label;
 	struct device *hdev;
 	int i, err, id;
 
@@ -752,6 +768,18 @@  __hwmon_device_register(struct device *dev, const char *name, void *drvdata,
 		goto ida_remove;
 	}
 
+	if (device_property_present(dev, "label")) {
+		err = device_property_read_string(dev, "label", &label);
+		if (err < 0)
+			goto free_hwmon;
+
+		hwdev->label = kstrdup(label, GFP_KERNEL);
+		if (hwdev->label == NULL) {
+			err = -ENOMEM;
+			goto free_hwmon;
+		}
+	}
+
 	hdev = &hwdev->dev;
 
 	if (chip) {