mmc: parse new binding for eMMC fixed driver type
authorWolfram Sang <wsa+renesas@sang-engineering.com>
Sun, 15 Oct 2017 12:46:14 +0000 (14:46 +0200)
committerUlf Hansson <ulf.hansson@linaro.org>
Mon, 30 Oct 2017 10:50:38 +0000 (11:50 +0100)
Parse the new binding and store it in the host struct after doing some
sanity checks. The code is designed to support fixed SD driver type if
we ever need that.

Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/core/host.c
drivers/mmc/core/mmc.c
include/linux/mmc/host.h

index e58be39b15685e6a1617daed823d122fa34c636d..35a9e4fd1a9f514ae61e4ec77455915e4870009e 100644 (file)
@@ -179,7 +179,7 @@ static void mmc_retune_timer(unsigned long data)
 int mmc_of_parse(struct mmc_host *host)
 {
        struct device *dev = host->parent;
-       u32 bus_width;
+       u32 bus_width, drv_type;
        int ret;
        bool cd_cap_invert, cd_gpio_invert = false;
        bool ro_cap_invert, ro_gpio_invert = false;
@@ -321,6 +321,15 @@ int mmc_of_parse(struct mmc_host *host)
        if (device_property_read_bool(dev, "no-mmc"))
                host->caps2 |= MMC_CAP2_NO_MMC;
 
+       /* Must be after "non-removable" check */
+       if (device_property_read_u32(dev, "fixed-emmc-driver-type", &drv_type) == 0) {
+               if (host->caps & MMC_CAP_NONREMOVABLE)
+                       host->fixed_drv_type = drv_type;
+               else
+                       dev_err(host->parent,
+                               "can't use fixed driver type, media is removable\n");
+       }
+
        host->dsr_req = !device_property_read_u32(dev, "dsr", &host->dsr);
        if (host->dsr_req && (host->dsr & ~0xffff)) {
                dev_err(host->parent,
@@ -393,6 +402,8 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
        host->max_blk_size = 512;
        host->max_blk_count = PAGE_SIZE / 512;
 
+       host->fixed_drv_type = -EINVAL;
+
        return host;
 }
 
index 066efbb89483d9deba76ba43481593f06c23c3a1..a552f61060d2127d2539f73abf0f3690829c0898 100644 (file)
@@ -1291,13 +1291,18 @@ out_err:
 static void mmc_select_driver_type(struct mmc_card *card)
 {
        int card_drv_type, drive_strength, drv_type;
+       int fixed_drv_type = card->host->fixed_drv_type;
 
        card_drv_type = card->ext_csd.raw_driver_strength |
                        mmc_driver_type_mask(0);
 
-       drive_strength = mmc_select_drive_strength(card,
-                                                  card->ext_csd.hs200_max_dtr,
-                                                  card_drv_type, &drv_type);
+       if (fixed_drv_type >= 0)
+               drive_strength = card_drv_type & mmc_driver_type_mask(fixed_drv_type)
+                                ? fixed_drv_type : 0;
+       else
+               drive_strength = mmc_select_drive_strength(card,
+                                                          card->ext_csd.hs200_max_dtr,
+                                                          card_drv_type, &drv_type);
 
        card->drive_strength = drive_strength;
 
index c296f4351c1da41becb74a50385a5f9c7c37f175..e7743eca1021969642c1bb04e2c41676c427d013 100644 (file)
@@ -354,6 +354,8 @@ struct mmc_host {
 #define MMC_CAP2_CQE           (1 << 23)       /* Has eMMC command queue engine */
 #define MMC_CAP2_CQE_DCMD      (1 << 24)       /* CQE can issue a direct command */
 
+       int                     fixed_drv_type; /* fixed driver type for non-removable media */
+
        mmc_pm_flag_t           pm_caps;        /* supported pm features */
 
        /* host specific block data */