summaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core
diff options
context:
space:
mode:
authorJanusz Krzysztofik <jmkrzyszt@gmail.com>2018-10-12 21:09:01 +0200
committerLinus Walleij <linus.walleij@linaro.org>2018-10-15 16:26:00 +0200
commit9c9f1ddee729846506b5d671ef5084f6e16dd1d1 (patch)
tree7fbc7a0a4900dcb0646227ccc7563a675c615856 /drivers/mmc/core
parenta7c0b4b80f02d748031c785e30d380cfa7fd41ee (diff)
downloadlinux-9c9f1ddee729846506b5d671ef5084f6e16dd1d1.tar.bz2
mmc: pwrseq_simple: Fix incorrect handling of GPIO bitmap
Commit b9762bebc633 ("gpiolib: Pass bitmaps, not integer arrays, to get/set array") changed the way GPIO values are passed to gpiod_get/set_array_value() and friends. The new code introduced into mmc_pwrseq_simple_set_gpios_value() incorrectly interpretes the 'value' argument as a bitmap of GPIO values and assigns it directly to the 'values' bitmap variable passed to gpiod_set_array_value_cansleep() instead of filling that bitmap with bits equal to the 'value' argument. As a result, only member 0 of the array is handled correctly. Moreover, wrong assumption is taken about the 'values' bitmap size not exceding the number of bits of the 'value' argument type. Fix it. Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com> Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Acked-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/mmc/core')
-rw-r--r--drivers/mmc/core/pwrseq_simple.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index 7f882a2bb872..ece34c734693 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -40,13 +40,22 @@ static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq,
struct gpio_descs *reset_gpios = pwrseq->reset_gpios;
if (!IS_ERR(reset_gpios)) {
- DECLARE_BITMAP(values, BITS_PER_TYPE(value));
+ unsigned long *values;
int nvalues = reset_gpios->ndescs;
- values[0] = value;
+ values = bitmap_alloc(nvalues, GFP_KERNEL);
+ if (!values)
+ return;
+
+ if (value)
+ bitmap_fill(values, nvalues);
+ else
+ bitmap_zero(values, nvalues);
gpiod_set_array_value_cansleep(nvalues, reset_gpios->desc,
reset_gpios->info, values);
+
+ kfree(values);
}
}