mmc: add support for write protection
authorNikita Kiryanov <nikita@compulab.co.il>
Mon, 3 Dec 2012 02:19:46 +0000 (02:19 +0000)
committerTom Rini <trini@ti.com>
Fri, 8 Mar 2013 21:41:13 +0000 (16:41 -0500)
Add generic mmc write protection functionality.

Signed-off-by: Nikita Kiryanov <nikita@compulab.co.il>
Signed-off-by: Igor Grinberg <grinberg@compulab.co.il>
16 files changed:
common/cmd_mmc.c
drivers/mmc/arm_pl180_mmci.c
drivers/mmc/bfin_sdh.c
drivers/mmc/davinci_mmc.c
drivers/mmc/fsl_esdhc.c
drivers/mmc/ftsdc010_esdhc.c
drivers/mmc/gen_atmel_mci.c
drivers/mmc/mmc.c
drivers/mmc/mmc_spi.c
drivers/mmc/mxcmmc.c
drivers/mmc/mxsmmc.c
drivers/mmc/omap_hsmmc.c
drivers/mmc/sdhci.c
drivers/mmc/sh_mmcif.c
drivers/mmc/tegra_mmc.c
include/mmc.h

index 7dacd5114ce1416bf1cb5c9af5589cd62530becd..8c53a10315ecec188d75d87c15b67a1971e59aa7 100644 (file)
@@ -282,6 +282,13 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
                mmc_init(mmc);
 
+               if ((state == MMC_WRITE || state == MMC_ERASE)) {
+                       if (mmc_getwp(mmc) == 1) {
+                               printf("Error: card is write protected!\n");
+                               return 1;
+                       }
+               }
+
                switch (state) {
                case MMC_READ:
                        n = mmc->block_dev.block_read(curr_device, blk,
index af1380a45504ad14bbca483b4becd06146b31ad5..ab2e81e5d43ced6484dcf399c7335cd8b3904a6e 100644 (file)
@@ -377,6 +377,7 @@ int arm_pl180_mmci_init(struct pl180_mmc_host *host)
        dev->set_ios = host_set_ios;
        dev->init = mmc_host_reset;
        dev->getcd = NULL;
+       dev->getwp = NULL;
        dev->host_caps = host->caps;
        dev->voltages = host->voltages;
        dev->f_min = host->clock_min;
index 8d59d46c646878b866834bf72eb9649c1e2b5f4f..81d8e5432f941f94d7eea769bb09f4309d9fd8eb 100644 (file)
@@ -251,6 +251,7 @@ int bfin_mmc_init(bd_t *bis)
        mmc->set_ios = bfin_sdh_set_ios;
        mmc->init = bfin_sdh_init;
        mmc->getcd = NULL;
+       mmc->getwp = NULL;
        mmc->host_caps = MMC_MODE_4BIT;
 
        mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
index ee8f2614de5d152231d30a3ee25c371a78f34ceb..e2379e326eeea7d367d08453d22d76c4627794fb 100644 (file)
@@ -388,6 +388,7 @@ int davinci_mmc_init(bd_t *bis, struct davinci_mmc *host)
        mmc->set_ios = dmmc_set_ios;
        mmc->init = dmmc_init;
        mmc->getcd = NULL;
+       mmc->getwp = NULL;
 
        mmc->f_min = 200000;
        mmc->f_max = 25000000;
index b90f3e77698636a1fff74d01e930fa4d355e7468..54b5363169b5d10f9ac747ab75eef724422a28a0 100644 (file)
@@ -552,6 +552,7 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
        mmc->set_ios = esdhc_set_ios;
        mmc->init = esdhc_init;
        mmc->getcd = esdhc_getcd;
+       mmc->getwp = NULL;
 
        voltage_caps = 0;
        caps = regs->hostcapblt;
index f1702fe33bedb560789bcb9afc4c465a531ab259..42f0e0ce55bc9c2c16683d0b15e584c90fe58b66 100644 (file)
@@ -666,6 +666,7 @@ int ftsdc010_mmc_init(int dev_index)
        mmc->set_ios = ftsdc010_set_ios;
        mmc->init = ftsdc010_core_init;
        mmc->getcd = NULL;
+       mmc->getwp = NULL;
 
        mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 
index 67b2dbe8d4c0b4d47339714ceaac0f4ff29aa60c..70a9f91c8d97408ed5e38347487094e2ff742bf4 100644 (file)
@@ -349,6 +349,7 @@ int atmel_mci_init(void *regs)
        mmc->set_ios = mci_set_ios;
        mmc->init = mci_init;
        mmc->getcd = NULL;
+       mmc->getwp = 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;
index 72e8ce6da423018e8714be88fd4a3722fd49dca6..7b5fdd9f66ed51445c2588b33a1e6c4ad0961b6f 100644 (file)
 static struct list_head mmc_devices;
 static int cur_dev_num = -1;
 
+int __weak board_mmc_getwp(struct mmc *mmc)
+{
+       return -1;
+}
+
+int mmc_getwp(struct mmc *mmc)
+{
+       int wp;
+
+       wp = board_mmc_getwp(mmc);
+
+       if ((wp < 0) && mmc->getwp)
+               wp = mmc->getwp(mmc);
+
+       return wp;
+}
+
 int __board_mmc_getcd(struct mmc *mmc) {
        return -1;
 }
index 11ba532b0c6d02ed96bf0394d1f56def57137c2f..fe6a5a166de8bbebcea7b15e7a9bfe14c3caaa63 100644 (file)
@@ -273,6 +273,7 @@ struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode)
        mmc->set_ios = mmc_spi_set_ios;
        mmc->init = mmc_spi_init_p;
        mmc->getcd = NULL;
+       mmc->getwp = NULL;
        mmc->host_caps = MMC_MODE_SPI;
 
        mmc->voltages = MMC_SPI_VOLTAGE;
index d58c18bc2a5b9ff05671172cab1d261efd15b781..4f99617b9a948da3c9b4f66c5a765fa3904dfb43 100644 (file)
@@ -499,6 +499,7 @@ static int mxcmci_initialize(bd_t *bis)
        mmc->set_ios = mxcmci_set_ios;
        mmc->init = mxcmci_init;
        mmc->getcd = NULL;
+       mmc->getwp = NULL;
        mmc->host_caps = MMC_MODE_4BIT;
 
        host->base = (struct mxcmci_regs *)CONFIG_MXC_MCI_REGS_BASE;
index a72f66cc7aa301aa51a0686c4ecc1699bf91042f..a87529dfc5d2deab2ec1fc4191643ace908a1926 100644 (file)
@@ -432,6 +432,7 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int))
        mmc->set_ios = mxsmmc_set_ios;
        mmc->init = mxsmmc_init;
        mmc->getcd = NULL;
