diff options
author | Zhangfei Gao <zhangfei.gao@linaro.org> | 2014-01-09 09:35:10 -0500 |
---|---|---|
committer | Chris Ball <chris@printf.net> | 2014-01-13 12:48:32 -0500 |
commit | bf626e5550f24aec24975a0e85ad8e572ca76a6b (patch) | |
tree | db5d75bee3790a3c481f9f9b35470f8dcdbfacea /drivers/mmc | |
parent | 01acf6917aed934388609177605d54ad1463b252 (diff) |
mmc: dw_mmc: use slot-gpio to handle cd pin
Suggested by Jaehoon: Use slot-gpio to handle cd-gpio
Add function dw_mci_of_get_cd_gpio to check "cd-gpios" from dts.
mmc_gpio_request_cd and mmc_gpio_get_cd are used to handle cd pin
Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
Acked-by: Jaehoon Chung <jh80.chung@samsung.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Chris Ball <chris@printf.net>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/dw_mmc.c | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 4bce0deec362..a776f24f4311 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/workqueue.h> | 36 | #include <linux/workqueue.h> |
37 | #include <linux/of.h> | 37 | #include <linux/of.h> |
38 | #include <linux/of_gpio.h> | 38 | #include <linux/of_gpio.h> |
39 | #include <linux/mmc/slot-gpio.h> | ||
39 | 40 | ||
40 | #include "dw_mmc.h" | 41 | #include "dw_mmc.h" |
41 | 42 | ||
@@ -1032,20 +1033,26 @@ static int dw_mci_get_cd(struct mmc_host *mmc) | |||
1032 | int present; | 1033 | int present; |
1033 | struct dw_mci_slot *slot = mmc_priv(mmc); | 1034 | struct dw_mci_slot *slot = mmc_priv(mmc); |
1034 | 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); | ||
1035 | 1037 | ||
1036 | /* Use platform get_cd function, else try onboard card detect */ | 1038 | /* Use platform get_cd function, else try onboard card detect */ |
1037 | if (brd->quirks & DW_MCI_QUIRK_BROKEN_CARD_DETECTION) | 1039 | if (brd->quirks & DW_MCI_QUIRK_BROKEN_CARD_DETECTION) |
1038 | present = 1; | 1040 | present = 1; |
1039 | else if (brd->get_cd) | 1041 | else if (brd->get_cd) |
1040 | present = !brd->get_cd(slot->id); | 1042 | present = !brd->get_cd(slot->id); |
1043 | else if (!IS_ERR_VALUE(gpio_cd)) | ||
1044 | present = !!gpio_cd; | ||
1041 | else | 1045 | else |
1042 | present = (mci_readl(slot->host, CDETECT) & (1 << slot->id)) | 1046 | present = (mci_readl(slot->host, CDETECT) & (1 << slot->id)) |
1043 | == 0 ? 1 : 0; | 1047 | == 0 ? 1 : 0; |
1044 | 1048 | ||
1045 | if (present) | 1049 | if (present) { |
1050 | set_bit(DW_MMC_CARD_PRESENT, &slot->flags); | ||
1046 | dev_dbg(&mmc->class_dev, "card is present\n"); | 1051 | dev_dbg(&mmc->class_dev, "card is present\n"); |
1047 | else | 1052 | } else { |
1053 | clear_bit(DW_MMC_CARD_PRESENT, &slot->flags); | ||
1048 | dev_dbg(&mmc->class_dev, "card is not present\n"); | 1054 | dev_dbg(&mmc->class_dev, "card is not present\n"); |
1055 | } | ||
1049 | 1056 | ||
1050 | return present; | 1057 | return present; |
1051 | } | 1058 | } |
@@ -1926,10 +1933,6 @@ static void dw_mci_work_routine_card(struct work_struct *work) | |||
1926 | /* Card change detected */ | 1933 | /* Card change detected */ |
1927 | slot->last_detect_state = present; | 1934 | slot->last_detect_state = present; |
1928 | 1935 | ||
1929 | /* Mark card as present if applicable */ | ||
1930 | if (present != 0) | ||
1931 | set_bit(DW_MMC_CARD_PRESENT, &slot->flags); | ||
1932 | |||
1933 | /* Clean up queue if present */ | 1936 | /* Clean up queue if present */ |
1934 | mrq = slot->mrq; | 1937 | mrq = slot->mrq; |
1935 | if (mrq) { | 1938 | if (mrq) { |
@@ -1977,8 +1980,6 @@ static void dw_mci_work_routine_card(struct work_struct *work) | |||
1977 | 1980 | ||
1978 | /* Power down slot */ | 1981 | /* Power down slot */ |
1979 | if (present == 0) { | 1982 | if (present == 0) { |
1980 | clear_bit(DW_MMC_CARD_PRESENT, &slot->flags); | ||
1981 | |||
1982 | /* Clear down the FIFO */ | 1983 | /* Clear down the FIFO */ |
1983 | dw_mci_fifo_reset(host); | 1984 | dw_mci_fifo_reset(host); |
1984 | #ifdef CONFIG_MMC_DW_IDMAC | 1985 | #ifdef CONFIG_MMC_DW_IDMAC |
@@ -2079,6 +2080,26 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) | |||
2079 | 2080 | ||
2080 | return gpio; | 2081 | return gpio; |
2081 | } | 2082 | } |
2083 | |||
2084 | /* find the cd gpio for a given slot; or -1 if none specified */ | ||
2085 | static void dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, | ||
2086 | struct mmc_host *mmc) | ||
2087 | { | ||
2088 | struct device_node *np = dw_mci_of_find_slot_node(dev, slot); | ||
2089 | int gpio; | ||
2090 | |||
2091 | if (!np) | ||
2092 | return; | ||
2093 | |||
2094 | gpio = of_get_named_gpio(np, "cd-gpios", 0); | ||
2095 | |||
2096 | /* Having a missing entry is valid; return silently */ | ||
2097 | if (!gpio_is_valid(gpio)) | ||
2098 | return; | ||
2099 | |||
2100 | if (mmc_gpio_request_cd(mmc, gpio, 0)) | ||
2101 | dev_warn(dev, "gpio [%d] request failed\n", gpio); | ||
2102 | } | ||
2082 | #else /* CONFIG_OF */ | 2103 | #else /* CONFIG_OF */ |
2083 | static int dw_mci_of_get_slot_quirks(struct device *dev, u8 slot) | 2104 | static int dw_mci_of_get_slot_quirks(struct device *dev, u8 slot) |
2084 | { | 2105 | { |
@@ -2096,6 +2117,11 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) | |||
2096 | { | 2117 | { |
2097 | return -EINVAL; | 2118 | return -EINVAL; |
2098 | } | 2119 | } |
2120 | static void dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, | ||
2121 | struct mmc_host *mmc) | ||
2122 | { | ||
2123 | return; | ||
2124 | } | ||
2099 | #endif /* CONFIG_OF */ | 2125 | #endif /* CONFIG_OF */ |
2100 | 2126 | ||
2101 | static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) | 2127 | static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) |
@@ -2197,12 +2223,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) | |||
2197 | #endif /* CONFIG_MMC_DW_IDMAC */ | 2223 | #endif /* CONFIG_MMC_DW_IDMAC */ |
2198 | } | 2224 | } |
2199 | 2225 | ||
2200 | if (dw_mci_get_cd(mmc)) | ||
2201 | set_bit(DW_MMC_CARD_PRESENT, &slot->flags); | ||
2202 | else | ||
2203 | clear_bit(DW_MMC_CARD_PRESENT, &slot->flags); | ||
2204 | |||
2205 | slot->wp_gpio = dw_mci_of_get_wp_gpio(host->dev, slot->id); | 2226 | slot->wp_gpio = dw_mci_of_get_wp_gpio(host->dev, slot->id); |
2227 | dw_mci_of_get_cd_gpio(host->dev, slot->id, mmc); | ||
2206 | 2228 | ||
2207 | ret = mmc_add_host(mmc); | 2229 | ret = mmc_add_host(mmc); |
2208 | if (ret) | 2230 | if (ret) |