Skip to content

Commit 7729c7a

Browse files
hormscjb
authored andcommitted
mmc: tmio: Provide separate interrupt handlers
Provide separate interrupt handlers which may be used by platforms where SDHI has three interrupt sources. This patch also removes the commented-out handling of CRC and other errors. Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Acked-by: Magnus Damm <magnus.damm@gmail.com> Signed-off-by: Simon Horman <horms@verge.net.au> Signed-off-by: Chris Ball <cjb@laptop.org>
1 parent 54680fe commit 7729c7a

File tree

2 files changed

+86
-48
lines changed

2 files changed

+86
-48
lines changed

drivers/mmc/host/tmio_mmc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ void tmio_mmc_do_data_irq(struct tmio_mmc_host *host);
9797
void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i);
9898
void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i);
9999
irqreturn_t tmio_mmc_irq(int irq, void *devid);
100+
irqreturn_t tmio_mmc_sdcard_irq(int irq, void *devid);
101+
irqreturn_t tmio_mmc_card_detect_irq(int irq, void *devid);
102+
irqreturn_t tmio_mmc_sdio_irq(int irq, void *devid);
100103

101104
static inline char *tmio_mmc_kmap_atomic(struct scatterlist *sg,
102105
unsigned long *flags)

drivers/mmc/host/tmio_mmc_pio.c

Lines changed: 83 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -545,44 +545,20 @@ static void tmio_mmc_cmd_irq(struct tmio_mmc_host *host,
545545
spin_unlock(&host->lock);
546546
}
547547

548-
irqreturn_t tmio_mmc_irq(int irq, void *devid)
548+
static void tmio_mmc_card_irq_status(struct tmio_mmc_host *host,
549+
int *ireg, int *status)
549550
{
550-
struct tmio_mmc_host *host = devid;
551-
struct mmc_host *mmc = host->mmc;
552-
struct tmio_mmc_data *pdata = host->pdata;
553-
unsigned int ireg, status;
554-
unsigned int sdio_ireg, sdio_status;
555-
556-
pr_debug("MMC IRQ begin\n");
557-
558-
status = sd_ctrl_read32(host, CTL_STATUS);
559-
ireg = status & TMIO_MASK_IRQ & ~host->sdcard_irq_mask;
551+
*status = sd_ctrl_read32(host, CTL_STATUS);
552+
*ireg = *status & TMIO_MASK_IRQ & ~host->sdcard_irq_mask;
560553

561-
sdio_ireg = 0;
562-
if (!ireg && pdata->flags & TMIO_MMC_SDIO_IRQ) {
563-
sdio_status = sd_ctrl_read16(host, CTL_SDIO_STATUS);
564-
sdio_ireg = sdio_status & TMIO_SDIO_MASK_ALL &
565-
~host->sdio_irq_mask;
566-
567-
sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status & ~TMIO_SDIO_MASK_ALL);
568-
569-
if (sdio_ireg && !host->sdio_irq_enabled) {
570-
pr_warning("tmio_mmc: Spurious SDIO IRQ, disabling! 0x%04x 0x%04x 0x%04x\n",
571-
sdio_status, host->sdio_irq_mask, sdio_ireg);
572-
tmio_mmc_enable_sdio_irq(mmc, 0);
573-
goto out;
574-
}
575-
576-
if (mmc->caps & MMC_CAP_SDIO_IRQ &&
577-
sdio_ireg & TMIO_SDIO_STAT_IOIRQ)
578-
mmc_signal_sdio_irq(mmc);
579-
580-
if (sdio_ireg)
581-
goto out;
582-
}
554+
pr_debug_status(*status);
555+
pr_debug_status(*ireg);
556+
}
583557

584-
pr_debug_status(status);
585-
pr_debug_status(ireg);
558+
static bool __tmio_mmc_card_detect_irq(struct tmio_mmc_host *host,
559+
int ireg, int status)
560+
{
561+
struct mmc_host *mmc = host->mmc;
586562

587563
/* Card insert / remove attempts */
588564
if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) {
@@ -592,43 +568,102 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid)
592568
((ireg & TMIO_STAT_CARD_INSERT) && !mmc->card)) &&
593569
!work_pending(&mmc->detect.work))
594570
mmc_detect_change(host->mmc, msecs_to_jiffies(100));
595-
goto out;
571+
return true;
596572
}
597573