+       mmc->getwp = NULL;
        mmc->priv = priv;
 
        mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
index cb1a7bdd6544ac00631c88006bc3c06cac22b7b6..fcbd1330d42a5a4d0a73b997ffa12543ee74980f 100644 (file)
@@ -590,6 +590,7 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio)
        mmc->set_ios = mmc_set_ios;
        mmc->init = mmc_init_setup;
        mmc->getcd = omap_mmc_getcd;
+       mmc->getwp = NULL;
        mmc->priv = priv_data;
 
        switch (dev_index) {
index b9cbe34f1f12f728471514ceac568576fe696b9c..daca0ea4f7021aa5138b3395ed3c7bca5e8834c0 100644 (file)
@@ -438,6 +438,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
        mmc->set_ios = sdhci_set_ios;
        mmc->init = sdhci_init;
        mmc->getcd = NULL;
+       mmc->getwp = NULL;
 
        caps = sdhci_readl(host, SDHCI_CAPABILITIES);
 #ifdef CONFIG_MMC_SDMA
index 4588568a6db63a640614954ff12b43b31699b474..011d4f3e638a62cad4bb05fd1e32e06ae359fe11 100644 (file)
@@ -599,6 +599,7 @@ int mmcif_mmc_init(void)
        mmc->set_ios = sh_mmcif_set_ios;
        mmc->init = sh_mmcif_init;
        mmc->getcd = NULL;
+       mmc->getwp = NULL;
        host->regs = (struct sh_mmcif_regs *)CONFIG_SH_MMCIF_ADDR;
        host->clk = CONFIG_SH_MMCIF_CLK;
        mmc->priv = host;
index d749ab095e3eecfe1d4070f5b37eacf5a9d3933b..72586193ca54063498f310ad32b7ed9a38b083d1 100644 (file)
@@ -563,6 +563,7 @@ int tegra_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio)
        mmc->set_ios = mmc_set_ios;
        mmc->init = mmc_core_init;
        mmc->getcd = tegra_mmc_getcd;
+       mmc->getwp = NULL;
 
        mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
        mmc->host_caps = 0;
index a13e2bdcf16886a755a8cf8b74974b3425ca373b..de6d497d530a611f6f4dc54cb226ec2aa532ea67 100644 (file)
@@ -259,6 +259,7 @@ struct mmc {
        void (*set_ios)(struct mmc *mmc);
        int (*init)(struct mmc *mmc);
        int (*getcd)(struct mmc *mmc);
+       int (*getwp)(struct mmc *mmc);
        uint b_max;
 };
 
@@ -274,6 +275,7 @@ 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);
+int mmc_getwp(struct mmc *mmc);
 void spl_mmc_load(void) __noreturn;
 
 #ifdef CONFIG_GENERIC_MMC