From: Daniel Mack <daniel@zonque.org>
To: sameo@linux.intel.com
Cc: linux-wireless@vger.kernel.org, colin.king@canonical.com,
shikha.singh@st.com, Daniel Mack <daniel@zonque.org>
Subject: [PATCH v2 05/10] NFC: st95hf: remove exchange_lock
Date: Tue, 24 Jul 2018 10:54:21 +0200 [thread overview]
Message-ID: <20180724085426.23999-6-daniel@zonque.org> (raw)
In-Reply-To: <20180724085426.23999-1-daniel@zonque.org>
This patch removes the exchange_lock sempahore. Its intended function
was two-fold:
a) Lock the remove() callback of the driver against the ISR, so that
the resources only go away after the ISR has finished. This is
unnecessary though, because `rm_lock' does that already, in
combination with the nullification of `scontext->ddev'.
b) Indicate whether a command was sent previously. If the semaphore
is found unused in the threaded ISR, an error is reported.
This case can be handled much nicer by checking whether `skb_resp'
is present in the context. For this, nullify the `skb_resp' pointer
in the callback context after it was sent back to the NFC core.
Signed-off-by: Daniel Mack <daniel@zonque.org>
---
drivers/nfc/st95hf/core.c | 52 +++++++--------------------------------
1 file changed, 9 insertions(+), 43 deletions(-)
diff --git a/drivers/nfc/st95hf/core.c b/drivers/nfc/st95hf/core.c
index d857197ec7b2..6761ab90f68d 100644
--- a/drivers/nfc/st95hf/core.c
+++ b/drivers/nfc/st95hf/core.c
@@ -214,8 +214,6 @@ struct st95_digital_cmd_complete_arg {
* @st95hf_supply: regulator "consumer" for NFC device.
* @sendrcv_trflag: last byte of frame send by sendrecv command
* of st95hf. This byte contains transmission flag info.
- * @exchange_lock: semaphore used for signaling the st95hf_remove
- * function that the last outstanding async nfc request is finished.
* @rm_lock: mutex for ensuring safe access of nfc digital object
* from threaded ISR. Usage of this mutex avoids any race between
* deletion of the object from st95hf_remove() and its access from
@@ -233,7 +231,6 @@ struct st95hf_context {
struct st95_digital_cmd_complete_arg complete_cb_arg;
struct regulator *st95hf_supply;
unsigned char sendrcv_trflag;
- struct semaphore exchange_lock;
struct mutex rm_lock;
u8 current_protocol;
u8 current_rf_tech;
@@ -785,29 +782,14 @@ static irqreturn_t st95hf_irq_thread_handler(int irq, void *st95hfcontext)
struct st95_digital_cmd_complete_arg *cb_arg;
spidevice = &stcontext->spicontext.spidev->dev;
+ cb_arg = &stcontext->complete_cb_arg;
+ skb_resp = cb_arg->skb_resp;
- /*
- * check semaphore, if not down() already, then we don't
- * know in which context the ISR is called and surely it
- * will be a bug. Note that down() of the semaphore is done
- * in the corresponding st95hf_in_send_cmd() and then
- * only this ISR should be called. ISR will up() the
- * semaphore before leaving. Hence when the ISR is called
- * the correct behaviour is down_trylock() should always
- * return 1 (indicating semaphore cant be taken and hence no
- * change in semaphore count).
- * If not, then we up() the semaphore and crash on
- * a BUG() !
- */
- if (!down_trylock(&stcontext->exchange_lock)) {
- up(&stcontext->exchange_lock);
+ if (unlikely(!skb_resp)) {
WARN(1, "unknown context in ST95HF ISR");
return IRQ_NONE;
}
- cb_arg = &stcontext->complete_cb_arg;
- skb_resp = cb_arg->skb_resp;
-
mutex_lock(&stcontext->rm_lock);
res_len = st95hf_spi_recv_response(&stcontext->spicontext,
skb_resp->data);
@@ -856,8 +838,13 @@ static irqreturn_t st95hf_irq_thread_handler(int irq, void *st95hfcontext)
/* call digital layer callback */
cb_arg->complete_cb(stcontext->ddev, cb_arg->cb_usrarg, skb_resp);
+ /*
+ * This skb is now owned by the core layer.
+ * Make sure not to use it again.
+ */
+ cb_arg->skb_resp = NULL;
+
/* up the semaphore before returning */
- up(&stcontext->exchange_lock);
mutex_unlock(&stcontext->rm_lock);
return IRQ_HANDLED;
@@ -868,8 +855,6 @@ static irqreturn_t st95hf_irq_thread_handler(int irq, void *st95hfcontext)
skb_resp = ERR_PTR(result);
/* call of callback with error */
cb_arg->complete_cb(stcontext->ddev, cb_arg->cb_usrarg, skb_resp);
- /* up the semaphore before returning */
- up(&stcontext->exchange_lock);
mutex_unlock(&stcontext->rm_lock);
return IRQ_HANDLED;
}
@@ -965,25 +950,12 @@ static int st95hf_in_send_cmd(struct nfc_digital_dev *ddev,
ddev->curr_protocol == NFC_PROTO_ISO14443)
stcontext->complete_cb_arg.rats = true;
- /*
- * down the semaphore to indicate to remove func that an
- * ISR is pending, note that it will not block here in any case.
- * If found blocked, it is a BUG!
- */
- rc = down_killable(&stcontext->exchange_lock);
- if (rc) {
- WARN(1, "Semaphore is not found up in st95hf_in_send_cmd\n");
- return rc;
- }
-
rc = st95hf_spi_send(&stcontext->spicontext, skb->data,
skb->len,
ASYNC);
if (rc) {
dev_err(&stcontext->nfcdev->dev,
"Error %d trying to perform data_exchange", rc);
- /* up the semaphore since ISR will never come in this case */
- up(&stcontext->exchange_lock);
goto free_skb_resp;
}
@@ -1104,7 +1076,6 @@ static int st95hf_probe(struct spi_device *nfc_spi_dev)
}
}
- sema_init(&st95context->exchange_lock, 1);
init_completion(&spicontext->done);
mutex_init(&spicontext->spi_lock);
mutex_init(&st95context->rm_lock);
@@ -1220,11 +1191,6 @@ static int st95hf_remove(struct spi_device *nfc_spi_dev)
mutex_unlock(&stcontext->rm_lock);
- /* if last in_send_cmd's ISR is pending, wait for it to finish */
- result = down_killable(&stcontext->exchange_lock);
- if (result == -EINTR)
- dev_err(&spictx->spidev->dev, "sleep for semaphore interrupted by signal\n");
-
/* next reset the ST95HF controller */
result = st95hf_spi_send(&stcontext->spicontext,
&reset_cmd,
--
2.17.1
next prev parent reply other threads:[~2018-07-24 10:00 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-07-24 8:54 [PATCH v2 00/10] NFC: A bunch of cleanups for st95hf Daniel Mack
2018-07-24 8:54 ` [PATCH v2 01/10] Revert "NFC: st95hf: drop illegal kfree_skb()" Daniel Mack
2018-07-24 8:54 ` [PATCH v2 02/10] NFC: st95hf: drop nfcdev_free Daniel Mack
2018-07-24 8:54 ` [PATCH v2 03/10] NFC: st95hf: drop illegal kfree_skb() in IRQ handler Daniel Mack
2018-07-24 8:54 ` [PATCH v2 04/10] NFC: st95hf: remove logging from spi functions Daniel Mack
2018-07-24 8:54 ` Daniel Mack [this message]
2018-07-24 8:54 ` [PATCH v2 06/10] NFC: st95hf: move skb allocation to ISR Daniel Mack
2018-07-24 8:54 ` [PATCH v2 07/10] NFC: st95hf: re-order command defines Daniel Mack
2018-07-24 8:54 ` [PATCH v2 08/10] NFC: st95hf: unify sync/async flags Daniel Mack
2018-07-24 8:54 ` [PATCH v2 09/10] NFC: st95hf: two small style nits Daniel Mack
2018-07-24 8:54 ` [PATCH v2 10/10] NFC: st95hf: add of match table Daniel Mack
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=20180724085426.23999-6-daniel@zonque.org \
--to=daniel@zonque.org \
--cc=colin.king@canonical.com \
--cc=linux-wireless@vger.kernel.org \
--cc=sameo@linux.intel.com \
--cc=shikha.singh@st.com \
/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).