summaryrefslogtreecommitdiff
path: root/drivers/base
diff options
context:
space:
mode:
authorJavier Martinez Canillas <javier.martinez@collabora.co.uk>2014-08-18 13:09:02 (GMT)
committerMatthew Weigel <Matthew.Weigel@freescale.com>2014-12-11 18:36:32 (GMT)
commita5749bf256d6ae6272f46feddbfcaa577505aaf8 (patch)
tree7b12a9c72f1236369bfb5c4349af4e4ad98e856d /drivers/base
parent26c46fba650d25e0c9fd91c31e955d202d2e0e22 (diff)
downloadlinux-fsl-qoriq-a5749bf256d6ae6272f46feddbfcaa577505aaf8.tar.xz
regmap: Fix DT endianess parsing logic
Commit d647c199510c ("regmap: add DT endianness binding support.") added support to parse the device endianness from the device tree but unfortunately the added logic doesn't have the same semantics than the old code. This leads to a NULL dereference pointer error when these properties are not provided by the Device Tree: Unable to handle kernel NULL pointer dereference at virtual address 00000044 pgd = c0004000 [00000044] *pgd=00000000 Internal error: Oops: 5 [#1] PREEMPT SMP ARM Modules linked in: CPU: 5 PID: 1 Comm: swapper/0 Not tainted 3.17.0-rc1-next-20140818ccu #671 task: ea412800 ti: ea484000 task.ti: ea484000 PC is at regmap_update_bits+0xc/0x5c The problem is that platforms that rely on the default value now gets different values due two related issues in the current code: a) It only parses the endianness from DT for the regmap registers and not for the regmap values but it checks unconditionally in both cases if the resulting endiannes is REGMAP_ENDIAN_NATIVE. b) REGMAP_ENDIAN_NATIVE is not even a valid DT property according to the regmap DT binding documentation so it shouldn't be set. Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk> Signed-off-by: Mark Brown <broonie@linaro.org> --- This patch is pulled back from upstream: commit ba1b53feb8cacbd84bcf0e48925e30ad29e141a6 Change-Id: Ifaf8389127b8c931b7f118c124ab0935b0b98dd2 Reviewed-on: http://git.am.freescale.net:8181/19857 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/regmap/regmap.c16
1 files changed, 4 insertions, 12 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 5c0169a..d790447 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -482,7 +482,6 @@ static int of_regmap_get_endian(struct device *dev,
* From the DT node the endianness value maybe:
* REGMAP_ENDIAN_BIG,
* REGMAP_ENDIAN_LITTLE,
- * REGMAP_ENDIAN_NATIVE,
*/
switch (type) {
case REGMAP_ENDIAN_VAL:
@@ -490,8 +489,10 @@ static int of_regmap_get_endian(struct device *dev,
*endian = REGMAP_ENDIAN_BIG;
else if (of_property_read_bool(np, "little-endian"))
*endian = REGMAP_ENDIAN_LITTLE;
- else
- *endian = REGMAP_ENDIAN_NATIVE;
+
+ if (*endian != REGMAP_ENDIAN_DEFAULT)
+ return 0;
+
break;
case REGMAP_ENDIAN_REG:
break;
@@ -500,15 +501,6 @@ static int of_regmap_get_endian(struct device *dev,
}
/*
- * If the endianness parsed from DT node is REGMAP_ENDIAN_NATIVE, that
- * maybe means the DT does not care the endianness or it should use
- * the regmap bus's default endianness, then we should try to check
- * whether the regmap bus has specified the default endianness.
- */
- if (*endian != REGMAP_ENDIAN_NATIVE)
- return 0;
-
- /*
* Finally, try to parse the endianness from regmap bus config
* if in device's DT node the endianness property is absent.
*/