Patchwork [U-Boot,6/7] mmc: add support for write protection

login
register
mail settings
Submitter Nikita Kiryanov
Date Dec. 3, 2012, 12:19 p.m.
Message ID <1354537187-26744-7-git-send-email-nikita@compulab.co.il>
Download mbox | patch
Permalink /patch/203337/
State Accepted
Delegated to: Tom Rini
Headers show

Comments

Nikita Kiryanov - Dec. 3, 2012, 12:19 p.m.
Add generic mmc write protection functionality.

Signed-off-by: Nikita Kiryanov <nikita@compulab.co.il>
Signed-off-by: Igor Grinberg <grinberg@compulab.co.il>
---
 common/cmd_mmc.c             |    7 +++++++
 drivers/mmc/arm_pl180_mmci.c |    1 +
 drivers/mmc/bfin_sdh.c       |    1 +
 drivers/mmc/davinci_mmc.c    |    1 +
 drivers/mmc/fsl_esdhc.c      |    1 +
 drivers/mmc/ftsdc010_esdhc.c |    1 +
 drivers/mmc/gen_atmel_mci.c  |    1 +
 drivers/mmc/mmc.c            |   17 +++++++++++++++++
 drivers/mmc/mmc_spi.c        |    1 +
 drivers/mmc/mxcmmc.c         |    1 +
 drivers/mmc/mxsmmc.c         |    1 +
 drivers/mmc/omap_hsmmc.c     |    1 +
 drivers/mmc/sdhci.c          |    1 +
 drivers/mmc/sh_mmcif.c       |    1 +
 drivers/mmc/tegra_mmc.c      |    1 +
 include/mmc.h                |    2 ++
 16 files changed, 39 insertions(+)

Patch

diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
index 4c19df7..337bf2b 100644
--- a/common/cmd_mmc.c
+++ b/common/cmd_mmc.c
@@ -283,6 +283,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,
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c
index af1380a..ab2e81e 100644
--- a/drivers/mmc/arm_pl180_mmci.c
+++ b/drivers/mmc/arm_pl180_mmci.c
@@ -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;
diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c
index 8d59d46..81d8e54 100644
--- a/drivers/mmc/bfin_sdh.c
+++ b/drivers/mmc/bfin_sdh.c
@@ -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;
diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c
index ee8f261..e2379e3 100644
--- a/drivers/mmc/davinci_mmc.c
+++ b/drivers/mmc/davinci_mmc.c
@@ -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;
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index e93e38a..9aef2c7 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -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;
diff --git a/drivers/mmc/ftsdc010_esdhc.c b/drivers/mmc/ftsdc010_esdhc.c
index f1702fe..42f0e0c 100644
--- a/drivers/mmc/ftsdc010_esdhc.c
+++ b/drivers/mmc/ftsdc010_esdhc.c
@@ -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;
 
diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c
index 67b2dbe..70a9f91 100644
--- a/drivers/mmc/gen_atmel_mci.c
+++ b/drivers/mmc/gen_atmel_mci.c
@@ -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;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 5ffd8c5..619200b 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -40,6 +40,23 @@ 
 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;
 }
diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c
index 11ba532..fe6a5a1 100644
--- a/drivers/mmc/mmc_spi.c
+++ b/drivers/mmc/mmc_spi.c
@@ -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;
diff --git a/drivers/mmc/mxcmmc.c b/drivers/mmc/mxcmmc.c
index d58c18b..4f99617 100644
--- a/drivers/mmc/mxcmmc.c
+++ b/drivers/mmc/mxcmmc.c
@@ -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;
diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c
index 109acbf..59d0fce 100644
--- a/drivers/mmc/mxsmmc.c
+++ b/drivers/mmc/mxsmmc.c
@@ -428,6 +428,7 @@  int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(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;
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index cb1a7bd..fcbd133 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -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) {
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 7845f87..1c0be72 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -435,6 +435,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
diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c
index 4588568..011d4f3 100644
--- a/drivers/mmc/sh_mmcif.c
+++ b/drivers/mmc/sh_mmcif.c
@@ -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;
diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c
index 8fea6a6..633173f 100644
--- a/drivers/mmc/tegra_mmc.c
+++ b/drivers/mmc/tegra_mmc.c
@@ -545,6 +545,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;
 	if (bus_width == 8)
diff --git a/include/mmc.h b/include/mmc.h
index a13e2bd..de6d497 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -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