[U-Boot] [PATCH v2 0/4] mmc: Implement central card-detection.

This series of patches implements central card-detection within the MMC framework. Before this patch series, many boards actually did implement the board_mmc_getcd() function, but it wasn't used except by one driver (fsl_esdhc). Unfortunately, implementations interpreted the meaning of the cd parameter differently, some taking it to signal card absence and others using it to detect card presence. Furthermore, the signature of the board_mmc_getcd() function was not at all consistent with other MMC related functions.
The first patch in this series therefore changes the board_mmc_getcd() function signature and consolidates all current implementations. The second patch adds a central card-detection implementation within the MMC framework by using the new board_mmc_getcd() function and adds a hook that can be provided by drivers to serve as a default card-detect mechanism if no board-specific implementation is provided. The third and fourth patches implement this driver hook for the fsl_esdhc and the tegra2 MMC drivers.
For reference, the following email thread contains the discussion that led to this patch series:
http://lists.denx.de/pipermail/u-boot/2011-November/110180.html
Changes in v2: - add a better rationale for the series and a reference to the email thread that started it - add an explanation to patch 3 why the call to board_mmc_getcd() is removed from the fsl_esdhc driver - add a cover letter which explains the series' goal
Thierry Reding (4): mmc: Change board_mmc_getcd() signature. mmc: Implement card detection. mmc: fsl_esdhc: Implement card-detect hook. mmc: tegra2: Implement card-detect hook.
board/efikamx/efikamx.c | 8 +++----- board/emk/top9000/top9000.c | 12 ++---------- board/freescale/mx51evk/mx51evk.c | 8 +++----- board/freescale/mx53ard/mx53ard.c | 8 +++----- board/freescale/mx53evk/mx53evk.c | 8 +++----- board/freescale/mx53loco/mx53loco.c | 8 +++----- board/freescale/mx53smd/mx53smd.c | 6 ++---- doc/README.atmel_mci | 12 ++---------- drivers/mmc/arm_pl180_mmci.c | 1 + drivers/mmc/bfin_sdh.c | 1 + drivers/mmc/davinci_mmc.c | 1 + drivers/mmc/fsl_esdhc.c | 27 ++++++++++++--------------- drivers/mmc/ftsdc010_esdhc.c | 1 + drivers/mmc/gen_atmel_mci.c | 1 + drivers/mmc/mmc.c | 22 ++++++++++++++++++++-- drivers/mmc/mmc_spi.c | 1 + drivers/mmc/mxcmmc.c | 1 + drivers/mmc/mxsmmc.c | 1 + drivers/mmc/omap_hsmmc.c | 1 + drivers/mmc/pxa_mmc_gen.c | 1 + drivers/mmc/s5p_mmc.c | 1 + drivers/mmc/sdhci.c | 1 + drivers/mmc/sh_mmcif.c | 1 + drivers/mmc/tegra2_mmc.c | 28 +++++++++++++--------------- include/mmc.h | 4 +++- 25 files changed, 82 insertions(+), 82 deletions(-)

