summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/core/sd.c33
-rw-r--r--drivers/mmc/core/sdio.c43
-rw-r--r--include/linux/mmc/host.h3
3 files changed, 33 insertions, 46 deletions
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 8f6864a2a055..5edd7d8b033e 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -388,18 +388,9 @@ static int sd_select_driver_type(struct mmc_card *card, u8 *status)
{
int host_drv_type = SD_DRIVER_TYPE_B;
int card_drv_type = SD_DRIVER_TYPE_B;
- int drive_strength;
+ int drive_strength, drv_type;
int err;
- /*
- * If the host doesn't support any of the Driver Types A,C or D,
- * or there is no board specific handler then default Driver
- * Type B is used.
- */
- if (!(card->host->caps & (MMC_CAP_DRIVER_TYPE_A | MMC_CAP_DRIVER_TYPE_C
- | MMC_CAP_DRIVER_TYPE_D)))
- return 0;
-
if (!card->host->ops->select_drive_strength)
return 0;
@@ -430,20 +421,22 @@ static int sd_select_driver_type(struct mmc_card *card, u8 *status)
mmc_host_clk_hold(card->host);
drive_strength = card->host->ops->select_drive_strength(
card->sw_caps.uhs_max_dtr,
- host_drv_type, card_drv_type);
+ host_drv_type, card_drv_type, &drv_type);
mmc_host_clk_release(card->host);
- err = mmc_sd_switch(card, 1, 2, drive_strength, status);
- if (err)
- return err;
-
- if ((status[15] & 0xF) != drive_strength) {
- pr_warn("%s: Problem setting drive strength!\n",
- mmc_hostname(card->host));
- return 0;
+ if (drive_strength) {
+ err = mmc_sd_switch(card, 1, 2, drive_strength, status);
+ if (err)
+ return err;
+ if ((status[15] & 0xF) != drive_strength) {
+ pr_warn("%s: Problem setting drive strength!\n",
+ mmc_hostname(card->host));
+ return 0;
+ }
}
- mmc_set_driver_type(card->host, drive_strength);
+ if (drv_type)
+ mmc_set_driver_type(card->host, drv_type);
return 0;
}
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 5c1423a3e7d7..9d87aeb7c752 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -404,21 +404,10 @@ static void sdio_select_driver_type(struct mmc_card *card)
{
int host_drv_type = SD_DRIVER_TYPE_B;
int card_drv_type = SD_DRIVER_TYPE_B;
- int drive_strength;
+ int drive_strength, drv_type;
unsigned char card_strength;
int err;
- /*
- * If the host doesn't support any of the Driver Types A,C or D,
- * or there is no board specific handler then default Driver
- * Type B is used.
- */
- if (!(card->host->caps &
- (MMC_CAP_DRIVER_TYPE_A |
- MMC_CAP_DRIVER_TYPE_C |
- MMC_CAP_DRIVER_TYPE_D)))
- return;
-
if (!card->host->ops->select_drive_strength)
return;
@@ -448,23 +437,27 @@ static void sdio_select_driver_type(struct mmc_card *card)
*/
drive_strength = card->host->ops->select_drive_strength(
card->sw_caps.uhs_max_dtr,
- host_drv_type, card_drv_type);
+ host_drv_type, card_drv_type, &drv_type);
- /* if error just use default for drive strength B */
- err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_DRIVE_STRENGTH, 0,
- &card_strength);
- if (err)
- return;
+ if (drive_strength) {
+ /* if error just use default for drive strength B */
+ err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_DRIVE_STRENGTH, 0,
+ &card_strength);
+ if (err)
+ return;
- card_strength &= ~(SDIO_DRIVE_DTSx_MASK<<SDIO_DRIVE_DTSx_SHIFT);
- card_strength |= host_drive_to_sdio_drive(drive_strength);
+ card_strength &= ~(SDIO_DRIVE_DTSx_MASK<<SDIO_DRIVE_DTSx_SHIFT);
+ card_strength |= host_drive_to_sdio_drive(drive_strength);
- err = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_DRIVE_STRENGTH,
- card_strength, NULL);
+ /* if error default to drive strength B */
+ err = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_DRIVE_STRENGTH,
+ card_strength, NULL);
+ if (err)
+ return;
+ }
- /* if error default to drive strength B */
- if (!err)
- mmc_set_driver_type(card->host, drive_strength);
+ if (drv_type)
+ mmc_set_driver_type(card->host, drv_type);
}
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 433eccb50838..da33d18c66c8 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -132,7 +132,8 @@ struct mmc_host_ops {
/* Prepare HS400 target operating frequency depending host driver */
int (*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios);
- int (*select_drive_strength)(unsigned int max_dtr, int host_drv, int card_drv);
+ int (*select_drive_strength)(unsigned int max_dtr, int host_drv,
+ int card_drv, int *drv_type);
void (*hw_reset)(struct mmc_host *host);
void (*card_event)(struct mmc_host *host);