Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d7753b35 authored by Subhash Jadavani's avatar Subhash Jadavani Committed by Stephen Boyd
Browse files

mmc: sdio: enable asynchronous interrupt support in 4-bit mode



SDIO 3.0 specification has added the support for asynchronous interrupt
period during which card allows the clock to be gated off. Host needs
to first read the "Support Asynchronous Interrupt" bit in CCCR register
space to check if the card supports the feature or not. If yes and if
the host wants to enable the feature, host needs to write '1' to
"Enable Asynchronous Interrupt" bit in CCCR register space.

This change allows the host controller driver to control whether to enable
the asynchronous interrupt in card or not and if the asynchronous interrupt
is enabled then clock gating feature would be enabled for such cards.

Change-Id: I678cffb63af6a2013640a5eafa6ce9bfad8a51d6
Signed-off-by: default avatarSubhash Jadavani <subhashj@codeaurora.org>
parent 3bc1e1f7
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -262,6 +262,14 @@ bool mmc_host_may_gate_card(struct mmc_card *card)
	/* If there is no card we may gate it */
	if (!card)
		return true;

	/*
	 * SDIO3.0 card allows the clock to be gated off so check if
	 * that is the case or not.
	 */
	if (mmc_card_sdio(card) && card->cccr.async_intr_sup)
		return true;

	/*
	 * Don't gate SDIO cards! These need to be clocked at all times
	 * since they may be independent systems generating interrupts
+17 −0
Original line number Diff line number Diff line
@@ -187,6 +187,23 @@ 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_EXTENSION, 0, &data);
			if (ret)
				goto out;
			if (data & SDIO_SUPPORT_ASYNC_INTR) {
				if (card->host->caps2 &
				    MMC_CAP2_ASYNC_SDIO_IRQ_4BIT_MODE) {
					data |= SDIO_ENABLE_ASYNC_INTR;
					ret = mmc_io_rw_direct(card, 1, 0,
						SDIO_CCCR_INTERRUPT_EXTENSION,
						data, NULL);
					if (ret)
						goto out;
					card->cccr.async_intr_sup = 1;
				}
			}
		}

		/* if no uhs mode ensure we check for high speed */
+2 −1
Original line number Diff line number Diff line
@@ -175,7 +175,8 @@ struct sdio_cccr {
				wide_bus:1,
				high_power:1,
				high_speed:1,
				disable_cd:1;
				disable_cd:1,
				async_intr_sup:1;
};

struct sdio_cis {
+2 −0
Original line number Diff line number Diff line
@@ -313,6 +313,8 @@ struct mmc_host {
/* Use runtime PM framework provided by MMC core */
#define MMC_CAP2_CORE_RUNTIME_PM (1 << 19)
#define MMC_CAP2_SANITIZE	(1 << 20)		/* Support Sanitize */
/* Allows Asynchronous SDIO irq while card is in 4-bit mode */
#define MMC_CAP2_ASYNC_SDIO_IRQ_4BIT_MODE (1 << 21)
	mmc_pm_flag_t		pm_caps;	/* supported pm features */

	int			clk_requests;	/* internal reference counter */
+4 −0
Original line number Diff line number Diff line
@@ -164,6 +164,10 @@
#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_EXTENSION	0x16
#define	SDIO_SUPPORT_ASYNC_INTR		(1<<0)
#define	SDIO_ENABLE_ASYNC_INTR		(1<<1)
/*
 * Function Basic Registers (FBR)
 */