]> Git Repo - linux.git/commitdiff
mmc: core: Add support for SDIO wakeup interrupt
authorAxe Yang <[email protected]>
Tue, 26 Jul 2022 06:28:41 +0000 (14:28 +0800)
committerUlf Hansson <[email protected]>
Tue, 26 Jul 2022 14:58:31 +0000 (16:58 +0200)
If wakeup-source flag is set in host dts node, parse EAI information
from SDIO CCCR interrupt externsion segment for in-band wakeup. If
async interrupt is supported by SDIO card then enable it and set
enable_async_irq flag in sdio_cccr structure to 1. The parse flow is
implemented in sdio_read_cccr().

Reviewed-by: AngeloGioacchino Del Regno <[email protected]>
Signed-off-by: Axe Yang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Ulf Hansson <[email protected]>
drivers/mmc/core/sdio.c
include/linux/mmc/card.h
include/linux/mmc/sdio.h

index b589df1c35e030b3aed861da1bc054e8cfc8ef91..0b682a31cd3e8ad9199fea87670413dcfb30ef9c 100644 (file)
@@ -226,6 +226,20 @@ static int sdio_read_cccr(struct mmc_card *card, u32 ocr)
                                card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_C;
                        if (data & SDIO_DRIVE_SDTD)
                                card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_D;
+
+                       ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTERRUPT_EXT, 0, &data);
+                       if (ret)
+                               goto out;
+
+                       if (data & SDIO_INTERRUPT_EXT_SAI) {
+                               data |= SDIO_INTERRUPT_EXT_EAI;
+                               ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_INTERRUPT_EXT,
+                                                      data, NULL);
+                               if (ret)
+                                       goto out;
+
+                               card->cccr.enable_async_irq = 1;
+                       }
                }
 
                /* if no uhs mode ensure we check for high speed */
index 156a7b673a2871569450f6ad592a80a78ca232dc..8a30de08e9139d7b4e4c8cb9a230bc795d95456f 100644 (file)
@@ -219,7 +219,8 @@ struct sdio_cccr {
                                wide_bus:1,
                                high_power:1,
                                high_speed:1,
-                               disable_cd:1;
+                               disable_cd:1,
+                               enable_async_irq:1;
 };
 
 struct sdio_cis {
@@ -343,6 +344,11 @@ static inline bool mmc_large_sector(struct mmc_card *card)
        return card->ext_csd.data_sector_size == 4096;
 }
 
+static inline int mmc_card_enable_async_irq(struct mmc_card *card)
+{
+       return card->cccr.enable_async_irq;
+}
+
 bool mmc_card_is_blockaddr(struct mmc_card *card);
 
 #define mmc_card_mmc(c)                ((c)->type == MMC_TYPE_MMC)
index 2a05d1ac4f0ed7c64c1a2173cde85fbffab576b5..1ef400f28642ef393e670dcbe6bb14b82eeade58 100644 (file)
 #define  SDIO_DTSx_SET_TYPE_A  (1 << SDIO_DRIVE_DTSx_SHIFT)
 #define  SDIO_DTSx_SET_TYPE_C  (2 << SDIO_DRIVE_DTSx_SHIFT)
 #define  SDIO_DTSx_SET_TYPE_D  (3 << SDIO_DRIVE_DTSx_SHIFT)
+
+#define SDIO_CCCR_INTERRUPT_EXT        0x16
+#define SDIO_INTERRUPT_EXT_SAI (1 << 0)
+#define SDIO_INTERRUPT_EXT_EAI (1 << 1)
+
 /*
  * Function Basic Registers (FBR)
  */
This page took 0.05644 seconds and 4 git commands to generate.