diff options
author | Zhangfei Gao <zhangfei.gao@linaro.org> | 2014-01-16 07:48:47 -0500 |
---|---|---|
committer | Chris Ball <chris@printf.net> | 2014-01-17 09:21:38 -0500 |
commit | 7cf347bd20ec8169add381ad23f9fb25c6c076f0 (patch) | |
tree | ae046124b883b03f346b2275aa38bddcb5f10cd7 /drivers/mmc/host/dw_mmc.c | |
parent | 85136b74dc7fbbcaf173b660406de8aa1dd0068a (diff) |
mmc: dw_mmc: fix dw_mci_get_cd
bf626e5550f24aec ("mmc: dw_mmc: use slot-gpio to handle cd pin") caused
CDETECT to be ignored, since negated return value of mmc_gpio_get_cd(mmc)
can not be checked by IS_ERR_VALUE.
Also, add spin_lock_bh(&host->lock) for atomic access to
DW_MMC_CARD_PRESENT, otherwise sd detect may occasionally fail.
Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
Reported-by: Kevin Hilman <khilman@linaro.org>
Reviewed-by: Sachin Kamat <sachin.kamat@linaro.org>
Tested-by: Sachin Kamat <sachin.kamat@linaro.org>
Tested-by: Kevin Hilman <khilman@linaro.org>
Acked-by: Seungwon Jeon <tgih.jun@samsung.com>
Signed-off-by: Chris Ball <chris@printf.net>
Diffstat (limited to 'drivers/mmc/host/dw_mmc.c')
-rw-r--r-- | drivers/mmc/host/dw_mmc.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index a776f24f4311..55cd110a49c4 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
@@ -1033,7 +1033,8 @@ static int dw_mci_get_cd(struct mmc_host *mmc) | |||
1033 | int present; | 1033 | int present; |
1034 | struct dw_mci_slot *slot = mmc_priv(mmc); | 1034 | struct dw_mci_slot *slot = mmc_priv(mmc); |
1035 | struct dw_mci_board *brd = slot->host->pdata; | 1035 | struct dw_mci_board *brd = slot->host->pdata; |
1036 | int gpio_cd = !mmc_gpio_get_cd(mmc); | 1036 | struct dw_mci *host = slot->host; |
1037 | int gpio_cd = mmc_gpio_get_cd(mmc); | ||
1037 | 1038 | ||
1038 | /* Use platform get_cd function, else try onboard card detect */ | 1039 | /* Use platform get_cd function, else try onboard card detect */ |
1039 | if (brd->quirks & DW_MCI_QUIRK_BROKEN_CARD_DETECTION) | 1040 | if (brd->quirks & DW_MCI_QUIRK_BROKEN_CARD_DETECTION) |
@@ -1041,11 +1042,12 @@ static int dw_mci_get_cd(struct mmc_host *mmc) | |||
1041 | else if (brd->get_cd) | 1042 | else if (brd->get_cd) |
1042 | present = !brd->get_cd(slot->id); | 1043 | present = !brd->get_cd(slot->id); |
1043 | else if (!IS_ERR_VALUE(gpio_cd)) | 1044 | else if (!IS_ERR_VALUE(gpio_cd)) |
1044 | present = !!gpio_cd; | 1045 | present = gpio_cd; |
1045 | else | 1046 | else |
1046 | present = (mci_readl(slot->host, CDETECT) & (1 << slot->id)) | 1047 | present = (mci_readl(slot->host, CDETECT) & (1 << slot->id)) |
1047 | == 0 ? 1 : 0; | 1048 | == 0 ? 1 : 0; |
1048 | 1049 | ||
1050 | spin_lock_bh(&host->lock); | ||
1049 | if (present) { | 1051 | if (present) { |
1050 | set_bit(DW_MMC_CARD_PRESENT, &slot->flags); | 1052 | set_bit(DW_MMC_CARD_PRESENT, &slot->flags); |
1051 | dev_dbg(&mmc->class_dev, "card is present\n"); | 1053 | dev_dbg(&mmc->class_dev, "card is present\n"); |
@@ -1053,6 +1055,7 @@ static int dw_mci_get_cd(struct mmc_host *mmc) | |||
1053 | clear_bit(DW_MMC_CARD_PRESENT, &slot->flags); | 1055 | clear_bit(DW_MMC_CARD_PRESENT, &slot->flags); |
1054 | dev_dbg(&mmc->class_dev, "card is not present\n"); | 1056 | dev_dbg(&mmc->class_dev, "card is not present\n"); |
1055 | } | 1057 | } |
1058 | spin_unlock_bh(&host->lock); | ||
1056 | 1059 | ||
1057 | return present; | 1060 | return present; |
1058 | } | 1061 | } |
@@ -2081,7 +2084,7 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) | |||
2081 | return gpio; | 2084 | return gpio; |
2082 | } | 2085 | } |
2083 | 2086 | ||
2084 | /* find the cd gpio for a given slot; or -1 if none specified */ | 2087 | /* find the cd gpio for a given slot */ |
2085 | static void dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, | 2088 | static void dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, |
2086 | struct mmc_host *mmc) | 2089 | struct mmc_host *mmc) |
2087 | { | 2090 | { |
@@ -2411,6 +2414,9 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) | |||
2411 | if (of_find_property(np, "caps2-mmc-hs200-1_2v", NULL)) | 2414 | if (of_find_property(np, "caps2-mmc-hs200-1_2v", NULL)) |
2412 | pdata->caps2 |= MMC_CAP2_HS200_1_2V_SDR; | 2415 | pdata->caps2 |= MMC_CAP2_HS200_1_2V_SDR; |
2413 | 2416 | ||
2417 | if (of_get_property(np, "cd-inverted", NULL)) | ||
2418 | pdata->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH; | ||
2419 | |||
2414 | return pdata; | 2420 | return pdata; |
2415 | } | 2421 | } |
2416 | 2422 | ||