From 5d64b48dce5678f916bd1caa363a1d817552b8ba Mon Sep 17 00:00:00 2001 From: Himanshu Aggarwal Date: Tue, 23 Jun 2015 21:24:30 +0530 Subject: input: synaptics_dsx_fw_update: update fw based on config id Update the firmware based on strict config ID versioning, rather than the entire config ID as a 4 byte number. This will also protect against config ID major number mismatches and packrat id mismatches. This is a propagated patch from 3.10 kernel. commit - 458cbab5c53d5141a66590441f9567d67d580c6f, input: synaptics_dsx_fw_update: update fw based on config id Change-Id: I1097585d3bd8b6ab753676dc56f268c7ce52680d Signed-off-by: Himanshu Aggarwal --- .../input/touchscreen/synaptics_dsx_i2c.txt | 2 + .../synaptics_dsx/synaptics_dsx_fw_update.c | 123 ++++++++++----------- .../touchscreen/synaptics_dsx/synaptics_dsx_i2c.c | 3 + include/linux/input/synaptics_dsx_v2.h | 1 + 4 files changed, 66 insertions(+), 63 deletions(-) diff --git a/Documentation/devicetree/bindings/input/touchscreen/synaptics_dsx_i2c.txt b/Documentation/devicetree/bindings/input/touchscreen/synaptics_dsx_i2c.txt index 27df06c7457b..833eb7a3eff2 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/synaptics_dsx_i2c.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/synaptics_dsx_i2c.txt @@ -49,6 +49,8 @@ Optional property: - clock-names: : Clock names used for secure touch. The names are: "iface_clk", "core_clk". - synaptics,config-id : Specifies the Config Id of touch controller. + - synaptics,bypass-packrat-id-check : Specifies if packrat ID needs to be ignored for smart + firmware upgrade Optional properties inside child node: These properties are defined only when synaptics,detect-device property is defined in DT. diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_fw_update.c b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_fw_update.c index a32222932ee1..012a5fbda94d 100644 --- a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_fw_update.c +++ b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_fw_update.c @@ -354,14 +354,6 @@ static unsigned int extract_uint_le(const unsigned char *ptr) (unsigned int)ptr[3] * 0x1000000; } -static unsigned int extract_uint_be(const unsigned char *ptr) -{ - return (unsigned int)ptr[3] + - (unsigned int)ptr[2] * 0x100 + - (unsigned int)ptr[1] * 0x10000 + - (unsigned int)ptr[0] * 0x1000000; -} - static void parse_header(struct image_header_data *header, const unsigned char *fw_image) { @@ -622,8 +614,6 @@ static enum flash_area fwu_go_nogo(struct image_header_data *header) enum flash_area flash_area = NONE; unsigned char index = 0; unsigned char config_id[4]; - unsigned int device_config_id; - unsigned int image_config_id; unsigned int device_fw_id; unsigned long image_fw_id; char *strptr; @@ -641,65 +631,67 @@ static enum flash_area fwu_go_nogo(struct image_header_data *header) goto exit; } - /* Get device firmware ID */ - device_fw_id = rmi4_data->firmware_id; - dev_info(rmi4_data->pdev->dev.parent, - "%s: Device firmware ID = %d\n", - __func__, device_fw_id); + if (!rmi4_data->hw_if->board_data->bypass_packrat_id_check) { + /* Get device firmware ID */ + device_fw_id = rmi4_data->firmware_id; + dev_info(rmi4_data->pdev->dev.parent, + "%s: Device firmware ID = %d\n", + __func__, device_fw_id); - /* Get image firmware ID */ - if (header->contains_firmware_id) { - image_fw_id = header->firmware_id; - } else { - strptr = strstr(fwu->image_name, "PR"); - if (!strptr) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: No valid PR number (PRxxxxxxx) " - "found in image file name (%s)\n", + /* Get image firmware ID */ + if (header->contains_firmware_id) { + image_fw_id = header->firmware_id; + } else { + strptr = strnstr(fwu->image_name, "PR", + sizeof(fwu->image_name)); + if (!strptr) { + dev_err(rmi4_data->pdev->dev.parent, + "%s: No valid PR number (PRxxxxxxx) found in image file name (%s)\n", __func__, fwu->image_name); - flash_area = NONE; - goto exit; - } + flash_area = NONE; + goto exit; + } - strptr += 2; - firmware_id = kzalloc(MAX_FIRMWARE_ID_LEN, GFP_KERNEL); - if (!firmware_id) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for firmware id\n", - __func__); - flash_area = NONE; - goto exit; - } + strptr += 2; + firmware_id = kzalloc(MAX_FIRMWARE_ID_LEN, GFP_KERNEL); + if (!firmware_id) { + dev_err(rmi4_data->pdev->dev.parent, + "%s: Failed to alloc mem for firmware id\n", + __func__); + flash_area = NONE; + goto exit; + } - while (strptr[index] >= '0' && strptr[index] <= '9') { - firmware_id[index] = strptr[index]; - index++; + while (strptr[index] >= '0' && strptr[index] <= '9') { + firmware_id[index] = strptr[index]; + index++; + } + + retval = sstrtoul(firmware_id, 10, &image_fw_id); + kfree(firmware_id); + if (retval) { + dev_err(rmi4_data->pdev->dev.parent, + "%s: Failed to obtain image firmware ID\n", + __func__); + flash_area = NONE; + goto exit; + } } + dev_info(rmi4_data->pdev->dev.parent, + "%s: Image firmware ID = %d\n", + __func__, (unsigned int)image_fw_id); - retval = sstrtoul(firmware_id, 10, &image_fw_id); - kfree(firmware_id); - if (retval) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to obtain image firmware ID\n", + if (image_fw_id > device_fw_id) { + flash_area = UI_FIRMWARE; + goto exit; + } else if (image_fw_id < device_fw_id) { + dev_info(rmi4_data->pdev->dev.parent, + "%s: Image firmware ID older than device firmware ID\n", __func__); flash_area = NONE; goto exit; } } - dev_info(rmi4_data->pdev->dev.parent, - "%s: Image firmware ID = %d\n", - __func__, (unsigned int)image_fw_id); - - if (image_fw_id > device_fw_id) { - flash_area = UI_FIRMWARE; - goto exit; - } else if (image_fw_id < device_fw_id) { - dev_info(rmi4_data->pdev->dev.parent, - "%s: Image firmware ID older than device firmware ID\n", - __func__); - flash_area = NONE; - goto exit; - } /* Get device config ID */ retval = synaptics_rmi4_reg_read(rmi4_data, @@ -713,7 +705,6 @@ static enum flash_area fwu_go_nogo(struct image_header_data *header) flash_area = NONE; goto exit; } - device_config_id = extract_uint_be(config_id); dev_info(rmi4_data->pdev->dev.parent, "%s: Device config ID = 0x%02x 0x%02x 0x%02x 0x%02x\n", __func__, @@ -723,7 +714,6 @@ static enum flash_area fwu_go_nogo(struct image_header_data *header) config_id[3]); /* Get image config ID */ - image_config_id = extract_uint_be(fwu->config_data); dev_info(rmi4_data->pdev->dev.parent, "%s: Image config ID = 0x%02x 0x%02x 0x%02x 0x%02x\n", __func__, @@ -732,9 +722,16 @@ static enum flash_area fwu_go_nogo(struct image_header_data *header) fwu->config_data[2], fwu->config_data[3]); - if (image_config_id > device_config_id) { - flash_area = CONFIG_AREA; - goto exit; + if (fwu->config_data[1] == config_id[1]) { + if (fwu->config_data[2] == config_id[2]) { + if (fwu->config_data[3] > config_id[3]) { + flash_area = CONFIG_AREA; + goto exit; + } + } else if (fwu->config_data[2] > config_id[2]) { + flash_area = CONFIG_AREA; + goto exit; + } } flash_area = NONE; diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_i2c.c b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_i2c.c index 3b1c726e0257..5f357965e9f1 100755 --- a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_i2c.c +++ b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_i2c.c @@ -317,6 +317,9 @@ static int synaptics_dsx_parse_dt(struct device *dev, rmi4_pdata->disable_gpios = of_property_read_bool(np, "synaptics,disable-gpios"); + rmi4_pdata->bypass_packrat_id_check = of_property_read_bool(np, + "synaptics,bypass-packrat-id-check"); + rmi4_pdata->reset_delay_ms = RESET_DELAY; rc = of_property_read_u32(np, "synaptics,reset-delay-ms", &temp_val); if (!rc) diff --git a/include/linux/input/synaptics_dsx_v2.h b/include/linux/input/synaptics_dsx_v2.h index 4395f32f57a9..13e8ae3df62e 100755 --- a/include/linux/input/synaptics_dsx_v2.h +++ b/include/linux/input/synaptics_dsx_v2.h @@ -100,6 +100,7 @@ struct synaptics_dsx_board_data { u32 config_id; bool disable_gpios; bool detect_device; + bool bypass_packrat_id_check; const char *fw_name; }; -- cgit v1.2.3