[PATCH 4/4] power: supply: hwmon: move interface to private header

Thomas Weißschuh posted 4 patches 1 month, 3 weeks ago
[PATCH 4/4] power: supply: hwmon: move interface to private header
Posted by Thomas Weißschuh 1 month, 3 weeks ago
The interface of power_supply_hwmon.c is only meant to be used by the
psy core. Remove it from the public header file and use the private one
instead.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 drivers/power/supply/power_supply.h       | 17 +++++++++++++++++
 drivers/power/supply/power_supply_hwmon.c |  2 ++
 include/linux/power_supply.h              | 13 -------------
 3 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/power/supply/power_supply.h b/drivers/power/supply/power_supply.h
index 4c558fb3db7211a610134960292790ea3584b363..7434a6f2477504ee6c0a3c7420e1444387b41180 100644
--- a/drivers/power/supply/power_supply.h
+++ b/drivers/power/supply/power_supply.h
@@ -44,3 +44,20 @@ static inline int power_supply_create_triggers(struct power_supply *psy)
 static inline void power_supply_remove_triggers(struct power_supply *psy) {}
 
 #endif /* CONFIG_LEDS_TRIGGERS */
+
+#ifdef CONFIG_POWER_SUPPLY_HWMON
+
+int power_supply_add_hwmon_sysfs(struct power_supply *psy);
+void power_supply_remove_hwmon_sysfs(struct power_supply *psy);
+
+#else
+
+static inline int power_supply_add_hwmon_sysfs(struct power_supply *psy)
+{
+	return 0;
+}
+
+static inline
+void power_supply_remove_hwmon_sysfs(struct power_supply *psy) {}
+
+#endif /* CONFIG_POWER_SUPPLY_HWMON */
diff --git a/drivers/power/supply/power_supply_hwmon.c b/drivers/power/supply/power_supply_hwmon.c
index 01be04903d7d2465ae2acb9eeb0b55a87868bb87..9b30175ba9aefb0ebc0fbe73fdd158fcefc3bdda 100644
--- a/drivers/power/supply/power_supply_hwmon.c
+++ b/drivers/power/supply/power_supply_hwmon.c
@@ -9,6 +9,8 @@
 #include <linux/slab.h>
 #include "power_supply.h"
 
+#include "power_supply.h"
+
 struct power_supply_hwmon {
 	struct power_supply *psy;
 	unsigned long *props;
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index ea0ba149f296644bd18717d91f338172602eb6d6..58264343fb8a1590d02ec18a2d7fe9d874e3bc31 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -943,19 +943,6 @@ static inline bool power_supply_is_watt_property(enum power_supply_property psp)
 	return false;
 }
 
