Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: temperature: ltc2983: Make use of device properties

Convert the module to be property provider agnostic and allow
it to be used on non-OF platforms.

The conversion slightly changes the logic behind property reading for
the configuration values. Original code allocates just as much memory
as needed. Then for each separate 32- or 64-bit value it reads it from
the property and converts to a raw one which will be fed to the sensor.
In the new code we allocate the amount of memory needed to retrieve all
values at once from the property and then convert them as required.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Nuno Sá <nuno.sa@analog.com>
Tested-by: Nuno Sá <nuno.sa@analog.com>
Link: https://lore.kernel.org/r/20220307203606.87258-3-andriy.shevchenko@linux.intel.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Andy Shevchenko and committed by
Jonathan Cameron
bc4c9499 e59b18a2

+106 -103
+106 -103
drivers/iio/temperature/ltc2983.c
··· 12 12 #include <linux/iio/iio.h> 13 13 #include <linux/interrupt.h> 14 14 #include <linux/list.h> 15 + #include <linux/mod_devicetable.h> 15 16 #include <linux/module.h> 16 - #include <linux/of_gpio.h> 17 + #include <linux/property.h> 17 18 #include <linux/regmap.h> 18 19 #include <linux/spi/spi.h> 20 + 21 + #include <asm/byteorder.h> 22 + #include <asm/unaligned.h> 19 23 20 24 /* register map */ 21 25 #define LTC2983_STATUS_REG 0x0000 ··· 223 219 224 220 struct ltc2983_custom_sensor { 225 221 /* raw table sensor data */ 226 - u8 *table; 222 + void *table; 227 223 size_t size; 228 224 /* address offset */ 229 225 s8 offset; ··· 381 377 return regmap_bulk_write(st->regmap, reg, custom->table, custom->size); 382 378 } 383 379 384 - static struct ltc2983_custom_sensor *__ltc2983_custom_sensor_new( 385 - struct ltc2983_data *st, 386 - const struct device_node *np, 387 - const char *propname, 388 - const bool is_steinhart, 389 - const u32 resolution, 390 - const bool has_signed) 380 + static struct ltc2983_custom_sensor * 381 + __ltc2983_custom_sensor_new(struct ltc2983_data *st, const struct fwnode_handle *fn, 382 + const char *propname, const bool is_steinhart, 383 + const u32 resolution, const bool has_signed) 391 384 { 392 385 struct ltc2983_custom_sensor *new_custom; 393 - u8 index, n_entries, tbl = 0; 394 386 struct device *dev = &st->spi->dev; 395 387 /* 396 388 * For custom steinhart, the full u32 is taken. For all the others 397 389 * the MSB is discarded. 398 390 */ 399 391 const u8 n_size = is_steinhart ? 4 : 3; 400 - const u8 e_size = is_steinhart ? sizeof(u32) : sizeof(u64); 392 + u8 index, n_entries; 393 + int ret; 401 394 402 - n_entries = of_property_count_elems_of_size(np, propname, e_size); 395 + if (is_steinhart) 396 + n_entries = fwnode_property_count_u32(fn, propname); 397 + else 398 + n_entries = fwnode_property_count_u64(fn, propname); 403 399 /* n_entries must be an even number */ 404 400 if (!n_entries || (n_entries % 2) != 0) { 405 401 dev_err(dev, "Number of entries either 0 or not even\n"); ··· 427 423 } 428 424 429 425 /* allocate the table */ 430 - new_custom->table = devm_kzalloc(dev, new_custom->size, GFP_KERNEL); 426 + if (is_steinhart) 427 + new_custom->table = devm_kcalloc(dev, n_entries, sizeof(u32), GFP_KERNEL); 428 + else 429 + new_custom->table = devm_kcalloc(dev, n_entries, sizeof(u64), GFP_KERNEL); 431 430 if (!new_custom->table) 432 431 return ERR_PTR(-ENOMEM); 433 432 434 - for (index = 0; index < n_entries; index++) { 435 - u64 temp = 0, j; 436 - /* 437 - * Steinhart sensors are configured with raw values in the 438 - * devicetree. For the other sensors we must convert the 439 - * value to raw. The odd index's correspond to temperarures 440 - * and always have 1/1024 of resolution. Temperatures also 441 - * come in kelvin, so signed values is not possible 442 - */ 443 - if (!is_steinhart) { 444 - of_property_read_u64_index(np, propname, index, &temp); 433 + /* 434 + * Steinhart sensors are configured with raw values in the firmware 435 + * node. For the other sensors we must convert the value to raw. 436 + * The odd index's correspond to temperatures and always have 1/1024 437 + * of resolution. Temperatures also come in Kelvin, so signed values 438 + * are not possible. 439 + */ 440 + if (is_steinhart) { 441 + ret = fwnode_property_read_u32_array(fn, propname, new_custom->table, n_entries); 442 + if (ret < 0) 443 + return ERR_PTR(ret); 444 + 445 + cpu_to_be32_array(new_custom->table, new_custom->table, n_entries); 446 + } else { 447 + ret = fwnode_property_read_u64_array(fn, propname, new_custom->table, n_entries); 448 + if (ret < 0) 449 + return ERR_PTR(ret); 450 + 451 + for (index = 0; index < n_entries; index++) { 452 + u64 temp = ((u64 *)new_custom->table)[index]; 445 453 446 454 if ((index % 2) != 0) 447 455 temp = __convert_to_raw(temp, 1024); ··· 461 445 temp = __convert_to_raw_sign(temp, resolution); 462 446 else 463 447 temp = __convert_to_raw(temp, resolution); 464 - } else { 465 - u32 t32; 466 448 467 - of_property_read_u32_index(np, propname, index, &t32); 468 - temp = t32; 449 + put_unaligned_be24(temp, new_custom->table + index * 3); 469 450 } 470 - 471 - for (j = 0; j < n_size; j++) 472 - new_custom->table[tbl++] = 473 - temp >> (8 * (n_size - j - 1)); 474 451 } 475 452 476 453 new_custom->is_steinhart = is_steinhart; ··· 606 597 return __ltc2983_chan_assign_common(st, sensor, chan_val); 607 598 } 608 599 609 - static struct ltc2983_sensor *ltc2983_thermocouple_new( 610 - const struct device_node *child, 611 - struct ltc2983_data *st, 612 - const struct ltc2983_sensor *sensor) 600 + static struct ltc2983_sensor * 601 + ltc2983_thermocouple_new(const struct fwnode_handle *child, struct ltc2983_data *st, 602 + const struct ltc2983_sensor *sensor) 613 603 { 614 604 struct ltc2983_thermocouple *thermo; 615 - struct device_node *phandle; 605 + struct fwnode_handle *ref; 616 606 u32 oc_current; 617 607 int ret; 618 608 ··· 619 611 if (!thermo) 620 612 return ERR_PTR(-ENOMEM); 621 613 622 - if (of_property_read_bool(child, "adi,single-ended")) 614 + if (fwnode_property_read_bool(child, "adi,single-ended")) 623 615 thermo->sensor_config = LTC2983_THERMOCOUPLE_SGL(1); 624 616 625 - ret = of_property_read_u32(child, "adi,sensor-oc-current-microamp", 626 - &oc_current); 617 + ret = fwnode_property_read_u32(child, "adi,sensor-oc-current-microamp", &oc_current); 627 618 if (!ret) { 628 619 switch (oc_current) { 629 620 case 10: ··· 658 651 return ERR_PTR(-EINVAL); 659 652 } 660 653 661 - phandle = of_parse_phandle(child, "adi,cold-junction-handle", 0); 662 - if (phandle) { 663 - ret = of_property_read_u32(phandle, "reg", 664 - &thermo->cold_junction_chan); 654 + ref = fwnode_find_reference(child, "adi,cold-junction-handle", 0); 655 + if (IS_ERR(ref)) { 656 + ref = NULL; 657 + } else { 658 + ret = fwnode_property_read_u32(ref, "reg", &thermo->cold_junction_chan); 665 659 if (ret) { 666 660 /* 667 661 * This would be catched later but we can just return ··· 690 682 thermo->sensor.fault_handler = ltc2983_thermocouple_fault_handler; 691 683 thermo->sensor.assign_chan = ltc2983_thermocouple_assign_chan; 692 684 693 - of_node_put(phandle); 685 + fwnode_handle_put(ref); 694 686 return &thermo->sensor; 695 687 696 688 fail: 697 - of_node_put(phandle); 689 + fwnode_handle_put(ref); 698 690 return ERR_PTR(ret); 699 691 } 700 692 701 - static struct ltc2983_sensor *ltc2983_rtd_new(const struct device_node *child, 702 - struct ltc2983_data *st, 703 - const struct ltc2983_sensor *sensor) 693 + static struct ltc2983_sensor * 694 + ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st, 695 + const struct ltc2983_sensor *sensor) 704 696 { 705 697 struct ltc2983_rtd *rtd; 706 698 int ret = 0; 707 699 struct device *dev = &st->spi->dev; 708 - struct device_node *phandle; 700 + struct fwnode_handle *ref; 709 701 u32 excitation_current = 0, n_wires = 0; 710 702 711 703 rtd = devm_kzalloc(dev, sizeof(*rtd), GFP_KERNEL); 712 704 if (!rtd) 713 705 return ERR_PTR(-ENOMEM); 714 706 715 - phandle = of_parse_phandle(child, "adi,rsense-handle", 0); 716 - if (!phandle) { 707 + ref = fwnode_find_reference(child, "adi,rsense-handle", 0); 708 + if (IS_ERR(ref)) { 717 709 dev_err(dev, "Property adi,rsense-handle missing or invalid"); 718 - return ERR_PTR(-EINVAL); 710 + return ERR_CAST(ref); 719 711 } 720 712 721 - ret = of_property_read_u32(phandle, "reg", &rtd->r_sense_chan); 713 + ret = fwnode_property_read_u32(ref, "reg", &rtd->r_sense_chan); 722 714 if (ret) { 723 715 dev_err(dev, "Property reg must be given\n"); 724 716 goto fail; 725 717 } 726 718 727 - ret = of_property_read_u32(child, "adi,number-of-wires", &n_wires); 719 + ret = fwnode_property_read_u32(child, "adi,number-of-wires", &n_wires); 728 720 if (!ret) { 729 721 switch (n_wires) { 730 722 case 2: ··· 747 739 } 748 740 } 749 741 750 - if (of_property_read_bool(child, "adi,rsense-share")) { 742 + if (fwnode_property_read_bool(child, "adi,rsense-share")) { 751 743 /* Current rotation is only available with rsense sharing */ 752 - if (of_property_read_bool(child, "adi,current-rotate")) { 744 + if (fwnode_property_read_bool(child, "adi,current-rotate")) { 753 745 if (n_wires == 2 || n_wires == 3) { 754 746 dev_err(dev, 755 747 "Rotation not allowed for 2/3 Wire RTDs"); ··· 821 813 rtd->sensor.fault_handler = ltc2983_common_fault_handler; 822 814 rtd->sensor.assign_chan = ltc2983_rtd_assign_chan; 823 815 824 - ret = of_property_read_u32(child, "adi,excitation-current-microamp", 825 - &excitation_current); 816 + ret = fwnode_property_read_u32(child, "adi,excitation-current-microamp", 817 + &excitation_current); 826 818 if (ret) { 827 819 /* default to 5uA */ 828 820 rtd->excitation_current = 1; ··· 861 853 } 862 854 } 863 855 864 - of_property_read_u32(child, "adi,rtd-curve", &rtd->rtd_curve); 856 + fwnode_property_read_u32(child, "adi,rtd-curve", &rtd->rtd_curve); 865 857 866 - of_node_put(phandle); 858 + fwnode_handle_put(ref); 867 859 return &rtd->sensor; 868 860 fail: 869 - of_node_put(phandle); 861 + fwnode_handle_put(ref); 870 862 return ERR_PTR(ret); 871 863 } 872 864 873 - static struct ltc2983_sensor *ltc2983_thermistor_new( 874 - const struct device_node *child, 875 - struct ltc2983_data *st, 876 - const struct ltc2983_sensor *sensor) 865 + static struct ltc2983_sensor * 866 + ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *st, 867 + const struct ltc2983_sensor *sensor) 877 868 { 878 869 struct ltc2983_thermistor *thermistor; 879 870 struct device *dev = &st->spi->dev; 880 - struct device_node *phandle; 871 + struct fwnode_handle *ref; 881 872 u32 excitation_current = 0; 882 873 int ret = 0; 883 874 ··· 884 877 if (!thermistor) 885 878 return ERR_PTR(-ENOMEM); 886 879 887 - phandle = of_parse_phandle(child, "adi,rsense-handle", 0); 888 - if (!phandle) { 880 + ref = fwnode_find_reference(child, "adi,rsense-handle", 0); 881 + if (IS_ERR(ref)) { 889 882 dev_err(dev, "Property adi,rsense-handle missing or invalid"); 890 - return ERR_PTR(-EINVAL); 883 + return ERR_CAST(ref); 891 884 } 892 885 893 - ret = of_property_read_u32(phandle, "reg", &thermistor->r_sense_chan); 886 + ret = fwnode_property_read_u32(ref, "reg", &thermistor->r_sense_chan); 894 887 if (ret) { 895 888 dev_err(dev, "rsense channel must be configured...\n"); 896 889 goto fail; 897 890 } 898 891 899 - if (of_property_read_bool(child, "adi,single-ended")) { 892 + if (fwnode_property_read_bool(child, "adi,single-ended")) { 900 893 thermistor->sensor_config = LTC2983_THERMISTOR_SGL(1); 901 - } else if (of_property_read_bool(child, "adi,rsense-share")) { 894 + } else if (fwnode_property_read_bool(child, "adi,rsense-share")) { 902 895 /* rotation is only possible if sharing rsense */ 903 - if (of_property_read_bool(child, "adi,current-rotate")) 896 + if (fwnode_property_read_bool(child, "adi,current-rotate")) 904 897 thermistor->sensor_config = 905 898 LTC2983_THERMISTOR_C_ROTATE(1); 906 899 else ··· 942 935 thermistor->sensor.fault_handler = ltc2983_common_fault_handler; 943 936 thermistor->sensor.assign_chan = ltc2983_thermistor_assign_chan; 944 937 945 - ret = of_property_read_u32(child, "adi,excitation-current-nanoamp", 946 - &excitation_current); 938 + ret = fwnode_property_read_u32(child, "adi,excitation-current-nanoamp", 939 + &excitation_current); 947 940 if (ret) { 948 941 /* Auto range is not allowed for custom sensors */ 949 942 if (sensor->type >= LTC2983_SENSOR_THERMISTOR_STEINHART) ··· 1007 1000 } 1008 1001 } 1009 1002 1010 - of_node_put(phandle); 1003 + fwnode_handle_put(ref); 1011 1004 return &thermistor->sensor; 1012 1005 fail: 1013 - of_node_put(phandle); 1006 + fwnode_handle_put(ref); 1014 1007 return ERR_PTR(ret); 1015 1008 } 1016 1009 1017 - static struct ltc2983_sensor *ltc2983_diode_new( 1018 - const struct device_node *child, 1019 - const struct ltc2983_data *st, 1020 - const struct ltc2983_sensor *sensor) 1010 + static struct ltc2983_sensor * 1011 + ltc2983_diode_new(const struct fwnode_handle *child, const struct ltc2983_data *st, 1012 + const struct ltc2983_sensor *sensor) 1021 1013 { 1022 1014 struct ltc2983_diode *diode; 1023 1015 u32 temp = 0, excitation_current = 0; ··· 1026 1020 if (!diode) 1027 1021 return ERR_PTR(-ENOMEM); 1028 1022 1029 - if (of_property_read_bool(child, "adi,single-ended")) 1023 + if (fwnode_property_read_bool(child, "adi,single-ended")) 1030 1024 diode->sensor_config = LTC2983_DIODE_SGL(1); 1031 1025 1032 - if (of_property_read_bool(child, "adi,three-conversion-cycles")) 1026 + if (fwnode_property_read_bool(child, "adi,three-conversion-cycles")) 1033 1027 diode->sensor_config |= LTC2983_DIODE_3_CONV_CYCLE(1); 1034 1028 1035 - if (of_property_read_bool(child, "adi,average-on")) 1029 + if (fwnode_property_read_bool(child, "adi,average-on")) 1036 1030 diode->sensor_config |= LTC2983_DIODE_AVERAGE_ON(1); 1037 1031 1038 1032 /* validate channel index */ ··· 1047 1041 diode->sensor.fault_handler = ltc2983_common_fault_handler; 1048 1042 diode->sensor.assign_chan = ltc2983_diode_assign_chan; 1049 1043 1050 - ret = of_property_read_u32(child, "adi,excitation-current-microamp", 1051 - &excitation_current); 1044 + ret = fwnode_property_read_u32(child, "adi,excitation-current-microamp", 1045 + &excitation_current); 1052 1046 if (!ret) { 1053 1047 switch (excitation_current) { 1054 1048 case 10: ··· 1071 1065 } 1072 1066 } 1073 1067 1074 - of_property_read_u32(child, "adi,ideal-factor-value", &temp); 1068 + fwnode_property_read_u32(child, "adi,ideal-factor-value", &temp); 1075 1069 1076 1070 /* 2^20 resolution */ 1077 1071 diode->ideal_factor_value = __convert_to_raw(temp, 1048576); ··· 1079 1073 return &diode->sensor; 1080 1074 } 1081 1075 1082 - static struct ltc2983_sensor *ltc2983_r_sense_new(struct device_node *child, 1076 + static struct ltc2983_sensor *ltc2983_r_sense_new(struct fwnode_handle *child, 1083 1077 struct ltc2983_data *st, 1084 1078 const struct ltc2983_sensor *sensor) 1085 1079 { ··· 1098 1092 return ERR_PTR(-EINVAL); 1099 1093 } 1100 1094 1101 - ret = of_property_read_u32(child, "adi,rsense-val-milli-ohms", &temp); 1095 + ret = fwnode_property_read_u32(child, "adi,rsense-val-milli-ohms", &temp); 1102 1096 if (ret) { 1103 1097 dev_err(&st->spi->dev, "Property adi,rsense-val-milli-ohms missing\n"); 1104 1098 return ERR_PTR(-EINVAL); ··· 1117 1111 return &rsense->sensor; 1118 1112 } 1119 1113 1120 - static struct ltc2983_sensor *ltc2983_adc_new(struct device_node *child, 1114 + static struct ltc2983_sensor *ltc2983_adc_new(struct fwnode_handle *child, 1121 1115 struct ltc2983_data *st, 1122 1116 const struct ltc2983_sensor *sensor) 1123 1117 { ··· 1127 1121 if (!adc) 1128 1122 return ERR_PTR(-ENOMEM); 1129 1123 1130 - if (of_property_read_bool(child, "adi,single-ended")) 1124 + if (fwnode_property_read_bool(child, "adi,single-ended")) 1131 1125 adc->single_ended = true; 1132 1126 1133 1127 if (!adc->single_ended && ··· 1271 1265 1272 1266 static int ltc2983_parse_dt(struct ltc2983_data *st) 1273 1267 { 1274 - struct device_node *child; 1275 1268 struct device *dev = &st->spi->dev; 1269 + struct fwnode_handle *child; 1276 1270 int ret = 0, chan = 0, channel_avail_mask = 0; 1277 1271 1278 - of_property_read_u32(dev->of_node, "adi,mux-delay-config-us", 1279 - &st->mux_delay_config); 1272 + device_property_read_u32(dev, "adi,mux-delay-config-us", &st->mux_delay_config); 1280 1273 1281 - of_property_read_u32(dev->of_node, "adi,filter-notch-freq", 1282 - &st->filter_notch_freq); 1274 + device_property_read_u32(dev, "adi,filter-notch-freq", &st->filter_notch_freq); 1283 1275 1284 - st->num_channels = of_get_available_child_count(dev->of_node); 1276 + st->num_channels = device_get_child_node_count(dev); 1285 1277 if (!st->num_channels) { 1286 1278 dev_err(&st->spi->dev, "At least one channel must be given!"); 1287 1279 return -EINVAL; ··· 1291 1287 return -ENOMEM; 1292 1288 1293 1289 st->iio_channels = st->num_channels; 1294 - for_each_available_child_of_node(dev->of_node, child) { 1290 + device_for_each_child_node(dev, child) { 1295 1291 struct ltc2983_sensor sensor; 1296 1292 1297 - ret = of_property_read_u32(child, "reg", &sensor.chan); 1293 + ret = fwnode_property_read_u32(child, "reg", &sensor.chan); 1298 1294 if (ret) { 1299 1295 dev_err(dev, "reg property must given for child nodes\n"); 1300 1296 goto put_child; ··· 1313 1309 goto put_child; 1314 1310 } 1315 1311 1316 - ret = of_property_read_u32(child, "adi,sensor-type", 1317 - &sensor.type); 1312 + ret = fwnode_property_read_u32(child, "adi,sensor-type", &sensor.type); 1318 1313 if (ret) { 1319 1314 dev_err(dev, 1320 1315 "adi,sensor-type property must given for child nodes\n"); ··· 1367 1364 1368 1365 return 0; 1369 1366 put_child: 1370 - of_node_put(child); 1367 + fwnode_handle_put(child); 1371 1368 return ret; 1372 1369 } 1373 1370