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

Commit 2b6be3a2 authored by San Mehat's avatar San Mehat Committed by Dmitry Shmidt
Browse files

ANDROID: mmc: Add concept of an 'embedded' SDIO device.



This is required to support chips which use SDIO for signaling/
communication but do not implement the various card enumeration registers
as required for full SD / SDIO cards.

mmc: sdio: Fix bug where we're freeing the CIS tables we never allocated when using EMBEDDED_SDIO
mmc: Add max_blksize to embedded SDIO data

Change-Id: Ibff2e3e991e5522f55ec8c6edc25ed09f2553736
Signed-off-by: default avatarSan Mehat <san@google.com>
parent 0a3f5620
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -23,8 +23,17 @@ config PWRSEQ_SIMPLE
	  This driver can also be built as a module. If so, the module
	  will be called pwrseq_simple.

config MMC_EMBEDDED_SDIO
	boolean "MMC embedded SDIO device support (EXPERIMENTAL)"
	depends on EXPERIMENTAL
	help
	  If you say Y here, support will be added for embedded SDIO
	  devices which do not contain the necessary enumeration
	  support in hardware to be properly detected.

config MMC_PARANOID_SD_INIT
	bool "Enable paranoid SD card initialization (EXPERIMENTAL)"
	depends on EXPERIMENTAL
	help
	  If you say Y here, the MMC layer will be extra paranoid
	  about re-trying SD init requests. This can be a useful
+16 −0
Original line number Diff line number Diff line
@@ -3026,6 +3026,22 @@ void mmc_init_context_info(struct mmc_host *host)
	init_waitqueue_head(&host->context_info.wait);
}

#ifdef CONFIG_MMC_EMBEDDED_SDIO
void mmc_set_embedded_sdio_data(struct mmc_host *host,
				struct sdio_cis *cis,
				struct sdio_cccr *cccr,
				struct sdio_embedded_func *funcs,
				int num_funcs)
{
	host->embedded_sdio_data.cis = cis;
	host->embedded_sdio_data.cccr = cccr;
	host->embedded_sdio_data.funcs = funcs;
	host->embedded_sdio_data.num_funcs = num_funcs;
}

EXPORT_SYMBOL(mmc_set_embedded_sdio_data);
#endif

static int __init mmc_init(void)
{
	int ret;
+58 −16
Original line number Diff line number Diff line
@@ -28,6 +28,10 @@
#include "sdio_ops.h"
#include "sdio_cis.h"

#ifdef CONFIG_MMC_EMBEDDED_SDIO
#include <linux/mmc/sdio_ids.h>
#endif

static int sdio_read_fbr(struct sdio_func *func)
{
	int ret;
@@ -697,19 +701,35 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
		goto finish;
	}

#ifdef CONFIG_MMC_EMBEDDED_SDIO
	if (host->embedded_sdio_data.cccr)
		memcpy(&card->cccr, host->embedded_sdio_data.cccr, sizeof(struct sdio_cccr));
	else {
#endif
		/*
		 * Read the common registers.
		 */
		err = sdio_read_cccr(card,  ocr);
		if (err)
			goto remove;
#ifdef CONFIG_MMC_EMBEDDED_SDIO
	}
#endif

#ifdef CONFIG_MMC_EMBEDDED_SDIO
	if (host->embedded_sdio_data.cis)
		memcpy(&card->cis, host->embedded_sdio_data.cis, sizeof(struct sdio_cis));
	else {
#endif
		/*
		 * Read the common CIS tuples.
		 */
		err = sdio_read_common_cis(card);
		if (err)
			goto remove;
#ifdef CONFIG_MMC_EMBEDDED_SDIO
	}
#endif

	if (oldcard) {
		int same = (card->cis.vendor == oldcard->cis.vendor &&
@@ -1118,14 +1138,36 @@ int mmc_attach_sdio(struct mmc_host *host)
	funcs = (ocr & 0x70000000) >> 28;
	card->sdio_funcs = 0;

#ifdef CONFIG_MMC_EMBEDDED_SDIO
	if (host->embedded_sdio_data.funcs)
		card->sdio_funcs = funcs = host->embedded_sdio_data.num_funcs;
#endif

	/*
	 * Initialize (but don't add) all present functions.
	 */
	for (i = 0; i < funcs; i++, card->sdio_funcs++) {
#ifdef CONFIG_MMC_EMBEDDED_SDIO
		if (host->embedded_sdio_data.funcs) {
			struct sdio_func *tmp;

			tmp = sdio_alloc_func(host->card);
			if (IS_ERR(tmp))
				goto remove;
			tmp->num = (i + 1);
			card->sdio_func[i] = tmp;
			tmp->class = host->embedded_sdio_data.funcs[i].f_class;
			tmp->max_blksize = host->embedded_sdio_data.funcs[i].f_maxblksize;
			tmp->vendor = card->cis.vendor;
			tmp->device = card->cis.device;
		} else {
#endif
			err = sdio_init_func(host->card, i + 1);
			if (err)
				goto remove;

#ifdef CONFIG_MMC_EMBEDDED_SDIO
		}
#endif
		/*
		 * Enable Runtime PM for this func (if supported)
		 */
+12 −1
Original line number Diff line number Diff line
@@ -28,6 +28,10 @@
#include "sdio_cis.h"
#include "sdio_bus.h"

#ifdef CONFIG_MMC_EMBEDDED_SDIO
#include <linux/mmc/host.h>
#endif

#define to_sdio_driver(d)	container_of(d, struct sdio_driver, drv)

/* show configuration fields */
@@ -263,6 +267,13 @@ static void sdio_release_func(struct device *dev)
{
	struct sdio_func *func = dev_to_sdio_func(dev);

#ifdef CONFIG_MMC_EMBEDDED_SDIO
	/*
	 * If this device is embedded then we never allocated
	 * cis tables for this func
	 */
	if (!func->card->host->embedded_sdio_data.funcs)
#endif
		sdio_free_func_cis(func);

	kfree(func->info);
+10 −0
Original line number Diff line number Diff line
@@ -5,6 +5,15 @@
#define AMBA_MMCI_H

#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#include <linux/mmc/sdio_func.h>

struct embedded_sdio_data {
        struct sdio_cis cis;
        struct sdio_cccr cccr;
        struct sdio_embedded_func *funcs;
        int num_funcs;
};

/**
 * struct mmci_platform_data - platform configuration for the MMCI
@@ -31,6 +40,7 @@ struct mmci_platform_data {
	int	gpio_wp;
	int	gpio_cd;
	bool	cd_invert;
	struct embedded_sdio_data *embedded_sdio;
};

#endif
Loading