* [PATCH v2 30/49] Input: atmel_mxt_ts - implement improved debug message interface
@ 2019-08-27 6:29 ` Jiada Wang
0 siblings, 0 replies; 10+ messages in thread
From: Jiada Wang @ 2019-08-27 6:29 UTC (permalink / raw)
To: nick, dmitry.torokhov; +Cc: linux-input, linux-kernel, jiada_wang, george_davis
From: Nick Dyer <nick.dyer@itdev.co.uk>
Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
(cherry picked from ndyer/linux/for-upstream commit 078569c13c88dcb6f8d882bfe17168587712df7d)
[gdavis: Resolve forward port conflicts due to v4.14.51 commit
960fe000b1d3 ("Input: atmel_mxt_ts - fix the firmware
update").]
Signed-off-by: George G. Davis <george_davis@mentor.com>
[gdavis: Squash fixes from Dirk Behme:
- Input: atmel_mxt_ts - add missing unlock in error path
- Input: atmel_mxt_ts - add missing unlock in error path
- Input: atmel_mxt_ts - call mxt_debug_msg_remove() in error path
- Input: atmel_mxt_ts - protect debug_v2_enabled by mutex
Signed-off-by: Dirk Behme <dirk.behme@de.bosch.com>
[gdavis: Squash fix from Vladimir Zapolskiy:
- Input: atmel_mxt_ts - simplify debug_msg binary attribute
handling]
Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
---
Notes:
- Squash fixes from Dirk Behme:
+ Input: atmel_mxt_ts - add missing unlock in error path
Unlock the mutex in case the function is exited in the error case.
+ Input: atmel_mxt_ts - add missing unlock in error path
+ Input: atmel_mxt_ts - protect debug_v2_enabled by mutex
Put the modification of debug_v2_enabled into the protected section.
Same as in mxt_debug_msg_enable().
+ Input: atmel_mxt_ts - call mxt_debug_msg_remove() in error path
Add the missing mxt_debug_msg_remove() to the error path.
- Squash fix from Vladimir Zapolskiy:
+ Input: atmel_mxt_ts - simplify debug_msg binary attribute handling
The change introduces several updates, but all of them are related to
"debug_msg" binary attribute:
* removed dynamic initialization of data->debug_msg_attr
* removed mxt_debug_msg_write callback
* removed wrong check in mxt_debug_msg_remove()
* mxt_debug_msg_remove() now is not called from mxt_free_object_table()
avoiding multiple double deallocations.
[jiada: Add NULL check for sysfs attribute debug_msg_attr]
Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 194 ++++++++++++++++++++++-
1 file changed, 192 insertions(+), 2 deletions(-)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 941c6970cb70..2d9d2c1e39dd 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -242,6 +242,8 @@ enum t100_type {
#define MXT_PIXELS_PER_MM 20
+#define DEBUG_MSG_MAX 200
+
struct mxt_info {
u8 family_id;
u8 variant_id;
@@ -336,6 +338,11 @@ struct mxt_data {
u8 t100_aux_area;
u8 t100_aux_vect;
bool debug_enabled;
+ bool debug_v2_enabled;
+ u8 *debug_msg_data;
+ u16 debug_msg_count;
+ struct bin_attribute *debug_msg_attr;
+ struct mutex debug_msg_lock;
u8 max_reportid;
u32 config_crc;
u32 info_crc;
@@ -465,6 +472,144 @@ static void mxt_dump_message(struct mxt_data *data, u8 *message)
data->T5_msg_size, message);
}
+static void mxt_debug_msg_enable(struct mxt_data *data)
+{
+ struct device *dev = &data->client->dev;
+
+ if (data->debug_v2_enabled)
+ return;
+
+ mutex_lock(&data->debug_msg_lock);
+
+ data->debug_msg_data = kcalloc(DEBUG_MSG_MAX,
+ data->T5_msg_size, GFP_KERNEL);
+ if (!data->debug_msg_data) {
+ mutex_unlock(&data->debug_msg_lock);
+ return;
+ }
+
+ data->debug_v2_enabled = true;
+ mutex_unlock(&data->debug_msg_lock);
+
+ dev_dbg(dev, "Enabled message output\n");
+}
+
+static void mxt_debug_msg_disable(struct mxt_data *data)
+{
+ struct device *dev = &data->client->dev;
+
+ if (!data->debug_v2_enabled)
+ return;
+
+ mutex_lock(&data->debug_msg_lock);
+
+ data->debug_v2_enabled = false;
+
+ kfree(data->debug_msg_data);
+ data->debug_msg_data = NULL;
+ data->debug_msg_count = 0;
+ mutex_unlock(&data->debug_msg_lock);
+ dev_dbg(dev, "Disabled message output\n");
+}
+
+static void mxt_debug_msg_add(struct mxt_data *data, u8 *msg)
+{
+ struct device *dev = &data->client->dev;
+
+ mutex_lock(&data->debug_msg_lock);
+
+ if (!data->debug_msg_data) {
+ mutex_unlock(&data->debug_msg_lock);
+ dev_err(dev, "No buffer!\n");
+ return;
+ }
+
+ if (data->debug_msg_count < DEBUG_MSG_MAX) {
+ memcpy(data->debug_msg_data +
+ data->debug_msg_count * data->T5_msg_size,
+ msg,
+ data->T5_msg_size);
+ data->debug_msg_count++;
+ } else {
+ dev_dbg(dev, "Discarding %u messages\n", data->debug_msg_count);
+ data->debug_msg_count = 0;
+ }
+
+ mutex_unlock(&data->debug_msg_lock);
+
+ sysfs_notify(&data->client->dev.kobj, NULL, "debug_notify");
+}
+
+static ssize_t mxt_debug_msg_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf, loff_t off, size_t bytes)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct mxt_data *data = dev_get_drvdata(dev);
+ int count;
+ size_t bytes_read;
+
+ if (!data->debug_msg_data) {
+ dev_err(dev, "No buffer!\n");
+ return 0;
+ }
+
+ count = bytes / data->T5_msg_size;
+
+ if (count > DEBUG_MSG_MAX)
+ count = DEBUG_MSG_MAX;
+
+ mutex_lock(&data->debug_msg_lock);
+
+ if (count > data->debug_msg_count)
+ count = data->debug_msg_count;
+
+ bytes_read = count * data->T5_msg_size;
+
+ memcpy(buf, data->debug_msg_data, bytes_read);
+ data->debug_msg_count = 0;
+
+ mutex_unlock(&data->debug_msg_lock);
+
+ return bytes_read;
+}
+
+static struct bin_attribute debug_msg_attr = {
+ .attr = {
+ .name = "debug_msg",
+ .mode = 0444,
+ },
+ .read = mxt_debug_msg_read,
+};
+
+static int mxt_debug_msg_init(struct mxt_data *data)
+{
+ /*
+ * Binary attribute is not used in callback, removal is done by name,
+ * so it is safe to update a single struct bin_attribute entity
+ */
+ debug_msg_attr.size = data->T5_msg_size * DEBUG_MSG_MAX;
+
+ if (sysfs_create_bin_file(&data->client->dev.kobj,
+ &debug_msg_attr) < 0) {
+ dev_err(&data->client->dev, "Failed to create %s\n",
+ debug_msg_attr.attr.name);
+ return -EINVAL;
+ }
+
+ data->debug_msg_attr = &debug_msg_attr;
+
+ return 0;
+}
+
+static void mxt_debug_msg_remove(struct mxt_data *data)
+{
+ if (data->debug_msg_attr) {
+ sysfs_remove_bin_file(&data->client->dev.kobj,
+ data->debug_msg_attr);
+ data->debug_msg_attr = NULL;
+ }
+}
+
static int mxt_wait_for_completion(struct mxt_data *data,
struct completion *comp,
unsigned int timeout_ms)
@@ -1256,6 +1401,9 @@ static int mxt_proc_message(struct mxt_data *data, u8 *message)
if (dump)
mxt_dump_message(data, message);
+ if (data->debug_v2_enabled)
+ mxt_debug_msg_add(data, message);
+
return 1;
}
@@ -2674,6 +2822,10 @@ static int mxt_initialize(struct mxt_data *data)
if (error)
return error;
+ error = mxt_debug_msg_init(data);
+ if (error)
+ goto err_free_sysfs;
+
if (data->cfg_name) {
error = request_firmware_nowait(THIS_MODULE, true,
data->cfg_name,
@@ -2683,16 +2835,18 @@ static int mxt_initialize(struct mxt_data *data)
if (error) {
dev_err(&client->dev, "Failed to invoke firmware loader: %d\n",
error);
- goto err_free_sysfs;
+ goto err_free_dbg_msg;
}
} else {
error = mxt_configure_objects(data, NULL);
if (error)
- goto err_free_sysfs;
+ goto err_free_dbg_msg;
}
return 0;
+err_free_dbg_msg:
+ mxt_debug_msg_remove(data);
err_free_sysfs:
mxt_sysfs_remove(data);
return error;
@@ -3354,6 +3508,7 @@ static int mxt_enter_bootloader(struct mxt_data *data)
return ret;
data->in_bootloader = true;
+ mxt_debug_msg_remove(data);
mxt_sysfs_remove(data);
mxt_free_input_device(data);
mxt_free_object_table(data);
@@ -3537,6 +3692,34 @@ static ssize_t mxt_debug_enable_show(struct device *dev,
return scnprintf(buf, PAGE_SIZE, "%c\n", c);
}
+static ssize_t mxt_debug_notify_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "0\n");
+}
+
+static ssize_t mxt_debug_v2_enable_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct mxt_data *data = dev_get_drvdata(dev);
+ u8 i;
+ ssize_t ret;
+
+ if (kstrtou8(buf, 0, &i) == 0 && i < 2) {
+ if (i == 1)
+ mxt_debug_msg_enable(data);
+ else
+ mxt_debug_msg_disable(data);
+
+ ret = count;
+ } else {
+ dev_dbg(dev, "debug_enabled write error\n");
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
static ssize_t mxt_debug_enable_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
@@ -3575,6 +3758,9 @@ static DEVICE_ATTR(update_cfg, S_IWUSR, NULL, mxt_update_cfg_store);
static DEVICE_ATTR(config_crc, S_IRUGO, mxt_config_crc_show, NULL);
static DEVICE_ATTR(debug_enable, S_IWUSR | S_IRUSR, mxt_debug_enable_show,
mxt_debug_enable_store);
+static DEVICE_ATTR(debug_v2_enable, S_IWUSR | S_IRUSR, NULL,
+ mxt_debug_v2_enable_store);
+static DEVICE_ATTR(debug_notify, S_IRUGO, mxt_debug_notify_show, NULL);
static struct attribute *mxt_attrs[] = {
&dev_attr_fw_version.attr,
@@ -3583,6 +3769,8 @@ static struct attribute *mxt_attrs[] = {
&dev_attr_update_cfg.attr,
&dev_attr_config_crc.attr,
&dev_attr_debug_enable.attr,
+ &dev_attr_debug_v2_enable.attr,
+ &dev_attr_debug_notify.attr,
NULL
};
@@ -3872,6 +4060,7 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
init_completion(&data->chg_completion);
init_completion(&data->reset_completion);
init_completion(&data->crc_completion);
+ mutex_init(&data->debug_msg_lock);
data->suspend_mode = dmi_check_system(chromebook_T9_suspend_dmi) ?
MXT_SUSPEND_T9_CTRL : MXT_SUSPEND_DEEP_SLEEP;
@@ -3930,6 +4119,7 @@ static int mxt_remove(struct i2c_client *client)
disable_irq(data->irq);
sysfs_remove_group(&client->dev.kobj, &mxt_fw_attr_group);
+ mxt_debug_msg_remove(data);
mxt_sysfs_remove(data);
mxt_free_input_device(data);
mxt_free_object_table(data);
--
2.19.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 30/49] Input: atmel_mxt_ts - implement improved debug message interface
@ 2019-08-27 6:29 ` Jiada Wang
0 siblings, 0 replies; 10+ messages in thread
From: Jiada Wang @ 2019-08-27 6:29 UTC (permalink / raw)
To: nick, dmitry.torokhov; +Cc: linux-input, linux-kernel, jiada_wang, george_davis
From: Nick Dyer <nick.dyer@itdev.co.uk>
Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
(cherry picked from ndyer/linux/for-upstream commit 078569c13c88dcb6f8d882bfe17168587712df7d)
[gdavis: Resolve forward port conflicts due to v4.14.51 commit
960fe000b1d3 ("Input: atmel_mxt_ts - fix the firmware
update").]
Signed-off-by: George G. Davis <george_davis@mentor.com>
[gdavis: Squash fixes from Dirk Behme:
- Input: atmel_mxt_ts - add missing unlock in error path
- Input: atmel_mxt_ts - add missing unlock in error path
- Input: atmel_mxt_ts - call mxt_debug_msg_remove() in error path
- Input: atmel_mxt_ts - protect debug_v2_enabled by mutex
Signed-off-by: Dirk Behme <dirk.behme@de.bosch.com>
[gdavis: Squash fix from Vladimir Zapolskiy:
- Input: atmel_mxt_ts - simplify debug_msg binary attribute
handling]
Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
---
Notes:
- Squash fixes from Dirk Behme:
+ Input: atmel_mxt_ts - add missing unlock in error path
Unlock the mutex in case the function is exited in the error case.
+ Input: atmel_mxt_ts - add missing unlock in error path
+ Input: atmel_mxt_ts - protect debug_v2_enabled by mutex
Put the modification of debug_v2_enabled into the protected section.
Same as in mxt_debug_msg_enable().
+ Input: atmel_mxt_ts - call mxt_debug_msg_remove() in error path
Add the missing mxt_debug_msg_remove() to the error path.
- Squash fix from Vladimir Zapolskiy:
+ Input: atmel_mxt_ts - simplify debug_msg binary attribute handling
The change introduces several updates, but all of them are related to
"debug_msg" binary attribute:
* removed dynamic initialization of data->debug_msg_attr
* removed mxt_debug_msg_write callback
* removed wrong check in mxt_debug_msg_remove()
* mxt_debug_msg_remove() now is not called from mxt_free_object_table()
avoiding multiple double deallocations.
[jiada: Add NULL check for sysfs attribute debug_msg_attr]
Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 194 ++++++++++++++++++++++-
1 file changed, 192 insertions(+), 2 deletions(-)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 941c6970cb70..2d9d2c1e39dd 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -242,6 +242,8 @@ enum t100_type {
#define MXT_PIXELS_PER_MM 20
+#define DEBUG_MSG_MAX 200
+
struct mxt_info {
u8 family_id;
u8 variant_id;
@@ -336,6 +338,11 @@ struct mxt_data {
u8 t100_aux_area;
u8 t100_aux_vect;
bool debug_enabled;
+ bool debug_v2_enabled;
+ u8 *debug_msg_data;
+ u16 debug_msg_count;
+ struct bin_attribute *debug_msg_attr;
+ struct mutex debug_msg_lock;
u8 max_reportid;
u32 config_crc;
u32 info_crc;
@@ -465,6 +472,144 @@ static void mxt_dump_message(struct mxt_data *data, u8 *message)
data->T5_msg_size, message);
}
+static void mxt_debug_msg_enable(struct mxt_data *data)
+{
+ struct device *dev = &data->client->dev;
+
+ if (data->debug_v2_enabled)
+ return;
+
+ mutex_lock(&data->debug_msg_lock);
+
+ data->debug_msg_data = kcalloc(DEBUG_MSG_MAX,
+ data->T5_msg_size, GFP_KERNEL);
+ if (!data->debug_msg_data) {
+ mutex_unlock(&data->debug_msg_lock);
+ return;
+ }
+
+ data->debug_v2_enabled = true;
+ mutex_unlock(&data->debug_msg_lock);
+
+ dev_dbg(dev, "Enabled message output\n");
+}
+
+static void mxt_debug_msg_disable(struct mxt_data *data)
+{
+ struct device *dev = &data->client->dev;
+
+ if (!data->debug_v2_enabled)
+ return;
+
+ mutex_lock(&data->debug_msg_lock);
+
+ data->debug_v2_enabled = false;
+
+ kfree(data->debug_msg_data);
+ data->debug_msg_data = NULL;
+ data->debug_msg_count = 0;
+ mutex_unlock(&data->debug_msg_lock);
+ dev_dbg(dev, "Disabled message output\n");
+}
+
+static void mxt_debug_msg_add(struct mxt_data *data, u8 *msg)
+{
+ struct device *dev = &data->client->dev;
+
+ mutex_lock(&data->debug_msg_lock);
+
+ if (!data->debug_msg_data) {
+ mutex_unlock(&data->debug_msg_lock);
+ dev_err(dev, "No buffer!\n");
+ return;
+ }
+
+ if (data->debug_msg_count < DEBUG_MSG_MAX) {
+ memcpy(data->debug_msg_data +
+ data->debug_msg_count * data->T5_msg_size,
+ msg,
+ data->T5_msg_size);
+ data->debug_msg_count++;
+ } else {
+ dev_dbg(dev, "Discarding %u messages\n", data->debug_msg_count);
+ data->debug_msg_count = 0;
+ }
+
+ mutex_unlock(&data->debug_msg_lock);
+
+ sysfs_notify(&data->client->dev.kobj, NULL, "debug_notify");
+}
+
+static ssize_t mxt_debug_msg_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf, loff_t off, size_t bytes)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct mxt_data *data = dev_get_drvdata(dev);
+ int count;
+ size_t bytes_read;
+
+ if (!data->debug_msg_data) {
+ dev_err(dev, "No buffer!\n");
+ return 0;
+ }
+
+ count = bytes / data->T5_msg_size;
+
+ if (count > DEBUG_MSG_MAX)
+ count = DEBUG_MSG_MAX;
+
+ mutex_lock(&data->debug_msg_lock);
+
+ if (count > data->debug_msg_count)
+ count = data->debug_msg_count;
+
+ bytes_read = count * data->T5_msg_size;
+
+ memcpy(buf, data->debug_msg_data, bytes_read);
+ data->debug_msg_count = 0;
+
+ mutex_unlock(&data->debug_msg_lock);
+
+ return bytes_read;
+}
+
+static struct bin_attribute debug_msg_attr = {
+ .attr = {
+ .name = "debug_msg",
+ .mode = 0444,
+ },
+ .read = mxt_debug_msg_read,
+};
+
+static int mxt_debug_msg_init(struct mxt_data *data)
+{
+ /*
+ * Binary attribute is not used in callback, removal is done by name,
+ * so it is safe to update a single struct bin_attribute entity
+ */
+ debug_msg_attr.size = data->T5_msg_size * DEBUG_MSG_MAX;
+
+ if (sysfs_create_bin_file(&data->client->dev.kobj,
+ &debug_msg_attr) < 0) {
+ dev_err(&data->client->dev, "Failed to create %s\n",
+ debug_msg_attr.attr.name);
+ return -EINVAL;
+ }
+
+ data->debug_msg_attr = &debug_msg_attr;
+
+ return 0;
+}
+
+static void mxt_debug_msg_remove(struct mxt_data *data)
+{
+ if (data->debug_msg_attr) {
+ sysfs_remove_bin_file(&data->client->dev.kobj,
+ data->debug_msg_attr);
+ data->debug_msg_attr = NULL;
+ }
+}
+
static int mxt_wait_for_completion(struct mxt_data *data,
struct completion *comp,
unsigned int timeout_ms)
@@ -1256,6 +1401,9 @@ static int mxt_proc_message(struct mxt_data *data, u8 *message)
if (dump)
mxt_dump_message(data, message);
+ if (data->debug_v2_enabled)
+ mxt_debug_msg_add(data, message);
+
return 1;
}
@@ -2674,6 +2822,10 @@ static int mxt_initialize(struct mxt_data *data)
if (error)
return error;
+ error = mxt_debug_msg_init(data);
+ if (error)
+ goto err_free_sysfs;
+
if (data->cfg_name) {
error = request_firmware_nowait(THIS_MODULE, true,
data->cfg_name,
@@ -2683,16 +2835,18 @@ static int mxt_initialize(struct mxt_data *data)
if (error) {
dev_err(&client->dev, "Failed to invoke firmware loader: %d\n",
error);
- goto err_free_sysfs;
+ goto err_free_dbg_msg;
}
} else {
error = mxt_configure_objects(data, NULL);
if (error)
- goto err_free_sysfs;
+ goto err_free_dbg_msg;
}
return 0;
+err_free_dbg_msg:
+ mxt_debug_msg_remove(data);
err_free_sysfs:
mxt_sysfs_remove(data);
return error;
@@ -3354,6 +3508,7 @@ static int mxt_enter_bootloader(struct mxt_data *data)
return ret;
data->in_bootloader = true;
+ mxt_debug_msg_remove(data);
mxt_sysfs_remove(data);
mxt_free_input_device(data);
mxt_free_object_table(data);
@@ -3537,6 +3692,34 @@ static ssize_t mxt_debug_enable_show(struct device *dev,
return scnprintf(buf, PAGE_SIZE, "%c\n", c);
}
+static ssize_t mxt_debug_notify_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "0\n");
+}
+
+static ssize_t mxt_debug_v2_enable_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct mxt_data *data = dev_get_drvdata(dev);
+ u8 i;
+ ssize_t ret;
+
+ if (kstrtou8(buf, 0, &i) == 0 && i < 2) {
+ if (i == 1)
+ mxt_debug_msg_enable(data);
+ else
+ mxt_debug_msg_disable(data);
+
+ ret = count;
+ } else {
+ dev_dbg(dev, "debug_enabled write error\n");
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
static ssize_t mxt_debug_enable_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
@@ -3575,6 +3758,9 @@ static DEVICE_ATTR(update_cfg, S_IWUSR, NULL, mxt_update_cfg_store);
static DEVICE_ATTR(config_crc, S_IRUGO, mxt_config_crc_show, NULL);
static DEVICE_ATTR(debug_enable, S_IWUSR | S_IRUSR, mxt_debug_enable_show,
mxt_debug_enable_store);
+static DEVICE_ATTR(debug_v2_enable, S_IWUSR | S_IRUSR, NULL,
+ mxt_debug_v2_enable_store);
+static DEVICE_ATTR(debug_notify, S_IRUGO, mxt_debug_notify_show, NULL);
static struct attribute *mxt_attrs[] = {
&dev_attr_fw_version.attr,
@@ -3583,6 +3769,8 @@ static struct attribute *mxt_attrs[] = {
&dev_attr_update_cfg.attr,
&dev_attr_config_crc.attr,
&dev_attr_debug_enable.attr,
+ &dev_attr_debug_v2_enable.attr,
+ &dev_attr_debug_notify.attr,
NULL
};
@@ -3872,6 +4060,7 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
init_completion(&data->chg_completion);
init_completion(&data->reset_completion);
init_completion(&data->crc_completion);
+ mutex_init(&data->debug_msg_lock);
data->suspend_mode = dmi_check_system(chromebook_T9_suspend_dmi) ?
MXT_SUSPEND_T9_CTRL : MXT_SUSPEND_DEEP_SLEEP;
@@ -3930,6 +4119,7 @@ static int mxt_remove(struct i2c_client *client)
disable_irq(data->irq);
sysfs_remove_group(&client->dev.kobj, &mxt_fw_attr_group);
+ mxt_debug_msg_remove(data);
mxt_sysfs_remove(data);
mxt_free_input_device(data);
mxt_free_object_table(data);
--
2.19.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 31/49] Input: atmel_mxt_ts - eliminate data->raw_info_block
2019-08-27 6:29 ` Jiada Wang
@ 2019-08-27 6:29 ` Jiada Wang
-1 siblings, 0 replies; 10+ messages in thread
From: Jiada Wang @ 2019-08-27 6:29 UTC (permalink / raw)
To: nick, dmitry.torokhov; +Cc: linux-input, linux-kernel, jiada_wang, george_davis
Dynamically allocated in mxt_read_info_block() buffer buf is assigned
both to data->info and data->raw_info_block, having both data->info
and data->raw_info_block is redundant and confusing.
This patch eliminates data->raw_info_block.
Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
Signed-off-by: George G. Davis <george_davis@mentor.com>
Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 2d9d2c1e39dd..f6d65930885a 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -323,7 +323,6 @@ struct mxt_data {
char phys[64]; /* device physical location */
struct mxt_object *object_table;
struct mxt_info *info;
- void *raw_info_block;
unsigned int irq;
unsigned int max_x;
unsigned int max_y;
@@ -2067,9 +2066,8 @@ static void mxt_free_object_table(struct mxt_data *data)
v4l2_device_unregister(&data->dbg.v4l2);
#endif
data->object_table = NULL;
+ kfree(data->info);
data->info = NULL;
- kfree(data->raw_info_block);
- data->raw_info_block = NULL;
kfree(data->msg_buf);
data->msg_buf = NULL;
data->T5_address = 0;
@@ -2238,7 +2236,7 @@ static int mxt_read_info_block(struct mxt_data *data)
u8 *crc_ptr;
/* If info block already allocated, free it */
- if (data->raw_info_block)
+ if (data->info)
mxt_free_object_table(data);
/* Read 7-byte ID information block starting at address 0 */
@@ -2289,7 +2287,6 @@ static int mxt_read_info_block(struct mxt_data *data)
goto err_free_mem;
}
- data->raw_info_block = id_buf;
data->info = (struct mxt_info *)id_buf;
dev_info(&client->dev,
--
2.19.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 31/49] Input: atmel_mxt_ts - eliminate data->raw_info_block
@ 2019-08-27 6:29 ` Jiada Wang
0 siblings, 0 replies; 10+ messages in thread
From: Jiada Wang @ 2019-08-27 6:29 UTC (permalink / raw)
To: nick, dmitry.torokhov; +Cc: linux-input, linux-kernel, jiada_wang, george_davis
Dynamically allocated in mxt_read_info_block() buffer buf is assigned
both to data->info and data->raw_info_block, having both data->info
and data->raw_info_block is redundant and confusing.
This patch eliminates data->raw_info_block.
Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
Signed-off-by: George G. Davis <george_davis@mentor.com>
Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 2d9d2c1e39dd..f6d65930885a 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -323,7 +323,6 @@ struct mxt_data {
char phys[64]; /* device physical location */
struct mxt_object *object_table;
struct mxt_info *info;
- void *raw_info_block;
unsigned int irq;
unsigned int max_x;
unsigned int max_y;
@@ -2067,9 +2066,8 @@ static void mxt_free_object_table(struct mxt_data *data)
v4l2_device_unregister(&data->dbg.v4l2);
#endif
data->object_table = NULL;
+ kfree(data->info);
data->info = NULL;
- kfree(data->raw_info_block);
- data->raw_info_block = NULL;
kfree(data->msg_buf);
data->msg_buf = NULL;
data->T5_address = 0;
@@ -2238,7 +2236,7 @@ static int mxt_read_info_block(struct mxt_data *data)
u8 *crc_ptr;
/* If info block already allocated, free it */
- if (data->raw_info_block)
+ if (data->info)
mxt_free_object_table(data);
/* Read 7-byte ID information block starting at address 0 */
@@ -2289,7 +2287,6 @@ static int mxt_read_info_block(struct mxt_data *data)
goto err_free_mem;
}
- data->raw_info_block = id_buf;
data->info = (struct mxt_info *)id_buf;
dev_info(&client->dev,
--
2.19.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 32/49] Input: atmel_mxt_ts - Change call-points of mxt_free_* functions
2019-08-27 6:29 ` Jiada Wang
@ 2019-08-27 6:29 ` Jiada Wang
-1 siblings, 0 replies; 10+ messages in thread
From: Jiada Wang @ 2019-08-27 6:29 UTC (permalink / raw)
To: nick, dmitry.torokhov; +Cc: linux-input, linux-kernel, jiada_wang, george_davis
From: Kautuk Consul <kautuk_consul@mentor.com>
Revamping the code to call mxt_free_object_table and mxt_free_input_device
functions only in the following scenarios and code paths:
1) The error path of the mxt_probe() entry point
2) The mxt_remove de-init path entry point
3) All paths which definitely expect to populate the object table
like:
- the mxt_update_fw_store path which first calls
mxt_load_fw and then resorts to calling mxt_initialize itself.
- the mxt_read_info_block function which attempts to fill in the
object table itself as the main non-error part of the logic.
4) All paths in the code expected to definitely allocate and register
the input device such as:
- the mxt_update_fw_store path which first calls
mxt_load_fw and then resorts to calling mxt_initialize itself.
- the mxt_update_cfg_store function which will call
mxt_configure_objects.
Signed-off-by: Kautuk Consul <kautuk_consul@mentor.com>
Signed-off-by: George G. Davis <george_davis@mentor.com>
Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index f6d65930885a..f8e80471be8a 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -3336,21 +3336,21 @@ static int mxt_configure_objects(struct mxt_data *data,
error = mxt_init_t7_power_cfg(data);
if (error) {
dev_err(dev, "Failed to initialize power cfg\n");
- goto err_free_object_table;
+ return error;
}
if (cfg) {
error = mxt_update_cfg(data, cfg);
if (error) {
dev_warn(dev, "Error %d updating config\n", error);
- goto err_free_object_table;
+ return error;
}
}
if (data->multitouch) {
error = mxt_initialize_input_device(data);
if (error)
- goto err_free_object_table;
+ return error;
} else {
dev_warn(dev, "No touch object detected\n");
}
@@ -3358,10 +3358,6 @@ static int mxt_configure_objects(struct mxt_data *data,
mxt_debug_init(data);
return 0;
-
-err_free_object_table:
- mxt_free_object_table(data);
- return error;
}
/* Configuration crc check sum is returned as hex xxxxxx */
@@ -4098,16 +4094,21 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
error = mxt_initialize(data);
if (error)
- return error;
+ goto err_free_object;
error = sysfs_create_group(&client->dev.kobj, &mxt_fw_attr_group);
if (error) {
dev_err(&client->dev, "Failure %d creating fw sysfs group\n",
error);
- return error;
+ goto err_free_object;
}
return 0;
+
+err_free_object:
+ mxt_free_input_device(data);
+ mxt_free_object_table(data);
+ return error;
}
static int mxt_remove(struct i2c_client *client)
--
2.19.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 32/49] Input: atmel_mxt_ts - Change call-points of mxt_free_* functions
@ 2019-08-27 6:29 ` Jiada Wang
0 siblings, 0 replies; 10+ messages in thread
From: Jiada Wang @ 2019-08-27 6:29 UTC (permalink / raw)
To: nick, dmitry.torokhov; +Cc: linux-input, linux-kernel, jiada_wang, george_davis
From: Kautuk Consul <kautuk_consul@mentor.com>
Revamping the code to call mxt_free_object_table and mxt_free_input_device
functions only in the following scenarios and code paths:
1) The error path of the mxt_probe() entry point
2) The mxt_remove de-init path entry point
3) All paths which definitely expect to populate the object table
like:
- the mxt_update_fw_store path which first calls
mxt_load_fw and then resorts to calling mxt_initialize itself.
- the mxt_read_info_block function which attempts to fill in the
object table itself as the main non-error part of the logic.
4) All paths in the code expected to definitely allocate and register
the input device such as:
- the mxt_update_fw_store path which first calls
mxt_load_fw and then resorts to calling mxt_initialize itself.
- the mxt_update_cfg_store function which will call
mxt_configure_objects.
Signed-off-by: Kautuk Consul <kautuk_consul@mentor.com>
Signed-off-by: George G. Davis <george_davis@mentor.com>
Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index f6d65930885a..f8e80471be8a 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -3336,21 +3336,21 @@ static int mxt_configure_objects(struct mxt_data *data,
error = mxt_init_t7_power_cfg(data);
if (error) {
dev_err(dev, "Failed to initialize power cfg\n");
- goto err_free_object_table;
+ return error;
}
if (cfg) {
error = mxt_update_cfg(data, cfg);
if (error) {
dev_warn(dev, "Error %d updating config\n", error);
- goto err_free_object_table;
+ return error;
}
}
if (data->multitouch) {
error = mxt_initialize_input_device(data);
if (error)
- goto err_free_object_table;
+ return error;
} else {
dev_warn(dev, "No touch object detected\n");
}
@@ -3358,10 +3358,6 @@ static int mxt_configure_objects(struct mxt_data *data,
mxt_debug_init(data);
return 0;
-
-err_free_object_table:
- mxt_free_object_table(data);
- return error;
}
/* Configuration crc check sum is returned as hex xxxxxx */
@@ -4098,16 +4094,21 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
error = mxt_initialize(data);
if (error)
- return error;
+ goto err_free_object;
error = sysfs_create_group(&client->dev.kobj, &mxt_fw_attr_group);
if (error) {
dev_err(&client->dev, "Failure %d creating fw sysfs group\n",
error);
- return error;
+ goto err_free_object;
}
return 0;
+
+err_free_object:
+ mxt_free_input_device(data);
+ mxt_free_object_table(data);
+ return error;
}
static int mxt_remove(struct i2c_client *client)
--
2.19.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 33/49] Input: atmel_mxt_ts - rely on calculated_crc rather than file config_crc
2019-08-27 6:29 ` Jiada Wang
@ 2019-08-27 6:29 ` Jiada Wang
-1 siblings, 0 replies; 10+ messages in thread
From: Jiada Wang @ 2019-08-27 6:29 UTC (permalink / raw)
To: nick, dmitry.torokhov; +Cc: linux-input, linux-kernel, jiada_wang, george_davis
From: Kautuk Consul <kautuk_consul@mentor.com>
We now prefer to rely on the calculated CRC and not on the CRC stored in
the file.
The new logic is as follows:
1) stored CRC of file != calculated CRC of file, then refuse the possible
corrupted file
2) calculated CRC of file != CRC of configuration in controller, then
update configuration in controller
3) calculated CRC of file == CRC of configuration in controller, then
ignore configuration file
Signed-off-by: Kautuk Consul <kautuk_consul@mentor.com>
Signed-off-by: George G. Davis <george_davis@mentor.com>
Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 65 +++++++++++++-----------
1 file changed, 36 insertions(+), 29 deletions(-)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index f8e80471be8a..560d46634bae 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1905,7 +1905,7 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *fw)
int ret;
int offset;
int i;
- u32 info_crc, config_crc, calculated_crc;
+ u32 info_crc, config_crc, calculated_crc = 0;
u16 crc_start = 0;
/* Make zero terminated copy of the OBP_RAW file */
@@ -1968,30 +1968,6 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *fw)
}
cfg.raw_pos += offset;
- /*
- * The Info Block CRC is calculated over mxt_info and the object
- * table. If it does not match then we are trying to load the
- * configuration from a different chip or firmware version, so
- * the configuration CRC is invalid anyway.
- */
- if (info_crc == data->info_crc) {
- if (config_crc == 0 || data->config_crc == 0) {
- dev_info(dev, "CRC zero, attempting to apply config\n");
- } else if (config_crc == data->config_crc) {
- dev_dbg(dev, "Config CRC 0x%06X: OK\n",
- data->config_crc);
- ret = 0;
- goto release_raw;
- } else {
- dev_info(dev, "Config CRC 0x%06X: does not match file 0x%06X\n",
- data->config_crc, config_crc);
- }
- } else {
- dev_warn(dev,
- "Warning: Info CRC error - device=0x%06X file=0x%06X\n",
- data->info_crc, info_crc);
- }
-
/* Malloc memory to store configuration */
cfg.start_ofs = MXT_OBJECT_START +
data->info->object_num * sizeof(struct mxt_object) +
@@ -2015,14 +1991,45 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *fw)
else
dev_warn(dev, "Could not find CRC start\n");
- if (crc_start > cfg.start_ofs) {
+ if (crc_start > cfg.start_ofs)
calculated_crc = mxt_calculate_crc(cfg.mem,
crc_start - cfg.start_ofs,
cfg.mem_size);
- if (config_crc > 0 && config_crc != calculated_crc)
- dev_warn(dev, "Config CRC in file inconsistent, calculated=%06X, file=%06X\n",
- calculated_crc, config_crc);
+ /* If the CRC stored in the file is not the same as what
+ * was calculated by mxt_calculate_crc, this means we
+ * have to refuse the config file and abort download.
+ */
+ if (config_crc != calculated_crc) {
+ dev_warn(dev,
+ "Config CRC in file inconsistent, calculated=%06X, file=%06X\n",
+ calculated_crc, config_crc);
+ ret = 0;
+ goto release_mem;
+ }
+
+ /*
+ * The Info Block CRC is calculated over mxt_info and the object
+ * table. If it does not match then we are trying to load the
+ * configuration from a different chip or firmware version, so
+ * the configuration CRC is invalid anyway.
+ */
+ if (info_crc == data->info_crc) {
+ if (config_crc == 0 || data->config_crc == 0) {
+ dev_info(dev, "CRC zero, attempting to apply config\n");
+ } else if (config_crc == data->config_crc) {
+ dev_dbg(dev, "Config CRC 0x%06X: OK\n",
+ data->config_crc);
+ ret = 0;
+ goto release_mem;
+ } else {
+ dev_info(dev, "Config CRC 0x%06X: does not match file 0x%06X\n",
+ data->config_crc, config_crc);
+ }
+ } else {
+ dev_warn(dev,
+ "Warning: Info CRC error - device=0x%06X file=0x%06X\n",
+ data->info_crc, info_crc);
}
ret = mxt_upload_cfg_mem(data, &cfg);
--
2.19.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 33/49] Input: atmel_mxt_ts - rely on calculated_crc rather than file config_crc
@ 2019-08-27 6:29 ` Jiada Wang
0 siblings, 0 replies; 10+ messages in thread
From: Jiada Wang @ 2019-08-27 6:29 UTC (permalink / raw)
To: nick, dmitry.torokhov; +Cc: linux-input, linux-kernel, jiada_wang, george_davis
From: Kautuk Consul <kautuk_consul@mentor.com>
We now prefer to rely on the calculated CRC and not on the CRC stored in
the file.
The new logic is as follows:
1) stored CRC of file != calculated CRC of file, then refuse the possible
corrupted file
2) calculated CRC of file != CRC of configuration in controller, then
update configuration in controller
3) calculated CRC of file == CRC of configuration in controller, then
ignore configuration file
Signed-off-by: Kautuk Consul <kautuk_consul@mentor.com>
Signed-off-by: George G. Davis <george_davis@mentor.com>
Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 65 +++++++++++++-----------
1 file changed, 36 insertions(+), 29 deletions(-)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index f8e80471be8a..560d46634bae 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1905,7 +1905,7 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *fw)
int ret;
int offset;
int i;
- u32 info_crc, config_crc, calculated_crc;
+ u32 info_crc, config_crc, calculated_crc = 0;
u16 crc_start = 0;
/* Make zero terminated copy of the OBP_RAW file */
@@ -1968,30 +1968,6 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *fw)
}
cfg.raw_pos += offset;
- /*
- * The Info Block CRC is calculated over mxt_info and the object
- * table. If it does not match then we are trying to load the
- * configuration from a different chip or firmware version, so
- * the configuration CRC is invalid anyway.
- */
- if (info_crc == data->info_crc) {
- if (config_crc == 0 || data->config_crc == 0) {
- dev_info(dev, "CRC zero, attempting to apply config\n");
- } else if (config_crc == data->config_crc) {
- dev_dbg(dev, "Config CRC 0x%06X: OK\n",
- data->config_crc);
- ret = 0;
- goto release_raw;
- } else {
- dev_info(dev, "Config CRC 0x%06X: does not match file 0x%06X\n",
- data->config_crc, config_crc);
- }
- } else {
- dev_warn(dev,
- "Warning: Info CRC error - device=0x%06X file=0x%06X\n",
- data->info_crc, info_crc);
- }
-
/* Malloc memory to store configuration */
cfg.start_ofs = MXT_OBJECT_START +
data->info->object_num * sizeof(struct mxt_object) +
@@ -2015,14 +1991,45 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *fw)
else
dev_warn(dev, "Could not find CRC start\n");
- if (crc_start > cfg.start_ofs) {
+ if (crc_start > cfg.start_ofs)
calculated_crc = mxt_calculate_crc(cfg.mem,
crc_start - cfg.start_ofs,
cfg.mem_size);
- if (config_crc > 0 && config_crc != calculated_crc)
- dev_warn(dev, "Config CRC in file inconsistent, calculated=%06X, file=%06X\n",
- calculated_crc, config_crc);
+ /* If the CRC stored in the file is not the same as what
+ * was calculated by mxt_calculate_crc, this means we
+ * have to refuse the config file and abort download.
+ */
+ if (config_crc != calculated_crc) {
+ dev_warn(dev,
+ "Config CRC in file inconsistent, calculated=%06X, file=%06X\n",
+ calculated_crc, config_crc);
+ ret = 0;
+ goto release_mem;
+ }
+
+ /*
+ * The Info Block CRC is calculated over mxt_info and the object
+ * table. If it does not match then we are trying to load the
+ * configuration from a different chip or firmware version, so
+ * the configuration CRC is invalid anyway.
+ */
+ if (info_crc == data->info_crc) {
+ if (config_crc == 0 || data->config_crc == 0) {
+ dev_info(dev, "CRC zero, attempting to apply config\n");
+ } else if (config_crc == data->config_crc) {
+ dev_dbg(dev, "Config CRC 0x%06X: OK\n",
+ data->config_crc);
+ ret = 0;
+ goto release_mem;
+ } else {
+ dev_info(dev, "Config CRC 0x%06X: does not match file 0x%06X\n",
+ data->config_crc, config_crc);
+ }
+ } else {
+ dev_warn(dev,
+ "Warning: Info CRC error - device=0x%06X file=0x%06X\n",
+ data->info_crc, info_crc);
}
ret = mxt_upload_cfg_mem(data, &cfg);
--
2.19.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 34/49] input: atmel_mxt_ts: export GPIO reset line via sysfs
2019-08-27 6:29 ` Jiada Wang
@ 2019-08-27 6:30 ` Jiada Wang
-1 siblings, 0 replies; 10+ messages in thread
From: Jiada Wang @ 2019-08-27 6:30 UTC (permalink / raw)
To: nick, dmitry.torokhov; +Cc: linux-input, linux-kernel, jiada_wang, george_davis
From: "George G. Davis" <george_davis@mentor.com>
N.B. Modifying the atmel_mxt_ts GPIO reset line during operation will
cause problems with normal driver operation. This feature is provided
as a diagnostic debug aid. It does not take into consideration any
pending operations which may be in progress. Modifying the atmel_mxt_ts
GPIO reset line at any time will inevitably cause the driver to fail.
Signed-off-by: George G. Davis <george_davis@mentor.com>
Signed-off-by: Rajeev Kumar <rajeev_kumar@mentor.com>
Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 560d46634bae..35f41bfa70d5 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -4083,6 +4083,19 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
return error;
}
+ if (data->reset_gpio) {
+ error = gpiod_export(data->reset_gpio, 0);
+ if (error)
+ return error;
+
+ error = gpiod_export_link(&client->dev, "reset",
+ data->reset_gpio);
+ if (error) {
+ gpiod_unexport(data->reset_gpio);
+ return error;
+ }
+ }
+
if (data->suspend_mode == MXT_SUSPEND_REGULATOR) {
error = mxt_acquire_irq(data);
if (error)
@@ -4115,6 +4128,10 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
err_free_object:
mxt_free_input_device(data);
mxt_free_object_table(data);
+ if (data->reset_gpio) {
+ sysfs_remove_link(&client->dev.kobj, "reset");
+ gpiod_unexport(data->reset_gpio);
+ }
return error;
}
@@ -4124,6 +4141,10 @@ static int mxt_remove(struct i2c_client *client)
disable_irq(data->irq);
sysfs_remove_group(&client->dev.kobj, &mxt_fw_attr_group);
+ if (data->reset_gpio) {
+ sysfs_remove_link(&client->dev.kobj, "reset");
+ gpiod_unexport(data->reset_gpio);
+ }
mxt_debug_msg_remove(data);
mxt_sysfs_remove(data);
mxt_free_input_device(data);
--
2.19.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 34/49] input: atmel_mxt_ts: export GPIO reset line via sysfs
@ 2019-08-27 6:30 ` Jiada Wang
0 siblings, 0 replies; 10+ messages in thread
From: Jiada Wang @ 2019-08-27 6:30 UTC (permalink / raw)
To: nick, dmitry.torokhov; +Cc: linux-input, linux-kernel, jiada_wang, george_davis
From: "George G. Davis" <george_davis@mentor.com>
N.B. Modifying the atmel_mxt_ts GPIO reset line during operation will
cause problems with normal driver operation. This feature is provided
as a diagnostic debug aid. It does not take into consideration any
pending operations which may be in progress. Modifying the atmel_mxt_ts
GPIO reset line at any time will inevitably cause the driver to fail.
Signed-off-by: George G. Davis <george_davis@mentor.com>
Signed-off-by: Rajeev Kumar <rajeev_kumar@mentor.com>
Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 560d46634bae..35f41bfa70d5 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -4083,6 +4083,19 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
return error;
}
+ if (data->reset_gpio) {
+ error = gpiod_export(data->reset_gpio, 0);
+ if (error)
+ return error;
+
+ error = gpiod_export_link(&client->dev, "reset",
+ data->reset_gpio);
+ if (error) {
+ gpiod_unexport(data->reset_gpio);
+ return error;
+ }
+ }
+
if (data->suspend_mode == MXT_SUSPEND_REGULATOR) {
error = mxt_acquire_irq(data);
if (error)
@@ -4115,6 +4128,10 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
err_free_object:
mxt_free_input_device(data);
mxt_free_object_table(data);
+ if (data->reset_gpio) {
+ sysfs_remove_link(&client->dev.kobj, "reset");
+ gpiod_unexport(data->reset_gpio);
+ }
return error;
}
@@ -4124,6 +4141,10 @@ static int mxt_remove(struct i2c_client *client)
disable_irq(data->irq);
sysfs_remove_group(&client->dev.kobj, &mxt_fw_attr_group);
+ if (data->reset_gpio) {
+ sysfs_remove_link(&client->dev.kobj, "reset");
+ gpiod_unexport(data->reset_gpio);
+ }
mxt_debug_msg_remove(data);
mxt_sysfs_remove(data);
mxt_free_input_device(data);
--
2.19.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2019-08-27 6:30 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-27 6:29 [PATCH v2 30/49] Input: atmel_mxt_ts - implement improved debug message interface Jiada Wang
2019-08-27 6:29 ` Jiada Wang
2019-08-27 6:29 ` [PATCH v2 31/49] Input: atmel_mxt_ts - eliminate data->raw_info_block Jiada Wang
2019-08-27 6:29 ` Jiada Wang
2019-08-27 6:29 ` [PATCH v2 32/49] Input: atmel_mxt_ts - Change call-points of mxt_free_* functions Jiada Wang
2019-08-27 6:29 ` Jiada Wang
2019-08-27 6:29 ` [PATCH v2 33/49] Input: atmel_mxt_ts - rely on calculated_crc rather than file config_crc Jiada Wang
2019-08-27 6:29 ` Jiada Wang
2019-08-27 6:30 ` [PATCH v2 34/49] input: atmel_mxt_ts: export GPIO reset line via sysfs Jiada Wang
2019-08-27 6:30 ` Jiada Wang
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.