The new API no longer uses the extra cd parameter that was used to store the card presence state. Instead, this information is returned via the function's return value. board_mmc_getcd() returns -1 to indicate that no card-detection mechanism is implemented; 0 indicates that no card is present and 1 is returned if it was detected that a card is present.
The rationale for this change can be found in the following email thread:
http://lists.denx.de/pipermail/u-boot/2011-November/110180.html
In summary, the old API was not consistent with the rest of the MMC API which always passes a struct mmc as the first parameter. Furthermore the cd parameter was used to mean "card absence" in some implementations and "card presence" in others.
Signed-off-by: Thierry Reding thierry.reding@avionic-design.de --- board/efikamx/efikamx.c | 8 +++----- board/emk/top9000/top9000.c | 12 ++---------- board/freescale/mx51evk/mx51evk.c | 8 +++----- board/freescale/mx53ard/mx53ard.c | 8 +++----- board/freescale/mx53evk/mx53evk.c | 8 +++----- board/freescale/mx53loco/mx53loco.c | 8 +++----- board/freescale/mx53smd/mx53smd.c | 6 ++---- doc/README.atmel_mci | 12 ++---------- drivers/mmc/fsl_esdhc.c | 8 +++++--- drivers/mmc/mmc.c | 4 ++-- include/mmc.h | 2 +- 11 files changed, 29 insertions(+), 55 deletions(-)
diff --git a/board/efikamx/efikamx.c b/board/efikamx/efikamx.c index b78bf6c..451d709 100644 --- a/board/efikamx/efikamx.c +++ b/board/efikamx/efikamx.c @@ -309,17 +309,15 @@ static inline uint32_t efika_mmc_cd(void) return MX51_PIN_EIM_CS2; }
-int board_mmc_getcd(u8 *absent, struct mmc *mmc) +int board_mmc_getcd(struct mmc *mmc) { struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; uint32_t cd = efika_mmc_cd();
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR) - *absent = gpio_get_value(IOMUX_TO_GPIO(cd)); - else - *absent = gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_8)); + return !gpio_get_value(IOMUX_TO_GPIO(cd));
- return 0; + return !gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_8)); }
int board_mmc_init(bd_t *bis) diff --git a/board/emk/top9000/top9000.c b/board/emk/top9000/top9000.c index 61dee62..d156e32 100644 --- a/board/emk/top9000/top9000.c +++ b/board/emk/top9000/top9000.c @@ -108,17 +108,9 @@ int board_mmc_init(bd_t *bd) }
/* this is a weak define that we are overriding */ -int board_mmc_getcd(u8 *cd, struct mmc *mmc) +int board_mmc_getcd(struct mmc *mmc) { - /* - * the only currently existing use of this function - * (fsl_esdhc.c) suggests this function must return - * *cs = TRUE if a card is NOT detected -> in most - * cases the value of the pin when the detect switch - * closes to GND - */ - *cd = at91_get_gpio_value(CONFIG_SYS_MMC_CD_PIN) ? 1 : 0; - return 0; + return !at91_get_gpio_value(CONFIG_SYS_MMC_CD_PIN); }
#endif diff --git a/board/freescale/mx51evk/mx51evk.c b/board/freescale/mx51evk/mx51evk.c index 37e6e4d..bc03496 100644 --- a/board/freescale/mx51evk/mx51evk.c +++ b/board/freescale/mx51evk/mx51evk.c @@ -261,16 +261,14 @@ static void power_init(void) }
#ifdef CONFIG_FSL_ESDHC -int board_mmc_getcd(u8 *cd, struct mmc *mmc) +int board_mmc_getcd(struct mmc *mmc) { struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR) - *cd = gpio_get_value(0); - else - *cd = gpio_get_value(6); + return !gpio_get_value(0);
- return 0; + return !gpio_get_value(6); }
int board_mmc_init(bd_t *bis) diff --git a/board/freescale/mx53ard/mx53ard.c b/board/freescale/mx53ard/mx53ard.c index be32aee..786770a 100644 --- a/board/freescale/mx53ard/mx53ard.c +++ b/board/freescale/mx53ard/mx53ard.c @@ -83,16 +83,14 @@ struct fsl_esdhc_cfg esdhc_cfg[2] = { {MMC_SDHC2_BASE_ADDR, 1 }, };
-int board_mmc_getcd(u8 *cd, struct mmc *mmc) +int board_mmc_getcd(struct mmc *mmc) { struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR) - *cd = gpio_get_value(1); /*GPIO1_1*/ - else - *cd = gpio_get_value(4); /*GPIO1_4*/ + return !gpio_get_value(1); /*GPIO1_1*/
- return 0; + return !gpio_get_value(4); /*GPIO1_4*/ }
int board_mmc_init(bd_t *bis) diff --git a/board/freescale/mx53evk/mx53evk.c b/board/freescale/mx53evk/mx53evk.c index 335661f..a4cd983 100644 --- a/board/freescale/mx53evk/mx53evk.c +++ b/board/freescale/mx53evk/mx53evk.c @@ -208,16 +208,14 @@ struct fsl_esdhc_cfg esdhc_cfg[2] = { {MMC_SDHC3_BASE_ADDR, 1}, };
-int board_mmc_getcd(u8 *cd, struct mmc *mmc) +int board_mmc_getcd(struct mmc *mmc) { struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR) - *cd = gpio_get_value(77); /*GPIO3_13*/ - else - *cd = gpio_get_value(75); /*GPIO3_11*/ + return !gpio_get_value(77); /*GPIO3_13*/
- return 0; + return !gpio_get_value(75); /*GPIO3_11*/ }
int board_mmc_init(bd_t *bis) diff --git a/board/freescale/mx53loco/mx53loco.c b/board/freescale/mx53loco/mx53loco.c index b4c7f33..a0fe5fd 100644 --- a/board/freescale/mx53loco/mx53loco.c +++ b/board/freescale/mx53loco/mx53loco.c @@ -136,16 +136,14 @@ struct fsl_esdhc_cfg esdhc_cfg[2] = { {MMC_SDHC3_BASE_ADDR, 1}, };
-int board_mmc_getcd(u8 *cd, struct mmc *mmc) +int board_mmc_getcd(struct mmc *mmc) { struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR) - *cd = gpio_get_value(77); /*GPIO3_13*/ - else - *cd = gpio_get_value(75); /*GPIO3_11*/ + return !gpio_get_value(77); /*GPIO3_13*/
- return 0; + return !gpio_get_value(75); /*GPIO3_11*/ }
int board_mmc_init(bd_t *bis) diff --git a/board/freescale/mx53smd/mx53smd.c b/board/freescale/mx53smd/mx53smd.c index 87fa7fa..39274f9 100644 --- a/board/freescale/mx53smd/mx53smd.c +++ b/board/freescale/mx53smd/mx53smd.c @@ -132,11 +132,9 @@ struct fsl_esdhc_cfg esdhc_cfg[1] = { {MMC_SDHC1_BASE_ADDR, 1}, };
-int board_mmc_getcd(u8 *cd, struct mmc *mmc) +int board_mmc_getcd(struct mmc *mmc) { - *cd = gpio_get_value(77); /*GPIO3_13*/ - - return 0; + return !gpio_get_value(77); /*GPIO3_13*/ }
int board_mmc_init(bd_t *bis) diff --git a/doc/README.atmel_mci b/doc/README.atmel_mci index dee0cf0..0cbd909 100644 --- a/doc/README.atmel_mci +++ b/doc/README.atmel_mci @@ -59,17 +59,9 @@ int board_mmc_init(bd_t *bd) }
/* this is a weak define that we are overriding */ -int board_mmc_getcd(u8 *cd, struct mmc *mmc) +int board_mmc_getcd(struct mmc *mmc) { - /* - * the only currently existing use of this function - * (fsl_esdhc.c) suggests this function must return - * *cs = TRUE if a card is NOT detected -> in most - * cases the value of the pin when the detect switch - * closes to GND - */ - *cd = at91_get_gpio_value (CONFIG_SYS_MMC_CD_PIN) ? 1 : 0; - return 0; + return !at91_get_gpio_value(CONFIG_SYS_MMC_CD_PIN); }
#endif diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index ec953f0..f719afd 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -413,7 +413,6 @@ static int esdhc_init(struct mmc *mmc) struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; int timeout = 1000; int ret = 0; - u8 card_absent;
/* Reset the entire host controller */ esdhc_write32(®s->sysctl, SYSCTL_RSTA); @@ -441,7 +440,8 @@ static int esdhc_init(struct mmc *mmc) esdhc_clrsetbits32(®s->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
/* Check if there is a callback for detecting the card */ - if (board_mmc_getcd(&card_absent, mmc)) { + ret = board_mmc_getcd(mmc); + if (ret < 0) { timeout = 1000; while (!(esdhc_read32(®s->prsstat) & PRSSTAT_CINS) && --timeout) @@ -450,8 +450,10 @@ static int esdhc_init(struct mmc *mmc) if (timeout <= 0) ret = NO_CARD_ERR; } else { - if (card_absent) + if (ret == 0) ret = NO_CARD_ERR; + else + ret = 0; }
return ret; diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 37ce6e8..936259f 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -40,11 +40,11 @@ static struct list_head mmc_devices; static int cur_dev_num = -1;
-int __board_mmc_getcd(u8 *cd, struct mmc *mmc) { +int __board_mmc_getcd(struct mmc *mmc) { return -1; }
-int board_mmc_getcd(u8 *cd, struct mmc *mmc)__attribute__((weak, +int board_mmc_getcd(struct mmc *mmc)__attribute__((weak, alias("__board_mmc_getcd")));
int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) diff --git a/include/mmc.h b/include/mmc.h index 015a7f3..a850174 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -314,7 +314,7 @@ struct mmc *find_mmc_device(int dev_num); int mmc_set_dev(int dev_num); void print_mmc_devices(char separator); int get_mmc_num(void); -int board_mmc_getcd(u8 *cd, struct mmc *mmc); +int board_mmc_getcd(struct mmc *mmc); int mmc_switch_part(int dev_num, unsigned int part_num);
#ifdef CONFIG_GENERIC_MMC

By "signature" you mean signedness ?
The new API no longer uses the extra cd parameter that was used to store the card presence state. Instead, this information is returned via the function's return value. board_mmc_getcd() returns -1 to indicate that no card-detection mechanism is implemented; 0 indicates that no card is present and 1 is returned if it was detected that a card is present.
The rationale for this change can be found in the following email thread:
http://lists.denx.de/pipermail/u-boot/2011-November/110180.html
In summary, the old API was not consistent with the rest of the MMC API which always passes a struct mmc as the first parameter. Furthermore the cd parameter was used to mean "card absence" in some implementations and "card presence" in others.
Signed-off-by: Thierry Reding thierry.reding@avionic-design.de
board/efikamx/efikamx.c | 8 +++----- board/emk/top9000/top9000.c | 12 ++---------- board/freescale/mx51evk/mx51evk.c | 8 +++----- board/freescale/mx53ard/mx53ard.c | 8 +++----- board/freescale/mx53evk/mx53evk.c | 8 +++----- board/freescale/mx53loco/mx53loco.c | 8 +++----- board/freescale/mx53smd/mx53smd.c | 6 ++---- doc/README.atmel_mci | 12 ++---------- drivers/mmc/fsl_esdhc.c | 8 +++++--- drivers/mmc/mmc.c | 4 ++-- include/mmc.h | 2 +- 11 files changed, 29 insertions(+), 55 deletions(-)
diff --git a/board/efikamx/efikamx.c b/board/efikamx/efikamx.c index b78bf6c..451d709 100644 --- a/board/efikamx/efikamx.c +++ b/board/efikamx/efikamx.c @@ -309,17 +309,15 @@ static inline uint32_t efika_mmc_cd(void) return MX51_PIN_EIM_CS2; }
-int board_mmc_getcd(u8 *absent, struct mmc *mmc) +int board_mmc_getcd(struct mmc *mmc) { struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; uint32_t cd = efika_mmc_cd();
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
*absent = gpio_get_value(IOMUX_TO_GPIO(cd));
- else
*absent = gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_8));
return !gpio_get_value(IOMUX_TO_GPIO(cd));
- return 0;
- return !gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_8));
int ret;
if (cfg->...) ret = ... else ret = ...
return ret;
}
int board_mmc_init(bd_t *bis) diff --git a/board/emk/top9000/top9000.c b/board/emk/top9000/top9000.c index 61dee62..d156e32 100644 --- a/board/emk/top9000/top9000.c +++ b/board/emk/top9000/top9000.c @@ -108,17 +108,9 @@ int board_mmc_init(bd_t *bd) }
/* this is a weak define that we are overriding */ -int board_mmc_getcd(u8 *cd, struct mmc *mmc) +int board_mmc_getcd(struct mmc *mmc) {
- /*
* the only currently existing use of this function
* (fsl_esdhc.c) suggests this function must return
* *cs = TRUE if a card is NOT detected -> in most
* cases the value of the pin when the detect switch
* closes to GND
*/
- *cd = at91_get_gpio_value(CONFIG_SYS_MMC_CD_PIN) ? 1 : 0;
- return 0;
- return !at91_get_gpio_value(CONFIG_SYS_MMC_CD_PIN);
}
#endif diff --git a/board/freescale/mx51evk/mx51evk.c b/board/freescale/mx51evk/mx51evk.c index 37e6e4d..bc03496 100644 --- a/board/freescale/mx51evk/mx51evk.c +++ b/board/freescale/mx51evk/mx51evk.c @@ -261,16 +261,14 @@ static void power_init(void) }
#ifdef CONFIG_FSL_ESDHC -int board_mmc_getcd(u8 *cd, struct mmc *mmc) +int board_mmc_getcd(struct mmc *mmc) { struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
*cd = gpio_get_value(0);
- else
*cd = gpio_get_value(6);
return !gpio_get_value(0);
- return 0;
- return !gpio_get_value(6);
DTTO
}
int board_mmc_init(bd_t *bis) diff --git a/board/freescale/mx53ard/mx53ard.c b/board/freescale/mx53ard/mx53ard.c index be32aee..786770a 100644 --- a/board/freescale/mx53ard/mx53ard.c +++ b/board/freescale/mx53ard/mx53ard.c @@ -83,16 +83,14 @@ struct fsl_esdhc_cfg esdhc_cfg[2] = { {MMC_SDHC2_BASE_ADDR, 1 }, };
-int board_mmc_getcd(u8 *cd, struct mmc *mmc) +int board_mmc_getcd(struct mmc *mmc) { struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
*cd = gpio_get_value(1); /*GPIO1_1*/
- else
*cd = gpio_get_value(4); /*GPIO1_4*/
return !gpio_get_value(1); /*GPIO1_1*/
- return 0;
- return !gpio_get_value(4); /*GPIO1_4*/
DTTO here please, also add spaces into the comment ... /* GPIO1_4 */
}
int board_mmc_init(bd_t *bis) diff --git a/board/freescale/mx53evk/mx53evk.c b/board/freescale/mx53evk/mx53evk.c index 335661f..a4cd983 100644 --- a/board/freescale/mx53evk/mx53evk.c +++ b/board/freescale/mx53evk/mx53evk.c @@ -208,16 +208,14 @@ struct fsl_esdhc_cfg esdhc_cfg[2] = { {MMC_SDHC3_BASE_ADDR, 1}, };
-int board_mmc_getcd(u8 *cd, struct mmc *mmc) +int board_mmc_getcd(struct mmc *mmc) { struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
*cd = gpio_get_value(77); /*GPIO3_13*/
- else
*cd = gpio_get_value(75); /*GPIO3_11*/
return !gpio_get_value(77); /*GPIO3_13*/
- return 0;
- return !gpio_get_value(75); /*GPIO3_11*/
DTTO
}
int board_mmc_init(bd_t *bis) diff --git a/board/freescale/mx53loco/mx53loco.c b/board/freescale/mx53loco/mx53loco.c index b4c7f33..a0fe5fd 100644 --- a/board/freescale/mx53loco/mx53loco.c +++ b/board/freescale/mx53loco/mx53loco.c @@ -136,16 +136,14 @@ struct fsl_esdhc_cfg esdhc_cfg[2] = { {MMC_SDHC3_BASE_ADDR, 1}, };
-int board_mmc_getcd(u8 *cd, struct mmc *mmc) +int board_mmc_getcd(struct mmc *mmc) { struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
*cd = gpio_get_value(77); /*GPIO3_13*/
- else
*cd = gpio_get_value(75); /*GPIO3_11*/
return !gpio_get_value(77); /*GPIO3_13*/
- return 0;
- return !gpio_get_value(75); /*GPIO3_11*/
}
int board_mmc_init(bd_t *bis) diff --git a/board/freescale/mx53smd/mx53smd.c b/board/freescale/mx53smd/mx53smd.c index 87fa7fa..39274f9 100644 --- a/board/freescale/mx53smd/mx53smd.c +++ b/board/freescale/mx53smd/mx53smd.c @@ -132,11 +132,9 @@ struct fsl_esdhc_cfg esdhc_cfg[1] = { {MMC_SDHC1_BASE_ADDR, 1}, };
-int board_mmc_getcd(u8 *cd, struct mmc *mmc) +int board_mmc_getcd(struct mmc *mmc) {
- *cd = gpio_get_value(77); /*GPIO3_13*/
- return 0;
- return !gpio_get_value(77); /*GPIO3_13*/
}
int board_mmc_init(bd_t *bis) diff --git a/doc/README.atmel_mci b/doc/README.atmel_mci index dee0cf0..0cbd909 100644 --- a/doc/README.atmel_mci +++ b/doc/README.atmel_mci @@ -59,17 +59,9 @@ int board_mmc_init(bd_t *bd) }
/* this is a weak define that we are overriding */ -int board_mmc_getcd(u8 *cd, struct mmc *mmc) +int board_mmc_getcd(struct mmc *mmc) {
- /*
* the only currently existing use of this function
* (fsl_esdhc.c) suggests this function must return
* *cs = TRUE if a card is NOT detected -> in most
* cases the value of the pin when the detect switch
* closes to GND
*/
- *cd = at91_get_gpio_value (CONFIG_SYS_MMC_CD_PIN) ? 1 : 0;
- return 0;
- return !at91_get_gpio_value(CONFIG_SYS_MMC_CD_PIN);
}
#endif diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index ec953f0..f719afd 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -413,7 +413,6 @@ static int esdhc_init(struct mmc *mmc) struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; int timeout = 1000; int ret = 0;
u8 card_absent;
/* Reset the entire host controller */ esdhc_write32(®s->sysctl, SYSCTL_RSTA);
@@ -441,7 +440,8 @@ static int esdhc_init(struct mmc *mmc) esdhc_clrsetbits32(®s->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
/* Check if there is a callback for detecting the card */
- if (board_mmc_getcd(&card_absent, mmc)) {
- ret = board_mmc_getcd(mmc);
- if (ret < 0) { timeout = 1000; while (!(esdhc_read32(®s->prsstat) & PRSSTAT_CINS) && --timeout)
@@ -450,8 +450,10 @@ static int esdhc_init(struct mmc *mmc) if (timeout <= 0) ret = NO_CARD_ERR; } else {
if (card_absent)
if (ret == 0) ret = NO_CARD_ERR;
else
ret = 0;
}
return ret;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 37ce6e8..936259f 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -40,11 +40,11 @@ static struct list_head mmc_devices; static int cur_dev_num = -1;
-int __board_mmc_getcd(u8 *cd, struct mmc *mmc) { +int __board_mmc_getcd(struct mmc *mmc) { return -1; }
-int board_mmc_getcd(u8 *cd, struct mmc *mmc)__attribute__((weak, +int board_mmc_getcd(struct mmc *mmc)__attribute__((weak, alias("__board_mmc_getcd")));
int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) diff --git a/include/mmc.h b/include/mmc.h index 015a7f3..a850174 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -314,7 +314,7 @@ struct mmc *find_mmc_device(int dev_num); int mmc_set_dev(int dev_num); void print_mmc_devices(char separator); int get_mmc_num(void); -int board_mmc_getcd(u8 *cd, struct mmc *mmc); +int board_mmc_getcd(struct mmc *mmc); int mmc_switch_part(int dev_num, unsigned int part_num);
#ifdef CONFIG_GENERIC_MMC
M

* Marek Vasut wrote:
By "signature" you mean signedness ?
No, I mean "signature" as synonymous to "function prototype".
[...]
-int board_mmc_getcd(u8 *absent, struct mmc *mmc) +int board_mmc_getcd(struct mmc *mmc) { struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; uint32_t cd = efika_mmc_cd();
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
*absent = gpio_get_value(IOMUX_TO_GPIO(cd));
- else
*absent = gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_8));
return !gpio_get_value(IOMUX_TO_GPIO(cd));
- return 0;
- return !gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_8));
int ret;
if (cfg->...) ret = ... else ret = ...
return ret;
That'll require an extra variable and will actually be longer. I don't see any advantage in converting it.
DTTO here please, also add spaces into the comment ... /* GPIO1_4 */
I was going to keep that as it was, but I guess since I'm already changing the line I can as well clean it up.
Thierry

- Marek Vasut wrote:
By "signature" you mean signedness ?
No, I mean "signature" as synonymous to "function prototype".
Please say so then, it was slightly confusing.
[...]
-int board_mmc_getcd(u8 *absent, struct mmc *mmc) +int board_mmc_getcd(struct mmc *mmc)
{
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; uint32_t cd = efika_mmc_cd();
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
*absent = gpio_get_value(IOMUX_TO_GPIO(cd));
- else
*absent = gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_8));
return !gpio_get_value(IOMUX_TO_GPIO(cd));
- return 0;
- return !gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_8));
int ret;
if (cfg->...)
ret = ...
else
ret = ...
return ret;
That'll require an extra variable and will actually be longer. I don't see any advantage in converting it.
It's slightly more readable IMO, but that's a matter of personal taste so I'd like others to comment on this one.
DTTO here please, also add spaces into the comment ... /* GPIO1_4 */
I was going to keep that as it was, but I guess since I'm already changing the line I can as well clean it up.
Thierry
Thanks!
M

