Thread (20 messages) flat view 20 messages, 4 authors, 2014-09-19

[PATCH v3] mfd: syscon: Decouple syscon interface from platform devices

From: Li.Xiubo at freescale.com <hidden>
Date: 2014-09-19 05:20:46
Also in: linux-samsung-soc, lkml

[...]
quoted
   create child: /dcsr at 20000000/dcsr-atbrepl at 3a8000
   create child: /dcsr at 20000000/dcsr-tsgen-ctrl at 3a9000
   create child: /dcsr at 20000000/dcsr-tsgen-read at 3aa000
   create child: /regulators/regulator at 0
   ...

As default the Linux will create all the platform device for each DT node,
which
quoted
Can be found from "drivers/of/platform.c".

So we can get the pdev node using the specified DT node, and feel safe to
use
quoted
it as Pankaj's patch does.
I mean before the devices are populated from device tree.
For example, we usually call of_platform_populate in .init_machine.
Before it, we may not be able to get it's device, isn't it?
Yes, right.

For this case, we'd better create the pdev or dev manually for the first time
We use it, right ?

Thanks,

BRs
Xiubo

Regards
Dong Aisheng
quoted
And also we must make sure that the 'syscon' DT nodes has the compatible
prop.
quoted
Thanks,

BRs
Xiubo

quoted
Regards
Dong Aisheng
quoted
----
static struct syscon *of_syscon_register(struct device_node *np)
 {
+	struct platform_device *pdev;
 	struct syscon *syscon;
 	struct regmap *regmap;
 	void __iomem *base;
@@ -142,7 +144,11 @@ static struct syscon *of_syscon_register(struct
device_node *np)
 	if (!base)
 		return ERR_PTR(-ENOMEM);

-	regmap = regmap_init_mmio(NULL, base, &syscon_regmap_config);
+	pdev = of_find_device_by_node(np);
+	if (!(&pdev->dev))
+		return ERR_PTR(-ENODEV);
+
+	regmap = regmap_init_mmio(&pdev->dev, base,
&syscon_regmap_config);
quoted
quoted
quoted
 	if (IS_ERR(regmap)) {
 		pr_err("regmap init failed\n");
 		return ERR_CAST(regmap);
-------

I have tested this in linux-next and it works well. In this way there
won't
quoted
quoted
quoted
be any issues of
dereferencing NULL pointer in regmap.c and at the same time, if DT has
{big,little}-endian
optional property in syscon device node, it will be taken care.

So I would wait for Arnd's opinion about above mentioned changes and
then
quoted
quoted
quoted
post a new
change after addressing Arnd's minor comment along with this fix in next
revision.


Thanks,
Pankaj Dubey
quoted
Maybe we could consider create device structure for each syscon
compatible
quoted
quoted
quoted
device in
quoted
syscon driver in of_syscon_register in first time which seems to be
reasonable.
quoted
Regards
Dong Aisheng
quoted
--------------------------------------------
Subject: [PATCH] regmap: fix NULL pointer dereference in
regmap_get_val_endian

Recent commits for getting reg endianess causing NULL pointer
dereference if dev is passed NULL in regmap_init_mmio. This patch
fixes this issue, and allows to parse reg endianess only if dev and
dev->of_node exist.

Signed-off-by: Pankaj Dubey <redacted>
---
 drivers/base/regmap/regmap.c |   23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/drivers/base/regmap/regmap.c
b/drivers/base/regmap/regmap.c index f2281af..455a877 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -477,7 +477,7 @@ static enum regmap_endian
regmap_get_val_endian(struct device *dev,
 					const struct regmap_bus *bus,
 					const struct regmap_config *config)
{
quoted
quoted
-	struct device_node *np = dev->of_node;
+	struct device_node *np;
 	enum regmap_endian endian;

 	/* Retrieve the endianness specification from the regmap config
*/
quoted
quoted
quoted
@@ -487,15 +487,20 @@ static enum regmap_endian
regmap_get_val_endian(struct device *dev,
 	if (endian != REGMAP_ENDIAN_DEFAULT)
 		return endian;

-	/* Parse the device's DT node for an endianness specification */
-	if (of_property_read_bool(np, "big-endian"))
-		endian = REGMAP_ENDIAN_BIG;
-	else if (of_property_read_bool(np, "little-endian"))
-		endian = REGMAP_ENDIAN_LITTLE;
+	/* If the dev and dev->of_node exist try to get endianness from
DT
quoted
quoted
quoted
*/
+	if (dev && dev->of_node) {
+		np = dev->of_node;

-	/* If the endianness was specified in DT, use that */
-	if (endian != REGMAP_ENDIAN_DEFAULT)
-		return endian;
+		/* Parse the device's DT node for an endianness
specification */
+		if (of_property_read_bool(np, "big-endian"))
+			endian = REGMAP_ENDIAN_BIG;
+		else if (of_property_read_bool(np, "little-endian"))
+			endian = REGMAP_ENDIAN_LITTLE;
+
+		/* If the endianness was specified in DT, use that */
+		if (endian != REGMAP_ENDIAN_DEFAULT)
+			return endian;
+	}

 	/* Retrieve the endianness specification from the bus config */
 	if (bus && bus->val_format_endian_default)
--

Thanks,
Pankaj Dubey
quoted
Regards
Dong Aisheng
quoted
Thanks,
Pankaj Dubey
quoted
Regards
Dong Aisheng
quoted

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help