diff options
-rw-r--r-- | Documentation/devicetree/bindings/mmc/fsl-esdhc.txt | 4 | ||||
-rw-r--r-- | drivers/mmc/core/core.c | 44 | ||||
-rw-r--r-- | include/linux/mmc/core.h | 2 |
3 files changed, 50 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt index bd9be0b5bc20..b7943f3f9995 100644 --- a/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt +++ b/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt | |||
@@ -19,6 +19,9 @@ Optional properties: | |||
19 | "bus-width = <1>" property. | 19 | "bus-width = <1>" property. |
20 | - sdhci,auto-cmd12: specifies that a controller can only handle auto | 20 | - sdhci,auto-cmd12: specifies that a controller can only handle auto |
21 | CMD12. | 21 | CMD12. |
22 | - voltage-ranges : two cells are required, first cell specifies minimum | ||
23 | slot voltage (mV), second cell specifies maximum slot voltage (mV). | ||
24 | Several ranges could be specified. | ||
22 | 25 | ||
23 | Example: | 26 | Example: |
24 | 27 | ||
@@ -29,4 +32,5 @@ sdhci@2e000 { | |||
29 | interrupt-parent = <&ipic>; | 32 | interrupt-parent = <&ipic>; |
30 | /* Filled in by U-Boot */ | 33 | /* Filled in by U-Boot */ |
31 | clock-frequency = <0>; | 34 | clock-frequency = <0>; |
35 | voltage-ranges = <3300 3300>; | ||
32 | }; | 36 | }; |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 49a5bca418bd..b9b9fb6e4496 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/fault-inject.h> | 27 | #include <linux/fault-inject.h> |
28 | #include <linux/random.h> | 28 | #include <linux/random.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/of.h> | ||
30 | 31 | ||
31 | #include <linux/mmc/card.h> | 32 | #include <linux/mmc/card.h> |
32 | #include <linux/mmc/host.h> | 33 | #include <linux/mmc/host.h> |
@@ -1196,6 +1197,49 @@ u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max) | |||
1196 | } | 1197 | } |
1197 | EXPORT_SYMBOL(mmc_vddrange_to_ocrmask); | 1198 | EXPORT_SYMBOL(mmc_vddrange_to_ocrmask); |
1198 | 1199 | ||
1200 | #ifdef CONFIG_OF | ||
1201 | |||
1202 | /** | ||
1203 | * mmc_of_parse_voltage - return mask of supported voltages | ||
1204 | * @np: The device node need to be parsed. | ||
1205 | * @mask: mask of voltages available for MMC/SD/SDIO | ||
1206 | * | ||
1207 | * 1. Return zero on success. | ||
1208 | * 2. Return negative errno: voltage-range is invalid. | ||
1209 | */ | ||
1210 | int mmc_of_parse_voltage(struct device_node *np, u32 *mask) | ||
1211 | { | ||
1212 | const u32 *voltage_ranges; | ||
1213 | int num_ranges, i; | ||
1214 | |||
1215 | voltage_ranges = of_get_property(np, "voltage-ranges", &num_ranges); | ||
1216 | num_ranges = num_ranges / sizeof(*voltage_ranges) / 2; | ||
1217 | if (!voltage_ranges || !num_ranges) { | ||
1218 | pr_info("%s: voltage-ranges unspecified\n", np->full_name); | ||
1219 | return -EINVAL; | ||
1220 | } | ||
1221 | |||
1222 | for (i = 0; i < num_ranges; i++) { | ||
1223 | const int j = i * 2; | ||
1224 | u32 ocr_mask; | ||
1225 | |||
1226 | ocr_mask = mmc_vddrange_to_ocrmask( | ||
1227 | be32_to_cpu(voltage_ranges[j]), | ||
1228 | be32_to_cpu(voltage_ranges[j + 1])); | ||
1229 | if (!ocr_mask) { | ||
1230 | pr_err("%s: voltage-range #%d is invalid\n", | ||
1231 | np->full_name, i); | ||
1232 | return -EINVAL; | ||
1233 | } | ||
1234 | *mask |= ocr_mask; | ||
1235 | } | ||
1236 | |||
1237 | return 0; | ||
1238 | } | ||
1239 | EXPORT_SYMBOL(mmc_of_parse_voltage); | ||
1240 | |||
1241 | #endif /* CONFIG_OF */ | ||
1242 | |||
1199 | #ifdef CONFIG_REGULATOR | 1243 | #ifdef CONFIG_REGULATOR |
1200 | 1244 | ||
1201 | /** | 1245 | /** |
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 443243b241d5..da51bec578c3 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h | |||
@@ -208,6 +208,8 @@ static inline void mmc_claim_host(struct mmc_host *host) | |||
208 | __mmc_claim_host(host, NULL); | 208 | __mmc_claim_host(host, NULL); |
209 | } | 209 | } |
210 | 210 | ||
211 | struct device_node; | ||
211 | extern u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max); | 212 | extern u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max); |
213 | extern int mmc_of_parse_voltage(struct device_node *np, u32 *mask); | ||
212 | 214 | ||
213 | #endif /* LINUX_MMC_CORE_H */ | 215 | #endif /* LINUX_MMC_CORE_H */ |