Check for card detect each time an MMC/SD device is initialized. If card detection is not implemented, this code behaves as before and continues assuming a card is present. If no card is detected, has_init is reset for the MMC/SD device (to force initialization next time) and an error is returned.
Signed-off-by: Thierry Reding thierry.reding@avionic-design.de --- drivers/mmc/arm_pl180_mmci.c | 1 + drivers/mmc/bfin_sdh.c | 1 + drivers/mmc/davinci_mmc.c | 1 + drivers/mmc/ftsdc010_esdhc.c | 1 + drivers/mmc/gen_atmel_mci.c | 1 + drivers/mmc/mmc.c | 18 ++++++++++++++++++ drivers/mmc/mmc_spi.c | 1 + drivers/mmc/mxcmmc.c | 1 + drivers/mmc/mxsmmc.c | 1 + drivers/mmc/omap_hsmmc.c | 1 + drivers/mmc/pxa_mmc_gen.c | 1 + drivers/mmc/s5p_mmc.c | 1 + drivers/mmc/sdhci.c | 1 + drivers/mmc/sh_mmcif.c | 1 + include/mmc.h | 2 ++ 15 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index e6467a2..09d443e 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -385,6 +385,7 @@ static int arm_pl180_mmci_host_init(struct mmc *dev) dev->send_cmd = host_request; dev->set_ios = host_set_ios; dev->init = mmc_host_reset; + dev->getcd = NULL; dev->host_caps = 0; dev->voltages = VOLTAGE_WINDOW_MMC; dev->f_min = dev->clock; diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c index bc9057f..08fc5c1 100644 --- a/drivers/mmc/bfin_sdh.c +++ b/drivers/mmc/bfin_sdh.c @@ -250,6 +250,7 @@ int bfin_mmc_init(bd_t *bis) mmc->send_cmd = bfin_sdh_request; mmc->set_ios = bfin_sdh_set_ios; mmc->init = bfin_sdh_init; + mmc->getcd = NULL; mmc->host_caps = MMC_MODE_4BIT;
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c index ce96736..ee8f261 100644 --- a/drivers/mmc/davinci_mmc.c +++ b/drivers/mmc/davinci_mmc.c @@ -387,6 +387,7 @@ int davinci_mmc_init(bd_t *bis, struct davinci_mmc *host) mmc->send_cmd = dmmc_send_cmd; mmc->set_ios = dmmc_set_ios; mmc->init = dmmc_init; + mmc->getcd = NULL;
mmc->f_min = 200000; mmc->f_max = 25000000; diff --git a/drivers/mmc/ftsdc010_esdhc.c b/drivers/mmc/ftsdc010_esdhc.c index e38dd87..0eb7196 100644 --- a/drivers/mmc/ftsdc010_esdhc.c +++ b/drivers/mmc/ftsdc010_esdhc.c @@ -645,6 +645,7 @@ int ftsdc010_mmc_init(int dev_index) mmc->send_cmd = ftsdc010_request; mmc->set_ios = ftsdc010_set_ios; mmc->init = ftsdc010_core_init; + mmc->getcd = NULL;
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index f346b24..4968c5e 100644 --- a/drivers/mmc/gen_atmel_mci.c +++ b/drivers/mmc/gen_atmel_mci.c @@ -337,6 +337,7 @@ int atmel_mci_init(void *regs) mmc->send_cmd = mci_send_cmd; mmc->set_ios = mci_set_ios; mmc->init = mci_init; + mmc->getcd = NULL;
/* need to be able to pass these in on a board by board basis */ mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 936259f..cf06d05 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -674,6 +674,18 @@ int mmc_switch_part(int dev_num, unsigned int part_num) | (part_num & PART_ACCESS_MASK)); }
+int mmc_getcd(struct mmc *mmc) +{ + int cd; + + cd = board_mmc_getcd(mmc); + + if ((cd < 0) && mmc->getcd) + cd = mmc->getcd(mmc); + + return cd; +} + int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp) { struct mmc_cmd cmd; @@ -1192,6 +1204,12 @@ int mmc_init(struct mmc *mmc) { int err, retry = 3;
+ if (mmc_getcd(mmc) == 0) { + mmc->has_init = 0; + printf("MMC: no card present\n"); + return NO_CARD_ERR; + } + if (mmc->has_init) return 0;
diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c index 49fb9e0..de43a85 100644 --- a/drivers/mmc/mmc_spi.c +++ b/drivers/mmc/mmc_spi.c @@ -272,6 +272,7 @@ struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode) mmc->send_cmd = mmc_spi_request; mmc->set_ios = mmc_spi_set_ios; mmc->init = mmc_spi_init_p; + mmc->getcd = NULL; mmc->host_caps = MMC_MODE_SPI;
mmc->voltages = MMC_SPI_VOLTAGE; diff --git a/drivers/mmc/mxcmmc.c b/drivers/mmc/mxcmmc.c index ab1fc82..8afb221 100644 --- a/drivers/mmc/mxcmmc.c +++ b/drivers/mmc/mxcmmc.c @@ -500,6 +500,7 @@ static int mxcmci_initialize(bd_t *bis) mmc->send_cmd = mxcmci_request; mmc->set_ios = mxcmci_set_ios; mmc->init = mxcmci_init; + mmc->getcd = NULL; mmc->host_caps = MMC_MODE_4BIT;
host->base = (struct mxcmci_regs *)CONFIG_MXC_MCI_REGS_BASE; diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c index 2a9949e..5f87a1e 100644 --- a/drivers/mmc/mxsmmc.c +++ b/drivers/mmc/mxsmmc.c @@ -329,6 +329,7 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int)) mmc->send_cmd = mxsmmc_send_cmd; mmc->set_ios = mxsmmc_set_ios; mmc->init = mxsmmc_init; + mmc->getcd = NULL; mmc->priv = priv;
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index c38b9e6..ef64e37 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -472,6 +472,7 @@ int omap_mmc_init(int dev_index) mmc->send_cmd = mmc_send_cmd; mmc->set_ios = mmc_set_ios; mmc->init = mmc_init_setup; + mmc->getcd = NULL;
switch (dev_index) { case 0: diff --git a/drivers/mmc/pxa_mmc_gen.c b/drivers/mmc/pxa_mmc_gen.c index 28e37b4..979e0da 100644 --- a/drivers/mmc/pxa_mmc_gen.c +++ b/drivers/mmc/pxa_mmc_gen.c @@ -411,6 +411,7 @@ int pxa_mmc_register(int card_index) mmc->send_cmd = pxa_mmc_request; mmc->set_ios = pxa_mmc_set_ios; mmc->init = pxa_mmc_init; + mmc->getcd = NULL;
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; mmc->f_max = PXAMMC_MAX_SPEED; diff --git a/drivers/mmc/s5p_mmc.c b/drivers/mmc/s5p_mmc.c index 7786ecf..4ae3aaf 100644 --- a/drivers/mmc/s5p_mmc.c +++ b/drivers/mmc/s5p_mmc.c @@ -463,6 +463,7 @@ static int s5p_mmc_initialize(int dev_index, int bus_width) mmc->send_cmd = mmc_send_cmd; mmc->set_ios = mmc_set_ios; mmc->init = mmc_core_init; + mmc->getcd = NULL;
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; if (bus_width == 8) diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index fce0ef0..fc904b5 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -390,6 +390,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) mmc->send_cmd = sdhci_send_command; mmc->set_ios = sdhci_set_ios; mmc->init = sdhci_init; + mmc->getcd = NULL;
caps = sdhci_readl(host, SDHCI_CAPABILITIES); #ifdef CONFIG_MMC_SDMA diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c index 567e2cb..2835e24 100644 --- a/drivers/mmc/sh_mmcif.c +++ b/drivers/mmc/sh_mmcif.c @@ -598,6 +598,7 @@ int mmcif_mmc_init(void) mmc->send_cmd = sh_mmcif_request; mmc->set_ios = sh_mmcif_set_ios; mmc->init = sh_mmcif_init; + mmc->getcd = NULL; host->regs = (struct sh_mmcif_regs *)CONFIG_SH_MMCIF_ADDR; host->clk = CONFIG_SH_MMCIF_CLK; mmc->priv = host; diff --git a/include/mmc.h b/include/mmc.h index a850174..8744604 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -302,6 +302,7 @@ struct mmc { struct mmc_cmd *cmd, struct mmc_data *data); void (*set_ios)(struct mmc *mmc); int (*init)(struct mmc *mmc); + int (*getcd)(struct mmc *mmc); uint b_max; };
@@ -316,6 +317,7 @@ void print_mmc_devices(char separator); int get_mmc_num(void); int board_mmc_getcd(struct mmc *mmc); int mmc_switch_part(int dev_num, unsigned int part_num); +int mmc_getcd(struct mmc *mmc);
#ifdef CONFIG_GENERIC_MMC int atmel_mci_init(void *regs);

