linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jerome Pouiller <Jerome.Pouiller@silabs.com>
To: devel@driverdev.osuosl.org, linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Kalle Valo" <kvalo@codeaurora.org>,
	"David S . Miller" <davem@davemloft.net>,
	"Jérôme Pouiller" <jerome.pouiller@silabs.com>
Subject: [PATCH 12/12] staging: wfx: add workaround for 'timeout while wake up chip'
Date: Thu, 20 Aug 2020 17:58:58 +0200	[thread overview]
Message-ID: <20200820155858.351292-12-Jerome.Pouiller@silabs.com> (raw)
In-Reply-To: <20200820155858.351292-1-Jerome.Pouiller@silabs.com>

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

The host and the device can be connected with a called Wake-Up GPIO.
When the host fall down this GPIO, it allows the device to enter in deep
sleep and no communication with the device is no more possible (the
device wakes up automatically on DTIM and fetch data if necessary).

So, before to communicate with the device, the driver have to raise the
Wake-up GPIO and then wait for an IRQ from the device.

Unfortunately, old firmwares have a race in sleep/wake-up process and
the device may never wake up. In this case, the IRQ is not sent and
driver complains with "timeout while wake up chip". Then, the driver
tries anyway to access the bus and an other error is raised by the bus.

Fortunately, when the bug occurs, it is possible to fall down the IRQ
and the device will eventually finish the sleep process. Then the driver
can wake it up normally.

The patch implements that workaround and add a retry limit in case
something goes very wrong.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/bh.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/wfx/bh.c b/drivers/staging/wfx/bh.c
index 07304a80c29b..f07bcee50e3f 100644
--- a/drivers/staging/wfx/bh.c
+++ b/drivers/staging/wfx/bh.c
@@ -18,25 +18,40 @@
 
 static void device_wakeup(struct wfx_dev *wdev)
 {
+	int max_retry = 3;
+
 	if (!wdev->pdata.gpio_wakeup)
 		return;
 	if (gpiod_get_value_cansleep(wdev->pdata.gpio_wakeup))
 		return;
 
-	gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 1);
 	if (wfx_api_older_than(wdev, 1, 4)) {
+		gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 1);
 		if (!completion_done(&wdev->hif.ctrl_ready))
 			usleep_range(2000, 2500);
-	} else {
+		return;
+	}
+	for (;;) {
+		gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 1);
 		// completion.h does not provide any function to wait
 		// completion without consume it (a kind of
 		// wait_for_completion_done_timeout()). So we have to emulate
 		// it.
 		if (wait_for_completion_timeout(&wdev->hif.ctrl_ready,
-						msecs_to_jiffies(2)))
+						msecs_to_jiffies(2))) {
 			complete(&wdev->hif.ctrl_ready);
-		else
+			return;
+		} else if (max_retry-- > 0) {
+			// Older firmwares have a race in sleep/wake-up process.
+			// Redo the process is sufficient to unfreeze the
+			// chip.
 			dev_err(wdev->dev, "timeout while wake up chip\n");
+			gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 0);
+			usleep_range(2000, 2500);
+		} else {
+			dev_err(wdev->dev, "max wake-up retries reached\n");
+			return;
+		}
 	}
 }
 
-- 
2.28.0


  parent reply	other threads:[~2020-08-20 16:01 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-20 15:58 [PATCH 01/12] staging: wfx: fix BA when device is AP and MFP is enabled Jerome Pouiller
2020-08-20 15:58 ` [PATCH 02/12] staging: wfx: improve usage of hif_map_link() Jerome Pouiller
2020-08-20 15:58 ` [PATCH 03/12] staging: wfx: fix BA when MFP is disabled but BSS is MFP capable Jerome Pouiller
2020-08-20 15:58 ` [PATCH 04/12] staging: wfx: fix spaces around binary operators Jerome Pouiller
2020-08-20 15:58 ` [PATCH 05/12] staging: wfx: fix support for cipher AES_CMAC (multicast PMF) Jerome Pouiller
2020-08-20 15:58 ` [PATCH 06/12] staging: wfx: drop useless field from struct wfx_tx_priv Jerome Pouiller
2020-08-20 15:58 ` [PATCH 07/12] staging: wfx: fix frame reordering Jerome Pouiller
2020-08-20 15:58 ` [PATCH 08/12] staging: wfx: fix potential use before init Jerome Pouiller
2020-08-20 15:58 ` [PATCH 09/12] staging: wfx: scan while AP is supported Jerome Pouiller
2020-08-20 15:58 ` [PATCH 10/12] staging: wfx: enable powersave on probe Jerome Pouiller
2020-08-20 15:58 ` [PATCH 11/12] staging: wfx: remove useless extra jiffy Jerome Pouiller
2020-08-20 15:58 ` Jerome Pouiller [this message]
2020-08-24  9:50 ` [PATCH 01/12] staging: wfx: fix BA when device is AP and MFP is enabled Dan Carpenter
2020-08-24 12:03   ` Jérôme Pouiller

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=20200820155858.351292-12-Jerome.Pouiller@silabs.com \
    --to=jerome.pouiller@silabs.com \
    --cc=davem@davemloft.net \
    --cc=devel@driverdev.osuosl.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=kvalo@codeaurora.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=netdev@vger.kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).