From patchwork Fri Aug 16 08:38:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wang, Jiada" X-Patchwork-Id: 11097291 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B451C14DB for ; Fri, 16 Aug 2019 08:39:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A4184289CA for ; Fri, 16 Aug 2019 08:39:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 97696289DC; Fri, 16 Aug 2019 08:39:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0FE0C289CA for ; Fri, 16 Aug 2019 08:39:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727447AbfHPIi5 (ORCPT ); Fri, 16 Aug 2019 04:38:57 -0400 Received: from esa3.mentor.iphmx.com ([68.232.137.180]:42050 "EHLO esa3.mentor.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725829AbfHPIi4 (ORCPT ); Fri, 16 Aug 2019 04:38:56 -0400 IronPort-SDR: vFh6jOLrYfbWk9oaR6SK/8Z7CsTXloxq8OFELQr5FhHQsuQNxZlMtK9115Y7BLk3jDYcJelgb0 lxEVRcf7zk9SFsGBcrZ5/FEuGFON8Z/+lZvVASKrowB5U0sGPtgHAQnlRNOjLWcoBMdgmhdn5/ nAGHyghOovaf/mFdA6uo1p0CSJOS3TUGMCdOTDurzA96/wxKovqXKE0xU3KBslkGTz4kwUc9uk wskO0Fa+4crUTKKlvqN3g+HOb1kYKEv6PNX55G3RLpvetNIKySNENNSmuzEPP96vd+hurvm2Sv O78= X-IronPort-AV: E=Sophos;i="5.64,391,1559548800"; d="scan'208";a="40507256" Received: from orw-gwy-02-in.mentorg.com ([192.94.38.167]) by esa3.mentor.iphmx.com with ESMTP; 16 Aug 2019 00:38:54 -0800 IronPort-SDR: VBNSupeNecNR22efIutayFm1ISF8kXEH65xgRAtOZXCQGfiS/sGWrUm6MQ83OhrUMzakpGLMlE GpvKc9qR688T/ZQW7tlt5f/MvL0SmNYnMbimQLS3754owrmT+1A/Qd8gQ2IrYu+IQQBYxXiT/A TOMPWtLtxT5w18NgQCDZRTBU2cyuRZVeZn/2Wg7hiAKiWthjGLi/6lU9E7Q78BdMJJu8QDxtJa 0i1DkjOfE7lKXrUAQua7iNbZuuVlIRM9BJczQNP0k+FiWg7G5+2rSt6kMvA+UbQU71DDr/KS4B Vfw= From: Jiada Wang To: , CC: , , , Subject: [PATCH v1 60/63] input: atmel_mxt_ts: added sysfs interface to update atmel T38 data Date: Fri, 16 Aug 2019 17:38:59 +0900 Message-ID: <20190816083902.19659-1-jiada_wang@mentor.com> X-Mailer: git-send-email 2.19.2 MIME-Version: 1.0 X-ClientProxiedBy: SVR-ORW-MBX-09.mgc.mentorg.com (147.34.90.209) To svr-orw-mbx-03.mgc.mentorg.com (147.34.90.203) Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Naveen Chakka Atmel touch controller contains T38 object where a user can store its own data of length 64 bytes. T38 data will not be part of checksum calculation on executing T6 BACKUP command. format used to update the T38 data is given below: offset: offset address of the data to be written in the t38 object (in decimal) length: length of the data to be written into the t38 object(in decimal) data: actual data bytes to be written into the t38 object (values should be in hex) Ex: 1. 0 2 10 20 updates first two bytes of the t38 data with values 10 and 20 2. 19 6 10 2f 30 4a 50 60 updates 6 bytes of t38 data from the index 19-24 with hex values Signed-off-by: Naveen Chakka Signed-off-by: Sanjeev Chugh Signed-off-by: George G. Davis Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 104 ++++++++++++++++++++++- 1 file changed, 102 insertions(+), 2 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 8e95f46a30d7..fd9a96ec3fd3 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -3024,8 +3024,6 @@ static void mxt_watchdog_timer(struct timer_list *t) { struct mxt_data *data = from_timer(data, t, watchdog_timer); - dev_dbg(&data->client->dev, "%s: Timer triggered\n", __func__); - if (!work_pending(&data->watchdog_work)) { if (!data->mxt_status.intp_triggered) schedule_work(&data->watchdog_work); @@ -4095,6 +4093,106 @@ static ssize_t mxt_touch_device_status(struct device *dev, struct return ret; } +static ssize_t mxt_t38_data_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mxt_data *data = dev_get_drvdata(dev); + struct mxt_object *object; + size_t count = 0, size; + u8 i, *t38_buf; + + if (!data->object_table) + return -ENXIO; + + object = mxt_get_object(data, MXT_SPT_USERDATA_T38); + size = mxt_obj_size(object); + + /* Pre-allocate buffer large enough to hold max size of t38 object.*/ + t38_buf = kmalloc(size, GFP_KERNEL); + if (!t38_buf) + return -ENOMEM; + + count = __mxt_read_reg(data->client, object->start_address, + size, t38_buf); + if (count) + goto end; + + for (i = 0; i < size; i++) + count += scnprintf(buf + count, PAGE_SIZE - count, + "[%2u]: %02x\n", i, t38_buf[i]); + count += scnprintf(buf + count, PAGE_SIZE - count, "\n"); +end: + kfree(t38_buf); + return count; +} + +static ssize_t mxt_t38_data_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct mxt_data *data = dev_get_drvdata(dev); + struct mxt_object *object; + ssize_t ret = 0, pos, offset; + unsigned int i, len, index; + u8 *t38_buf; + + if (!data->object_table) + return -ENXIO; + + object = mxt_get_object(data, MXT_SPT_USERDATA_T38); + + /* Pre-allocate buffer large enough to hold max size of t38 object.*/ + t38_buf = kmalloc(mxt_obj_size(object), GFP_KERNEL); + if (!t38_buf) + return -ENOMEM; + + ret = sscanf(buf, "%zd %d%zd", &offset, &len, &pos); + if (ret != 2) { + dev_err(dev, "Bad format: Invalid parameter to update t38\n"); + ret = -EINVAL; + goto end; + } + + if (len == 0) { + dev_err(dev, + "Bad format: Data length should not be equal to 0\n"); + ret = -EINVAL; + goto end; + } + + if (offset < 0 || ((offset + len) > 64)) { + dev_err(dev, "Invalid offset value to update t38\n"); + ret = -EINVAL; + goto end; + } + + index = pos; + for (i = 0; i < len; i++) { + ret = sscanf(buf + index, "%hhx%zd", t38_buf + i, &pos); + if (ret != 1) { + dev_err(dev, "Bad format: Invalid Data\n"); + ret = -EINVAL; + goto end; + } + index += pos; + } + + ret = __mxt_write_reg(data->client, object->start_address + offset, + len, t38_buf); + if (ret) + goto end; + + ret = mxt_t6_command(data, MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE, + true); + if (ret) + dev_err(dev, "backup command failed\n"); + else + ret = count; +end: + kfree(t38_buf); + return ret; +} + static DEVICE_ATTR(fw_version, S_IRUGO, mxt_fw_version_show, NULL); static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL); static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL); @@ -4107,6 +4205,7 @@ static DEVICE_ATTR(debug_v2_enable, S_IWUSR | S_IRUSR, NULL, static DEVICE_ATTR(debug_notify, S_IRUGO, mxt_debug_notify_show, NULL); static DEVICE_ATTR(t25, 0600, mxt_t25_selftest_show, mxt_t25_selftest_store); static DEVICE_ATTR(touch_dev_stat, 0444, mxt_touch_device_status, NULL); +static DEVICE_ATTR(t38_data, 0600, mxt_t38_data_show, mxt_t38_data_store); static struct attribute *mxt_attrs[] = { &dev_attr_fw_version.attr, @@ -4119,6 +4218,7 @@ static struct attribute *mxt_attrs[] = { &dev_attr_debug_notify.attr, &dev_attr_t25.attr, &dev_attr_touch_dev_stat.attr, + &dev_attr_t38_data.attr, NULL }; From patchwork Fri Aug 16 08:39:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wang, Jiada" X-Patchwork-Id: 11097289 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CE94614DB for ; Fri, 16 Aug 2019 08:39:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BEECE289CA for ; Fri, 16 Aug 2019 08:39:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B334B289DC; Fri, 16 Aug 2019 08:39:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5022C289CA for ; Fri, 16 Aug 2019 08:39:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726972AbfHPIi6 (ORCPT ); Fri, 16 Aug 2019 04:38:58 -0400 Received: from esa3.mentor.iphmx.com ([68.232.137.180]:42050 "EHLO esa3.mentor.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727452AbfHPIi6 (ORCPT ); Fri, 16 Aug 2019 04:38:58 -0400 IronPort-SDR: bJDvfmK7W7Dp+vt0VfiWyVQXmgS8F8OdYDNtdPjnZj2LxSmO/JqwLC/cQVO56puVrLYwpUFkk7 viM3zGRy+rZ3XkyWoPU4Ibd3TtUmGt2vXNwcX9JNhvX3eVyjqtci0iS/d4xZaFXG7G4Itycv18 dNFEqPYNA2MzgO/Fo3bKEd11P/8MEljoSjBrUiwY7U+15gVDopkLgHLluotoSny3sNk/bljQ9T 4oJ3k9g3iXjAsCupPYDJqYpgb+O0ZbYADSJPt5FxXpsC7jVmURtFror1dzARuZlqBJghX6xfds H6Q= X-IronPort-AV: E=Sophos;i="5.64,391,1559548800"; d="scan'208";a="40507258" Received: from orw-gwy-02-in.mentorg.com ([192.94.38.167]) by esa3.mentor.iphmx.com with ESMTP; 16 Aug 2019 00:38:57 -0800 IronPort-SDR: KIiv3wif9mW1SXUBGBWoBPp61yd7mEa405/fvPDmOxkZ5GxtLnLkM20fv4h8ySFE3cBdAvZsNs ttdHh9UkByB16wbztMjQhq1H0qxuimzajaBKrnouFej4c1UgAoSwIaRhAx6pOBTwhejUw3KBsw wN5oJLz+mEdfq7okVVFGDDArsMAmBidF9+T+IaY47vOUsCO0pwgC+bh6C4eougQkCqGi8VyQTC ywoSVUxzQ0Ztne0MuQ5h5VM+45+REcNndSjKQAXjUms/QlRn3qtppZoDthWZFtenMVItKfFoFv Dbg= From: Jiada Wang To: , CC: , , , Subject: [PATCH v1 61/63] input: atmel_mxt_ts: Add NULL check for sysfs attribute debug_msg_attr Date: Fri, 16 Aug 2019 17:39:00 +0900 Message-ID: <20190816083902.19659-2-jiada_wang@mentor.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190816083902.19659-1-jiada_wang@mentor.com> References: <20190816083902.19659-1-jiada_wang@mentor.com> MIME-Version: 1.0 X-ClientProxiedBy: SVR-ORW-MBX-09.mgc.mentorg.com (147.34.90.209) To svr-orw-mbx-03.mgc.mentorg.com (147.34.90.203) Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Balasubramani Vivekanandan In some scenarios mxt_debug_msg_remove() can be called from mxt_remove() even before the data->debug_msg_attr is updated. So a NULL check is required for data->debug_msg_attr before accessing it. There is also an additional change in mxt_debug_msg_init() to update data->debug_msg_attr only when sysfs_create_bin_file is successful. Consider the following scenario: Atmel MXT driver module is being loaded hence mxt_probe() is called, then mxt_probe() calls mxt_initialize() and in mxt_initialize() function if the Atmel MXT is in bootloader mode there is a possibility that it can return before calling mxt_debug_msg_init(), with a value of 0 meaning no error. In this case data->debug_msg_attr is now at the initialized state only, which is NULL as allocation of data pointer was done with devm_kzalloc() call in mxt_probe function. Completion of initialisation will be deferred until some later time. If there is now an attempt to remove the Atmel MXT driver module, in mxt_remove() there is a call to mxt_debug_msg_remove() which calls sysfs_remove_bin_file() with a NULL data->debug_msg_attr. Therefore, we need to have check in mxt_debug_msg_remove() for data->debug_msg_attr being NULL. Signed-off-by: Balasubramani Vivekanandan Signed-off-by: Mark Craske Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index fd9a96ec3fd3..1179f90a8077 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -615,21 +615,26 @@ static int mxt_debug_msg_init(struct mxt_data *data) * so it is safe to update a single struct bin_attribute entity */ debug_msg_attr.size = data->T5_msg_size * DEBUG_MSG_MAX; - data->debug_msg_attr = &debug_msg_attr; if (sysfs_create_bin_file(&data->client->dev.kobj, - data->debug_msg_attr) < 0) { + &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) { - sysfs_remove_bin_file(&data->client->dev.kobj, data->debug_msg_attr); + 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, From patchwork Fri Aug 16 08:39:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wang, Jiada" X-Patchwork-Id: 11097275 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 76B3714DB for ; Fri, 16 Aug 2019 08:39:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5F7B5289CA for ; Fri, 16 Aug 2019 08:39:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 51272289DC; Fri, 16 Aug 2019 08:39:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6DC5A289CA for ; Fri, 16 Aug 2019 08:39:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727042AbfHPIjO (ORCPT ); Fri, 16 Aug 2019 04:39:14 -0400 Received: from esa3.mentor.iphmx.com ([68.232.137.180]:42050 "EHLO esa3.mentor.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727478AbfHPIjB (ORCPT ); Fri, 16 Aug 2019 04:39:01 -0400 IronPort-SDR: b8lMd1Nm5w/9/nW1OpxPT4lXXzuUeI8QIRi1t5VHBwAwga6GNWZhUDgOLp7dOgfPVcVr+Qu1Ld F2GrtN2XqtO+4Ourq7j3qclYjhBNNSzE3PzepqKHollgryDiKweKES5uV/WMH3In5PhXFoQpq3 yFREa4wA5Faf4oqCB2e/3jkNla+9p+hs3U5+Xrv4HVAfcSdH22+/H2b98aiYCTYHjrnBTw59pd Zmk1UazzaQyCD5JvTdgj6ltTlFwnehADxCeC//3phr+5PoD2JPC/2xOs+QJjtXQkdfLzeXxE/7 GbY= X-IronPort-AV: E=Sophos;i="5.64,391,1559548800"; d="scan'208";a="40507261" Received: from orw-gwy-02-in.mentorg.com ([192.94.38.167]) by esa3.mentor.iphmx.com with ESMTP; 16 Aug 2019 00:39:00 -0800 IronPort-SDR: IlZL1vsqFJNmAi4VrJ9Um0lLPLfHLgClgIXvK8O2IkGFH2Kll35/g71yG6nDWbGBPnoIeVwHd/ Y6GM9Gf4QM7FMHX0zpBCn35gHtjBHCHBvs7Ykc/s9E03vNtvyzOltdbRXdM8yzAXprgFRp5N2H D9TwuoXJrZP7VFowv+uUGqAaVLfEPb/o1E9zra5QkrxXsIKl5aw3FLFxPABl4g2Zs76bpEIaks rUvtezlVd1WhWypEZ36+MIWgvyv3IF18AgIvocwQdDHkzRk2NAe+5Gz8dcQotss9YbVPyjjMN1 lpo= From: Jiada Wang To: , CC: , , , Subject: [PATCH v1 62/63] Input: atmel_mxt_ts: Implement synchronization during various operation Date: Fri, 16 Aug 2019 17:39:01 +0900 Message-ID: <20190816083902.19659-3-jiada_wang@mentor.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190816083902.19659-1-jiada_wang@mentor.com> References: <20190816083902.19659-1-jiada_wang@mentor.com> MIME-Version: 1.0 X-ClientProxiedBy: SVR-ORW-MBX-09.mgc.mentorg.com (147.34.90.209) To svr-orw-mbx-03.mgc.mentorg.com (147.34.90.203) Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Sanjeev Chugh There could be scope of race conditions when sysfs is being handled and at the same time, device removal is occurring. For example, we don't want the device removal to begin if the Atmel device cfg update is going on or firmware update is going on. In such cases, wait for device update to be completed before the removal continues. Thread Thread 2: ========================= ========================= mxt_update_fw_store() mxt_remove() mutex_lock(&data->lock) ... mxt_initialize() //Tries to acquire lock request_firmware_nowait() mutex_lock(&data->lock) ... ==>waits for lock() ... . ... . mutex_unlock(&data->lock) . //Gets lock and proceeds mxt_free_input_device(); ... mutex_unlock(&data->lock) //Frees atmel driver data kfree(data) If the request_firmware_nowait() completes after the driver removal, and callback is triggered. But kernel crashes since the module is already removed. This commit adds state machine to serialize such scenarios. Signed-off-by: Sanjeev Chugh Signed-off-by: Bhuvanesh Surachari Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 222 ++++++++++++++++++++--- 1 file changed, 196 insertions(+), 26 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 1179f90a8077..6e5fad91c379 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -224,6 +224,7 @@ enum t100_type { #define MXT_POWERON_DELAY 150 /* msec */ #define MXT_BOOTLOADER_WAIT 36E5 /* 1 minute */ #define MXT_WATCHDOG_TIMEOUT 1000 /* msec */ +#define MXT_CONFIG_TIMEOUT 1000 /* msec */ /* Command to unlock bootloader */ #define MXT_UNLOCK_CMD_MSB 0xaa @@ -247,6 +248,20 @@ enum t100_type { #define DEBUG_MSG_MAX 200 +enum device_state { + MXT_STATE_READY, + MXT_STATE_UPDATING_CONFIG, + MXT_STATE_UPDATING_CONFIG_ASYNC, + MXT_STATE_START, + MXT_STATE_STOP, + MXT_STATE_GOING_AWAY +}; + +enum mxt_cmd { + UPDATE_CFG, + UPDATE_FW +}; + struct mxt_info { u8 family_id; u8 variant_id; @@ -427,8 +442,7 @@ struct mxt_data { /* Indicates whether device is in suspend */ bool suspended; - /* Indicates whether device is updating configuration */ - bool updating_config; + struct mutex lock; unsigned long gpio_input_pin_status; struct attribute_group gpio_attrs; @@ -436,6 +450,11 @@ struct mxt_data { unsigned int mtu; bool t25_status; + + /* State handling for probe/remove, open/close and config update */ + enum device_state e_state; + + struct completion update_cfg_completion; }; struct mxt_gpio_attr { @@ -1664,6 +1683,7 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id) struct mxt_data *data = dev_id; int ret; + mutex_lock(&data->lock); data->mxt_status.intp_triggered = true; if (data->in_bootloader) { @@ -1691,6 +1711,8 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id) exit: data->mxt_status.intp_triggered = false; + mutex_unlock(&data->lock); + return ret; } @@ -2275,6 +2297,8 @@ static void mxt_free_object_table(struct mxt_data *data) video_unregister_device(&data->dbg.vdev); v4l2_device_unregister(&data->dbg.v4l2); #endif + mutex_lock(&data->lock); + data->object_table = NULL; kfree(data->info); data->info = NULL; @@ -2304,6 +2328,8 @@ static void mxt_free_object_table(struct mxt_data *data) data->T100_reportid_min = 0; data->T100_reportid_max = 0; data->max_reportid = 0; + + mutex_unlock(&data->lock); } static int mxt_parse_object_table(struct mxt_data *data, @@ -2995,8 +3021,15 @@ static int mxt_configure_objects(struct mxt_data *data, static void mxt_config_cb(const struct firmware *cfg, void *ctx) { + struct mxt_data *data = ctx; + mxt_configure_objects(ctx, cfg); release_firmware(cfg); + complete(&data->update_cfg_completion); + mutex_lock(&data->lock); + if (data->e_state != MXT_STATE_GOING_AWAY) + data->e_state = MXT_STATE_READY; + mutex_unlock(&data->lock); } static int mxt_bootloader_status(struct mxt_data *data) @@ -3109,6 +3142,15 @@ static int mxt_initialize(struct mxt_data *data) goto err_free_sysfs; if (data->cfg_name) { + mutex_lock(&data->lock); + if (data->e_state != MXT_STATE_GOING_AWAY) { + data->e_state = MXT_STATE_UPDATING_CONFIG_ASYNC; + } else { + mutex_unlock(&data->lock); + return -EBUSY; + } + reinit_completion(&data->update_cfg_completion); + mutex_unlock(&data->lock); error = request_firmware_nowait(THIS_MODULE, true, data->cfg_name, &client->dev, @@ -3888,30 +3930,58 @@ static int mxt_update_file_name(struct device *dev, char **file_name, return 0; } +static int mxt_process_operation(struct mxt_data *data, + enum mxt_cmd cmd, + void *cmd_data); + static ssize_t mxt_update_fw_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) + struct device_attribute *attr, + const char *buf, size_t count) { struct mxt_data *data = dev_get_drvdata(dev); + char *filename = NULL; + int ret; + + ret = mxt_update_file_name(dev, &filename, buf, count); + if (ret) + goto out; + + ret = mxt_process_operation(data, UPDATE_FW, filename); + kfree(filename); + + if (ret) + goto out; + + return count; +out: + return ret; +} + +static int mxt_fw_update(struct mxt_data *data, + const char *filename) +{ + struct device *dev = &data->client->dev; + unsigned int len = 0; int error; - error = mxt_update_file_name(dev, &data->fw_name, buf, count); + len = strlen(filename); + error = mxt_update_file_name(dev, &data->fw_name, filename, len); if (error) return error; error = mxt_load_fw(dev); if (error) { dev_err(dev, "The firmware update failed(%d)\n", error); - count = error; - } else { - dev_info(dev, "The firmware update succeeded\n"); - - error = mxt_initialize(data); - if (error) - return error; + return error; } - return count; + error = mxt_initialize(data); + if (error) + return error; + + dev_info(dev, "The firmware update succeeded\n"); + + return error; } static ssize_t mxt_update_cfg_store(struct device *dev, @@ -3919,14 +3989,38 @@ static ssize_t mxt_update_cfg_store(struct device *dev, const char *buf, size_t count) { struct mxt_data *data = dev_get_drvdata(dev); + char *filename = NULL; + int ret; + + ret = mxt_update_file_name(dev, &filename, buf, count); + if (ret) + goto out; + + ret = mxt_process_operation(data, UPDATE_CFG, filename); + kfree(filename); + + if (ret) + goto out; + + return count; +out: + return ret; +} + +static int mxt_cfg_update(struct mxt_data *data, + char *filename) +{ + struct device *dev = &data->client->dev; const struct firmware *cfg; + unsigned int len = 0; int ret; - ret = mxt_update_file_name(dev, &data->cfg_name, buf, count); + len = strlen(filename); + ret = mxt_update_file_name(dev, &data->cfg_name, filename, len); if (ret) return ret; - ret = request_firmware(&cfg, data->cfg_name, dev); + ret = request_firmware(&cfg, data->cfg_name, &data->client->dev); if (ret < 0) { dev_err(dev, "Failure to request config file %s\n", data->cfg_name); @@ -3934,8 +4028,6 @@ static ssize_t mxt_update_cfg_store(struct device *dev, goto out; } - data->updating_config = true; - mxt_free_input_device(data); if (data->suspended) { @@ -3951,15 +4043,8 @@ static ssize_t mxt_update_cfg_store(struct device *dev, } ret = mxt_configure_objects(data, cfg); - if (ret) - goto release; - - ret = count; - -release: release_firmware(cfg); out: - data->updating_config = false; return ret; } @@ -4296,8 +4381,17 @@ static int mxt_start(struct mxt_data *data) { int ret = 0; - if (!data->suspended || data->in_bootloader) + mutex_lock(&data->lock); + if (!data->suspended) { + mutex_unlock(&data->lock); return 0; + } + if (data->in_bootloader || data->e_state != MXT_STATE_READY) { + mutex_unlock(&data->lock); + return -EBUSY; + } + data->e_state = MXT_STATE_START; + mutex_unlock(&data->lock); switch (data->suspend_mode) { case MXT_SUSPEND_T9_CTRL: @@ -4341,8 +4435,12 @@ static int mxt_start(struct mxt_data *data) ret = mxt_acquire_irq(data); } + mutex_lock(&data->lock); if (!ret) data->suspended = false; + if (data->e_state != MXT_STATE_GOING_AWAY) + data->e_state = MXT_STATE_READY; + mutex_unlock(&data->lock); return ret; } @@ -4351,8 +4449,19 @@ static int mxt_stop(struct mxt_data *data) { int ret; - if (data->suspended || data->in_bootloader || data->updating_config) + mutex_lock(&data->lock); + if (data->suspended) { + mutex_unlock(&data->lock); return 0; + } + if (data->in_bootloader || (data->e_state != MXT_STATE_READY && + data->e_state != MXT_STATE_GOING_AWAY)) { + mutex_unlock(&data->lock); + return -EBUSY; + } + if (data->e_state != MXT_STATE_GOING_AWAY) + data->e_state = MXT_STATE_STOP; + mutex_unlock(&data->lock); switch (data->suspend_mode) { case MXT_SUSPEND_T9_CTRL: @@ -4382,8 +4491,15 @@ static int mxt_stop(struct mxt_data *data) break; } + mutex_lock(&data->lock); data->suspended = true; + + if (data->e_state != MXT_STATE_GOING_AWAY) + data->e_state = MXT_STATE_READY; + mutex_unlock(&data->lock); + return 0; + } static int mxt_input_open(struct input_dev *dev) @@ -4637,6 +4753,8 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0", client->adapter->nr, client->addr); + mutex_init(&data->lock); + irq_set_status_flags(client->irq, IRQ_DISABLE_UNLAZY); data->client = client; @@ -4645,6 +4763,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); + init_completion(&data->update_cfg_completion); mutex_init(&data->debug_msg_lock); data->suspend_mode = dmi_check_system(chromebook_T9_suspend_dmi) ? @@ -4743,6 +4862,18 @@ static int mxt_remove(struct i2c_client *client) { struct mxt_data *data = i2c_get_clientdata(client); + mutex_lock(&data->lock); + if (data->e_state == MXT_STATE_UPDATING_CONFIG_ASYNC || + data->e_state == MXT_STATE_UPDATING_CONFIG) { + data->e_state = MXT_STATE_GOING_AWAY; + mutex_unlock(&data->lock); + mxt_wait_for_completion(data, &data->update_cfg_completion, + MXT_CONFIG_TIMEOUT); + } else { + data->e_state = MXT_STATE_GOING_AWAY; + mutex_unlock(&data->lock); + } + disable_irq(data->irq); sysfs_remove_group(&client->dev.kobj, &mxt_fw_attr_group); if (data->reset_gpio) { @@ -4801,6 +4932,45 @@ static int __maybe_unused mxt_resume(struct device *dev) return ret; } +static int mxt_process_operation(struct mxt_data *data, + enum mxt_cmd cmd, + void *cmd_data) +{ + int ret = 0; + + mutex_lock(&data->lock); + if (data->e_state != MXT_STATE_READY) { + mutex_unlock(&data->lock); + dev_err(&data->client->dev, "Atmel touch device is shutting down\n"); + return -EBUSY; + } + data->e_state = MXT_STATE_UPDATING_CONFIG; + reinit_completion(&data->update_cfg_completion); + mutex_unlock(&data->lock); + + switch (cmd) { + case UPDATE_CFG: + case UPDATE_FW: + if (cmd == UPDATE_CFG) + ret = mxt_cfg_update(data, (char *)cmd_data); + else + ret = mxt_fw_update(data, (char *)cmd_data); + break; + + default: + break; + } + mutex_lock(&data->lock); + if (data->e_state != MXT_STATE_UPDATING_CONFIG_ASYNC) { + complete(&data->update_cfg_completion); + if (data->e_state != MXT_STATE_GOING_AWAY) + data->e_state = MXT_STATE_READY; + } + mutex_unlock(&data->lock); + + return ret; +} + static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume); static const struct of_device_id mxt_of_match[] = { From patchwork Fri Aug 16 08:39:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wang, Jiada" X-Patchwork-Id: 11097283 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2C43D14F7 for ; Fri, 16 Aug 2019 08:39:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1B5D6289CA for ; Fri, 16 Aug 2019 08:39:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0C8D5289D4; Fri, 16 Aug 2019 08:39:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AFAFB289E1 for ; Fri, 16 Aug 2019 08:39:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727116AbfHPIjT (ORCPT ); Fri, 16 Aug 2019 04:39:19 -0400 Received: from esa3.mentor.iphmx.com ([68.232.137.180]:42057 "EHLO esa3.mentor.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727519AbfHPIjT (ORCPT ); Fri, 16 Aug 2019 04:39:19 -0400 IronPort-SDR: rhV3hDnFVIIdujUjvqAJwMio7Pm8J+A+zBP5ZzHTkclgeOhVTcZBScl+O65hKDquz8pRmeZbd+ zDZkLt1P33LcTWn5qHJU9tvf9gRXGwX7DKLdOmicI8dmdrKq8R8u81Uc6OjXmQ/bLfip4hfuC3 YwZSjCasU+lpUwRoKhhO/FtzZPCZFVZI9SIi9Jnf4nPvxikOcHZXCdgy8x0NWiQCrnfhKTdjGP D52mlNNBPxpGQlR2xRD0mA5zgGLXAqm2Qaz+tNXf55Opcq9zPXgcVn5AP20jz7n70cG+oQwCe8 /RU= X-IronPort-AV: E=Sophos;i="5.64,391,1559548800"; d="scan'208";a="40507262" Received: from orw-gwy-02-in.mentorg.com ([192.94.38.167]) by esa3.mentor.iphmx.com with ESMTP; 16 Aug 2019 00:39:03 -0800 IronPort-SDR: KpBfaGbIc1jMikhxq9noTnNdCkmy+laTPt8mVUXnd6C6GRF4wdScsNBESmhWsdNZXF+K40wNLQ j62f7E2gpZ4LH+rF57AL8mKwNimNZWPyFGjCPgYCelyRaD4hNr2cDRBnE7J7tbwiX7UX1FE0Fh QQe0Ydp4qE+hif1YrDENQAi/dZKxo6zKNiMIqGmONZLUE2cu9ter4R3RQku1WWsVETxC9hWyvB cJrwUx2jdzrq3V0mc3fZogODPfImWPjJ8u+AYNGLNa4eRPIytDNRP2snNuuETW1knj23SBLkVU fbo= From: Jiada Wang To: , CC: , , , Subject: [PATCH v1 63/63] Input: atmel_mxt_ts - Fix compilation warning Date: Fri, 16 Aug 2019 17:39:02 +0900 Message-ID: <20190816083902.19659-4-jiada_wang@mentor.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190816083902.19659-1-jiada_wang@mentor.com> References: <20190816083902.19659-1-jiada_wang@mentor.com> MIME-Version: 1.0 X-ClientProxiedBy: SVR-ORW-MBX-09.mgc.mentorg.com (147.34.90.209) To svr-orw-mbx-03.mgc.mentorg.com (147.34.90.203) Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP fix "make W=1" compilation warnings from Atmel driver as per the compilation logs. Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 6e5fad91c379..063565511ae1 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -2056,7 +2056,7 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data, struct mxt_cfg *cfg) byte_offset = reg + i - cfg->start_ofs; - if (byte_offset >= 0 && byte_offset < cfg->mem_size) { + if (byte_offset < cfg->mem_size) { *(cfg->mem + byte_offset) = val; } else { dev_err(dev, "Bad object: reg:%d, T%d, ofs=%d\n",