[PATCH 1/2] mmc: Add support for marking hpi as broken through devicetree
Ulf Hansson
ulf.hansson at linaro.org
Mon Mar 30 02:14:19 PDT 2015
On 29 March 2015 at 20:09, Hans de Goede <hdegoede at redhat.com> wrote:
> The eMMC on a tablet I've will stop working / communicating as soon as
> the kernel executes:
>
> mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> EXT_CSD_HPI_MGMT, 1,
> card->ext_csd.generic_cmd6_time);
>
> There seems to be no way to reliable identify eMMC-s which have a broken
> hpi implementation, but at least for eMMC's which are soldered onto a board
> we can work around this by specifying that hpi is broken in devicetree.
Seems like a reasonable approach!
>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> ---
> Documentation/devicetree/bindings/mmc/mmc-card.txt | 31 ++++++++++++++++++++++
> drivers/mmc/core/mmc.c | 10 ++++++-
> 2 files changed, 40 insertions(+), 1 deletion(-)
> create mode 100644 Documentation/devicetree/bindings/mmc/mmc-card.txt
>
> diff --git a/Documentation/devicetree/bindings/mmc/mmc-card.txt b/Documentation/devicetree/bindings/mmc/mmc-card.txt
> new file mode 100644
> index 0000000..0cc67fb
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mmc/mmc-card.txt
> @@ -0,0 +1,31 @@
> +mmc-card / eMMC bindings
> +------------------------
> +
> +This documents describes the devicetree bindings for a mmc-host controller
> +child node describing a mmc-card / an eMMC, see "Use of Function subnodes"
> +in mmc.txt
> +
> +Required properties:
> +-compatible : Must be "mmc-card"
> +-reg : Must be <0>
Instead of using a compatible, why can we just use "reg = <0>"?
> +
> +Optional properties:
> +-broken-hpi : Use this to indicate that the mmc-card has a broken hpi
> + implementation, and that hpi should not be used
> +
> +Example:
> +
> +&mmc2 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&mmc2_pins_a>;
> + vmmc-supply = <®_vcc3v3>;
> + bus-width = <8>;
> + non-removable;
> + status = "okay";
> +
> + mmmcard: mmccard at 0 {
> + reg = <0>;
> + compatible = "mmc-card";
> + broken-hpi;
> + };
> +};
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index 1d41e85..8d18920 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -11,6 +11,7 @@
> */
>
> #include <linux/err.h>
> +#include <linux/of.h>
> #include <linux/slab.h>
> #include <linux/stat.h>
> #include <linux/pm_runtime.h>
> @@ -336,6 +337,8 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd)
> {
> int err = 0, idx;
> unsigned int part_size;
> + struct device_node *np = card->dev.of_node;
> + bool broken_hpi = false;
>
> /* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */
> card->ext_csd.raw_ext_csd_structure = ext_csd[EXT_CSD_STRUCTURE];
> @@ -349,6 +352,9 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd)
> }
> }
>
> + if (np && of_device_is_compatible(np, "mmc-card"))
> + broken_hpi = of_property_read_bool(np, "broken-hpi");
> +
> /*
> * The EXT_CSD format is meant to be forward compatible. As long
> * as CSD_STRUCTURE does not change, all values for EXT_CSD_REV
> @@ -494,7 +500,7 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd)
> }
>
> /* check whether the eMMC card supports HPI */
> - if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x1) {
> + if (!broken_hpi && (ext_csd[EXT_CSD_HPI_FEATURES] & 0x1)) {
> card->ext_csd.hpi = 1;
> if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x2)
> card->ext_csd.hpi_cmd = MMC_STOP_TRANSMISSION;
> @@ -1251,6 +1257,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
> card->ocr = ocr;
> card->type = MMC_TYPE_MMC;
> card->rca = 1;
> + /* Also gets done by mmc_add_card, but we need early access */
> + card->dev.of_node = mmc_of_find_child_device(host, 0);
> memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
> }
>
> --
> 2.3.4
>
Kind regards
Uffe
More information about the linux-arm-kernel
mailing list