From patchwork Thu Aug 25 01:27:25 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 1094832 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p7P1RgF2002532 for ; Thu, 25 Aug 2011 01:27:43 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752217Ab1HYB1m (ORCPT ); Wed, 24 Aug 2011 21:27:42 -0400 Received: from kirsty.vergenet.net ([202.4.237.240]:51712 "EHLO kirsty.vergenet.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752179Ab1HYB1l (ORCPT ); Wed, 24 Aug 2011 21:27:41 -0400 Received: from joe.akashicho.tokyo.vergenet.net (joe.akashicho.tokyo.vergenet.net [IPv6:2001:470:f44f:403:1ec1:deff:fe98:754d]) by kirsty.vergenet.net (Postfix) with ESMTP id EF121245A6; Thu, 25 Aug 2011 11:27:36 +1000 (EST) Received: by joe.akashicho.tokyo.vergenet.net (Postfix, from userid 7100) id 42B6328A03C; Thu, 25 Aug 2011 10:27:36 +0900 (JST) From: Simon Horman To: linux-mmc@vger.kernel.org, linux-sh@vger.kernel.org Cc: Chris Ball , Paul Mundt , Guennadi Liakhovetski , Magnus Damm , Simon Horman Subject: [PATCH v8 1/4] mmc: tmio: Cache interrupt masks Date: Thu, 25 Aug 2011 10:27:25 +0900 Message-Id: <1314235648-8959-2-git-send-email-horms@verge.net.au> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1314235648-8959-1-git-send-email-horms@verge.net.au> References: <1314235648-8959-1-git-send-email-horms@verge.net.au> Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Thu, 25 Aug 2011 01:27:43 +0000 (UTC) This avoids the need to look up the masks each time an interrupt is handled. As suggested by Guennadi. Cc: Guennadi Liakhovetski Acked-by: Magnus Damm Signed-off-by: Simon Horman --- * SDCARD portion tested on AP4/Mackerel * SDIO portion untested v3 * As suggested by Guennadi Liakhovetski - Only read sdcard_irq_mask once and never read sdio_irq_mask, instead use the cached values as much as possible v2 * Initial release --- drivers/mmc/host/tmio_mmc.h | 4 ++++ drivers/mmc/host/tmio_mmc_pio.c | 34 ++++++++++++++++++---------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index eeaf643..1cf8db5 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h @@ -79,6 +79,10 @@ struct tmio_mmc_host { struct delayed_work delayed_reset_work; struct work_struct done; + /* Cache IRQ mask */ + u32 sdcard_irq_mask; + u32 sdio_irq_mask; + spinlock_t lock; /* protect host private data */ unsigned long last_req_ts; struct mutex ios_lock; /* protect set_ios() context */ diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index 1f16357..f0c7830 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c @@ -48,14 +48,14 @@ void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i) { - u32 mask = sd_ctrl_read32(host, CTL_IRQ_MASK) & ~(i & TMIO_MASK_IRQ); - sd_ctrl_write32(host, CTL_IRQ_MASK, mask); + host->sdcard_irq_mask &= ~(i & TMIO_MASK_IRQ); + sd_ctrl_write32(host, CTL_IRQ_MASK, host->sdcard_irq_mask); } void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i) { - u32 mask = sd_ctrl_read32(host, CTL_IRQ_MASK) | (i & TMIO_MASK_IRQ); - sd_ctrl_write32(host, CTL_IRQ_MASK, mask); + host->sdcard_irq_mask |= (i & TMIO_MASK_IRQ); + sd_ctrl_write32(host, CTL_IRQ_MASK, host->sdcard_irq_mask); } static void tmio_mmc_ack_mmc_irqs(struct tmio_mmc_host *host, u32 i) @@ -127,11 +127,13 @@ static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) if (enable) { host->sdio_irq_enabled = 1; + host->sdio_irq_mask = TMIO_SDIO_MASK_ALL & + ~TMIO_SDIO_STAT_IOIRQ; sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001); - sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, - (TMIO_SDIO_MASK_ALL & ~TMIO_SDIO_STAT_IOIRQ)); + sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask); } else { - sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, TMIO_SDIO_MASK_ALL); + host->sdio_irq_mask = TMIO_SDIO_MASK_ALL; + sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask); sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0000); host->sdio_irq_enabled = 0; } @@ -548,26 +550,25 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid) struct tmio_mmc_host *host = devid; struct mmc_host *mmc = host->mmc; struct tmio_mmc_data *pdata = host->pdata; - unsigned int ireg, irq_mask, status; - unsigned int sdio_ireg, sdio_irq_mask, sdio_status; + unsigned int ireg, status; + unsigned int sdio_ireg, sdio_status; pr_debug("MMC IRQ begin\n"); status = sd_ctrl_read32(host, CTL_STATUS); - irq_mask = sd_ctrl_read32(host, CTL_IRQ_MASK); - ireg = status & TMIO_MASK_IRQ & ~irq_mask; + ireg = status & TMIO_MASK_IRQ & ~host->sdcard_irq_mask; sdio_ireg = 0; if (!ireg && pdata->flags & TMIO_MMC_SDIO_IRQ) { sdio_status = sd_ctrl_read16(host, CTL_SDIO_STATUS); - sdio_irq_mask = sd_ctrl_read16(host, CTL_SDIO_IRQ_MASK); - sdio_ireg = sdio_status & TMIO_SDIO_MASK_ALL & ~sdio_irq_mask; + sdio_ireg = sdio_status & TMIO_SDIO_MASK_ALL & + ~host->sdio_irq_mask; sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status & ~TMIO_SDIO_MASK_ALL); if (sdio_ireg && !host->sdio_irq_enabled) { pr_warning("tmio_mmc: Spurious SDIO IRQ, disabling! 0x%04x 0x%04x 0x%04x\n", - sdio_status, sdio_irq_mask, sdio_ireg); + sdio_status, host->sdio_irq_mask, sdio_ireg); tmio_mmc_enable_sdio_irq(mmc, 0); goto out; } @@ -623,9 +624,9 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid) } pr_warning("tmio_mmc: Spurious irq, disabling! " - "0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg); + "0x%08x 0x%08x 0x%08x\n", status, host->sdcard_irq_mask, ireg); pr_debug_status(status); - tmio_mmc_disable_mmc_irqs(host, status & ~irq_mask); + tmio_mmc_disable_mmc_irqs(host, status & ~host->sdcard_irq_mask); out: return IRQ_HANDLED; @@ -882,6 +883,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host, tmio_mmc_clk_stop(_host); tmio_mmc_reset(_host); + _host->sdcard_irq_mask = sd_ctrl_read32(_host, CTL_IRQ_MASK); tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL); if (pdata->flags & TMIO_MMC_SDIO_IRQ) tmio_mmc_enable_sdio_irq(mmc, 0);