Lines Matching +full:mmc +full:- +full:card
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * linux/drivers/mmc/core/sdio_irq.c
20 #include <linux/mmc/core.h>
21 #include <linux/mmc/host.h>
22 #include <linux/mmc/card.h>
23 #include <linux/mmc/sdio.h>
24 #include <linux/mmc/sdio_func.h>
28 #include "card.h"
32 struct mmc_card *card = host->card; in sdio_get_pending_irqs() local
35 WARN_ON(!host->claimed); in sdio_get_pending_irqs()
37 ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, pending); in sdio_get_pending_irqs()
40 mmc_card_id(card), ret); in sdio_get_pending_irqs()
44 if (*pending && mmc_card_broken_irq_polling(card) && in sdio_get_pending_irqs()
45 !(host->caps & MMC_CAP_SDIO_IRQ)) { in sdio_get_pending_irqs()
49 * register with a Marvell SD8797 card. A dummy CMD52 read to in sdio_get_pending_irqs()
52 mmc_io_rw_direct(card, 0, 0, 0xff, 0, &dummy); in sdio_get_pending_irqs()
60 struct mmc_card *card = host->card; in process_sdio_pending_irqs() local
62 bool sdio_irq_pending = host->sdio_irq_pending; in process_sdio_pending_irqs()
66 /* Don't process SDIO IRQs if the card is suspended. */ in process_sdio_pending_irqs()
67 if (mmc_card_suspended(card)) in process_sdio_pending_irqs()
71 host->sdio_irq_pending = false; in process_sdio_pending_irqs()
78 func = card->sdio_single_irq; in process_sdio_pending_irqs()
80 func->irq_handler(func); in process_sdio_pending_irqs()
91 func = card->sdio_func[i - 1]; in process_sdio_pending_irqs()
93 pr_warn("%s: pending IRQ for non-existent function\n", in process_sdio_pending_irqs()
94 mmc_card_id(card)); in process_sdio_pending_irqs()
95 ret = -EINVAL; in process_sdio_pending_irqs()
96 } else if (func->irq_handler) { in process_sdio_pending_irqs()
97 func->irq_handler(func); in process_sdio_pending_irqs()
102 ret = -EINVAL; in process_sdio_pending_irqs()
116 if (host->sdio_irqs) { in sdio_run_irqs()
118 if (!host->sdio_irq_pending) in sdio_run_irqs()
119 host->ops->ack_sdio_irq(host); in sdio_run_irqs()
134 host->sdio_irq_pending = true; in sdio_signal_irq()
135 schedule_work(&host->sdio_irq_work); in sdio_signal_irq()
150 * asynchronous notification of pending SDIO card interrupts in sdio_irq_thread()
154 period = (host->caps & MMC_CAP_SDIO_IRQ) ? in sdio_irq_thread()
175 &host->sdio_irq_thread_abort); in sdio_irq_thread()
197 if (!(host->caps & MMC_CAP_SDIO_IRQ)) { in sdio_irq_thread()
208 if (host->caps & MMC_CAP_SDIO_IRQ) in sdio_irq_thread()
209 host->ops->enable_sdio_irq(host, 1); in sdio_irq_thread()
215 if (host->caps & MMC_CAP_SDIO_IRQ) in sdio_irq_thread()
216 host->ops->enable_sdio_irq(host, 0); in sdio_irq_thread()
224 static int sdio_card_irq_get(struct mmc_card *card) in sdio_card_irq_get() argument
226 struct mmc_host *host = card->host; in sdio_card_irq_get()
228 WARN_ON(!host->claimed); in sdio_card_irq_get()
230 if (!host->sdio_irqs++) { in sdio_card_irq_get()
231 if (!(host->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD)) { in sdio_card_irq_get()
232 atomic_set(&host->sdio_irq_thread_abort, 0); in sdio_card_irq_get()
233 host->sdio_irq_thread = in sdio_card_irq_get()
236 if (IS_ERR(host->sdio_irq_thread)) { in sdio_card_irq_get()
237 int err = PTR_ERR(host->sdio_irq_thread); in sdio_card_irq_get()
238 host->sdio_irqs--; in sdio_card_irq_get()
241 } else if (host->caps & MMC_CAP_SDIO_IRQ) { in sdio_card_irq_get()
242 host->ops->enable_sdio_irq(host, 1); in sdio_card_irq_get()
249 static int sdio_card_irq_put(struct mmc_card *card) in sdio_card_irq_put() argument
251 struct mmc_host *host = card->host; in sdio_card_irq_put()
253 WARN_ON(!host->claimed); in sdio_card_irq_put()
255 if (host->sdio_irqs < 1) in sdio_card_irq_put()
256 return -EINVAL; in sdio_card_irq_put()
258 if (!--host->sdio_irqs) { in sdio_card_irq_put()
259 if (!(host->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD)) { in sdio_card_irq_put()
260 atomic_set(&host->sdio_irq_thread_abort, 1); in sdio_card_irq_put()
261 kthread_stop(host->sdio_irq_thread); in sdio_card_irq_put()
262 } else if (host->caps & MMC_CAP_SDIO_IRQ) { in sdio_card_irq_put()
263 host->ops->enable_sdio_irq(host, 0); in sdio_card_irq_put()
271 static void sdio_single_irq_set(struct mmc_card *card) in sdio_single_irq_set() argument
276 card->sdio_single_irq = NULL; in sdio_single_irq_set()
277 if ((card->host->caps & MMC_CAP_SDIO_IRQ) && in sdio_single_irq_set()
278 card->host->sdio_irqs == 1) { in sdio_single_irq_set()
279 for (i = 0; i < card->sdio_funcs; i++) { in sdio_single_irq_set()
280 func = card->sdio_func[i]; in sdio_single_irq_set()
281 if (func && func->irq_handler) { in sdio_single_irq_set()
282 card->sdio_single_irq = func; in sdio_single_irq_set()
290 * sdio_claim_irq - claim the IRQ for a SDIO function
305 return -EINVAL; in sdio_claim_irq()
309 if (func->irq_handler) { in sdio_claim_irq()
311 return -EBUSY; in sdio_claim_irq()
314 ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, ®); in sdio_claim_irq()
318 reg |= 1 << func->num; in sdio_claim_irq()
322 ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, reg, NULL); in sdio_claim_irq()
326 func->irq_handler = handler; in sdio_claim_irq()
327 ret = sdio_card_irq_get(func->card); in sdio_claim_irq()
329 func->irq_handler = NULL; in sdio_claim_irq()
330 sdio_single_irq_set(func->card); in sdio_claim_irq()
337 * sdio_release_irq - release the IRQ for a SDIO function
348 return -EINVAL; in sdio_release_irq()
352 if (func->irq_handler) { in sdio_release_irq()
353 func->irq_handler = NULL; in sdio_release_irq()
354 sdio_card_irq_put(func->card); in sdio_release_irq()
355 sdio_single_irq_set(func->card); in sdio_release_irq()
358 ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, ®); in sdio_release_irq()
362 reg &= ~(1 << func->num); in sdio_release_irq()
368 ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, reg, NULL); in sdio_release_irq()