598-
/* CRC and other errors */
599-
/* if (ireg & TMIO_STAT_ERR_IRQ)
600-
* handled |= tmio_error_irq(host, irq, stat);
601-
*/
574+
return false;
575+
}
576+
577+
irqreturn_t tmio_mmc_card_detect_irq(int irq, void *devid)
578+
{
579+
unsigned int ireg, status;
580+
struct tmio_mmc_host *host = devid;
602581

582+
tmio_mmc_card_irq_status(host, &ireg, &status);
583+
__tmio_mmc_card_detect_irq(host, ireg, status);
584+
585+
return IRQ_HANDLED;
586+
}
587+
EXPORT_SYMBOL(tmio_mmc_card_detect_irq);
588+
589+
static bool __tmio_mmc_sdcard_irq(struct tmio_mmc_host *host,
590+
int ireg, int status)
591+
{
603592
/* Command completion */
604593
if (ireg & (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT)) {
605594
tmio_mmc_ack_mmc_irqs(host,
606595
TMIO_STAT_CMDRESPEND |
607596
TMIO_STAT_CMDTIMEOUT);
608597
tmio_mmc_cmd_irq(host, status);
609-
goto out;
598+
return true;
610599
}
611600

612601
/* Data transfer */
613602
if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) {
614603
tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ);
615604
tmio_mmc_pio_irq(host);
616-
goto out;
605+
return true;
617606
}
618607

619608
/* Data transfer completion */
620609
if (ireg & TMIO_STAT_DATAEND) {
621610
tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_DATAEND);
622611
tmio_mmc_data_irq(host);
623-
goto out;
612+
return true;
624613
}
625614

626-
pr_warning("tmio_mmc: Spurious irq, disabling! "
627-
"0x%08x 0x%08x 0x%08x\n", status, host->sdcard_irq_mask, ireg);
628-
pr_debug_status(status);
629-
tmio_mmc_disable_mmc_irqs(host, status & ~host->sdcard_irq_mask);
615+
return false;
616+
}
617+
618+
irqreturn_t tmio_mmc_sdcard_irq(int irq, void *devid)
619+
{
620+
unsigned int ireg, status;
621+
struct tmio_mmc_host *host = devid;
622+
623+
tmio_mmc_card_irq_status(host, &ireg, &status);
624+
__tmio_mmc_sdcard_irq(host, ireg, status);
625+
626+
return IRQ_HANDLED;
627+
}
628+
EXPORT_SYMBOL(tmio_mmc_sdcard_irq);
629+
630+
irqreturn_t tmio_mmc_sdio_irq(int irq, void *devid)
631+
{
632+
struct tmio_mmc_host *host = devid;
633+
struct mmc_host *mmc = host->mmc;
634+
struct tmio_mmc_data *pdata = host->pdata;
635+
unsigned int ireg, status;
636+
637+
if (!(pdata->flags & TMIO_MMC_SDIO_IRQ))
638+
return IRQ_HANDLED;
639+
640+
status = sd_ctrl_read16(host, CTL_SDIO_STATUS);
641+
ireg = status & TMIO_SDIO_MASK_ALL & ~host->sdcard_irq_mask;
642+
643+
sd_ctrl_write16(host, CTL_SDIO_STATUS, status & ~TMIO_SDIO_MASK_ALL);
644+
645+
if (mmc->caps & MMC_CAP_SDIO_IRQ && ireg & TMIO_SDIO_STAT_IOIRQ)
646+
mmc_signal_sdio_irq(mmc);
647+
648+
return IRQ_HANDLED;
649+
}
650+
EXPORT_SYMBOL(tmio_mmc_sdio_irq);
651+
652+
irqreturn_t tmio_mmc_irq(int irq, void *devid)
653+
{
654+
struct tmio_mmc_host *host = devid;
655+
unsigned int ireg, status;
656+
657+
pr_debug("MMC IRQ begin\n");
658+
659+
tmio_mmc_card_irq_status(host, &ireg, &status);
660+
if (__tmio_mmc_card_detect_irq(host, ireg, status))
661+
return IRQ_HANDLED;
662+
if (__tmio_mmc_sdcard_irq(host, ireg, status))
663+
return IRQ_HANDLED;
664+
665+
tmio_mmc_sdio_irq(irq, devid);
630666

631-
out:
632667
return IRQ_HANDLED;
633668
}
634669
EXPORT_SYMBOL(tmio_mmc_irq);

0 commit comments

Comments
 (0)