* [PATCH 0/3] mfd: syscon: Cleanup, fix race condition and remove platform driver
@ 2024-12-11 20:57 Rob Herring (Arm)
2024-12-11 20:57 ` [PATCH 1/3] mfd: syscon: Fix race in device_node_get_regmap() Rob Herring (Arm)
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Rob Herring (Arm) @ 2024-12-11 20:57 UTC (permalink / raw)
To: Lee Jones, Arnd Bergmann, Pankaj Dubey, Heiko Stuebner,
Liviu Dudau, Sudeep Holla, Lorenzo Pieralisi
Cc: Peter Griffin, Will McVicker, Krzysztof Kozlowski, linux-kernel,
linux-arm-kernel
Questions from Krzysztof and a syscon related binding review got me
looking at the syscon "driver". This series is the result.
This short series drops the stale platform driver part of syscon
support, fixes a race condition in device_node_get_regmap()
which is used by all the lookup functions, and allows for registering
nodes without "syscon" compatibles.
Compile tested only. Testing on Tensor, the one user of
of_syscon_register_regmap(), would be helpful.
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
---
Rob Herring (Arm) (3):
mfd: syscon: Fix race in device_node_get_regmap()
mfd: syscon: Remove the platform driver support
mfd: syscon: Allow syscon nodes without a "syscon" compatible
drivers/mfd/syscon.c | 92 +++++-------------------------------
drivers/mfd/vexpress-sysreg.c | 1 -
include/linux/platform_data/syscon.h | 9 ----
3 files changed, 13 insertions(+), 89 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241211-syscon-fixes-9f35ecb9bfbe
Best regards,
--
Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/3] mfd: syscon: Fix race in device_node_get_regmap()
2024-12-11 20:57 [PATCH 0/3] mfd: syscon: Cleanup, fix race condition and remove platform driver Rob Herring (Arm)
@ 2024-12-11 20:57 ` Rob Herring (Arm)
2024-12-12 9:31 ` Krzysztof Kozlowski
2024-12-12 10:21 ` Krzysztof Kozlowski
2024-12-11 20:57 ` [PATCH 2/3] mfd: syscon: Remove the platform driver support Rob Herring (Arm)
2024-12-11 20:57 ` [PATCH 3/3] mfd: syscon: Allow syscon nodes without a "syscon" compatible Rob Herring (Arm)
2 siblings, 2 replies; 11+ messages in thread
From: Rob Herring (Arm) @ 2024-12-11 20:57 UTC (permalink / raw)
To: Lee Jones, Arnd Bergmann, Pankaj Dubey, Heiko Stuebner,
Liviu Dudau, Sudeep Holla, Lorenzo Pieralisi
Cc: Peter Griffin, Will McVicker, Krzysztof Kozlowski, linux-kernel,
linux-arm-kernel
It is possible for multiple, simultaneous callers calling
device_node_get_regmap() with the same node to fail to find an entry in
the syscon_list. There is a period of time while the first caller is
calling of_syscon_register() that subsequent callers also fail to find
an entry in the syscon_list and then call of_syscon_register() a second
time.
Fix this by keeping the lock held until after of_syscon_register()
completes and adds the node to syscon_list. Convert the spinlock to a
mutex as many of the functions called in of_syscon_register() may sleep.
Fixes: bdb0066df96e ("mfd: syscon: Decouple syscon interface from platform devices")
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
---
drivers/mfd/syscon.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index 3e1d699ba934..72f20de9652d 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -15,6 +15,7 @@
#include <linux/io.h>
#include <linux/init.h>
#include <linux/list.h>
+#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
@@ -27,7 +28,7 @@
static struct platform_driver syscon_driver;
-static DEFINE_SPINLOCK(syscon_list_slock);
+static DEFINE_MUTEX(syscon_list_lock);
static LIST_HEAD(syscon_list);
struct syscon {
@@ -54,6 +55,8 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_res)
struct resource res;
struct reset_control *reset;
+ WARN_ON(!mutex_is_locked(&syscon_list_lock));
+
struct syscon *syscon __free(kfree) = kzalloc(sizeof(*syscon), GFP_KERNEL);
if (!syscon)
return ERR_PTR(-ENOMEM);
@@ -146,9 +149,7 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_res)
syscon->regmap = regmap;
syscon->np = np;
- spin_lock(&syscon_list_slock);
list_add_tail(&syscon->list, &syscon_list);
- spin_unlock(&syscon_list_slock);
return_ptr(syscon);
@@ -169,7 +170,7 @@ static struct regmap *device_node_get_regmap(struct device_node *np,
{
struct syscon *entry, *syscon = NULL;
- spin_lock(&syscon_list_slock);
+ mutex_lock(&syscon_list_lock);
list_for_each_entry(entry, &syscon_list, list)
if (entry->np == np) {
@@ -177,11 +178,11 @@ static struct regmap *device_node_get_regmap(struct device_node *np,
break;
}
- spin_unlock(&syscon_list_slock);
-
if (!syscon)
syscon = of_syscon_register(np, check_res);
+ mutex_unlock(&syscon_list_lock);
+
if (IS_ERR(syscon))
return ERR_CAST(syscon);
@@ -212,7 +213,7 @@ int of_syscon_register_regmap(struct device_node *np, struct regmap *regmap)
return -ENOMEM;
/* check if syscon entry already exists */
- spin_lock(&syscon_list_slock);
+ mutex_lock(&syscon_list_lock);
list_for_each_entry(entry, &syscon_list, list)
if (entry->np == np) {
@@ -225,12 +226,12 @@ int of_syscon_register_regmap(struct device_node *np, struct regmap *regmap)
/* register the regmap in syscon list */
list_add_tail(&syscon->list, &syscon_list);
- spin_unlock(&syscon_list_slock);
+ mutex_unlock(&syscon_list_lock);
return 0;
err_unlock:
- spin_unlock(&syscon_list_slock);
+ mutex_unlock(&syscon_list_lock);
kfree(syscon);
return ret;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/3] mfd: syscon: Remove the platform driver support
2024-12-11 20:57 [PATCH 0/3] mfd: syscon: Cleanup, fix race condition and remove platform driver Rob Herring (Arm)
2024-12-11 20:57 ` [PATCH 1/3] mfd: syscon: Fix race in device_node_get_regmap() Rob Herring (Arm)
@ 2024-12-11 20:57 ` Rob Herring (Arm)
2024-12-12 10:21 ` Krzysztof Kozlowski
2024-12-11 20:57 ` [PATCH 3/3] mfd: syscon: Allow syscon nodes without a "syscon" compatible Rob Herring (Arm)
2 siblings, 1 reply; 11+ messages in thread
From: Rob Herring (Arm) @ 2024-12-11 20:57 UTC (permalink / raw)
To: Lee Jones, Arnd Bergmann, Pankaj Dubey, Heiko Stuebner,
Liviu Dudau, Sudeep Holla, Lorenzo Pieralisi
Cc: Peter Griffin, Will McVicker, Krzysztof Kozlowski, linux-kernel,
linux-arm-kernel
The platform driver is dead code. It is not used by DT platforms since
commit bdb0066df96e ("mfd: syscon: Decouple syscon interface from
platform devices") which said:
For non-DT based platforms, this patch keeps syscon platform driver
structure so that syscon can be probed and such non-DT based drivers
can use syscon_regmap_lookup_by_pdev API and access regmap handles.
Once all users of "syscon_regmap_lookup_by_pdev" migrated to DT based,
we can completely remove platform driver of syscon, and keep only helper
functions to get regmap handles.
The last user of syscon_regmap_lookup_by_pdevname() was removed in 2018.
syscon_regmap_lookup_by_pdevname() was then removed in 2019, but that
commit failed to remove the rest of the platform driver.
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
---
drivers/mfd/syscon.c | 66 ------------------------------------
drivers/mfd/vexpress-sysreg.c | 1 -
include/linux/platform_data/syscon.h | 9 -----
3 files changed, 76 deletions(-)
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index 72f20de9652d..bfb1f69fcff1 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -12,22 +12,15 @@
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/hwspinlock.h>
-#include <linux/io.h>
-#include <linux/init.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/of_platform.h>
-#include <linux/platform_data/syscon.h>
-#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/mfd/syscon.h>
#include <linux/slab.h>
-static struct platform_driver syscon_driver;
-
static DEFINE_MUTEX(syscon_list_lock);
static LIST_HEAD(syscon_list);
@@ -337,62 +330,3 @@ struct regmap *syscon_regmap_lookup_by_phandle_optional(struct device_node *np,
return regmap;
}
EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_phandle_optional);
-
-static int syscon_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct syscon_platform_data *pdata = dev_get_platdata(dev);
- struct syscon *syscon;
- struct regmap_config syscon_config = syscon_regmap_config;
- struct resource *res;
- void __iomem *base;
-
- syscon = devm_kzalloc(dev, sizeof(*syscon), GFP_KERNEL);
- if (!syscon)
- return -ENOMEM;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENOENT;
-
- base = devm_ioremap(dev, res->start, resource_size(res));
- if (!base)
- return -ENOMEM;
-
- syscon_config.max_register = resource_size(res) - 4;
- if (!syscon_config.max_register)
- syscon_config.max_register_is_0 = true;
-
- if (pdata)
- syscon_config.name = pdata->label;
- syscon->regmap = devm_regmap_init_mmio(dev, base, &syscon_config);
- if (IS_ERR(syscon->regmap)) {
- dev_err(dev, "regmap init failed\n");
- return PTR_ERR(syscon->regmap);
- }
-
- platform_set_drvdata(pdev, syscon);
-
- dev_dbg(dev, "regmap %pR registered\n", res);
-
- return 0;
-}
-
-static const struct platform_device_id syscon_ids[] = {
- { "syscon", },
- { }
-};
-
-static struct platform_driver syscon_driver = {
- .driver = {
- .name = "syscon",
- },
- .probe = syscon_probe,
- .id_table = syscon_ids,
-};
-
-static int __init syscon_init(void)
-{
- return platform_driver_register(&syscon_driver);
-}
-postcore_initcall(syscon_init);
diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c
index d34d58ce46db..ef03d6cec9ff 100644
--- a/drivers/mfd/vexpress-sysreg.c
+++ b/drivers/mfd/vexpress-sysreg.c
@@ -10,7 +10,6 @@
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/of_platform.h>
-#include <linux/platform_data/syscon.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/stat.h>
diff --git a/include/linux/platform_data/syscon.h b/include/linux/platform_data/syscon.h
deleted file mode 100644
index 2c089dd3e2bd..000000000000
--- a/include/linux/platform_data/syscon.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef PLATFORM_DATA_SYSCON_H
-#define PLATFORM_DATA_SYSCON_H
-
-struct syscon_platform_data {
- const char *label;
-};
-
-#endif
--
2.45.2
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/3] mfd: syscon: Allow syscon nodes without a "syscon" compatible
2024-12-11 20:57 [PATCH 0/3] mfd: syscon: Cleanup, fix race condition and remove platform driver Rob Herring (Arm)
2024-12-11 20:57 ` [PATCH 1/3] mfd: syscon: Fix race in device_node_get_regmap() Rob Herring (Arm)
2024-12-11 20:57 ` [PATCH 2/3] mfd: syscon: Remove the platform driver support Rob Herring (Arm)
@ 2024-12-11 20:57 ` Rob Herring (Arm)
2024-12-11 23:33 ` William McVicker
2024-12-15 20:33 ` John Madieu
2 siblings, 2 replies; 11+ messages in thread
From: Rob Herring (Arm) @ 2024-12-11 20:57 UTC (permalink / raw)
To: Lee Jones, Arnd Bergmann, Pankaj Dubey, Heiko Stuebner,
Liviu Dudau, Sudeep Holla, Lorenzo Pieralisi
Cc: Peter Griffin, Will McVicker, Krzysztof Kozlowski, linux-kernel,
linux-arm-kernel
of_syscon_register_regmap() was added for nodes which need a custom
regmap setup. It's not really correct for those nodes to claim they are
compatible with "syscon" as the default handling likely doesn't work in
those cases. If device_node_get_regmap() happens to be called first,
then of_syscon_register() will be called and an incorrect regmap will be
created (barring some other error). That may lead to unknown results in
the worst case. In the best case, of_syscon_register_regmap() will fail
with -EEXIST. This problem remains unless these cases drop "syscon" (an
ABI issue) or we exclude them using their specific compatible. ATM,
there is only one user: "google,gs101-pmu"
There are also cases of adding "syscon" compatible to existing nodes
after the fact in order to register the syscon. That presents a
potential DT ABI problem. Instead, if there's a kernel change needing a
syscon for a node, then it should be possible to allow the kernel to
register a syscon without a DT change. That's only possible by using
of_syscon_register_regmap() currently, but in the future we may want to
support a match list for cases which don't need a custom regmap.
With this change, the lookup functions will succeed for any node
registered by of_syscon_register_regmap() regardless of whether the node
compatible contains "syscon".
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
---
drivers/mfd/syscon.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index bfb1f69fcff1..e6df2825c14d 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -171,8 +171,10 @@ static struct regmap *device_node_get_regmap(struct device_node *np,
break;
}
- if (!syscon)
+ if (!syscon && of_device_is_compatible(np, "syscon"))
syscon = of_syscon_register(np, check_res);
+ else
+ syscon = ERR_PTR(-EINVAL);
mutex_unlock(&syscon_list_lock);
@@ -238,9 +240,6 @@ EXPORT_SYMBOL_GPL(device_node_to_regmap);
struct regmap *syscon_node_to_regmap(struct device_node *np)
{
- if (!of_device_is_compatible(np, "syscon"))
- return ERR_PTR(-EINVAL);
-
return device_node_get_regmap(np, true);
}
EXPORT_SYMBOL_GPL(syscon_node_to_regmap);
--
2.45.2
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 3/3] mfd: syscon: Allow syscon nodes without a "syscon" compatible
2024-12-11 20:57 ` [PATCH 3/3] mfd: syscon: Allow syscon nodes without a "syscon" compatible Rob Herring (Arm)
@ 2024-12-11 23:33 ` William McVicker
2024-12-15 20:33 ` John Madieu
1 sibling, 0 replies; 11+ messages in thread
From: William McVicker @ 2024-12-11 23:33 UTC (permalink / raw)
To: Rob Herring (Arm)
Cc: Lee Jones, Arnd Bergmann, Pankaj Dubey, Heiko Stuebner,
Liviu Dudau, Sudeep Holla, Lorenzo Pieralisi, Peter Griffin,
Krzysztof Kozlowski, linux-kernel, linux-arm-kernel, kernel-team
Hi Rob,
Thanks for working on this!
On 12/11/2024, Rob Herring (Arm) wrote:
> of_syscon_register_regmap() was added for nodes which need a custom
> regmap setup. It's not really correct for those nodes to claim they are
> compatible with "syscon" as the default handling likely doesn't work in
> those cases. If device_node_get_regmap() happens to be called first,
> then of_syscon_register() will be called and an incorrect regmap will be
> created (barring some other error). That may lead to unknown results in
> the worst case. In the best case, of_syscon_register_regmap() will fail
> with -EEXIST. This problem remains unless these cases drop "syscon" (an
> ABI issue) or we exclude them using their specific compatible. ATM,
> there is only one user: "google,gs101-pmu"
>
> There are also cases of adding "syscon" compatible to existing nodes
> after the fact in order to register the syscon. That presents a
> potential DT ABI problem. Instead, if there's a kernel change needing a
> syscon for a node, then it should be possible to allow the kernel to
> register a syscon without a DT change. That's only possible by using
> of_syscon_register_regmap() currently, but in the future we may want to
> support a match list for cases which don't need a custom regmap.
>
> With this change, the lookup functions will succeed for any node
> registered by of_syscon_register_regmap() regardless of whether the node
> compatible contains "syscon".
>
> Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
> ---
> drivers/mfd/syscon.c | 7 +++----
> 1 file changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
> index bfb1f69fcff1..e6df2825c14d 100644
> --- a/drivers/mfd/syscon.c
> +++ b/drivers/mfd/syscon.c
> @@ -171,8 +171,10 @@ static struct regmap *device_node_get_regmap(struct device_node *np,
> break;
> }
>
> - if (!syscon)
> + if (!syscon && of_device_is_compatible(np, "syscon"))
> syscon = of_syscon_register(np, check_res);
> + else
> + syscon = ERR_PTR(-EINVAL);
This else case actually breaks Pixel 6 (Tensor) since you are now returning
-EINVAL when the syscon is created by the exynos-pmu driver and present in the
list. Instead you should only return -EINVAL if the syscon doesn't exist and
the device node is not a compatible syscon device. If you still want to check
for `of_device_is_compatible(np, "syscon")` even when the syscon is found in
the list, that should be okay , but it's probably best to check that before
inserting the regmap in the list to begin with.
This worked for me on my Pixel 6 device:
if (!syscon) {
if (of_device_is_compatible(np, "syscon"))
syscon = of_syscon_register(np, check_res);
else
syscon = ERR_PTR(-EINVAL);
}
Thanks,
Will
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] mfd: syscon: Fix race in device_node_get_regmap()
2024-12-11 20:57 ` [PATCH 1/3] mfd: syscon: Fix race in device_node_get_regmap() Rob Herring (Arm)
@ 2024-12-12 9:31 ` Krzysztof Kozlowski
2024-12-12 10:21 ` Krzysztof Kozlowski
1 sibling, 0 replies; 11+ messages in thread
From: Krzysztof Kozlowski @ 2024-12-12 9:31 UTC (permalink / raw)
To: Rob Herring (Arm), Lee Jones, Arnd Bergmann, Pankaj Dubey,
Heiko Stuebner, Liviu Dudau, Sudeep Holla, Lorenzo Pieralisi
Cc: Peter Griffin, Will McVicker, linux-kernel, linux-arm-kernel
On 11/12/2024 21:57, Rob Herring (Arm) wrote:
> It is possible for multiple, simultaneous callers calling
> device_node_get_regmap() with the same node to fail to find an entry in
> the syscon_list. There is a period of time while the first caller is
> calling of_syscon_register() that subsequent callers also fail to find
> an entry in the syscon_list and then call of_syscon_register() a second
> time.
>
> Fix this by keeping the lock held until after of_syscon_register()
> completes and adds the node to syscon_list. Convert the spinlock to a
> mutex as many of the functions called in of_syscon_register() may sleep.
Maybe mention the reason for conversion to mutex: lock will be now
containing non-atomic kzalloc and regmap_init_mmio, where the latter
calls clk_get and clk_prepare, which both are sleeping, I believe.
Otherwise it feels you are converting to mutex just to make code better,
which would be then a separate commit.
Everything else looks good.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] mfd: syscon: Fix race in device_node_get_regmap()
2024-12-11 20:57 ` [PATCH 1/3] mfd: syscon: Fix race in device_node_get_regmap() Rob Herring (Arm)
2024-12-12 9:31 ` Krzysztof Kozlowski
@ 2024-12-12 10:21 ` Krzysztof Kozlowski
1 sibling, 0 replies; 11+ messages in thread
From: Krzysztof Kozlowski @ 2024-12-12 10:21 UTC (permalink / raw)
To: Rob Herring (Arm), Lee Jones, Arnd Bergmann, Pankaj Dubey,
Heiko Stuebner, Liviu Dudau, Sudeep Holla, Lorenzo Pieralisi
Cc: Peter Griffin, Will McVicker, linux-kernel, linux-arm-kernel
On 11/12/2024 21:57, Rob Herring (Arm) wrote:
> It is possible for multiple, simultaneous callers calling
> device_node_get_regmap() with the same node to fail to find an entry in
> the syscon_list. There is a period of time while the first caller is
> calling of_syscon_register() that subsequent callers also fail to find
> an entry in the syscon_list and then call of_syscon_register() a second
> time.
>
> Fix this by keeping the lock held until after of_syscon_register()
> completes and adds the node to syscon_list. Convert the spinlock to a
> mutex as many of the functions called in of_syscon_register() may sleep.
>
> Fixes: bdb0066df96e ("mfd: syscon: Decouple syscon interface from platform devices")
> Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Tested on arm64: Qualcomm SM8450
Tested on armv7: Exynos5422
Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/3] mfd: syscon: Remove the platform driver support
2024-12-11 20:57 ` [PATCH 2/3] mfd: syscon: Remove the platform driver support Rob Herring (Arm)
@ 2024-12-12 10:21 ` Krzysztof Kozlowski
0 siblings, 0 replies; 11+ messages in thread
From: Krzysztof Kozlowski @ 2024-12-12 10:21 UTC (permalink / raw)
To: Rob Herring (Arm), Lee Jones, Arnd Bergmann, Pankaj Dubey,
Heiko Stuebner, Liviu Dudau, Sudeep Holla, Lorenzo Pieralisi
Cc: Peter Griffin, Will McVicker, linux-kernel, linux-arm-kernel
On 11/12/2024 21:57, Rob Herring (Arm) wrote:
> The platform driver is dead code. It is not used by DT platforms since
> commit bdb0066df96e ("mfd: syscon: Decouple syscon interface from
> platform devices") which said:
>
> For non-DT based platforms, this patch keeps syscon platform driver
> structure so that syscon can be probed and such non-DT based drivers
> can use syscon_regmap_lookup_by_pdev API and access regmap handles.
> Once all users of "syscon_regmap_lookup_by_pdev" migrated to DT based,
> we can completely remove platform driver of syscon, and keep only helper
> functions to get regmap handles.
>
> The last user of syscon_regmap_lookup_by_pdevname() was removed in 2018.
> syscon_regmap_lookup_by_pdevname() was then removed in 2019, but that
> commit failed to remove the rest of the platform driver.
>
> Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
FWIW:
Tested on arm64: Qualcomm SM8450
Tested on armv7: Samsung Exynos5422
Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 3/3] mfd: syscon: Allow syscon nodes without a "syscon" compatible
2024-12-11 20:57 ` [PATCH 3/3] mfd: syscon: Allow syscon nodes without a "syscon" compatible Rob Herring (Arm)
2024-12-11 23:33 ` William McVicker
@ 2024-12-15 20:33 ` John Madieu
2024-12-16 17:39 ` Rob Herring
1 sibling, 1 reply; 11+ messages in thread
From: John Madieu @ 2024-12-15 20:33 UTC (permalink / raw)
To: robh
Cc: arnd, heiko, krzysztof.kozlowski, lee, linux-arm-kernel,
linux-kernel, liviu.dudau, lpieralisi, pankaj.dubey,
peter.griffin, sudeep.holla, willmcvicker, biju.das.jz
Hi Rob,
On Wed, 11 Dec 2024 14:57:14 -0600 Rob Herring wrote:
> diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
> index bfb1f69fcff1..e6df2825c14d 100644
> --- a/drivers/mfd/syscon.c
> +++ b/drivers/mfd/syscon.c
> @@ -171,8 +171,10 @@ static struct regmap *device_node_get_regmap(struct device_node *np,
> break;
> }
>
> - if (!syscon)
> + if (!syscon && of_device_is_compatible(np, "syscon"))
> syscon = of_syscon_register(np, check_res);
> + else
> + syscon = ERR_PTR(-EINVAL);
The current modification will make device_node_get_regmap() return -EINVAL even
for syscons that were already found in the syscon_list, which I believe is not
the intended behavior.
I suggest modifying it this way to maintain lookup functionality for registered
syscons while implementing your intended changes:
static struct regmap *device_node_get_regmap(struct device_node *np,
bool check_res)
{
struct syscon *entry, *syscon = NULL;
struct regmap *regmap;
mutex_lock(&syscon_list_lock);
list_for_each_entry(entry, &syscon_list, list)
if (entry->np == np) {
syscon = entry;
break;
}
if (syscon) {
regmap = syscon->regmap;
mutex_unlock(&syscon_list_lock);
return regmap;
}
if (of_device_is_compatible(np, "syscon")) {
syscon = of_syscon_register(np, check_res);
mutex_unlock(&syscon_list_lock);
if (IS_ERR(syscon))
return ERR_CAST(syscon);
return syscon->regmap;
}
mutex_unlock(&syscon_list_lock);
return ERR_PTR(-EINVAL);
}
The above is the resulting working function I've obtained while testing with
different scenarios. This ensures that:
1. Already registered syscons are found and returned correctly
2. New syscons with "syscon" compatible are registered as before
3. Nodes without "syscon" compatible return -EINVAL only if not found in the list
This has been tested with my v1 syscon work [1] and with v2, where I remove the
"syscon" compatible string for custom regmap initialization, aligning with your
goals for this series.
Let me know if I should add this series as a dependency of my v2 or how I should proceed.
Thanks,
John Madieu
[1] https://lore.kernel.org/all/20241206212559.192705-2-john.madieu.xa@bp.renesas.com
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 3/3] mfd: syscon: Allow syscon nodes without a "syscon" compatible
2024-12-15 20:33 ` John Madieu
@ 2024-12-16 17:39 ` Rob Herring
2024-12-18 10:50 ` John Madieu
0 siblings, 1 reply; 11+ messages in thread
From: Rob Herring @ 2024-12-16 17:39 UTC (permalink / raw)
To: John Madieu
Cc: arnd, heiko, krzysztof.kozlowski, lee, linux-arm-kernel,
linux-kernel, liviu.dudau, lpieralisi, pankaj.dubey,
peter.griffin, sudeep.holla, willmcvicker, biju.das.jz
On Sun, Dec 15, 2024 at 2:34 PM John Madieu
<john.madieu.xa@bp.renesas.com> wrote:
>
> Hi Rob,
>
> On Wed, 11 Dec 2024 14:57:14 -0600 Rob Herring wrote:
> > diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
> > index bfb1f69fcff1..e6df2825c14d 100644
> > --- a/drivers/mfd/syscon.c
> > +++ b/drivers/mfd/syscon.c
> > @@ -171,8 +171,10 @@ static struct regmap *device_node_get_regmap(struct device_node *np,
> > break;
> > }
> >
> > - if (!syscon)
> > + if (!syscon && of_device_is_compatible(np, "syscon"))
> > syscon = of_syscon_register(np, check_res);
> > + else
> > + syscon = ERR_PTR(-EINVAL);
>
> The current modification will make device_node_get_regmap() return -EINVAL even
> for syscons that were already found in the syscon_list, which I believe is not
> the intended behavior.
Yes, it is. Doesn't Will's fix work for you?
>
> I suggest modifying it this way to maintain lookup functionality for registered
> syscons while implementing your intended changes:
>
> static struct regmap *device_node_get_regmap(struct device_node *np,
> bool check_res)
> {
> struct syscon *entry, *syscon = NULL;
> struct regmap *regmap;
>
> mutex_lock(&syscon_list_lock);
>
> list_for_each_entry(entry, &syscon_list, list)
> if (entry->np == np) {
> syscon = entry;
> break;
> }
>
> if (syscon) {
> regmap = syscon->regmap;
> mut ix_unlock(&syscon_list_lock);
> return regmap;
> }
>
> if (of_device_is_compatible(np, "syscon")) {
> syscon = of_syscon_register(np, check_res);
> mutex_unlock(&syscon_list_lock);
> if (IS_ERR(syscon))
> return ERR_CAST(syscon);
> return syscon->regmap;
> }
>
> mutex_unlock(&syscon_list_lock);
3 unlock calls is a sign the code structure could be improved. A goto
or a guard() for example. However, I think this is the same logic as
what Will suggested.
Rob
^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [PATCH 3/3] mfd: syscon: Allow syscon nodes without a "syscon" compatible
2024-12-16 17:39 ` Rob Herring
@ 2024-12-18 10:50 ` John Madieu
0 siblings, 0 replies; 11+ messages in thread
From: John Madieu @ 2024-12-18 10:50 UTC (permalink / raw)
To: Rob Herring
Cc: arnd@arndb.de, heiko@sntech.de, krzysztof.kozlowski@linaro.org,
lee@kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, liviu.dudau@arm.com,
lpieralisi@kernel.org, pankaj.dubey@samsung.com,
peter.griffin@linaro.org, sudeep.holla@arm.com,
willmcvicker@google.com, Biju Das, Fabrizio Castro
Hi Rob,
> -----Original Message-----
> From: Rob Herring <robh@kernel.org>
> Sent: Monday, December 16, 2024 6:40 PM
> To: John Madieu <john.madieu.xa@bp.renesas.com>
> Cc: arnd@arndb.de; heiko@sntech.de; krzysztof.kozlowski@linaro.org;
> lee@kernel.org; linux-arm-kernel@lists.infradead.org; linux-
> kernel@vger.kernel.org; liviu.dudau@arm.com; lpieralisi@kernel.org;
> pankaj.dubey@samsung.com; peter.griffin@linaro.org; sudeep.holla@arm.com;
> willmcvicker@google.com; Biju Das <biju.das.jz@bp.renesas.com>
> Subject: Re: [PATCH 3/3] mfd: syscon: Allow syscon nodes without a
> "syscon" compatible
>
> On Sun, Dec 15, 2024 at 2:34 PM John Madieu
> <john.madieu.xa@bp.renesas.com> wrote:
> >
> > Hi Rob,
> >
> > On Wed, 11 Dec 2024 14:57:14 -0600 Rob Herring wrote:
> > > diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index
> > > bfb1f69fcff1..e6df2825c14d 100644
> > > --- a/drivers/mfd/syscon.c
> > > +++ b/drivers/mfd/syscon.c
> > > @@ -171,8 +171,10 @@ static struct regmap
> *device_node_get_regmap(struct device_node *np,
> > > break;
> > > }
> > >
> > > - if (!syscon)
> > > + if (!syscon && of_device_is_compatible(np, "syscon"))
> > > syscon = of_syscon_register(np, check_res);
> > > + else
> > > + syscon = ERR_PTR(-EINVAL);
> >
> > The current modification will make device_node_get_regmap() return
> > -EINVAL even for syscons that were already found in the syscon_list,
> > which I believe is not the intended behavior.
>
> Yes, it is. Doesn't Will's fix work for you?
Did not see Will's answer while doing my tests. I however tested it and it
works. I did also test your v2 series, which worked with me as well.
I'll then drop syscon compatible string in my series and send the v2.
Thanks,
John
>
> >
> > I suggest modifying it this way to maintain lookup functionality for
> > registered syscons while implementing your intended changes:
> >
> > static struct regmap *device_node_get_regmap(struct device_node *np,
> > bool check_res) {
> > struct syscon *entry, *syscon = NULL;
> > struct regmap *regmap;
> >
> > mutex_lock(&syscon_list_lock);
> >
> > list_for_each_entry(entry, &syscon_list, list)
> > if (entry->np == np) {
> > syscon = entry;
> > break;
> > }
> >
> > if (syscon) {
> > regmap = syscon->regmap;
> > mut ix_unlock(&syscon_list_lock);
> > return regmap;
> > }
> >
> > if (of_device_is_compatible(np, "syscon")) {
> > syscon = of_syscon_register(np, check_res);
> > mutex_unlock(&syscon_list_lock);
> > if (IS_ERR(syscon))
> > return ERR_CAST(syscon);
> > return syscon->regmap;
> > }
> >
> > mutex_unlock(&syscon_list_lock);
>
> 3 unlock calls is a sign the code structure could be improved. A goto or a
> guard() for example. However, I think this is the same logic as what Will
> suggested.
>
> Rob
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2024-12-18 10:52 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-11 20:57 [PATCH 0/3] mfd: syscon: Cleanup, fix race condition and remove platform driver Rob Herring (Arm)
2024-12-11 20:57 ` [PATCH 1/3] mfd: syscon: Fix race in device_node_get_regmap() Rob Herring (Arm)
2024-12-12 9:31 ` Krzysztof Kozlowski
2024-12-12 10:21 ` Krzysztof Kozlowski
2024-12-11 20:57 ` [PATCH 2/3] mfd: syscon: Remove the platform driver support Rob Herring (Arm)
2024-12-12 10:21 ` Krzysztof Kozlowski
2024-12-11 20:57 ` [PATCH 3/3] mfd: syscon: Allow syscon nodes without a "syscon" compatible Rob Herring (Arm)
2024-12-11 23:33 ` William McVicker
2024-12-15 20:33 ` John Madieu
2024-12-16 17:39 ` Rob Herring
2024-12-18 10:50 ` John Madieu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).