[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,whichquoted
Can be found from "drivers/of/platform.c". So we can get the pdev node using the specified DT node, and feel safe tousequoted
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 Aishengquoted
And also we must make sure that the 'syscon' DT nodes has the compatibleprop.quoted
Thanks, BRs Xiuboquoted
Regards Dong Aishengquoted
---- 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(structdevice_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 therewon'tquoted
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 andthenquoted
quoted
quoted
post a new change after addressing Arnd's minor comment along with this fix in next revision. Thanks, Pankaj Dubeyquoted
Maybe we could consider create device structure for each sysconcompatiblequoted
quoted
quoted
device inquoted
syscon driver in of_syscon_register in first time which seems to bereasonable.quoted
Regards Dong Aishengquoted
-------------------------------------------- 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.cb/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_endianregmap_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_endianregmap_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 fromDTquoted
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 Dubeyquoted
Regards Dong Aishengquoted
Thanks, Pankaj Dubeyquoted
Regards Dong Aishengquoted
_______________________________________________ linux-arm-kernel mailing list linux-arm-kernel at lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel