diff --git a/drivers/mci/atmel_mci.c b/drivers/mci/atmel_mci.c index 9de079d..dbfb53c 100644 --- a/drivers/mci/atmel_mci.c +++ b/drivers/mci/atmel_mci.c @@ -355,18 +355,25 @@ return 0; } +static int atmci_card_present(struct mci_host *mci) +{ + struct atmel_mci *host = to_mci_host(mci); + struct atmel_mci_platform_data *pd = host->hw_dev->platform_data; + int ret; + + /* No gpio, assume card is present */ + if (!gpio_is_valid(pd->detect_pin)) + return 1; + + ret = gpio_get_value(pd->detect_pin); + + return ret == 0 ? 1 : 0; +} + /** init the host interface */ static int atmci_reset(struct mci_host *mci, struct device_d *mci_dev) { - int ret; struct atmel_mci *host = to_mci_host(mci); - struct atmel_mci_platform_data *pd = host->hw_dev->platform_data; - - ret = gpio_get_value(pd->detect_pin); - dev_dbg(host->hw_dev, "card %sdetected\n", ret != 0 ? "not " : ""); - - if (pd->detect_pin && ret == 1) - return -ENODEV; clk_enable(host->clk); atmci_writel(host, ATMCI_DTOR, 0x7f); @@ -554,6 +561,7 @@ host->mci.send_cmd = atmci_request; host->mci.set_ios = atmci_set_ios; host->mci.init = atmci_reset; + host->mci.card_present = atmci_card_present; host->mci.hw_dev = hw_dev; if (pd->bus_width >= 4) diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c index dfeb509..aad1b86 100644 --- a/drivers/mci/imx-esdhc.c +++ b/drivers/mci/imx-esdhc.c @@ -421,8 +421,9 @@ } -static int esdhc_card_detect(struct fsl_esdhc_host *host) +static int esdhc_card_present(struct mci_host *mci) { + struct fsl_esdhc_host *host = to_fsl_esdhc(mci); struct fsl_esdhc __iomem *regs = host->regs; struct esdhc_platform_data *pdata = host->dev->platform_data; int ret; @@ -453,16 +454,6 @@ int timeout = 1000; int ret = 0; - ret = esdhc_card_detect(host); - - if (ret == 0) - return -ENODEV; - - if (ret < 0) - return ret; - - ret = 0; - /* Enable cache snooping */ if (host && !host->no_snoop) esdhc_write32(®s->scr, 0x00000040); @@ -561,6 +552,7 @@ host->mci.send_cmd = esdhc_send_cmd; host->mci.set_ios = esdhc_set_ios; host->mci.init = esdhc_init; + host->mci.card_present = esdhc_card_present; host->mci.hw_dev = dev; rate = clk_get_rate(host->clk); diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c index 559f8ab..a269aee 100644 --- a/drivers/mci/mci-core.c +++ b/drivers/mci/mci-core.c @@ -1111,8 +1111,14 @@ const void *buffer, int block, int num_blocks) { struct mci *mci = container_of(blk, struct mci, blk); + struct mci_host *host = mci->host; int rc; + if (host->card_write_protected && host->card_write_protected(host)) { + dev_err(mci->mci_dev, "card write protected\n"); + return -EPERM; + } + dev_dbg(mci->mci_dev, "%s: Write %d block(s), starting at %d\n", __func__, num_blocks, block); @@ -1352,6 +1358,11 @@ struct mci_host *host = mci->host; int rc, disknum; + if (host->card_present && !host->card_present(host)) { + dev_err(mci->mci_dev, "no card inserted\n"); + return -ENODEV; + } + /* start with a host interface reset */ rc = (host->init)(host, mci->mci_dev); if (rc) { @@ -1448,7 +1459,7 @@ rc = mci_check_if_already_initialized(mci); if (rc != 0) - return rc; + return 0; probe = simple_strtoul(val, NULL, 0); if (probe != 0) { @@ -1499,34 +1510,18 @@ dev_info(mci->host->hw_dev, "registered as %s\n", dev_name(mci_dev)); -#ifdef CONFIG_MCI_STARTUP - /* if enabled, probe the attached card immediately */ - rc = mci_card_probe(mci); - if (rc) { - /* - * If it fails, add the 'probe' parameter to give the user - * a chance to insert a card and try again. Note: This may fail - * systems that rely on the MCI card for startup (for the - * persistant environment for example) - */ - rc = add_mci_parameter(mci_dev); - if (rc != 0) { - dev_dbg(mci->mci_dev, "Failed to add 'probe' parameter to the MCI device\n"); - goto on_error; - } - } -#endif - -#ifndef CONFIG_MCI_STARTUP - /* add params on demand */ rc = add_mci_parameter(mci_dev); if (rc != 0) { dev_dbg(mci->mci_dev, "Failed to add 'probe' parameter to the MCI device\n"); goto on_error; } + +#ifdef CONFIG_MCI_STARTUP + /* if enabled, probe the attached card immediately */ + mci_card_probe(mci); #endif - return rc; + return 0; on_error: free(mci); diff --git a/include/mci.h b/include/mci.h index 0041e27..cf9582d 100644 --- a/include/mci.h +++ b/include/mci.h @@ -300,6 +300,10 @@ void (*set_ios)(struct mci_host*, struct mci_ios *); /** handle a command */ int (*send_cmd)(struct mci_host*, struct mci_cmd*, struct mci_data*); + /** check if a card is inserted */ + int (*card_present)(struct mci_host *); + /** check if a card is write protected */ + int (*card_write_protected)(struct mci_host *); }; /** MMC/SD and interface instance information */