Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: dw_mmc: Support SDIO interrupts for all slots

The Patch adds the support for SDIO interrupts for all slots.
It includes enabling of SDIO interrupts through dw_mci_enable_sdio_irq
and the handling of the slot specific interrupts in the Interrupt Service
Routine.

Signed-off-by: Shashidhar Hiremath <shashidharh@vayavyalabs.com>
Acked-by: James Hogan <james.hogan@imgtec.com>
Signed-off-by: Chris Ball <cjb@laptop.org>

authored by

Shashidhar Hiremath and committed by
Chris Ball
1a5c8e1f 190657c9

+33 -5
+32 -4
drivers/mmc/host/dw_mmc.c
··· 764 764 return present; 765 765 } 766 766 767 + static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb) 768 + { 769 + struct dw_mci_slot *slot = mmc_priv(mmc); 770 + struct dw_mci *host = slot->host; 771 + u32 int_mask; 772 + 773 + /* Enable/disable Slot Specific SDIO interrupt */ 774 + int_mask = mci_readl(host, INTMASK); 775 + if (enb) { 776 + mci_writel(host, INTMASK, 777 + (int_mask | (1 << SDMMC_INT_SDIO(slot->id)))); 778 + } else { 779 + mci_writel(host, INTMASK, 780 + (int_mask & ~(1 << SDMMC_INT_SDIO(slot->id)))); 781 + } 782 + } 783 + 767 784 static const struct mmc_host_ops dw_mci_ops = { 768 - .request = dw_mci_request, 769 - .set_ios = dw_mci_set_ios, 770 - .get_ro = dw_mci_get_ro, 771 - .get_cd = dw_mci_get_cd, 785 + .request = dw_mci_request, 786 + .set_ios = dw_mci_set_ios, 787 + .get_ro = dw_mci_get_ro, 788 + .get_cd = dw_mci_get_cd, 789 + .enable_sdio_irq = dw_mci_enable_sdio_irq, 772 790 }; 773 791 774 792 static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq) ··· 1424 1406 struct dw_mci *host = dev_id; 1425 1407 u32 status, pending; 1426 1408 unsigned int pass_count = 0; 1409 + int i; 1427 1410 1428 1411 do { 1429 1412 status = mci_readl(host, RINTSTS); ··· 1494 1475 if (pending & SDMMC_INT_CD) { 1495 1476 mci_writel(host, RINTSTS, SDMMC_INT_CD); 1496 1477 queue_work(dw_mci_card_workqueue, &host->card_work); 1478 + } 1479 + 1480 + /* Handle SDIO Interrupts */ 1481 + for (i = 0; i < host->num_slots; i++) { 1482 + struct dw_mci_slot *slot = host->slot[i]; 1483 + if (pending & SDMMC_INT_SDIO(i)) { 1484 + mci_writel(host, RINTSTS, SDMMC_INT_SDIO(i)); 1485 + mmc_signal_sdio_irq(slot->mmc); 1486 + } 1497 1487 } 1498 1488 1499 1489 } while (pass_count++ < 5);
+1 -1
drivers/mmc/host/dw_mmc.h
··· 82 82 #define SDMMC_CTYPE_4BIT BIT(0) 83 83 #define SDMMC_CTYPE_1BIT 0 84 84 /* Interrupt status & mask register defines */ 85 - #define SDMMC_INT_SDIO BIT(16) 85 + #define SDMMC_INT_SDIO(n) BIT(16 + (n)) 86 86 #define SDMMC_INT_EBE BIT(15) 87 87 #define SDMMC_INT_ACD BIT(14) 88 88 #define SDMMC_INT_SBE BIT(13)