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

Merge tag 'tag-chrome-platform-fixes-for-v5.7-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux

Pull chrome platform fix from Benson Leung:
"Fix a resource allocation issue in cros_ec_sensorhub.c"

* tag 'tag-chrome-platform-fixes-for-v5.7-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux:
platform/chrome: cros_ec_sensorhub: Allocate sensorhub resource before claiming sensors

+94 -62
+46 -34
drivers/platform/chrome/cros_ec_sensorhub.c
··· 52 52 int sensor_type[MOTIONSENSE_TYPE_MAX] = { 0 }; 53 53 struct cros_ec_command *msg = sensorhub->msg; 54 54 struct cros_ec_dev *ec = sensorhub->ec; 55 - int ret, i, sensor_num; 55 + int ret, i; 56 56 char *name; 57 57 58 - sensor_num = cros_ec_get_sensor_count(ec); 59 - if (sensor_num < 0) { 60 - dev_err(dev, 61 - "Unable to retrieve sensor information (err:%d)\n", 62 - sensor_num); 63 - return sensor_num; 64 - } 65 - 66 - sensorhub->sensor_num = sensor_num; 67 - if (sensor_num == 0) { 68 - dev_err(dev, "Zero sensors reported.\n"); 69 - return -EINVAL; 70 - } 71 58 72 59 msg->version = 1; 73 60 msg->insize = sizeof(struct ec_response_motion_sense); 74 61 msg->outsize = sizeof(struct ec_params_motion_sense); 75 62 76 - for (i = 0; i < sensor_num; i++) { 63 + for (i = 0; i < sensorhub->sensor_num; i++) { 77 64 sensorhub->params->cmd = MOTIONSENSE_CMD_INFO; 78 65 sensorhub->params->info.sensor_num = i; 79 66 ··· 127 140 struct cros_ec_dev *ec = dev_get_drvdata(dev->parent); 128 141 struct cros_ec_sensorhub *data; 129 142 struct cros_ec_command *msg; 130 - int ret; 131 - int i; 143 + int ret, i, sensor_num; 132 144 133 145 msg = devm_kzalloc(dev, sizeof(struct cros_ec_command) + 134 146 max((u16)sizeof(struct ec_params_motion_sense), ··· 152 166 dev_set_drvdata(dev, data); 153 167 154 168 /* Check whether this EC is a sensor hub. */ 155 - if (cros_ec_check_features(data->ec, EC_FEATURE_MOTION_SENSE)) { 169 + if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE)) { 170 + sensor_num = cros_ec_get_sensor_count(ec); 171 + if (sensor_num < 0) { 172 + dev_err(dev, 173 + "Unable to retrieve sensor information (err:%d)\n", 174 + sensor_num); 175 + return sensor_num; 176 + } 177 + if (sensor_num == 0) { 178 + dev_err(dev, "Zero sensors reported.\n"); 179 + return -EINVAL; 180 + } 181 + data->sensor_num = sensor_num; 182 + 183 + /* 184 + * Prepare the ring handler before enumering the 185 + * sensors. 186 + */ 187 + if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) { 188 + ret = cros_ec_sensorhub_ring_allocate(data); 189 + if (ret) 190 + return ret; 191 + } 192 + 193 + /* Enumerate the sensors.*/ 156 194 ret = cros_ec_sensorhub_register(dev, data); 157 195 if (ret) 158 196 return ret; 197 + 198 + /* 199 + * When the EC does not have a FIFO, the sensors will query 200 + * their data themselves via sysfs or a software trigger. 201 + */ 202 + if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) { 203 + ret = cros_ec_sensorhub_ring_add(data); 204 + if (ret) 205 + return ret; 206 + /* 207 + * The msg and its data is not under the control of the 208 + * ring handler. 209 + */ 210 + return devm_add_action_or_reset(dev, 211 + cros_ec_sensorhub_ring_remove, 212 + data); 213 + } 214 + 159 215 } else { 160 216 /* 161 217 * If the device has sensors but does not claim to ··· 212 184 } 213 185 } 214 186 215 - /* 216 - * If the EC does not have a FIFO, the sensors will query their data 217 - * themselves via sysfs or a software trigger. 218 - */ 219 - if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) { 220 - ret = cros_ec_sensorhub_ring_add(data); 221 - if (ret) 222 - return ret; 223 - /* 224 - * The msg and its data is not under the control of the ring 225 - * handler. 226 - */ 227 - return devm_add_action_or_reset(dev, 228 - cros_ec_sensorhub_ring_remove, 229 - data); 230 - } 231 187 232 188 return 0; 233 189 }
+47 -28
drivers/platform/chrome/cros_ec_sensorhub_ring.c
··· 957 957 } 958 958 959 959 /** 960 + * cros_ec_sensorhub_ring_allocate() - Prepare the FIFO functionality if the EC 961 + * supports it. 962 + * 963 + * @sensorhub : Sensor Hub object. 964 + * 965 + * Return: 0 on success. 966 + */ 967 + int cros_ec_sensorhub_ring_allocate(struct cros_ec_sensorhub *sensorhub) 968 + { 969 + int fifo_info_length = 970 + sizeof(struct ec_response_motion_sense_fifo_info) + 971 + sizeof(u16) * sensorhub->sensor_num; 972 + 973 + /* Allocate the array for lost events. */ 974 + sensorhub->fifo_info = devm_kzalloc(sensorhub->dev, fifo_info_length, 975 + GFP_KERNEL); 976 + if (!sensorhub->fifo_info) 977 + return -ENOMEM; 978 + 979 + /* 980 + * Allocate the callback area based on the number of sensors. 981 + * Add one for the sensor ring. 982 + */ 983 + sensorhub->push_data = devm_kcalloc(sensorhub->dev, 984 + sensorhub->sensor_num, 985 + sizeof(*sensorhub->push_data), 986 + GFP_KERNEL); 987 + if (!sensorhub->push_data) 988 + return -ENOMEM; 989 + 990 + sensorhub->tight_timestamps = cros_ec_check_features( 991 + sensorhub->ec, 992 + EC_FEATURE_MOTION_SENSE_TIGHT_TIMESTAMPS); 993 + 994 + if (sensorhub->tight_timestamps) { 995 + sensorhub->batch_state = devm_kcalloc(sensorhub->dev, 996 + sensorhub->sensor_num, 997 + sizeof(*sensorhub->batch_state), 998 + GFP_KERNEL); 999 + if (!sensorhub->batch_state) 1000 + return -ENOMEM; 1001 + } 1002 + 1003 + return 0; 1004 + } 1005 + 1006 + /** 960 1007 * cros_ec_sensorhub_ring_add() - Add the FIFO functionality if the EC 961 1008 * supports it. 962 1009 * ··· 1018 971 int fifo_info_length = 1019 972 sizeof(struct ec_response_motion_sense_fifo_info) + 1020 973 sizeof(u16) * sensorhub->sensor_num; 1021 - 1022 - /* Allocate the array for lost events. */ 1023 - sensorhub->fifo_info = devm_kzalloc(sensorhub->dev, fifo_info_length, 1024 - GFP_KERNEL); 1025 - if (!sensorhub->fifo_info) 1026 - return -ENOMEM; 1027 974 1028 975 /* Retrieve FIFO information */ 1029 976 sensorhub->msg->version = 2; ··· 1039 998 if (!sensorhub->ring) 1040 999 return -ENOMEM; 1041 1000 1042 - /* 1043 - * Allocate the callback area based on the number of sensors. 1044 - */ 1045 - sensorhub->push_data = devm_kcalloc( 1046 - sensorhub->dev, sensorhub->sensor_num, 1047 - sizeof(*sensorhub->push_data), 1048 - GFP_KERNEL); 1049 - if (!sensorhub->push_data) 1050 - return -ENOMEM; 1051 - 1052 1001 sensorhub->fifo_timestamp[CROS_EC_SENSOR_LAST_TS] = 1053 1002 cros_ec_get_time_ns(); 1054 - 1055 - sensorhub->tight_timestamps = cros_ec_check_features( 1056 - ec, EC_FEATURE_MOTION_SENSE_TIGHT_TIMESTAMPS); 1057 - 1058 - if (sensorhub->tight_timestamps) { 1059 - sensorhub->batch_state = devm_kcalloc(sensorhub->dev, 1060 - sensorhub->sensor_num, 1061 - sizeof(*sensorhub->batch_state), 1062 - GFP_KERNEL); 1063 - if (!sensorhub->batch_state) 1064 - return -ENOMEM; 1065 - } 1066 1003 1067 1004 /* Register the notifier that will act as a top half interrupt. */ 1068 1005 sensorhub->notifier.notifier_call = cros_ec_sensorhub_event;
+1
include/linux/platform_data/cros_ec_sensorhub.h
··· 185 185 void cros_ec_sensorhub_unregister_push_data(struct cros_ec_sensorhub *sensorhub, 186 186 u8 sensor_num); 187 187 188 + int cros_ec_sensorhub_ring_allocate(struct cros_ec_sensorhub *sensorhub); 188 189 int cros_ec_sensorhub_ring_add(struct cros_ec_sensorhub *sensorhub); 189 190 void cros_ec_sensorhub_ring_remove(void *arg); 190 191 int cros_ec_sensorhub_ring_fifo_enable(struct cros_ec_sensorhub *sensorhub,