Message ID | 20241005-power-supply-cleanups-v1-4-45303b2d0a4d@weissschuh.net |
---|---|
State | New |
Headers | show |
Series | power: supply: core: random cleanups and optimizations | expand |
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
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,
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(-)