Instead of reading each object separately, fetch the whole table in one large i2c transaction. A 6 byte table object requires 10 bytes to read, so doing this dramatically reduces overhead. Also, as a cleanup, move object_table allocation (and post-fw-update reallocation) into mxt_get_object_table(). Signed-off-by: Daniel Kurtz <djkurtz@xxxxxxxxxxxx> --- drivers/input/touchscreen/atmel_mxt_ts.c | 66 +++++++++++++++--------------- 1 files changed, 33 insertions(+), 33 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 9d88faf..0d0dab6 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -437,14 +437,7 @@ static int mxt_write_reg(struct i2c_client *client, u16 reg, u16 len, return 0; } -static int mxt_read_object_table(struct i2c_client *client, - u16 reg, u8 *object_buf) -{ - return mxt_read_reg(client, reg, MXT_OBJECT_SIZE, object_buf); -} - -static struct mxt_object * -mxt_get_object(struct mxt_data *data, u8 type) +static struct mxt_object *mxt_get_object(struct mxt_data *data, u8 type) { struct mxt_object *object; int i; @@ -733,25 +726,41 @@ static void mxt_handle_pdata(struct mxt_data *data) static int mxt_get_object_table(struct mxt_data *data) { + struct i2c_client *client = data->client; + struct device *dev = &client->dev; int error; int i; - u16 reg; u8 reportid = 0; - u8 buf[MXT_OBJECT_SIZE]; + u8 *buf; + size_t buf_size; - for (i = 0; i < data->info.object_num; i++) { - struct mxt_object *object = data->object_table + i; + /* Free old object table, if there was one. */ + kfree(data->object_table); + data->object_table = kcalloc(data->info.object_num, + sizeof(struct mxt_object), GFP_KERNEL); + if (!data->object_table) { + dev_err(dev, "Failed to allocate object table\n"); + return -ENOMEM; + } - reg = MXT_OBJECT_START + MXT_OBJECT_SIZE * i; - error = mxt_read_object_table(data->client, reg, buf); - if (error) - return error; + buf_size = MXT_OBJECT_SIZE * data->info.object_num; + buf = kmalloc(buf_size, GFP_KERNEL); + if (!buf) + return -ENOMEM; - object->type = buf[0]; - object->start_address = (buf[2] << 8) | buf[1]; - object->size = buf[3] + 1; - object->instances = buf[4] + 1; - object->num_report_ids = buf[5]; + error = mxt_read_reg(client, MXT_OBJECT_START, buf_size, buf); + if (error) + goto done; + + for (i = 0; i < data->info.object_num; i++) { + struct mxt_object *object = &data->object_table[i]; + u8 *obj_buf = &buf[i * MXT_OBJECT_SIZE]; + + object->type = obj_buf[0]; + object->start_address = (obj_buf[2] << 8) | obj_buf[1]; + object->size = obj_buf[3] + 1; + object->instances = obj_buf[4] + 1; + object->num_report_ids = obj_buf[5]; if (object->num_report_ids) { reportid += object->num_report_ids * object->instances; @@ -759,7 +768,9 @@ static int mxt_get_object_table(struct mxt_data *data) } } - return 0; +done: + kfree(buf); + return error; } static int mxt_initialize(struct mxt_data *data) @@ -774,14 +785,6 @@ static int mxt_initialize(struct mxt_data *data) if (error) return error; - data->object_table = kcalloc(info->object_num, - sizeof(struct mxt_object), - GFP_KERNEL); - if (!data->object_table) { - dev_err(&client->dev, "Failed to allocate memory\n"); - return -ENOMEM; - } - /* Get object table information */ error = mxt_get_object_table(data); if (error) @@ -971,9 +974,6 @@ static ssize_t mxt_update_fw_store(struct device *dev, /* Wait for reset */ msleep(MXT_FWRESET_TIME); - kfree(data->object_table); - data->object_table = NULL; - mxt_initialize(data); } -- 1.7.7.3 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html