Add generic mmc write protection functionality.
Signed-off-by: Nikita Kiryanov <nikita@compulab.co.il>
Signed-off-by: Igor Grinberg <grinberg@compulab.co.il>
 
                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,
 
        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;
 
        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;
 
        mmc->set_ios = dmmc_set_ios;
        mmc->init = dmmc_init;
        mmc->getcd = NULL;
+       mmc->getwp = NULL;
 
        mmc->f_min = 200000;
        mmc->f_max = 25000000;
 
        mmc->set_ios = esdhc_set_ios;
        mmc->init = esdhc_init;
        mmc->getcd = esdhc_getcd;
+       mmc->getwp = NULL;
 
        voltage_caps = 0;
        caps = regs->hostcapblt;
 
        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;
 
 
        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;
 
 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;
 }
 
        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;
 
        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;
 
        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;
 
        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) {
 
        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
 
        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;
 
        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;
 
        void (*set_ios)(struct mmc *mmc);
        int (*init)(struct mmc *mmc);
        int (*getcd)(struct mmc *mmc);
+       int (*getwp)(struct mmc *mmc);
        uint b_max;
 };
 
 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