aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/mmc/fsl-esdhc.txt4
-rw-r--r--drivers/mmc/core/core.c44
-rw-r--r--include/linux/mmc/core.h2
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
23Example: 26Example:
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}
1197EXPORT_SYMBOL(mmc_vddrange_to_ocrmask); 1198EXPORT_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 */
1210int 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}
1239EXPORT_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
211struct device_node;
211extern u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max); 212extern u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max);
213extern 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 */