-#ifdef CONFIG_POWER_SUPPLY_HWMON
-int power_supply_add_hwmon_sysfs(struct power_supply *psy);
-void power_supply_remove_hwmon_sysfs(struct power_supply *psy);
-#else
-static inline int power_supply_add_hwmon_sysfs(struct power_supply *psy)
-{
-	return 0;
-}
-
-static inline
-void power_supply_remove_hwmon_sysfs(struct power_supply *psy) {}
-#endif
-
 #ifdef CONFIG_SYSFS
 ssize_t power_supply_charge_behaviour_show(struct device *dev,
 					   unsigned int available_behaviours,

-- 
2.46.2

Re: [PATCH 4/4] power: supply: hwmon: move interface to private header
Posted by kernel test robot 1 month, 3 weeks ago
Hi Thomas,

kernel test robot noticed the following build errors:

[auto build test ERROR on 27cc6fdf720183dce1dbd293483ec5a9cb6b595e]

url:    https://github.com/intel-lab-lkp/linux/commits/Thomas-Wei-schuh/power-supply-core-use-device-mutex-wrappers/20241005-181114
base:   27cc6fdf720183dce1dbd293483ec5a9cb6b595e
patch link:    https://lore.kernel.org/r/20241005-power-supply-cleanups-v1-4-45303b2d0a4d%40weissschuh.net
patch subject: [PATCH 4/4] power: supply: hwmon: move interface to private header
config: x86_64-randconfig-003-20241007 (https://download.01.org/0day-ci/archive/20241007/202410072120.3jlD28CJ-lkp@intel.com/config)
compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241007/202410072120.3jlD28CJ-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410072120.3jlD28CJ-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/power/supply/power_supply_hwmon.c:12:
>> drivers/power/supply/power_supply.h:41:20: error: redefinition of 'power_supply_update_leds'
      41 | static inline void power_supply_update_leds(struct power_supply *psy) {}
         |                    ^
   drivers/power/supply/power_supply.h:41:20: note: previous definition is here
      41 | static inline void power_supply_update_leds(struct power_supply *psy) {}
         |                    ^
   In file included from drivers/power/supply/power_supply_hwmon.c:12:
>> drivers/power/supply/power_supply.h:42:19: error: redefinition of 'power_supply_create_triggers'
      42 | static inline int power_supply_create_triggers(struct power_supply *psy)
         |                   ^
   drivers/power/supply/power_supply.h:42:19: note: previous definition is here
      42 | static inline int power_supply_create_triggers(struct power_supply *psy)
         |                   ^
   In file included from drivers/power/supply/power_supply_hwmon.c:12:
>> drivers/power/supply/power_supply.h:44:20: error: redefinition of 'power_supply_remove_triggers'
      44 | static inline void power_supply_remove_triggers(struct power_supply *psy) {}
         |                    ^
   drivers/power/supply/power_supply.h:44:20: note: previous definition is here
      44 | static inline void power_supply_remove_triggers(struct power_supply *psy) {}
         |                    ^
   3 errors generated.


vim +/power_supply_update_leds +41 drivers/power/supply/power_supply.h

4a11b59d828366 drivers/power/power_supply.h Anton Vorontsov 2007-05-04  40  
4a11b59d828366 drivers/power/power_supply.h Anton Vorontsov 2007-05-04 @41  static inline void power_supply_update_leds(struct power_supply *psy) {}
4a11b59d828366 drivers/power/power_supply.h Anton Vorontsov 2007-05-04 @42  static inline int power_supply_create_triggers(struct power_supply *psy)
4a11b59d828366 drivers/power/power_supply.h Anton Vorontsov 2007-05-04  43  { return 0; }
4a11b59d828366 drivers/power/power_supply.h Anton Vorontsov 2007-05-04 @44  static inline void power_supply_remove_triggers(struct power_supply *psy) {}
4a11b59d828366 drivers/power/power_supply.h Anton Vorontsov 2007-05-04  45  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH 4/4] power: supply: hwmon: move interface to private header
Posted by kernel test robot 1 month, 3 weeks ago
Hi Thomas,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 27cc6fdf720183dce1dbd293483ec5a9cb6b595e]

url:    https://github.com/intel-lab-lkp/linux/commits/Thomas-Wei-schuh/power-supply-core-use-device-mutex-wrappers/20241005-181114
base:   27cc6fdf720183dce1dbd293483ec5a9cb6b595e
patch link:    https://lore.kernel.org/r/20241005-power-supply-cleanups-v1-4-45303b2d0a4d%40weissschuh.net
patch subject: [PATCH 4/4] power: supply: hwmon: move interface to private header
compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410060751.fvcDrsTY-lkp@intel.com/

includecheck warnings: (new ones prefixed by >>)
>> drivers/power/supply/power_supply_hwmon.c: power_supply.h is included more than once.