This card-detect hook probably doesn't work. Perhaps somebody with more knowledge about the hardware can comment on this. I think that perhaps even the complete code from esdhc_init() could go into the getcd() function instead or mmc_getcd() needs to be called at some later time after mmc_init(), which, however, would require many other drivers to change.
In addition to implementing the hook, this patch also removes the call to the board_mmc_getcd() function which is now called from the MMC framework and is no longer required here.
Signed-off-by: Thierry Reding thierry.reding@avionic-design.de --- drivers/mmc/fsl_esdhc.c | 29 ++++++++++++----------------- 1 files changed, 12 insertions(+), 17 deletions(-)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index f719afd..b46bf9f 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -412,7 +412,6 @@ static int esdhc_init(struct mmc *mmc) struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; int timeout = 1000; - int ret = 0;
/* Reset the entire host controller */ esdhc_write32(®s->sysctl, SYSCTL_RSTA); @@ -439,24 +438,19 @@ static int esdhc_init(struct mmc *mmc) /* Set timout to the maximum value */ esdhc_clrsetbits32(®s->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
- /* Check if there is a callback for detecting the card */ - ret = board_mmc_getcd(mmc); - if (ret < 0) { - timeout = 1000; - while (!(esdhc_read32(®s->prsstat) & PRSSTAT_CINS) && - --timeout) - udelay(1000); + return 0; +}
- if (timeout <= 0) - ret = NO_CARD_ERR; - } else { - if (ret == 0) - ret = NO_CARD_ERR; - else - ret = 0; - } +static int esdhc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; + int timeout = 1000; + + while (!(esdhc_read32(®s->prsstat) & PRSSTAT_CINS) && --timeout) + udelay(1000);
- return ret; + return timeout > 0; }
static void esdhc_reset(struct fsl_esdhc *regs) @@ -494,6 +488,7 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) mmc->send_cmd = esdhc_send_cmd; mmc->set_ios = esdhc_set_ios; mmc->init = esdhc_init; + mmc->getcd = esdhc_getcd;
voltage_caps = 0; caps = regs->hostcapblt;

