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

Input: synaptics-rmi4 - add sysfs attribute update_fw_status

The attribute returns the percentage complete. If the firmware update fails, it
reports a negative error code.

Signed-off-by: Nick Dyer <nick@shmanahar.org>
Tested-by: Chris Healy <cphealy@gmail.com>
Acked-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Nick Dyer and committed by
Dmitry Torokhov
5a89916d ed77bdf4

+80 -27
+65 -27
drivers/input/rmi4/rmi_f34.c
··· 157 157 i + 1, block_count); 158 158 159 159 data += f34->v5.block_size; 160 + f34->update_progress += f34->v5.block_size; 161 + f34->update_status = (f34->update_progress * 100) / 162 + f34->update_size; 160 163 } 161 164 162 165 return 0; ··· 177 174 F34_WRITE_CONFIG_BLOCK); 178 175 } 179 176 180 - int rmi_f34_enable_flash(struct f34_data *f34) 177 + static int rmi_f34_enable_flash(struct f34_data *f34) 181 178 { 182 179 return rmi_f34_command(f34, F34_ENABLE_FLASH_PROG, 183 180 F34_ENABLE_WAIT_MS, true); ··· 187 184 const struct rmi_f34_firmware *syn_fw) 188 185 { 189 186 struct rmi_function *fn = f34->fn; 187 + u32 image_size = le32_to_cpu(syn_fw->image_size); 188 + u32 config_size = le32_to_cpu(syn_fw->config_size); 190 189 int ret; 191 190 192 - if (syn_fw->image_size) { 191 + f34->update_progress = 0; 192 + f34->update_size = image_size + config_size; 193 + 194 + if (image_size) { 193 195 dev_info(&fn->dev, "Erasing firmware...\n"); 194 196 ret = rmi_f34_command(f34, F34_ERASE_ALL, 195 197 F34_ERASE_WAIT_MS, true); ··· 202 194 return ret; 203 195 204 196 dev_info(&fn->dev, "Writing firmware (%d bytes)...\n", 205 - syn_fw->image_size); 197 + image_size); 206 198 ret = rmi_f34_write_firmware(f34, syn_fw->data); 207 199 if (ret) 208 200 return ret; 209 201 } 210 202 211 - if (syn_fw->config_size) { 203 + if (config_size) { 212 204 /* 213 205 * We only need to erase config if we haven't updated 214 206 * firmware. 215 207 */ 216 - if (!syn_fw->image_size) { 208 + if (!image_size) { 217 209 dev_info(&fn->dev, "Erasing config...\n"); 218 210 ret = rmi_f34_command(f34, F34_ERASE_CONFIG, 219 211 F34_ERASE_WAIT_MS, true); ··· 222 214 } 223 215 224 216 dev_info(&fn->dev, "Writing config (%d bytes)...\n", 225 - syn_fw->config_size); 226 - ret = rmi_f34_write_config(f34, 227 - &syn_fw->data[syn_fw->image_size]); 217 + config_size); 218 + ret = rmi_f34_write_config(f34, &syn_fw->data[image_size]); 228 219 if (ret) 229 220 return ret; 230 221 } ··· 231 224 return 0; 232 225 } 233 226 234 - int rmi_f34_update_firmware(struct f34_data *f34, const struct firmware *fw) 227 + static int rmi_f34_update_firmware(struct f34_data *f34, 228 + const struct firmware *fw) 235 229 { 236 - const struct rmi_f34_firmware *syn_fw; 230 + const struct rmi_f34_firmware *syn_fw = 231 + (const struct rmi_f34_firmware *)fw->data; 232 + u32 image_size = le32_to_cpu(syn_fw->image_size); 233 + u32 config_size = le32_to_cpu(syn_fw->config_size); 237 234 int ret; 238 235 239 - syn_fw = (const struct rmi_f34_firmware *)fw->data; 240 236 BUILD_BUG_ON(offsetof(struct rmi_f34_firmware, data) != 241 237 F34_FW_IMAGE_OFFSET); 242 238 243 239 rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, 244 - "FW size:%d, checksum:%08x, image_size:%d, config_size:%d\n", 245 - (int)fw->size, 240 + "FW size:%zd, checksum:%08x, image_size:%d, config_size:%d\n", 241 + fw->size, 246 242 le32_to_cpu(syn_fw->checksum), 247 - le32_to_cpu(syn_fw->image_size), 248 - le32_to_cpu(syn_fw->config_size)); 243 + image_size, config_size); 249 244 250 245 rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, 251 246 "FW bootloader_id:%02x, product_id:%.*s, info: %02x%02x\n", ··· 255 246 (int)sizeof(syn_fw->product_id), syn_fw->product_id, 256 247 syn_fw->product_info[0], syn_fw->product_info[1]); 257 248 258 - if (syn_fw->image_size && 259 - syn_fw->image_size != f34->v5.fw_blocks * f34->v5.block_size) { 249 + if (image_size && image_size != f34->v5.fw_blocks * f34->v5.block_size) { 260 250 dev_err(&f34->fn->dev, 261 251 "Bad firmware image: fw size %d, expected %d\n", 262 - syn_fw->image_size, 263 - f34->v5.fw_blocks * f34->v5.block_size); 252 + image_size, f34->v5.fw_blocks * f34->v5.block_size); 264 253 ret = -EILSEQ; 265 254 goto out; 266 255 } 267 256 268 - if (syn_fw->config_size && 269 - syn_fw->config_size != f34->v5.config_blocks * f34->v5.block_size) { 257 + if (config_size && 258 + config_size != f34->v5.config_blocks * f34->v5.block_size) { 270 259 dev_err(&f34->fn->dev, 271 260 "Bad firmware image: config size %d, expected %d\n", 272 - syn_fw->config_size, 261 + config_size, 273 262 f34->v5.config_blocks * f34->v5.block_size); 274 263 ret = -EILSEQ; 275 264 goto out; 276 265 } 277 266 278 - if (syn_fw->image_size && !syn_fw->config_size) { 267 + if (image_size && !config_size) { 279 268 dev_err(&f34->fn->dev, "Bad firmware image: no config data\n"); 280 269 ret = -EILSEQ; 281 270 goto out; ··· 288 281 289 282 out: 290 283 return ret; 284 + } 285 + 286 + static int rmi_f34_status(struct rmi_function *fn) 287 + { 288 + struct f34_data *f34 = dev_get_drvdata(&fn->dev); 289 + 290 + /* 291 + * The status is the percentage complete, or once complete, 292 + * zero for success or a negative return code. 293 + */ 294 + return f34->update_status; 291 295 } 292 296 293 297 static int rmi_firmware_update(struct rmi_driver_data *data, ··· 364 346 else 365 347 ret = rmi_f34_update_firmware(f34, fw); 366 348 367 - dev_info(&f34->fn->dev, "Firmware update complete, status:%d\n", ret); 349 + if (ret) { 350 + f34->update_status = ret; 351 + dev_err(&f34->fn->dev, 352 + "Firmware update failed, status: %d\n", ret); 353 + } else { 354 + dev_info(&f34->fn->dev, "Firmware update complete\n"); 355 + } 368 356 369 357 rmi_disable_irq(rmi_dev, false); 370 358 ··· 400 376 401 377 return ret; 402 378 } 403 - 404 - static int rmi_firmware_update(struct rmi_driver_data *data, 405 - const struct firmware *fw); 406 379 407 380 static ssize_t rmi_driver_update_fw_store(struct device *dev, 408 381 struct device_attribute *dattr, ··· 435 414 436 415 static DEVICE_ATTR(update_fw, 0200, NULL, rmi_driver_update_fw_store); 437 416 417 + static ssize_t rmi_driver_update_fw_status_show(struct device *dev, 418 + struct device_attribute *dattr, 419 + char *buf) 420 + { 421 + struct rmi_driver_data *data = dev_get_drvdata(dev); 422 + int update_status = 0; 423 + 424 + if (data->f34_container) 425 + update_status = rmi_f34_status(data->f34_container); 426 + 427 + return scnprintf(buf, PAGE_SIZE, "%d\n", update_status); 428 + } 429 + 430 + static DEVICE_ATTR(update_fw_status, 0444, 431 + rmi_driver_update_fw_status_show, NULL); 432 + 438 433 static struct attribute *rmi_firmware_attrs[] = { 439 434 &dev_attr_update_fw.attr, 435 + &dev_attr_update_fw_status.attr, 440 436 NULL 441 437 }; 442 438
+4
drivers/input/rmi4/rmi_f34.h
··· 301 301 unsigned char bootloader_id[5]; 302 302 unsigned char configuration_id[CONFIG_ID_SIZE*2 + 1]; 303 303 304 + int update_status; 305 + int update_progress; 306 + int update_size; 307 + 304 308 union { 305 309 struct f34v5_data v5; 306 310 struct f34v7_data v7;
+11
drivers/input/rmi4/rmi_f34v7.c
··· 588 588 u16 block_count; 589 589 590 590 block_count = f34->v7.img.ui_firmware.size / f34->v7.block_size; 591 + f34->update_size += block_count; 591 592 592 593 if (block_count != f34->v7.blkcount.ui_firmware) { 593 594 dev_err(&f34->fn->dev, ··· 605 604 u16 block_count; 606 605 607 606 block_count = f34->v7.img.ui_config.size / f34->v7.block_size; 607 + f34->update_size += block_count; 608 608 609 609 if (block_count != f34->v7.blkcount.ui_config) { 610 610 dev_err(&f34->fn->dev, "UI config size mismatch\n"); ··· 620 618 u16 block_count; 621 619 622 620 block_count = f34->v7.img.dp_config.size / f34->v7.block_size; 621 + f34->update_size += block_count; 623 622 624 623 if (block_count != f34->v7.blkcount.dp_config) { 625 624 dev_err(&f34->fn->dev, "Display config size mismatch\n"); ··· 635 632 u16 block_count; 636 633 637 634 block_count = f34->v7.img.guest_code.size / f34->v7.block_size; 635 + f34->update_size += block_count; 636 + 638 637 if (block_count != f34->v7.blkcount.guest_code) { 639 638 dev_err(&f34->fn->dev, "Guest code size mismatch\n"); 640 639 return -EINVAL; ··· 650 645 u16 block_count; 651 646 652 647 block_count = f34->v7.img.bl_config.size / f34->v7.block_size; 648 + f34->update_size += block_count; 653 649 654 650 if (block_count != f34->v7.blkcount.bl_config) { 655 651 dev_err(&f34->fn->dev, "Bootloader config size mismatch\n"); ··· 887 881 888 882 block_ptr += (transfer * f34->v7.block_size); 889 883 remaining -= transfer; 884 + f34->update_progress += transfer; 885 + f34->update_status = (f34->update_progress * 100) / 886 + f34->update_size; 890 887 } while (remaining); 891 888 892 889 return 0; ··· 1200 1191 rmi_f34v7_read_queries_bl_version(f34); 1201 1192 1202 1193 f34->v7.image = fw->data; 1194 + f34->update_progress = 0; 1195 + f34->update_size = 0; 1203 1196 1204 1197 ret = rmi_f34v7_parse_image_info(f34); 1205 1198 if (ret < 0)