]> git.sur5r.net Git - u-boot/blobdiff - drivers/mmc/fsl_esdhc.c
mmc: sdhci: use the generic error number
[u-boot] / drivers / mmc / fsl_esdhc.c
index c5f08ea08bb9af98729c069b1e26f86c0b348ef7..9796d39c65bd00a2cd21b4495815d3c45f20a5e7 100644 (file)
 #include <config.h>
 #include <common.h>
 #include <command.h>
+#include <errno.h>
 #include <hwconfig.h>
 #include <mmc.h>
 #include <part.h>
 #include <malloc.h>
-#include <mmc.h>
 #include <fsl_esdhc.h>
 #include <fdt_support.h>
 #include <asm/io.h>
@@ -91,7 +91,9 @@ struct fsl_esdhc {
  * Following is used when Driver Model is enabled for MMC
  * @dev: pointer for the device
  * @non_removable: 0: removable; 1: non-removable
+ * @wp_enable: 1: enable checking wp; 0: no check
  * @cd_gpio: gpio for card detection
+ * @wp_gpio: gpio for write protection
  */
 struct fsl_esdhc_priv {
        struct fsl_esdhc *esdhc_regs;
@@ -101,7 +103,9 @@ struct fsl_esdhc_priv {
        struct mmc *mmc;
        struct udevice *dev;
        int non_removable;
+       int wp_enable;
        struct gpio_desc cd_gpio;
+       struct gpio_desc wp_gpio;
 };
 
 /* Return the XFERTYP flags for a given command and data packet */
@@ -245,9 +249,12 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
 #endif
                if (wml_value > WML_WR_WML_MAX)
                        wml_value = WML_WR_WML_MAX_VAL;
-               if ((esdhc_read32(&regs->prsstat) & PRSSTAT_WPSPL) == 0) {
-                       printf("\nThe SD card is locked. Can not write to a locked card.\n\n");
-                       return TIMEOUT;
+               if (priv->wp_enable) {
+                       if ((esdhc_read32(&regs->prsstat) &
+                           PRSSTAT_WPSPL) == 0) {
+                               printf("\nThe SD card is locked. Can not write to a locked card.\n\n");
+                               return -ETIMEDOUT;
+                       }
                }
 
                esdhc_clrsetbits32(&regs->wml, WML_WR_WML_MASK,
@@ -404,12 +411,12 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
        irqstat = esdhc_read32(&regs->irqstat);
 
        if (irqstat & CMD_ERR) {
-               err = COMM_ERR;
+               err = -ECOMM;
                goto out;
        }
 
        if (irqstat & IRQSTAT_CTOE) {
-               err = TIMEOUT;
+               err = -ETIMEDOUT;
                goto out;
        }
 
@@ -435,7 +442,7 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 
                if (timeout <= 0) {
                        printf("Timeout waiting for DAT0 to go high!\n");
-                       err = TIMEOUT;
+                       err = -ETIMEDOUT;
                        goto out;
                }
        }
@@ -464,12 +471,12 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
                        irqstat = esdhc_read32(&regs->irqstat);
 
                        if (irqstat & IRQSTAT_DTOE) {
-                               err = TIMEOUT;
+                               err = -ETIMEDOUT;
                                goto out;
                        }
 
                        if (irqstat & DATA_ERR) {
-                               err = COMM_ERR;
+                               err = -ECOMM;
                                goto out;
                        }
                } while ((irqstat & DATA_COMPLETE) != DATA_COMPLETE);
@@ -721,6 +728,7 @@ static int fsl_esdhc_cfg_to_priv(struct fsl_esdhc_cfg *cfg,
        priv->esdhc_regs = (struct fsl_esdhc *)(unsigned long)(cfg->esdhc_base);
        priv->bus_width = cfg->max_bus_width;
        priv->sdhc_clk = cfg->sdhc_clk;
+       priv->wp_enable  = cfg->wp_enable;
 
        return 0;
 };
@@ -963,6 +971,13 @@ static int fsl_esdhc_probe(struct udevice *dev)
                                           &priv->cd_gpio, GPIOD_IS_IN);
        }
 
+       priv->wp_enable = 1;
+
+       ret = gpio_request_by_name_nodev(fdt, node, "wp-gpios", 0,
+                                        &priv->wp_gpio, GPIOD_IS_IN);
+       if (ret)
+               priv->wp_enable = 0;
+
        /*
         * TODO:
         * Because lack of clk driver, if SDHC clk is not enabled,
@@ -995,6 +1010,7 @@ static int fsl_esdhc_probe(struct udevice *dev)
        }
 
        upriv->mmc = priv->mmc;
+       priv->mmc->dev = dev;
 
        return 0;
 }