aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorStefan Nilsson XK <stefan.xk.nilsson@stericsson.com>2011-05-11 11:48:05 -0400
committerChris Ball <cjb@laptop.org>2011-05-24 23:53:50 -0400
commit06e8935febe687e2a561707d4c7ca4245d261dbe (patch)
tree0eef896f5b1614576fb0a1b744b4f87e8124f515 /drivers/mmc
parent253d6a280f77a9b61a76f9b1bfb83545fbd58726 (diff)
mmc: sdio: optimized SDIO IRQ handling for single irq
If there is only 1 function interrupt registered it is possible to improve performance by directly calling the irq handler and avoiding the overhead of reading the CCCR registers. Signed-off-by: Per Forlin <per.forlin@linaro.org> Acked-by: Ulf Hansson <ulf.hansson@stericsson.com> Reviewed-by: Nicolas Pitre <nicolas.pitre@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/sdio_irq.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
index b3001617e67d..03ead028d2ce 100644
--- a/drivers/mmc/core/sdio_irq.c
+++ b/drivers/mmc/core/sdio_irq.c
@@ -31,6 +31,17 @@ static int process_sdio_pending_irqs(struct mmc_card *card)
31{ 31{
32 int i, ret, count; 32 int i, ret, count;
33 unsigned char pending; 33 unsigned char pending;
34 struct sdio_func *func;
35
36 /*
37 * Optimization, if there is only 1 function interrupt registered
38 * call irq handler directly
39 */
40 func = card->sdio_single_irq;
41 if (func) {
42 func->irq_handler(func);
43 return 1;
44 }
34 45
35 ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending); 46 ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending);
36 if (ret) { 47 if (ret) {
@@ -42,7 +53,7 @@ static int process_sdio_pending_irqs(struct mmc_card *card)
42 count = 0; 53 count = 0;
43 for (i = 1; i <= 7; i++) { 54 for (i = 1; i <= 7; i++) {
44 if (pending & (1 << i)) { 55 if (pending & (1 << i)) {
45 struct sdio_func *func = card->sdio_func[i - 1]; 56 func = card->sdio_func[i - 1];
46 if (!func) { 57 if (!func) {
47 printk(KERN_WARNING "%s: pending IRQ for " 58 printk(KERN_WARNING "%s: pending IRQ for "
48 "non-existent function\n", 59 "non-existent function\n",
@@ -186,6 +197,24 @@ static int sdio_card_irq_put(struct mmc_card *card)
186 return 0; 197 return 0;
187} 198}
188 199
200/* If there is only 1 function registered set sdio_single_irq */
201static void sdio_single_irq_set(struct mmc_card *card)
202{
203 struct sdio_func *func;
204 int i;
205
206 card->sdio_single_irq = NULL;
207 if ((card->host->caps & MMC_CAP_SDIO_IRQ) &&
208 card->host->sdio_irqs == 1)
209 for (i = 0; i < card->sdio_funcs; i++) {
210 func = card->sdio_func[i];
211 if (func && func->irq_handler) {
212 card->sdio_single_irq = func;
213 break;
214 }
215 }
216}
217
189/** 218/**
190 * sdio_claim_irq - claim the IRQ for a SDIO function 219 * sdio_claim_irq - claim the IRQ for a SDIO function
191 * @func: SDIO function 220 * @func: SDIO function
@@ -227,6 +256,7 @@ int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler)
227 ret = sdio_card_irq_get(func->card); 256 ret = sdio_card_irq_get(func->card);
228 if (ret) 257 if (ret)
229 func->irq_handler = NULL; 258 func->irq_handler = NULL;
259 sdio_single_irq_set(func->card);
230 260
231 return ret; 261 return ret;
232} 262}
@@ -251,6 +281,7 @@ int sdio_release_irq(struct sdio_func *func)
251 if (func->irq_handler) { 281 if (func->irq_handler) {
252 func->irq_handler = NULL; 282 func->irq_handler = NULL;
253 sdio_card_irq_put(func->card); 283 sdio_card_irq_put(func->card);
284 sdio_single_irq_set(func->card);
254 } 285 }
255 286
256 ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, &reg); 287 ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, &reg);