mmc: Split mmc struct, rework mmc initialization (v2)

The way that struct mmc was implemented was a bit of a mess;
configuration and internal state all jumbled up in a single structure.

On top of that the way initialization is done with mmc_register leads
to a lot of duplicated code in drivers.

Typically the initialization got something like this in every driver.

	struct mmc *mmc = malloc(sizeof(struct mmc));
	memset(mmc, 0, sizeof(struct mmc);
	/* fill in fields of mmc struct */
	/* store private data pointer */
	mmc_register(mmc);

By using the new mmc_create call one just passes an mmc config struct
and an optional private data pointer like this:

	struct mmc = mmc_create(&cfg, priv);

All in tree drivers have been updated to the new form, and expect
mmc_register to go away before long.

Changes since v1:

* Use calloc instead of manually calling memset.
* Mark mmc_register as deprecated.

Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
diff --git a/include/dwmmc.h b/include/dwmmc.h
index b641558..c9bdf51 100644
--- a/include/dwmmc.h
+++ b/include/dwmmc.h
@@ -143,6 +143,8 @@
 	void (*clksel)(struct dwmci_host *host);
 	void (*board_init)(struct dwmci_host *host);
 	unsigned int (*get_mmc_clk)(struct dwmci_host *host);
+
+	struct mmc_config cfg;
 };
 
 struct dwmci_idmac {
diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h
index 89bcbd1..a6e3a5d 100644
--- a/include/fsl_esdhc.h
+++ b/include/fsl_esdhc.h
@@ -13,6 +13,9 @@
 #include <asm/errno.h>
 #include <asm/byteorder.h>
 
+/* needed for the mmc_cfg definition */
+#include <mmc.h>
+
 /* FSL eSDHC-specific constants */
 #define SYSCTL			0x0002e02c
 #define SYSCTL_INITA		0x08000000
@@ -155,6 +158,7 @@
 	u32	esdhc_base;
 	u32	sdhc_clk;
 	u8	max_bus_width;
+	struct mmc_config cfg;
 };
 
 /* Select the correct accessors depending on endianess */
diff --git a/include/mmc.h b/include/mmc.h
index 6b08c62..0172979 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -262,20 +262,28 @@
 	int (*getwp)(struct mmc *mmc);
 };
 
-struct mmc {
-	struct list_head link;
-	const char *name;	/* no need for this to be an array */
-	void *priv;
+struct mmc_config {
+	const char *name;
+	const struct mmc_ops *ops;
+	uint host_caps;
 	uint voltages;
-	uint version;
-	uint has_init;
 	uint f_min;
 	uint f_max;
+	uint b_max;
+	unsigned char part_type;
+};
+
+/* TODO struct mmc should be in mmc_private but it's hard to fix right now */
+struct mmc {
+	struct list_head link;
+	const struct mmc_config *cfg;	/* provided configuration */
+	uint version;
+	void *priv;
+	uint has_init;
 	int high_capacity;
 	uint bus_width;
 	uint clock;
 	uint card_caps;
-	uint host_caps;
 	uint ocr;
 	uint dsr;
 	uint dsr_imp;
@@ -295,8 +303,6 @@
 	u64 capacity_rpmb;
 	u64 capacity_gp[4];
 	block_dev_desc_t block_dev;
-	const struct mmc_ops *ops;
-	uint b_max;
 	char op_cond_pending;	/* 1 if we are waiting on an op_cond command */
 	char init_in_progress;	/* 1 if we have done mmc_start_init() */
 	char preinit;		/* start init as early as possible */
@@ -304,6 +310,8 @@
 };
 
 int mmc_register(struct mmc *mmc);
+struct mmc *mmc_create(const struct mmc_config *cfg, void *priv);
+void mmc_destroy(struct mmc *mmc);
 int mmc_initialize(bd_t *bis);
 int mmc_init(struct mmc *mmc);
 int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size);
@@ -352,7 +360,7 @@
 
 #ifdef CONFIG_GENERIC_MMC
 #ifdef CONFIG_MMC_SPI
-#define mmc_host_is_spi(mmc)	((mmc)->host_caps & MMC_MODE_SPI)
+#define mmc_host_is_spi(mmc)	((mmc)->cfg.host_caps & MMC_MODE_SPI)
 #else
 #define mmc_host_is_spi(mmc)	0
 #endif
@@ -361,4 +369,9 @@
 int mmc_legacy_init(int verbose);
 #endif
 
+/* Set block count limit because of 16 bit register limit on some hardware*/
+#ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT
+#define CONFIG_SYS_MMC_MAX_BLK_COUNT 65535
+#endif
+
 #endif /* _MMC_H_ */
diff --git a/include/sdhci.h b/include/sdhci.h
index 74d06ae..2c480d0 100644
--- a/include/sdhci.h
+++ b/include/sdhci.h
@@ -247,6 +247,8 @@
 	void (*set_control_reg)(struct sdhci_host *host);
 	void (*set_clock)(int dev_index, unsigned int div);
 	uint	voltages;
+
+	struct mmc_config cfg;
 };
 
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS