From: Russell King <rmk+kernel@arm.linux.org.uk>
To: Chris Ball <chris@printf.net>, linux-mmc@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org,
Ulf Hansson <ulf.hansson@linaro.org>
Subject: [PATCH 07/38] mmc: sdhci: more efficient interrupt enable register handling
Date: Wed, 23 Apr 2014 20:06:45 +0100 [thread overview]
Message-ID: <E1Wd2VJ-0003ui-VE@rmk-PC.arm.linux.org.uk> (raw)
In-Reply-To: <20140423185534.GA26756@n2100.arm.linux.org.uk>
Rather than wasting cycles read-modify-writing the interrupt enable
registers, cache the value locally instead.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/mmc/host/sdhci.c | 98 +++++++++++++++++++++++------------------------
include/linux/mmc/sdhci.h | 3 ++
2 files changed, 50 insertions(+), 51 deletions(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 3af58f3cc165..d568c8e4ee33 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -131,27 +131,6 @@ static void sdhci_dumpregs(struct sdhci_host *host)
* *
\*****************************************************************************/
-static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
-{
- u32 ier;
-
- ier = sdhci_readl(host, SDHCI_INT_ENABLE);
- ier &= ~clear;
- ier |= set;
- sdhci_writel(host, ier, SDHCI_INT_ENABLE);
- sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
-}
-
-static void sdhci_unmask_irqs(struct sdhci_host *host, u32 irqs)
-{
- sdhci_clear_set_irqs(host, 0, irqs);
-}
-
-static void sdhci_mask_irqs(struct sdhci_host *host, u32 irqs)
-{
- sdhci_clear_set_irqs(host, irqs, 0);
-}
-
static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
{
u32 present, irqs;
@@ -165,9 +144,12 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
irqs = present ? SDHCI_INT_CARD_REMOVE : SDHCI_INT_CARD_INSERT;
if (enable)
- sdhci_unmask_irqs(host, irqs);
+ host->ier |= irqs;
else
- sdhci_mask_irqs(host, irqs);
+ host->ier &= ~irqs;
+
+ sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
+ sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
}
static void sdhci_enable_card_detection(struct sdhci_host *host)
@@ -183,17 +165,12 @@ static void sdhci_disable_card_detection(struct sdhci_host *host)
static void sdhci_reset(struct sdhci_host *host, u8 mask)
{
unsigned long timeout;
- u32 uninitialized_var(ier);
-
if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
SDHCI_CARD_PRESENT))
return;
}
- if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
- ier = sdhci_readl(host, SDHCI_INT_ENABLE);
-
if (host->ops->platform_reset_enter)
host->ops->platform_reset_enter(host, mask);
@@ -224,8 +201,10 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
if (host->ops->platform_reset_exit)
host->ops->platform_reset_exit(host, mask);
- if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
- sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
+ if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) {
+ sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
+ sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
+ }
if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
if ((host->ops->enable_dma) && (mask & SDHCI_RESET_ALL))
@@ -242,11 +221,14 @@ static void sdhci_init(struct sdhci_host *host, int soft)
else
sdhci_reset(host, SDHCI_RESET_ALL);
- sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK,
- SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
- SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
- SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
- SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
+ host->ier = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
+ SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT |
+ SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC |
+ SDHCI_INT_TIMEOUT | SDHCI_INT_DATA_END |
+ SDHCI_INT_RESPONSE;
+
+ sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
+ sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
if (soft) {
/* force clock reconfiguration */
@@ -721,9 +703,12 @@ static void sdhci_set_transfer_irqs(struct sdhci_host *host)
u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR;
if (host->flags & SDHCI_REQ_USE_DMA)
- sdhci_clear_set_irqs(host, pio_irqs, dma_irqs);
+ host->ier = (host->ier & ~pio_irqs) | dma_irqs;
else
- sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
+ host->ier = (host->ier & ~dma_irqs) | pio_irqs;
+
+ sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
+ sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
}
static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
@@ -1711,9 +1696,12 @@ static void sdhci_enable_sdio_irq_nolock(struct sdhci_host *host, int enable)
{
if (!(host->flags & SDHCI_DEVICE_DEAD)) {
if (enable)
- sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
+ host->ier |= SDHCI_INT_CARD_INT;
else
- sdhci_mask_irqs(host, SDHCI_INT_CARD_INT);
+ host->ier &= ~SDHCI_INT_CARD_INT;
+
+ sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
+ sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
mmiowb();
}
}
@@ -1855,7 +1843,6 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
{
struct sdhci_host *host;
u16 ctrl;
- u32 ier;
int tuning_loop_counter = MAX_TUNING_LOOP;
unsigned long timeout;
int err = 0;
@@ -1909,8 +1896,8 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
* to make sure we don't hit a controller bug, we _only_
* enable Buffer Read Ready interrupt here.
*/
- ier = sdhci_readl(host, SDHCI_INT_ENABLE);
- sdhci_clear_set_irqs(host, ier, SDHCI_INT_DATA_AVAIL);
+ sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE);
+ sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE);
/*
* Issue CMD19 repeatedly till Execute Tuning is set to 0 or the number
@@ -2042,7 +2029,8 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
if (err && (host->flags & SDHCI_USING_RETUNING_TIMER))
err = 0;
- sdhci_clear_set_irqs(host, SDHCI_INT_DATA_AVAIL, ier);
+ sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
+ sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
spin_unlock_irqrestore(&host->lock, flags);
sdhci_runtime_pm_put(host);
@@ -2455,10 +2443,12 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
* More testing are needed here to ensure it works
* for other platforms though.
*/
- sdhci_mask_irqs(host, present ? SDHCI_INT_CARD_INSERT :
- SDHCI_INT_CARD_REMOVE);
- sdhci_unmask_irqs(host, present ? SDHCI_INT_CARD_REMOVE :
- SDHCI_INT_CARD_INSERT);
+ host->ier &= ~(SDHCI_INT_CARD_INSERT |
+ SDHCI_INT_CARD_REMOVE);
+ host->ier |= present ? SDHCI_INT_CARD_REMOVE :
+ SDHCI_INT_CARD_INSERT;
+ sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
+ sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
@@ -2587,7 +2577,9 @@ int sdhci_suspend_host(struct sdhci_host *host)
}
if (!device_may_wakeup(mmc_dev(host->mmc))) {
- sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
+ host->ier = 0;
+ sdhci_writel(host, 0, SDHCI_INT_ENABLE);
+ sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
free_irq(host->irq, host);
} else {
sdhci_enable_irq_wakeups(host);
@@ -2686,7 +2678,9 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
}
spin_lock_irqsave(&host->lock, flags);
- sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK & ~SDHCI_INT_CARD_INT);
+ host->ier &= SDHCI_INT_CARD_INT;
+ sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
+ sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
spin_unlock_irqrestore(&host->lock, flags);
synchronize_hardirq(host->irq);
@@ -3277,7 +3271,8 @@ int sdhci_add_host(struct sdhci_host *host)
#ifdef SDHCI_USE_LEDS_CLASS
reset:
sdhci_reset(host, SDHCI_RESET_ALL);
- sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
+ sdhci_writel(host, 0, SDHCI_INT_ENABLE);
+ sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
free_irq(host->irq, host);
#endif
untasklet:
@@ -3319,7 +3314,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
if (!dead)
sdhci_reset(host, SDHCI_RESET_ALL);
- sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
+ sdhci_writel(host, 0, SDHCI_INT_ENABLE);
+ sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
free_irq(host->irq, host);
del_timer_sync(&host->timer);
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index f1c8e14e8751..9361d8ef509d 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -178,6 +178,9 @@ struct sdhci_host {
u32 thread_isr;
+ /* cached registers */
+ u32 ier;
+
wait_queue_head_t buf_ready_int; /* Waitqueue for Buffer Read Ready interrupt */
unsigned int tuning_done; /* Condition flag set when CMD19 succeeds */
--
1.8.3.1
next prev parent reply other threads:[~2014-04-23 19:06 UTC|newest]
Thread overview: 94+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-04-23 18:55 [PATCH 00/38] MMC updates, plus CuBox-i WiFi support Russell King - ARM Linux
2014-04-23 19:06 ` [PATCH 01/38] mmc: sdio_irq: rework sdio irq handling Russell King
2014-04-24 7:58 ` Ulf Hansson
2014-04-24 8:46 ` Russell King - ARM Linux
2014-04-24 8:58 ` Ulf Hansson
2014-04-23 19:06 ` [PATCH 02/38] mmc: sdhci: clean up interrupt handling Russell King
2014-04-23 19:06 ` [PATCH 03/38] mmc: sdhci: clean up sdio interrupt enable handling Russell King
2014-04-23 19:06 ` [PATCH 04/38] mmc: sdhci: convert to new SDIO IRQ handling Russell King
2014-04-23 19:06 ` [PATCH 05/38] mmc: sdhci: push card_tasklet into threaded irq handler Russell King
2014-04-23 19:06 ` [PATCH 06/38] mmc: sdhci: allow sdio interrupts while sdhci runtime suspended Russell King
2014-04-23 19:06 ` Russell King [this message]
2014-04-23 19:06 ` [PATCH 08/38] mmc: sdhci: plug hole in disabling card detection interrupts Russell King
2014-04-23 19:06 ` [PATCH 09/38] mmc: sdhci: convert generic bus width setup to library function Russell King
2014-04-23 19:07 ` [PATCH 10/38] mmc: sdhci: convert reset into a " Russell King
2014-04-23 19:07 ` [PATCH 11/38] mmc: sdhci: move FSL ESDHC reset handling quirk into esdhc code Russell King
2014-04-23 19:07 ` [PATCH 12/38] mmc: sdhci: avoid sync'ing the SG if there's no misalignment Russell King
2014-04-23 19:07 ` [PATCH 13/38] mmc: sdhci: convert ADMA descriptors to a coherent allocation Russell King
2014-04-23 19:07 ` [PATCH 14/38] mmc: sdhci: clean up sdhci_update_clock()/sdhci_set_clock() Russell King
2014-04-23 19:07 ` [PATCH 15/38] mmc: sdhci: move setting host->clock into sdhci_do_set_ios() Russell King
2014-04-23 19:07 ` [PATCH 16/38] mmc: sdhci: move setting mmc->actual_clock into set_clock handlers Russell King
2014-04-23 19:07 ` [PATCH 17/38] mmc: sdhci: convert sdhci_set_clock() into a library function Russell King
2014-04-23 19:07 ` [PATCH 18/38] mmc: sdhci-esdhc-imx: avoid DMA to kernel stack Russell King
2014-04-23 19:07 ` [PATCH 19/38] mmc: sdhci-esdhc-imx: comment runtime_pm_get_sync() in esdhc_prepare_tuning() Russell King
2014-04-23 19:07 ` [PATCH 20/38] mmc: sdhci-esdhc-imx: fix lockdep splat upon tuning Russell King
2014-04-23 19:07 ` [PATCH 21/38] mmc: sdhci: hack up driver to make it more compliant with UHS-1 Russell King
2014-04-25 12:38 ` Markus Pargmann
2014-04-25 12:49 ` Russell King - ARM Linux
2014-04-25 13:08 ` Markus Pargmann
2014-04-25 13:15 ` Russell King - ARM Linux
2014-04-25 13:22 ` Russell King - ARM Linux
2014-04-25 13:26 ` [PATCH 21/32] mmc: sdhci: set_uhs_signaling() need not return a value Russell King
2014-04-25 13:26 ` [PATCH 22/32] mmc: sdhci: convert sdhci_set_uhs_signaling() into a library function Russell King
2014-04-25 13:26 ` [PATCH 23/32] mmc: sdhci: cache timing information locally Russell King
2014-04-25 13:26 ` [PATCH 24/32] mmc: sdhci: clean up sdhci_execute_tuning() decision Russell King
2014-04-25 13:26 ` [PATCH 25/32] mmc: sdhci-esdhc-imx: remove emulation of uhs_mode Russell King
2014-04-25 13:26 ` [PATCH 26/32] mmc: sdhci-of-esdhc: remove platform_suspend/platform_resume callbacks Russell King
2014-04-25 13:26 ` [PATCH 27/32] mmc: sdhci: " Russell King
2014-04-25 13:27 ` [PATCH 28/32] mmc: sdhci-tegra: get rid of special PRESENT_STATE register handling Russell King
2014-04-25 13:27 ` [PATCH 29/32] mmc: sdhci: move regulator handling into sdhci_set_power() Russell King
2014-04-25 13:27 ` [PATCH 30/32] mmc: sdhci: move remaining power " Russell King
2014-04-25 13:27 ` [PATCH 31/32] mmc: sdhci: track whether preset mode is currently enabled in hardware Russell King
2014-04-25 13:27 ` [PATCH 32/32] mmc: sdhci: fix SDHCI dependencies Russell King
2014-04-28 13:10 ` [PATCH 21/38] mmc: sdhci: hack up driver to make it more compliant with UHS-1 Markus Pargmann
2014-04-25 16:20 ` Russell King - ARM Linux
2014-04-28 10:50 ` Ulf Hansson
2014-04-28 11:02 ` Russell King - ARM Linux
2014-04-28 11:11 ` Ulf Hansson
2014-04-28 11:51 ` Russell King - ARM Linux
2014-04-23 19:08 ` [PATCH 22/38] mmc: sdhci: set_uhs_signaling() need not return a value Russell King
2014-04-23 19:08 ` [PATCH 23/38] mmc: sdhci: convert sdhci_set_uhs_signaling() into a library function Russell King
[not found] ` <E1Wd2Wd-0003vp-S2-eh5Bv4kxaXIANfyc6IWni62ZND6+EDdj@public.gmane.org>
2014-06-16 10:46 ` Russell King - ARM Linux
2014-06-16 12:17 ` Ulf Hansson
[not found] ` <CAPDyKFrp8JokqBbo3rg2i6WYykU1C9CuPF0FL7AOHh=Gcp5=hg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-06-16 16:10 ` Ulf Hansson
2014-06-17 23:42 ` Russell King - ARM Linux
2014-06-19 12:28 ` Russell King - ARM Linux
[not found] ` <20140619122830.GP32514-l+eeeJia6m9vn6HldHNs0ANdhmdF6hFW@public.gmane.org>
2014-06-19 15:57 ` Stephen Warren
2014-06-19 17:02 ` Olof Johansson
2014-04-23 19:08 ` [PATCH 24/38] mmc: sdhci: cache timing information locally Russell King
2014-04-23 19:08 ` [PATCH 25/38] mmc: sdhci: clean up sdhci_execute_tuning() decision Russell King
2014-04-23 19:08 ` [PATCH 26/38] mmc: sdhci-esdhc-imx: remove emulation of uhs_mode Russell King
2014-04-23 19:08 ` [PATCH 27/38] mmc: sdhci-of-esdhc: remove platform_suspend/platform_resume callbacks Russell King
2014-04-24 7:32 ` Ulf Hansson
2014-04-24 11:18 ` Russell King - ARM Linux
2014-04-24 11:32 ` Ulf Hansson
2014-04-24 12:27 ` Russell King - ARM Linux
2014-04-24 13:15 ` Ulf Hansson
2014-04-23 19:08 ` [PATCH 28/38] mmc: sdhci: " Russell King
2014-04-24 7:33 ` Ulf Hansson
2014-04-23 19:08 ` [PATCH 29/38] mmc: sdhci-tegra: get rid of special PRESENT_STATE register handling Russell King
2014-04-23 19:08 ` [PATCH 30/38] mmc: sdhci: move regulator handling into sdhci_set_power() Russell King
2014-04-23 19:08 ` [PATCH 31/38] mmc: sdhci: move remaining power " Russell King
2014-04-23 19:08 ` [PATCH 32/38] mmc: sdhci: track whether preset mode is currently enabled in hardware Russell King
2014-04-23 19:08 ` [PATCH 33/38] mmc: sdhci: fix SDHCI dependencies Russell King
2014-04-28 16:28 ` Stephen Warren
2014-04-23 19:09 ` [PATCH 34/38] mmc: add support for power-on sequencing through DT Russell King
2014-04-24 9:05 ` Maxime Ripard
2014-04-23 19:09 ` [PATCH 35/38] mmc: dw_mmc: call mmc_of_parse to fill in common options Russell King
2014-04-24 0:31 ` Jaehoon Chung
2014-04-24 19:42 ` Russell King - ARM Linux
2014-04-23 19:09 ` [PATCH 36/38] mmc: fix power-on sequencing for esdhc-imx driver Russell King
[not found] ` <20140423185534.GA26756-l+eeeJia6m9vn6HldHNs0ANdhmdF6hFW@public.gmane.org>
2014-04-23 19:09 ` [PATCH 37/38] ARM: cubox-i: add support for SD UHS-1 cards Russell King
2014-04-24 8:25 ` [PATCH 00/38] MMC updates, plus CuBox-i WiFi support Ulf Hansson
2014-04-24 10:17 ` Russell King - ARM Linux
2014-04-24 10:52 ` Ulf Hansson
2014-04-24 10:57 ` Russell King - ARM Linux
[not found] ` <20140424105745.GM26756-l+eeeJia6m9vn6HldHNs0ANdhmdF6hFW@public.gmane.org>
2014-04-24 11:13 ` Ulf Hansson
2014-04-25 9:03 ` Russell King - ARM Linux
2014-04-25 11:18 ` Ulf Hansson
[not found] ` <CAPDyKFpAiegwfh=kA8NyB+DdwKT=wSGJsB=gbEgLbyv0RJ2EOQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-04-25 11:20 ` Russell King - ARM Linux
2014-04-25 11:40 ` Ulf Hansson
2014-04-23 19:09 ` [PATCH 38/38] ARM: cubox-i: add support for Wifi/BT Russell King
2014-04-28 16:42 ` [PATCH 00/38] MMC updates, plus CuBox-i WiFi support Stephen Warren
2014-04-28 16:52 ` Chris Ball
2014-05-07 20:49 ` Tim Kryger
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=E1Wd2VJ-0003ui-VE@rmk-PC.arm.linux.org.uk \
--to=rmk+kernel@arm.linux.org.uk \
--cc=chris@printf.net \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-mmc@vger.kernel.org \
--cc=ulf.hansson@linaro.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).