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

mmc: core: Add support for SDIO wakeup interrupt

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 <angelogioacchino.delregno@collabora.com>
Signed-off-by: Axe Yang <axe.yang@mediatek.com>
Link: https://lore.kernel.org/r/20220726062842.18846-3-axe.yang@mediatek.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Axe Yang and committed by
Ulf Hansson
019e442b 035cc395

+26 -1
+14
drivers/mmc/core/sdio.c
··· 226 226 card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_C; 227 227 if (data & SDIO_DRIVE_SDTD) 228 228 card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_D; 229 + 230 + ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTERRUPT_EXT, 0, &data); 231 + if (ret) 232 + goto out; 233 + 234 + if (data & SDIO_INTERRUPT_EXT_SAI) { 235 + data |= SDIO_INTERRUPT_EXT_EAI; 236 + ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_INTERRUPT_EXT, 237 + data, NULL); 238 + if (ret) 239 + goto out; 240 + 241 + card->cccr.enable_async_irq = 1; 242 + } 229 243 } 230 244 231 245 /* if no uhs mode ensure we check for high speed */
+7 -1
include/linux/mmc/card.h
··· 219 219 wide_bus:1, 220 220 high_power:1, 221 221 high_speed:1, 222 - disable_cd:1; 222 + disable_cd:1, 223 + enable_async_irq:1; 223 224 }; 224 225 225 226 struct sdio_cis { ··· 342 341 static inline bool mmc_large_sector(struct mmc_card *card) 343 342 { 344 343 return card->ext_csd.data_sector_size == 4096; 344 + } 345 + 346 + static inline int mmc_card_enable_async_irq(struct mmc_card *card) 347 + { 348 + return card->cccr.enable_async_irq; 345 349 } 346 350 347 351 bool mmc_card_is_blockaddr(struct mmc_card *card);
+5
include/linux/mmc/sdio.h
··· 159 159 #define SDIO_DTSx_SET_TYPE_A (1 << SDIO_DRIVE_DTSx_SHIFT) 160 160 #define SDIO_DTSx_SET_TYPE_C (2 << SDIO_DRIVE_DTSx_SHIFT) 161 161 #define SDIO_DTSx_SET_TYPE_D (3 << SDIO_DRIVE_DTSx_SHIFT) 162 + 163 + #define SDIO_CCCR_INTERRUPT_EXT 0x16 164 + #define SDIO_INTERRUPT_EXT_SAI (1 << 0) 165 + #define SDIO_INTERRUPT_EXT_EAI (1 << 1) 166 + 162 167 /* 163 168 * Function Basic Registers (FBR) 164 169 */