On Tegra2, card-detection is implemented by passing the card-detection GPIOs to the MMC driver at initialization time. Instead of implementing the board_mmc_getcd() function, use the card-detect hook and allow boards to override it by providing their own board_mmc_getcd() implementation.
Signed-off-by: Thierry Reding thierry.reding@avionic-design.de --- drivers/mmc/tegra2_mmc.c | 28 +++++++++++++--------------- 1 files changed, 13 insertions(+), 15 deletions(-)
diff --git a/drivers/mmc/tegra2_mmc.c b/drivers/mmc/tegra2_mmc.c index fe562ed..5b4c9f6 100644 --- a/drivers/mmc/tegra2_mmc.c +++ b/drivers/mmc/tegra2_mmc.c @@ -474,6 +474,18 @@ static int mmc_core_init(struct mmc *mmc) return 0; }
+int tegra2_mmc_getcd(struct mmc *mmc) +{ + struct mmc_host *host = (struct mmc_host *)mmc->priv; + + debug("tegra2_mmc_getcd called\n"); + + if (host->cd_gpio >= 0) + return !gpio_get_value(host->cd_gpio); + + return 1; +} + int tegra2_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio) { struct mmc_host *host; @@ -512,6 +524,7 @@ int tegra2_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio) mmc->send_cmd = mmc_send_cmd; mmc->set_ios = mmc_set_ios; mmc->init = mmc_core_init; + mmc->getcd = tegra2_mmc_getcd;
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; if (bus_width == 8) @@ -535,18 +548,3 @@ int tegra2_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio)
return 0; } - -/* this is a weak define that we are overriding */ -int board_mmc_getcd(u8 *cd, struct mmc *mmc) -{ - struct mmc_host *host = (struct mmc_host *)mmc->priv; - - debug("board_mmc_getcd called\n"); - - if (host->cd_gpio >= 0) - *cd = !gpio_get_value(host->cd_gpio); - else - *cd = 1; - - return 0; -}
participants (2)
-
Marek Vasut
-
Thierry Reding