From: Haijun Zhang Date: Mon, 26 Aug 2013 01:19:22 +0000 (+0800) Subject: mmc: core: parse voltage from device-tree X-Git-Tag: firefly_0821_release~6165^2~43 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=1c9aaaee2c1a3395cff05f600e7668b6d0335308;p=firefly-linux-kernel-4.4.55.git mmc: core: parse voltage from device-tree Add function to support getting voltage from device-tree. If voltage-range is specified in device-tree node, this function will parse it and return the available voltage mask. Signed-off-by: Haijun Zhang Acked-by: Anton Vorontsov Signed-off-by: Chris Ball Conflicts: drivers/mmc/core/core.c --- 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: "bus-width = <1>" property. - sdhci,auto-cmd12: specifies that a controller can only handle auto CMD12. + - voltage-ranges : two cells are required, first cell specifies minimum + slot voltage (mV), second cell specifies maximum slot voltage (mV). + Several ranges could be specified. Example: @@ -29,4 +32,5 @@ sdhci@2e000 { interrupt-parent = <&ipic>; /* Filled in by U-Boot */ clock-frequency = <0>; + voltage-ranges = <3300 3300>; }; diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index c16f76385e1a..73a395e2621c 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -27,9 +27,7 @@ #include #include #include -#include - -#include +#include #include #include @@ -175,7 +173,6 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) pr_debug("%s: %d bytes transferred: %d\n", mmc_hostname(host), mrq->data->bytes_xfered, mrq->data->error); - trace_mmc_blk_rw_end(cmd->opcode, cmd->arg, mrq->data); } if (mrq->stop) { @@ -560,9 +557,6 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host, } if (!err && areq) { - trace_mmc_blk_rw_start(areq->mrq->cmd->opcode, - areq->mrq->cmd->arg, - areq->mrq->data); start_err = __mmc_start_data_req(host, areq->mrq); } @@ -1204,6 +1198,49 @@ u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max) } EXPORT_SYMBOL(mmc_vddrange_to_ocrmask); +#ifdef CONFIG_OF + +/** + * mmc_of_parse_voltage - return mask of supported voltages + * @np: The device node need to be parsed. + * @mask: mask of voltages available for MMC/SD/SDIO + * + * 1. Return zero on success. + * 2. Return negative errno: voltage-range is invalid. + */ +int mmc_of_parse_voltage(struct device_node *np, u32 *mask) +{ + const u32 *voltage_ranges; + int num_ranges, i; + + voltage_ranges = of_get_property(np, "voltage-ranges", &num_ranges); + num_ranges = num_ranges / sizeof(*voltage_ranges) / 2; + if (!voltage_ranges || !num_ranges) { + pr_info("%s: voltage-ranges unspecified\n", np->full_name); + return -EINVAL; + } + + for (i = 0; i < num_ranges; i++) { + const int j = i * 2; + u32 ocr_mask; + + ocr_mask = mmc_vddrange_to_ocrmask( + be32_to_cpu(voltage_ranges[j]), + be32_to_cpu(voltage_ranges[j + 1])); + if (!ocr_mask) { + pr_err("%s: voltage-range #%d is invalid\n", + np->full_name, i); + return -EINVAL; + } + *mask |= ocr_mask; + } + + return 0; +} +EXPORT_SYMBOL(mmc_of_parse_voltage); + +#endif /* CONFIG_OF */ + #ifdef CONFIG_REGULATOR /** @@ -1902,7 +1939,6 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, fr = from; nr = to - from + 1; - trace_mmc_blk_erase_start(arg, fr, nr); /* * qty is used to calculate the erase timeout which depends on how many @@ -2008,7 +2044,6 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, (R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG)); out: - trace_mmc_blk_erase_end(arg, fr, nr); return err; } 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) __mmc_claim_host(host, NULL); } +struct device_node; extern u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max); +extern int mmc_of_parse_voltage(struct device_node *np, u32 *mask); #endif /* LINUX_MMC_CORE_H */