vim +3 drivers/power/supply/power_supply_hwmon.c

   > 3	 *  power_supply_hwmon.c - power supply hwmon support.
     4	 */
     5	
     6	#include <linux/err.h>
     7	#include <linux/hwmon.h>
   > 8	#include <linux/power_supply.h>
     9	#include <linux/slab.h>
  > 10	#include "power_supply.h"
    11	
  > 12	#include "power_supply.h"
    13	
  > 14	struct power_supply_hwmon {
    15		struct power_supply *psy;
    16		unsigned long *props;
    17	};
    18	
    19	static const char *const ps_temp_label[] = {
    20		"temp",
    21		"ambient temp",
    22	};
    23	
  > 24	static int power_supply_hwmon_in_to_property(u32 attr)
    25	{
    26		switch (attr) {
    27		case hwmon_in_average:
    28			return POWER_SUPPLY_PROP_VOLTAGE_AVG;
    29		case hwmon_in_min:
    30			return POWER_SUPPLY_PROP_VOLTAGE_MIN;
    31		case hwmon_in_max:
    32			return POWER_SUPPLY_PROP_VOLTAGE_MAX;
    33		case hwmon_in_input:
    34			return POWER_SUPPLY_PROP_VOLTAGE_NOW;
    35		default:
    36			return -EINVAL;
    37		}
    38	}
    39	
  > 40	static int power_supply_hwmon_curr_to_property(u32 attr)
    41	{
    42		switch (attr) {
    43		case hwmon_curr_average:
    44			return POWER_SUPPLY_PROP_CURRENT_AVG;
    45		case hwmon_curr_max:
    46			return POWER_SUPPLY_PROP_CURRENT_MAX;
    47		case hwmon_curr_input:
    48			return POWER_SUPPLY_PROP_CURRENT_NOW;
    49		default:
    50			return -EINVAL;
    51		}
    52	}
    53	
  > 54	static int power_supply_hwmon_power_to_property(u32 attr)
    55	{
    56		switch (attr) {
    57		case hwmon_power_input:
    58			return POWER_SUPPLY_PROP_POWER_NOW;
    59		case hwmon_power_average:
    60			return POWER_SUPPLY_PROP_POWER_AVG;
    61		default:
    62			return -EINVAL;
    63		}
    64	}
    65	
  > 66	static int power_supply_hwmon_temp_to_property(u32 attr, int channel)
    67	{
    68		if (channel) {
    69			switch (attr) {
    70			case hwmon_temp_input:
    71				return POWER_SUPPLY_PROP_TEMP_AMBIENT;
    72			case hwmon_temp_min_alarm:
    73				return POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN;
    74			case hwmon_temp_max_alarm:
    75				return POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX;
    76			default:
    77				break;
    78			}
    79		} else {
    80			switch (attr) {
    81			case hwmon_temp_input:
    82				return POWER_SUPPLY_PROP_TEMP;
    83			case hwmon_temp_max:
    84				return POWER_SUPPLY_PROP_TEMP_MAX;
    85			case hwmon_temp_min:
    86				return POWER_SUPPLY_PROP_TEMP_MIN;
    87			case hwmon_temp_min_alarm:
    88				return POWER_SUPPLY_PROP_TEMP_ALERT_MIN;
    89			case hwmon_temp_max_alarm:
    90				return POWER_SUPPLY_PROP_TEMP_ALERT_MAX;
    91			default:
    92				break;
    93			}
    94		}
    95	
    96		return -EINVAL;
    97	}
    98	
    99	static int
 > 100	power_supply_hwmon_to_property(enum hwmon_sensor_types type,
   101				       u32 attr, int channel)
   102	{
   103		switch (type) {
   104		case hwmon_in:
 > 105			return power_supply_hwmon_in_to_property(attr);
   106		case hwmon_curr:
 > 107			return power_supply_hwmon_curr_to_property(attr);
   108		case hwmon_power:
 > 109			return power_supply_hwmon_power_to_property(attr);
   110		case hwmon_temp:
 > 111			return power_supply_hwmon_temp_to_property(attr, channel);
   112		default:
   113			return -EINVAL;
   114		}
   115	}
   116	
 > 117	static bool power_supply_hwmon_is_a_label(enum hwmon_sensor_types type,
   118						   u32 attr)
   119	{
   120		return type == hwmon_temp && attr == hwmon_temp_label;
   121	}
   122	
   123	struct hwmon_type_attr_list {
   124		const u32 *attrs;
   125		size_t n_attrs;
   126	};
   127	
   128	static const u32 ps_temp_attrs[] = {
   129		hwmon_temp_input,
   130		hwmon_temp_min, hwmon_temp_max,
   131		hwmon_temp_min_alarm, hwmon_temp_max_alarm,
   132	};
   133	
   134	static const struct hwmon_type_attr_list ps_type_attrs[hwmon_max] = {
   135		[hwmon_temp] = { ps_temp_attrs, ARRAY_SIZE(ps_temp_attrs) },
   136	};
   137	
 > 138	static bool power_supply_hwmon_has_input(
 > 139		const struct power_supply_hwmon *psyhw,
   140		enum hwmon_sensor_types type, int channel)
   141	{
   142		const struct hwmon_type_attr_list *attr_list = &ps_type_attrs[type];
   143		size_t i;
   144	
   145		for (i = 0; i < attr_list->n_attrs; ++i) {
 > 146			int prop = power_supply_hwmon_to_property(type,
   147				attr_list->attrs[i], channel);
   148	
   149			if (prop >= 0 && test_bit(prop, psyhw->props))
   150				return true;
   151		}
   152	
   153		return false;
   154	}
   155	
 > 156	static bool power_supply_hwmon_is_writable(enum hwmon_sensor_types type,
   157						   u32 attr)
   158	{
   159		switch (type) {
   160		case hwmon_in:
   161			return attr == hwmon_in_min ||
   162			       attr == hwmon_in_max;
   163		case hwmon_curr:
   164			return attr == hwmon_curr_max;
   165		case hwmon_temp:
   166			return attr == hwmon_temp_max ||
   167			       attr == hwmon_temp_min ||
   168			       attr == hwmon_temp_min_alarm ||
   169			       attr == hwmon_temp_max_alarm;
   170		default:
   171			return false;
   172		}
   173	}
   174	
 > 175	static umode_t power_supply_hwmon_is_visible(const void *data,
   176						     enum hwmon_sensor_types type,
   177						     u32 attr, int channel)
   178	{
 > 179		const struct power_supply_hwmon *psyhw = data;
   180		int prop;
   181	
 > 182		if (power_supply_hwmon_is_a_label(type, attr)) {
 > 183			if (power_supply_hwmon_has_input(psyhw, type, channel))
   184				return 0444;
   185			else
   186				return 0;
   187		}
   188	
 > 189		prop = power_supply_hwmon_to_property(type, attr, channel);
   190		if (prop < 0 || !test_bit(prop, psyhw->props))
   191			return 0;
   192	
   193		if (power_supply_property_is_writeable(psyhw->psy, prop) > 0 &&
 > 194		    power_supply_hwmon_is_writable(type, attr))
   195			return 0644;
   196	
   197		return 0444;
   198	}
   199	
 > 200	static int power_supply_hwmon_read_string(struct device *dev,
   201						  enum hwmon_sensor_types type,
   202						  u32 attr, int channel,
   203						  const char **str)
   204	{
   205		switch (type) {
   206		case hwmon_temp:
   207			*str = ps_temp_label[channel];
   208			break;
   209		default:
   210			/* unreachable, but see:
   211			 * gcc bug #51513 [1] and clang bug #978 [2]
   212			 *
   213			 * [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51513
   214			 * [2] https://github.com/ClangBuiltLinux/linux/issues/978
   215			 */
   216			break;
   217		}
   218	
   219		return 0;
   220	}
   221	
   222	static int
 > 223	power_supply_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
   224				u32 attr, int channel, long *val)
   225	{
 > 226		struct power_supply_hwmon *psyhw = dev_get_drvdata(dev);
   227		struct power_supply *psy = psyhw->psy;
   228		union power_supply_propval pspval;
   229		int ret, prop;
   230	
 > 231		prop = power_supply_hwmon_to_property(type, attr, channel);
   232		if (prop < 0)
   233			return prop;
   234	
   235		ret  = power_supply_get_property(psy, prop, &pspval);
   236		if (ret)
   237			return ret;
   238	
   239		switch (type) {
   240		/*
   241		 * Both voltage and current is reported in units of
   242		 * microvolts/microamps, so we need to adjust it to
   243		 * milliamps(volts)
   244		 */
   245		case hwmon_curr:
   246		case hwmon_in:
   247			pspval.intval = DIV_ROUND_CLOSEST(pspval.intval, 1000);
   248			break;
   249		case hwmon_power:
   250			/*
   251			 * Power properties are already in microwatts.
   252			 */
   253			break;
   254		/*
   255		 * Temp needs to be converted from 1/10 C to milli-C
   256		 */
   257		case hwmon_temp:
   258			if (check_mul_overflow(pspval.intval, 100,
   259					       &pspval.intval))
   260				return -EOVERFLOW;
   261			break;
   262		default:
   263			return -EINVAL;
   264		}
   265	
   266		*val = pspval.intval;
   267	
   268		return 0;
   269	}
   270	
   271	static int
 > 272	power_supply_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
   273				 u32 attr, int channel, long val)
   274	{
 > 275		struct power_supply_hwmon *psyhw = dev_get_drvdata(dev);
   276		struct power_supply *psy = psyhw->psy;
   277		union power_supply_propval pspval;
   278		int prop;
   279	
 > 280		prop = power_supply_hwmon_to_property(type, attr, channel);
   281		if (prop < 0)
   282			return prop;
   283	
   284		pspval.intval = val;
   285	
   286		switch (type) {
   287		/*
   288		 * Both voltage and current is reported in units of
   289		 * microvolts/microamps, so we need to adjust it to
   290		 * milliamps(volts)
   291		 */
   292		case hwmon_curr:
   293		case hwmon_in:
   294			if (check_mul_overflow(pspval.intval, 1000,
   295					       &pspval.intval))
   296				return -EOVERFLOW;
   297			break;
   298		/*
   299		 * Temp needs to be converted from 1/10 C to milli-C
   300		 */
   301		case hwmon_temp:
   302			pspval.intval = DIV_ROUND_CLOSEST(pspval.intval, 100);
   303			break;
   304		default:
   305			return -EINVAL;
   306		}
   307	
   308		return power_supply_set_property(psy, prop, &pspval);
   309	}
   310	
 > 311	static const struct hwmon_ops power_supply_hwmon_ops = {
 > 312		.is_visible	= power_supply_hwmon_is_visible,
 > 313		.read		= power_supply_hwmon_read,
 > 314		.write		= power_supply_hwmon_write,
 > 315		.read_string	= power_supply_hwmon_read_string,
   316	};
   317	
 > 318	static const struct hwmon_channel_info * const power_supply_hwmon_info[] = {
   319		HWMON_CHANNEL_INFO(temp,
   320				   HWMON_T_LABEL     |
   321				   HWMON_T_INPUT     |
   322				   HWMON_T_MAX       |
   323				   HWMON_T_MIN       |
   324				   HWMON_T_MIN_ALARM |
   325				   HWMON_T_MAX_ALARM,
   326	
   327				   HWMON_T_LABEL     |
   328				   HWMON_T_INPUT     |
   329				   HWMON_T_MIN_ALARM |
   330				   HWMON_T_MAX_ALARM),
   331	
   332		HWMON_CHANNEL_INFO(curr,
   333				   HWMON_C_AVERAGE |
   334				   HWMON_C_MAX     |
   335				   HWMON_C_INPUT),
   336	
   337		HWMON_CHANNEL_INFO(power,
   338				   HWMON_P_INPUT |
   339				   HWMON_P_AVERAGE),
   340	
   341		HWMON_CHANNEL_INFO(in,
   342				   HWMON_I_AVERAGE |
   343				   HWMON_I_MIN     |
   344				   HWMON_I_MAX     |
   345				   HWMON_I_INPUT),
   346		NULL
   347	};
   348	
 > 349	static const struct hwmon_chip_info power_supply_hwmon_chip_info = {
 > 350		.ops = &power_supply_hwmon_ops,
 > 351		.info = power_supply_hwmon_info,
   352	};
   353	
   354	int power_supply_add_hwmon_sysfs(struct power_supply *psy)
   355	{
   356		const struct power_supply_desc *desc = psy->desc;
 > 357		struct power_supply_hwmon *psyhw;
   358		struct device *dev = &psy->dev;
   359		struct device *hwmon;
   360		int ret, i;
   361		const char *name;
   362	
   363		if (!devres_open_group(dev, power_supply_add_hwmon_sysfs,
   364				       GFP_KERNEL))
   365			return -ENOMEM;
   366	
   367		psyhw = devm_kzalloc(dev, sizeof(*psyhw), GFP_KERNEL);
   368		if (!psyhw) {
   369			ret = -ENOMEM;
   370			goto error;
   371		}
   372	
   373		psyhw->psy = psy;
   374		psyhw->props = devm_bitmap_zalloc(dev,
   375						  POWER_SUPPLY_PROP_TIME_TO_FULL_AVG + 1,
   376						  GFP_KERNEL);
   377		if (!psyhw->props) {
   378			ret = -ENOMEM;
   379			goto error;
   380		}
   381	
   382		for (i = 0; i < desc->num_properties; i++) {
   383			const enum power_supply_property prop = desc->properties[i];
   384	
   385			switch (prop) {
   386			case POWER_SUPPLY_PROP_CURRENT_AVG:
   387			case POWER_SUPPLY_PROP_CURRENT_MAX:
   388			case POWER_SUPPLY_PROP_CURRENT_NOW:
   389			case POWER_SUPPLY_PROP_POWER_AVG:
   390			case POWER_SUPPLY_PROP_POWER_NOW:
   391			case POWER_SUPPLY_PROP_TEMP:
   392			case POWER_SUPPLY_PROP_TEMP_MAX:
   393			case POWER_SUPPLY_PROP_TEMP_MIN:
   394			case POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
   395			case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
   396			case POWER_SUPPLY_PROP_TEMP_AMBIENT:
   397			case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN:
   398			case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX:
   399			case POWER_SUPPLY_PROP_VOLTAGE_AVG:
   400			case POWER_SUPPLY_PROP_VOLTAGE_MIN:
   401			case POWER_SUPPLY_PROP_VOLTAGE_MAX:
   402			case POWER_SUPPLY_PROP_VOLTAGE_NOW:
   403				set_bit(prop, psyhw->props);
   404				break;
   405			default:
   406				break;
   407			}
   408		}
   409	
   410		name = psy->desc->name;
   411		if (strchr(name, '-')) {
   412			char *new_name;
   413	
   414			new_name = devm_kstrdup(dev, name, GFP_KERNEL);
   415			if (!new_name) {
   416				ret = -ENOMEM;
   417				goto error;
   418			}
   419			strreplace(new_name, '-', '_');
   420			name = new_name;
   421		}
   422		hwmon = devm_hwmon_device_register_with_info(dev, name,
   423							psyhw,
 > 424							&power_supply_hwmon_chip_info,
   425							NULL);
   426		ret = PTR_ERR_OR_ZERO(hwmon);
   427		if (ret)
   428			goto error;
   429	
   430		devres_close_group(dev, power_supply_add_hwmon_sysfs);
   431		return 0;
   432	error:
   433		devres_release_group(dev, NULL);
   434		return ret;
   435	}
   436	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki