Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1351767
| From | Boris Brezillon <boris.brezillon@free-electrons.com> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | [PATCH 16/16] mtd: nand: sunxi: poll for events instead of using interrupts |
| Date | 2016-03-07 17:30 +0100 |
| Message-ID | <ra6cH-5dM-27@gated-at.bofh.it> (permalink) |
| References | <ra630-57L-7@gated-at.bofh.it> <ra6cH-5dM-21@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
Some NAND operations are so fast that it doesn't make any sense to use
interrupt based waits (the scheduling overhead is not worth it).
Rename sunxi_nfc_wait_int() into sunxi_nfc_wait_events() and add a
parameter to specify whether polling should be used or not.
Note that all sunxi_nfc_wait_int() are moved to the polling approach now,
but this should change as soon as we have more information about the
approximate time we are about to wait (can be extracted from the NAND
timings, and the type of operation).
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/mtd/nand/sunxi_nand.c | 45 +++++++++++++++++++++++++++++--------------
1 file changed, 31 insertions(+), 14 deletions(-)
diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
index 002194b..0616f3b 100644
--- a/drivers/mtd/nand/sunxi_nand.c
+++ b/drivers/mtd/nand/sunxi_nand.c
@@ -302,23 +302,40 @@ static irqreturn_t sunxi_nfc_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int sunxi_nfc_wait_int(struct sunxi_nfc *nfc, u32 flags,
- unsigned int timeout_ms)
+static int sunxi_nfc_wait_events(struct sunxi_nfc *nfc, u32 events,
+ bool use_polling, unsigned int timeout_ms)
{
- init_completion(&nfc->complete);
+ int ret;
- writel(flags, nfc->regs + NFC_REG_INT);
+ if (events & ~NFC_INT_MASK)
+ return -EINVAL;
if (!timeout_ms)
timeout_ms = NFC_DEFAULT_TIMEOUT_MS;
- if (!wait_for_completion_timeout(&nfc->complete,
- msecs_to_jiffies(timeout_ms))) {
- dev_err(nfc->dev, "wait interrupt timedout\n");
- return -ETIMEDOUT;
+ if (!use_polling) {
+ init_completion(&nfc->complete);
+
+ writel(events, nfc->regs + NFC_REG_INT);
+
+ ret = wait_for_completion_timeout(&nfc->complete,
+ msecs_to_jiffies(timeout_ms));
+
+ writel(0, nfc->regs + NFC_REG_INT);
+ } else {
+ u32 status;
+
+ ret = readl_poll_timeout(nfc->regs + NFC_REG_ST, status,
+ (status & events) == events, 1,
+ timeout_ms * 1000);
}
- return 0;
+ writel(events & NFC_INT_MASK, nfc->regs + NFC_REG_ST);
+
+ if (ret)
+ dev_err(nfc->dev, "wait interrupt timedout\n");
+
+ return ret;
}
static int sunxi_nfc_wait_cmd_fifo_empty(struct sunxi_nfc *nfc)
@@ -449,7 +466,7 @@ static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD;
writel(tmp, nfc->regs + NFC_REG_CMD);
- ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
+ ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0);
if (ret)
break;
@@ -484,7 +501,7 @@ static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
NFC_ACCESS_DIR;
writel(tmp, nfc->regs + NFC_REG_CMD);
- ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
+ ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0);
if (ret)
break;
@@ -546,7 +563,7 @@ static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
sunxi_nand->addr[0] = 0;
sunxi_nand->addr[1] = 0;
sunxi_nand->addr_cycles = 0;
- sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
+ sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0);
}
if (ctrl & NAND_CLE) {
@@ -789,7 +806,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP,
nfc->regs + NFC_REG_CMD);
- ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
+ ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0);
sunxi_nfc_randomizer_disable(mtd);
if (ret)
return ret;
@@ -927,7 +944,7 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd,
NFC_ACCESS_DIR | NFC_ECC_OP,
nfc->regs + NFC_REG_CMD);
- ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
+ ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0);
sunxi_nfc_randomizer_disable(mtd);
if (ret)
return ret;
--
2.1.4
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
[PATCH 00/16] mtd: nand: sunxi: various improvements/fixes Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-03-07 17:20 +0100
[PATCH 03/16] mtd: nand: sunxi: fix EDO mode selection Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-03-07 17:20 +0100
[PATCH 12/16] mtd: nand: sunxi: disable clks on device removal Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-03-07 17:30 +0100
[PATCH 14/16] mtd: nand: sunxi: fix ->dev_ready() implementation Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-03-07 17:30 +0100
[PATCH 09/16] mtd: nand: sunxi: let the NAND controller control the CE line Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-03-07 17:30 +0100
[PATCH 16/16] mtd: nand: sunxi: poll for events instead of using interrupts Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-03-07 17:30 +0100
[PATCH 07/16] mtd: nand: sunxi: implement ->read_subpage() Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-03-07 17:30 +0100
[PATCH 10/16] mtd: nand: sunxi: fix the NFC_ECC_ERR_CNT() macro Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-03-07 17:30 +0100
[PATCH 13/16] mtd: nand: enable ECC pipelining Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-03-07 17:30 +0100
[PATCH 11/16] mtd: nand: sunxi: fix NFC_CTL setting Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-03-07 17:30 +0100
[PATCH 15/16] mtd: nand: sunxi: make use of readl_poll_timeout() Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-03-07 17:30 +0100
[PATCH 05/16] mtd: nand: export default read/write oob functions Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-03-07 17:30 +0100
[PATCH 08/16] mtd: nand: sunxi: improve ->cmd_ctrl() function Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-03-07 17:30 +0100
csiph-web