diff options
author | Nick Dyer <nick@shmanahar.org> | 2017-02-01 02:25:56 +0300 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2017-02-01 02:51:21 +0300 |
commit | 5a89916df2c8d2635b82a457cd4945dd73c1de3c (patch) | |
tree | dcaf9a4e4696cb9e15732198c00b61bee219282c /drivers/input/rmi4/rmi_f34.c | |
parent | ed77bdf4e4bea810014cdf68b771bcbe3d47163f (diff) | |
download | linux-5a89916df2c8d2635b82a457cd4945dd73c1de3c.tar.xz |
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>
Diffstat (limited to 'drivers/input/rmi4/rmi_f34.c')
-rw-r--r-- | drivers/input/rmi4/rmi_f34.c | 92 |
1 files changed, 65 insertions, 27 deletions
diff --git a/drivers/input/rmi4/rmi_f34.c b/drivers/input/rmi4/rmi_f34.c index c3285cefe9b6..902b99007885 100644 --- a/drivers/input/rmi4/rmi_f34.c +++ b/drivers/input/rmi4/rmi_f34.c @@ -157,6 +157,9 @@ static int rmi_f34_write_blocks(struct f34_data *f34, const void *data, i + 1, block_count); data += f34->v5.block_size; + f34->update_progress += f34->v5.block_size; + f34->update_status = (f34->update_progress * 100) / + f34->update_size; } return 0; @@ -174,7 +177,7 @@ static int rmi_f34_write_config(struct f34_data *f34, const void *data) F34_WRITE_CONFIG_BLOCK); } -int rmi_f34_enable_flash(struct f34_data *f34) +static int rmi_f34_enable_flash(struct f34_data *f34) { return rmi_f34_command(f34, F34_ENABLE_FLASH_PROG, F34_ENABLE_WAIT_MS, true); @@ -184,9 +187,14 @@ static int rmi_f34_flash_firmware(struct f34_data *f34, const struct rmi_f34_firmware *syn_fw) { struct rmi_function *fn = f34->fn; + u32 image_size = le32_to_cpu(syn_fw->image_size); + u32 config_size = le32_to_cpu(syn_fw->config_size); int ret; - if (syn_fw->image_size) { + f34->update_progress = 0; + f34->update_size = image_size + config_size; + + if (image_size) { dev_info(&fn->dev, "Erasing firmware...\n"); ret = rmi_f34_command(f34, F34_ERASE_ALL, F34_ERASE_WAIT_MS, true); @@ -194,18 +202,18 @@ static int rmi_f34_flash_firmware(struct f34_data *f34, return ret; dev_info(&fn->dev, "Writing firmware (%d bytes)...\n", - syn_fw->image_size); + image_size); ret = rmi_f34_write_firmware(f34, syn_fw->data); if (ret) return ret; } - if (syn_fw->config_size) { + if (config_size) { /* * We only need to erase config if we haven't updated * firmware. */ - if (!syn_fw->image_size) { + if (!image_size) { dev_info(&fn->dev, "Erasing config...\n"); ret = rmi_f34_command(f34, F34_ERASE_CONFIG, F34_ERASE_WAIT_MS, true); @@ -214,9 +222,8 @@ static int rmi_f34_flash_firmware(struct f34_data *f34, } dev_info(&fn->dev, "Writing config (%d bytes)...\n", - syn_fw->config_size); - ret = rmi_f34_write_config(f34, - &syn_fw->data[syn_fw->image_size]); + config_size); + ret = rmi_f34_write_config(f34, &syn_fw->data[image_size]); if (ret) return ret; } @@ -224,21 +231,23 @@ static int rmi_f34_flash_firmware(struct f34_data *f34, return 0; } -int rmi_f34_update_firmware(struct f34_data *f34, const struct firmware *fw) +static int rmi_f34_update_firmware(struct f34_data *f34, + const struct firmware *fw) { - const struct rmi_f34_firmware *syn_fw; + const struct rmi_f34_firmware *syn_fw = + (const struct rmi_f34_firmware *)fw->data; + u32 image_size = le32_to_cpu(syn_fw->image_size); + u32 config_size = le32_to_cpu(syn_fw->config_size); int ret; - syn_fw = (const struct rmi_f34_firmware *)fw->data; BUILD_BUG_ON(offsetof(struct rmi_f34_firmware, data) != F34_FW_IMAGE_OFFSET); rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, - "FW size:%d, checksum:%08x, image_size:%d, config_size:%d\n", - (int)fw->size, + "FW size:%zd, checksum:%08x, image_size:%d, config_size:%d\n", + fw->size, le32_to_cpu(syn_fw->checksum), - le32_to_cpu(syn_fw->image_size), - le32_to_cpu(syn_fw->config_size)); + image_size, config_size); rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "FW bootloader_id:%02x, product_id:%.*s, info: %02x%02x\n", @@ -246,27 +255,25 @@ int rmi_f34_update_firmware(struct f34_data *f34, const struct firmware *fw) (int)sizeof(syn_fw->product_id), syn_fw->product_id, syn_fw->product_info[0], syn_fw->product_info[1]); - if (syn_fw->image_size && - syn_fw->image_size != f34->v5.fw_blocks * f34->v5.block_size) { + if (image_size && image_size != f34->v5.fw_blocks * f34->v5.block_size) { dev_err(&f34->fn->dev, "Bad firmware image: fw size %d, expected %d\n", - syn_fw->image_size, - f34->v5.fw_blocks * f34->v5.block_size); + image_size, f34->v5.fw_blocks * f34->v5.block_size); ret = -EILSEQ; goto out; } - if (syn_fw->config_size && - syn_fw->config_size != f34->v5.config_blocks * f34->v5.block_size) { + if (config_size && + config_size != f34->v5.config_blocks * f34->v5.block_size) { dev_err(&f34->fn->dev, "Bad firmware image: config size %d, expected %d\n", - syn_fw->config_size, + config_size, f34->v5.config_blocks * f34->v5.block_size); ret = -EILSEQ; goto out; } - if (syn_fw->image_size && !syn_fw->config_size) { + if (image_size && !config_size) { dev_err(&f34->fn->dev, "Bad firmware image: no config data\n"); ret = -EILSEQ; goto out; @@ -283,6 +290,17 @@ out: return ret; } +static int rmi_f34_status(struct rmi_function *fn) +{ + struct f34_data *f34 = dev_get_drvdata(&fn->dev); + + /* + * The status is the percentage complete, or once complete, + * zero for success or a negative return code. + */ + return f34->update_status; +} + static int rmi_firmware_update(struct rmi_driver_data *data, const struct firmware *fw) { @@ -346,7 +364,13 @@ static int rmi_firmware_update(struct rmi_driver_data *data, else ret = rmi_f34_update_firmware(f34, fw); - dev_info(&f34->fn->dev, "Firmware update complete, status:%d\n", ret); + if (ret) { + f34->update_status = ret; + dev_err(&f34->fn->dev, + "Firmware update failed, status: %d\n", ret); + } else { + dev_info(&f34->fn->dev, "Firmware update complete\n"); + } rmi_disable_irq(rmi_dev, false); @@ -377,9 +401,6 @@ static int rmi_firmware_update(struct rmi_driver_data *data, return ret; } -static int rmi_firmware_update(struct rmi_driver_data *data, - const struct firmware *fw); - static ssize_t rmi_driver_update_fw_store(struct device *dev, struct device_attribute *dattr, const char *buf, size_t count) @@ -414,8 +435,25 @@ static ssize_t rmi_driver_update_fw_store(struct device *dev, static DEVICE_ATTR(update_fw, 0200, NULL, rmi_driver_update_fw_store); +static ssize_t rmi_driver_update_fw_status_show(struct device *dev, + struct device_attribute *dattr, + char *buf) +{ + struct rmi_driver_data *data = dev_get_drvdata(dev); + int update_status = 0; + + if (data->f34_container) + update_status = rmi_f34_status(data->f34_container); + + return scnprintf(buf, PAGE_SIZE, "%d\n", update_status); +} + +static DEVICE_ATTR(update_fw_status, 0444, + rmi_driver_update_fw_status_show, NULL); + static struct attribute *rmi_firmware_attrs[] = { &dev_attr_update_fw.attr, + &dev_attr_update_fw_status.attr, NULL }; |