All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiada Wang <jiada_wang@mentor.com>
To: <nick@shmanahar.org>, <dmitry.torokhov@gmail.com>,
	<jikos@kernel.org>, <benjamin.tissoires@redhat.com>,
	<bsz@semihalf.com>
Cc: <linux-input@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<erosca@de.adit-jv.com>, <Andrew_Gabbasov@mentor.com>,
	<jiada_wang@mentor.com>
Subject: [PATCH v11 30/56] Input: atmel_mxt_ts - improve bootloader state machine handling
Date: Thu, 7 May 2020 22:56:30 -0700	[thread overview]
Message-ID: <20200508055656.96389-31-jiada_wang@mentor.com> (raw)
In-Reply-To: <20200508055656.96389-1-jiada_wang@mentor.com>

From: Nick Dyer <nick.dyer@itdev.co.uk>

The code is much clearer if we switch on the actual state the bootloader
is in, rather than the state we want it to be in, and allows the removal
of a goto retry tangle.

Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
(cherry picked from ndyer/linux/for-upstream commit 463e15ee95ee6e6274017ff645839dbe34d75c99)
[gdavis: Squash fix from George G. Davis:
	 - input: atmel_mxt_ts - Fix 'mxt_send_bootloader_cmd' was not
	   declared warning]
Signed-off-by: George G. Davis <george_davis@mentor.com>
[jiada: only wait on some status change,
	cleanup code style]
Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 165 +++++++++++++----------
 1 file changed, 95 insertions(+), 70 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index e2538c2dd3f7..4d2240971387 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -306,6 +306,9 @@ struct mxt_flash {
 	size_t frame_size;
 	unsigned int count;
 	unsigned int retry;
+	u8 previous;
+	bool complete;
+	bool wait;
 };
 
 /* Each client has this additional data */
@@ -584,15 +587,27 @@ static int mxt_probe_bootloader(struct mxt_data *data, bool alt_address)
 	return 0;
 }
 
