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

staging: iio: tsl2x7x: check return value from tsl2x7x_invoke_change()

The return value from tsl2x7x_invoke_change() was not checked in most
places in the driver. This patch adds the proper error checks. The
return values inside tsl2x7x_invoke_change() are now checked by
this patch as well.

Previously, if there was an error turning the chip back on, then the
driver would attempt to turn the chip off and incorrectly return
success. The code to power off the chip is removed by this patch
since we should fail fast.

Signed-off-by: Brian Masney <masneyb@onstation.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Brian Masney and committed by
Jonathan Cameron
0503deb8 36a28e4a

+37 -18
+37 -18
drivers/staging/iio/light/tsl2x7x.c
··· 771 771 { 772 772 struct tsl2X7X_chip *chip = iio_priv(indio_dev); 773 773 int device_status = chip->tsl2x7x_chip_status; 774 + int ret; 774 775 775 776 mutex_lock(&chip->als_mutex); 776 777 mutex_lock(&chip->prox_mutex); 777 778 778 - if (device_status == TSL2X7X_CHIP_WORKING) 779 - tsl2x7x_chip_off(indio_dev); 779 + if (device_status == TSL2X7X_CHIP_WORKING) { 780 + ret = tsl2x7x_chip_off(indio_dev); 781 + if (ret < 0) 782 + goto unlock; 783 + } 780 784 781 - tsl2x7x_chip_on(indio_dev); 785 + ret = tsl2x7x_chip_on(indio_dev); 782 786 783 - if (device_status != TSL2X7X_CHIP_WORKING) 784 - tsl2x7x_chip_off(indio_dev); 785 - 787 + unlock: 786 788 mutex_unlock(&chip->prox_mutex); 787 789 mutex_unlock(&chip->als_mutex); 788 790 789 - return 0; 791 + return ret; 790 792 } 791 793 792 794 static ··· 967 965 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 968 966 struct tsl2X7X_chip *chip = iio_priv(indio_dev); 969 967 unsigned long value; 968 + int ret; 970 969 971 970 if (kstrtoul(buf, 0, &value)) 972 971 return -EINVAL; ··· 975 972 if (value) 976 973 chip->tsl2x7x_settings.als_cal_target = value; 977 974 978 - tsl2x7x_invoke_change(indio_dev); 975 + ret = tsl2x7x_invoke_change(indio_dev); 976 + if (ret < 0) 977 + return ret; 979 978 980 979 return len; 981 980 } ··· 1026 1021 dev_info(&chip->client->dev, "%s: als persistence = %d", 1027 1022 __func__, filter_delay); 1028 1023 1029 - tsl2x7x_invoke_change(indio_dev); 1024 + ret = tsl2x7x_invoke_change(indio_dev); 1025 + if (ret < 0) 1026 + return ret; 1030 1027 1031 1028 return IIO_VAL_INT_PLUS_MICRO; 1032 1029 } ··· 1076 1069 dev_info(&chip->client->dev, "%s: prox persistence = %d", 1077 1070 __func__, filter_delay); 1078 1071 1079 - tsl2x7x_invoke_change(indio_dev); 1072 + ret = tsl2x7x_invoke_change(indio_dev); 1073 + if (ret < 0) 1074 + return ret; 1075 + 1080 1076 1081 1077 return IIO_VAL_INT_PLUS_MICRO; 1082 1078 } ··· 1090 1080 { 1091 1081 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 1092 1082 bool value; 1083 + int ret; 1093 1084 1094 1085 if (strtobool(buf, &value)) 1095 1086 return -EINVAL; ··· 1098 1087 if (value) 1099 1088 tsl2x7x_als_calibrate(indio_dev); 1100 1089 1101 - tsl2x7x_invoke_change(indio_dev); 1090 + ret = tsl2x7x_invoke_change(indio_dev); 1091 + if (ret < 0) 1092 + return ret; 1102 1093 1103 1094 return len; 1104 1095 } ··· 1140 1127 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 1141 1128 struct tsl2X7X_chip *chip = iio_priv(indio_dev); 1142 1129 int value[ARRAY_SIZE(chip->tsl2x7x_device_lux) * 3 + 1]; 1143 - int n; 1130 + int n, ret; 1144 1131 1145 1132 get_options(buf, ARRAY_SIZE(value), value); 1146 1133 ··· 1168 1155 memset(chip->tsl2x7x_device_lux, 0, sizeof(chip->tsl2x7x_device_lux)); 1169 1156 memcpy(chip->tsl2x7x_device_lux, &value[1], (value[0] * 4)); 1170 1157 1171 - tsl2x7x_invoke_change(indio_dev); 1158 + ret = tsl2x7x_invoke_change(indio_dev); 1159 + if (ret < 0) 1160 + return ret; 1172 1161 1173 1162 return len; 1174 1163 } ··· 1181 1166 { 1182 1167 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 1183 1168 bool value; 1169 + int ret; 1184 1170 1185 1171 if (strtobool(buf, &value)) 1186 1172 return -EINVAL; ··· 1189 1173 if (value) 1190 1174 tsl2x7x_prox_cal(indio_dev); 1191 1175 1192 - tsl2x7x_invoke_change(indio_dev); 1176 + ret = tsl2x7x_invoke_change(indio_dev); 1177 + if (ret < 0) 1178 + return ret; 1193 1179 1194 1180 return len; 1195 1181 } ··· 1219 1201 int val) 1220 1202 { 1221 1203 struct tsl2X7X_chip *chip = iio_priv(indio_dev); 1204 + int ret; 1222 1205 1223 1206 if (chan->type == IIO_INTENSITY) { 1224 1207 if (val) ··· 1233 1214 chip->tsl2x7x_settings.interrupts_en &= 0x10; 1234 1215 } 1235 1216 1236 - tsl2x7x_invoke_change(indio_dev); 1217 + ret = tsl2x7x_invoke_change(indio_dev); 1218 + if (ret < 0) 1219 + return ret; 1237 1220 1238 1221 return 0; 1239 1222 } ··· 1471 1450 return -EINVAL; 1472 1451 } 1473 1452 1474 - tsl2x7x_invoke_change(indio_dev); 1475 - 1476 - return 0; 1453 + return tsl2x7x_invoke_change(indio_dev); 1477 1454 } 1478 1455 1479 1456 static DEVICE_ATTR_RO(in_proximity0_calibscale_available);