-static int mxt_check_bootloader(struct mxt_data *data, unsigned int state,
-				bool wait)
+static int mxt_send_bootloader_cmd(struct mxt_data *data, bool unlock);
+
+static int mxt_write_firmware_frame(struct mxt_data *data, struct mxt_flash *f)
+{
+	f->frame = (struct mxt_fw_frame *)(f->fw->data + f->pos);
+
+	/* Take account of CRC bytes */
+	f->frame_size = __be16_to_cpu(f->frame->size) + 2U;
+
+	/* Write one frame to device */
+	return mxt_bootloader_write(data, f->fw->data + f->pos,
+				   f->frame_size);
+}
+
+static int mxt_check_bootloader(struct mxt_data *data, struct mxt_flash *f)
 {
 	struct device *dev = &data->client->dev;
-	u8 val;
+	u8 state;
 	int ret;
 
-recheck:
-	if (wait) {
+	if (f->wait) {
 		/*
 		 * In application update mode, the interrupt
 		 * line signals state transitions. We must wait for the
@@ -608,40 +623,96 @@ static int mxt_check_bootloader(struct mxt_data *data, unsigned int state,
 			 * by writing length 0x000 to device (iff we are in
 			 * WAITING_FRAME_DATA state).
 			 */
-			dev_err(dev, "Update wait error %d\n", ret);
+			dev_warn(dev, "Update wait error %d\n", ret);
 			return ret;
 		}
 	}
 
-	ret = mxt_bootloader_read(data, &val, 1);
+	f->wait = false;
+
+	ret = mxt_bootloader_read(data, &state, 1);
 	if (ret)
 		return ret;
 
+	/* Remove don't care bits */
+	if (state & ~MXT_BOOT_STATUS_MASK)
+		state &= ~MXT_BOOT_STATUS_MASK;
+
 	switch (state) {
 	case MXT_WAITING_BOOTLOAD_CMD:
+		dev_info(dev, "Unlocking bootloader\n");
+		ret = mxt_send_bootloader_cmd(data, true);
+		if (ret)
+			return ret;
+		f->wait = true;
+
+		break;
+
 	case MXT_WAITING_FRAME_DATA:
-	case MXT_APP_CRC_FAIL:
-		val &= ~MXT_BOOT_STATUS_MASK;
+		if (f->previous != MXT_WAITING_BOOTLOAD_CMD &&
+		    f->previous != MXT_FRAME_CRC_PASS &&
+		    f->previous != MXT_FRAME_CRC_FAIL)
+			goto unexpected;
+
+		ret = mxt_write_firmware_frame(data, f);
+		if (ret)
+			return ret;
+
+		f->wait = true;
+
+		break;
+
+	case MXT_FRAME_CRC_CHECK:
+		if (f->previous != MXT_WAITING_FRAME_DATA)
+			goto unexpected;
+		f->wait = true;
 		break;
+
 	case MXT_FRAME_CRC_PASS:
-		if (val == MXT_FRAME_CRC_CHECK) {
-			goto recheck;
-		} else if (val == MXT_FRAME_CRC_FAIL) {
-			dev_err(dev, "Bootloader CRC fail\n");
-			return -EINVAL;
+		if (f->previous != MXT_FRAME_CRC_CHECK)
+			goto unexpected;
+
+		/* Next frame */
+		f->retry = 0;
+		f->pos += f->frame_size;
+		f->count++;
+		f->wait = true;
+
+		if (f->pos >= f->fw->size) {
+			f->complete = true;
+			dev_info(dev, "Sent %u frames, %zu bytes\n",
+				f->count, f->fw->size);
+		} else if (f->count % 50 == 0) {
+			dev_dbg(dev, "Sent %u frames, %lld/%zu bytes\n",
+				f->count, f->pos, f->fw->size);
+		}
+
+		break;
+
+	case MXT_FRAME_CRC_FAIL:
+		if (f->retry > 20) {
+			dev_err(dev, "Retry count exceeded\n");
+			return -EIO;
 		}
+
+		/* Back off by 20ms per retry */
+		dev_dbg(dev, "Bootloader frame CRC failure\n");
+		f->retry++;
+		f->wait = true;
+		msleep(f->retry * 20);
 		break;
+
 	default:
 		return -EINVAL;
 	}
 
-	if (val != state) {
-		dev_err(dev, "Invalid bootloader state %02X != %02X\n",
-			val, state);
-		return -EINVAL;
-	}
+	f->previous = state;
 
 	return 0;
+
+unexpected:
+	dev_err(dev, "Unexpected state transition\n");
+	return -EINVAL;
 }
 
 static int mxt_send_bootloader_cmd(struct mxt_data *data, bool unlock)
@@ -3297,57 +3368,13 @@ static int mxt_load_fw(struct device *dev)
 	if (ret)
 		goto release_firmware;
 
-	ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD, false);
-	if (ret) {
-		/* Bootloader may still be unlocked from previous attempt */
-		ret = mxt_check_bootloader(data, MXT_WAITING_FRAME_DATA, false);
-		if (ret)
-			goto disable_irq;
-	} else {
-		dev_info(dev, "Unlocking bootloader\n");
-
-		/* Unlock bootloader */
-		ret = mxt_send_bootloader_cmd(data, true);
+	while (true) {
+		ret = mxt_check_bootloader(data, &f);
 		if (ret)
-			goto disable_irq;
-	}
-
-	while (f.pos < f.fw->size) {
-		f.frame = (struct mxt_fw_frame *)(f.fw->data + f.pos);
-
-		ret = mxt_check_bootloader(data, MXT_WAITING_FRAME_DATA, true);
-		if (ret)
-			goto disable_irq;
-
-		/* Take account of CRC bytes */
-		f.frame_size = __be16_to_cpu(f.frame->size) + 2U;
-
-		/* Write one frame to device */
-		ret = mxt_bootloader_write(data, f.fw->data + f.pos,
-					   f.frame_size);
-		if (ret)
-			goto disable_irq;
-
-		ret = mxt_check_bootloader(data, MXT_FRAME_CRC_PASS, true);
-		if (ret) {
-			f.retry++;
-
-			/* Back off by 20ms per retry */
-			msleep(f.retry * 20);
-
-			if (f.retry > 20) {
-				dev_err(dev, "Retry count exceeded\n");
-				goto disable_irq;
-			}
-		} else {
-			f.retry = 0;
-			f.pos += f.frame_size;
-			f.count++;
-		}
+			return ret;
 
-		if (f.count % 50 == 0)
-			dev_dbg(dev, "Sent %u frames, %lld/%zu bytes\n",
-				f.count, f.pos, f.fw->size);
+		if (f.complete)
+			break;
 	}
 
 	/* Wait for flash. */
@@ -3356,7 +3383,6 @@ static int mxt_load_fw(struct device *dev)
 	if (ret)
 		goto disable_irq;
 
-	dev_dbg(dev, "Sent %u frames, %lld bytes\n", f.count, f.pos);
 
 	/*
 	 * Wait for device to reset. Some bootloader versions do not assert
@@ -3366,7 +3392,6 @@ static int mxt_load_fw(struct device *dev)
 	mxt_wait_for_completion(data, &data->bl_completion, MXT_FW_RESET_TIME);
 
 	data->in_bootloader = false;
-
 disable_irq:
 	disable_irq(data->irq);
 release_firmware:
-- 
2.17.1


  parent reply	other threads:[~2020-05-08  5:59 UTC|newest]

Thread overview: 81+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-08  5:56 [PATCH v11 00/56] atmel_mxt_ts misc Jiada Wang
2020-05-08  5:56 ` [PATCH v11 01/56] Input: introduce input_mt_report_slot_inactive Jiada Wang
2020-05-08  5:56 ` [PATCH v11 02/56] Input: atmel_mxt_ts - rework sysfs init/remove Jiada Wang
2020-05-08  5:56 ` [PATCH v11 03/56] Input: atmel_mxt_ts - only read messages in mxt_acquire_irq() when necessary Jiada Wang
2020-05-08  5:56 ` [PATCH v11 04/56] Input: atmel_mxt_ts - split large i2c transfers into blocks Jiada Wang
2020-05-11 22:19   ` Dmitry Torokhov
2020-06-30 14:33     ` Wang, Jiada
2020-05-08  5:56 ` [PATCH v11 05/56] Input: atmel_mxt_ts - output status from T48 Noise Supression Jiada Wang
2020-05-11 22:23   ` Dmitry Torokhov
2020-06-30 14:34     ` Wang, Jiada
2020-05-08  5:56 ` [PATCH v11 06/56] Input: atmel_mxt_ts - output status from T42 Touch Suppression Jiada Wang
2020-05-08  5:56 ` [PATCH v11 07/56] Input: atmel_mxt_ts - implement T9 vector/orientation support Jiada Wang
2020-05-11 22:53   ` Dmitry Torokhov
2020-06-30 14:35     ` Wang, Jiada
2020-05-08  5:56 ` [PATCH v11 08/56] Input: atmel_mxt_ts - implement T15 Key Array support Jiada Wang
2020-05-12  2:35   ` Dmitry Torokhov
2020-05-08  5:56 ` [PATCH v11 09/56] Input: atmel_mxt_ts - handle reports from T47 Stylus object Jiada Wang
2020-05-08  5:56 ` [PATCH v11 10/56] Input: atmel_mxt_ts - implement support for T107 active stylus Jiada Wang
2020-05-08  5:56 ` [PATCH v11 11/56] Input: atmel_mxt_ts - add debug for T92 gesture and T93 touch seq msgs Jiada Wang
2020-05-08  5:56 ` [PATCH v11 12/56] Input: atmel_mxt_ts - release touch state during suspend Jiada Wang
2020-05-08  5:56 ` [PATCH v11 13/56] dt-bindings: input: atmel: add suspend mode support Jiada Wang
2020-05-08  5:56 ` [PATCH v11 14/56] Input: atmel_mxt_ts - add regulator control support Jiada Wang
2020-05-08  5:56 ` [PATCH v11 15/56] Input: atmel_mxt_ts - report failures in suspend/resume Jiada Wang
2020-05-08  5:56 ` [PATCH v11 16/56] Input: atmel_mxt_ts - allow specification of firmware file name Jiada Wang
2020-05-08  5:56 ` [PATCH v11 17/56] Input: atmel_mxt_ts: Rename mxt_fw_version_show to fw_version_show Jiada Wang
2020-05-08  5:56 ` [PATCH v11 18/56] Input: atmel_mxt_ts: Rename mxt_hw_version_show to hw_version_show Jiada Wang
2020-05-08  5:56 ` [PATCH v11 19/56] Input: atmel_mxt_ts: rename mxt_update_fw_store to update_fw_store Jiada Wang
2020-05-08  5:56 ` [PATCH v11 20/56] Input: atmel_mxt_ts - handle cfg filename via pdata/sysfs Jiada Wang
2020-05-08  5:56 ` [PATCH v11 21/56] Input: atmel_mxt_ts - check data->input_dev is not null in mxt_input_sync() Jiada Wang
2020-05-08  5:56 ` [PATCH v11 22/56] dt-bindings: input: atmel: provide name of configuration file Jiada Wang
2020-05-08  5:56 ` [PATCH v11 23/56] Input: atmel_mxt_ts - allow input name to be specified in platform data Jiada Wang
2020-05-08  5:56 ` [PATCH v11 24/56] dt-bindings: input: atmel: support to specify input name Jiada Wang
2020-05-08  5:56 ` [PATCH v11 25/56] Input: atmel_mxt_ts - add config checksum attribute to sysfs Jiada Wang
2020-05-08  5:56 ` [PATCH v11 26/56] Input: atmel_mxt_ts - rename mxt_object_show to object_show Jiada Wang
2020-05-08  5:56 ` [PATCH v11 27/56] Input: atmel_mxt_ts - refactor firmware flash to extract context into struct Jiada Wang
2020-05-08  5:56 ` [PATCH v11 28/56] Input: atmel_mxt_ts - refactor code to enter bootloader into separate func Jiada Wang
2020-05-08  5:56 ` [PATCH v11 29/56] Input: atmel_mxt_ts - combine bootloader version query with probe Jiada Wang
2020-05-08  5:56 ` Jiada Wang [this message]
2020-05-08  5:56 ` [PATCH v11 31/56] Input: atmel_mxt_ts - rename bl_completion to chg_completion Jiada Wang
2020-05-08  5:56 ` [PATCH v11 32/56] Input: atmel_mxt_ts - make bootloader interrupt driven Jiada Wang
2020-05-08  5:56 ` [PATCH v11 33/56] Input: atmel_mxt_ts - delay enabling IRQ when not using regulators Jiada Wang
2020-05-11  1:05   ` Dmitry Osipenko
2020-05-11  2:05     ` Wang, Jiada
2020-05-11 23:13       ` Dmitry Osipenko
2020-05-13  5:07         ` Wang, Jiada
2020-05-14  4:53           ` Dmitry Osipenko
2020-05-17  3:32             ` Wang, Jiada
2020-05-17 13:08               ` Dmitry Osipenko
2020-05-17 13:26                 ` Dmitry Osipenko
2020-05-25 14:51                   ` Wang, Jiada
2020-05-26 17:36                     ` Dmitry Osipenko
2020-05-08  5:56 ` [PATCH v11 34/56] Input: atmel_mxt_ts - implement I2C retries Jiada Wang
2020-05-08  5:56 ` [PATCH v11 35/56] Input: atmel_mxt_ts - orientation is not present in hover Jiada Wang
2020-05-08  5:56 ` [PATCH v11 36/56] Input: atmel_mxt_ts - implement debug output for messages Jiada Wang
2020-05-08  5:56 ` [PATCH v11 37/56] Input: atmel_mxt_ts - implement improved debug message interface Jiada Wang
2020-05-08  5:56 ` [PATCH v11 38/56] Input: atmel_mxt_ts - eliminate data->raw_info_block Jiada Wang
2020-05-08  5:56 ` [PATCH v11 39/56] Input: atmel_mxt_ts - Change call-points of mxt_free_* functions Jiada Wang
2020-05-08  5:56 ` [PATCH v11 40/56] Input: atmel_mxt_ts - rely on calculated_crc rather than file config_crc Jiada Wang
2020-05-08  5:56 ` [PATCH v11 41/56] input: atmel_mxt_ts: export GPIO reset line via sysfs Jiada Wang
2020-05-08  5:56 ` [PATCH v11 42/56] input: atmel_mxt_ts: Add Missing Delay for reset handling of Atmel touch panel controller in detachable displays Jiada Wang
2020-05-08  5:56 ` [PATCH v11 43/56] Input: atmel_mxt_ts: Add support for run self-test routine Jiada Wang
2020-05-08  5:56 ` [PATCH v11 44/56] Input: atmel_mxt_ts: Limit the max bytes transferred in an i2c transaction Jiada Wang
2020-05-08  5:56 ` [PATCH v11 45/56] Input: atmel_mxt_ts: return error from mxt_process_messages_until_invalid() Jiada Wang
2020-05-08  5:56 ` [PATCH v11 46/56] Input: Atmel: improve error handling in mxt_start() Jiada Wang
2020-05-08  5:56 ` [PATCH v11 47/56] Input: Atmel: improve error handling in mxt_initialize() Jiada Wang
2020-05-08  5:56 ` [PATCH v11 48/56] Input: Atmel: improve error handling in mxt_update_cfg() Jiada Wang
2020-05-08  5:56 ` [PATCH v11 49/56] Input: Atmel: Improve error handling in mxt_initialize_input_device() Jiada Wang
2020-05-08  5:56 ` [PATCH v11 50/56] Input: Atmel: handle ReportID "0x00" while processing T5 messages Jiada Wang
2020-05-08  5:56 ` [PATCH v11 51/56] Input: Atmel: use T44 object to process " Jiada Wang
2020-05-08  5:56 ` [PATCH v11 52/56] Input: atmel_mxt_ts: use gpiod_set_value_cansleep for reset pin Jiada Wang
2020-05-08  5:56 ` [PATCH v11 53/56] input: touchscreen: atmel_mxt_ts: Added sysfs entry for touchscreen status Jiada Wang
2020-05-08  5:56 ` [PATCH v11 54/56] input: atmel_mxt_ts: added sysfs interface to update atmel T38 data Jiada Wang
2020-05-10 12:03   ` kbuild test robot
2020-05-10 12:03     ` kbuild test robot
2020-05-08  5:56 ` [PATCH v11 55/56] input: atmel_mxt_ts: don't disable IRQ before remove of mxt_fw_attr_group Jiada Wang
2020-05-08  5:56 ` [PATCH v11 56/56] Input: atmel_mxt_ts - Fix compilation warning Jiada Wang
2020-05-24 21:28 ` [PATCH v11 00/56] atmel_mxt_ts misc Pavel Machek
2020-05-27  6:43 ` Dmitry Torokhov
2020-06-25 13:50   ` Wang, Jiada
2020-07-08 13:05     ` Wang, Jiada
2020-07-17  7:21       ` Wang, Jiada

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200508055656.96389-31-jiada_wang@mentor.com \
    --to=jiada_wang@mentor.com \
    --cc=Andrew_Gabbasov@mentor.com \
    --cc=benjamin.tissoires@redhat.com \
    --cc=bsz@semihalf.com \
    --cc=dmitry.torokhov@gmail.com \
    --cc=erosca@de.adit-jv.com \
    --cc=jikos@kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nick@shmanahar.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.