Platform device core assumes the ownership of dev.platform_data as
well as that it is dynamically allocated and it will try to kfree it
as a part of platform_device_release(). Change the code to pass
kzalloc'ed chunk of memory instead of a pointer to a static memory to
avoid causing a BUG() when calling platform_device_put().

The problem can be reproduced by artificially enabling the error path
of platform_device_add() call (around line 452).

Cc: Shawn Guo <[email protected]>
Cc: Stefan Agner <[email protected]>
Cc: Lucas Stach <[email protected]>
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Andrey Smirnov <[email protected]>
---

This patch is a follow up to fix one of the bugs discussed in
lkml.kernel.org/r/[email protected]

 drivers/soc/imx/gpc.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/imx/gpc.c b/drivers/soc/imx/gpc.c
index 47e7aa963dbb..ec8b79abebac 100644
--- a/drivers/soc/imx/gpc.c
+++ b/drivers/soc/imx/gpc.c
@@ -18,6 +18,7 @@
 #include <linux/pm_domain.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 
 #define GPC_CNTR               0x000
 
@@ -428,13 +429,19 @@ static int imx_gpc_probe(struct platform_device *pdev)
                        if (domain_index >= of_id_data->num_domains)
                                continue;
 
-                       domain = &imx_gpc_domains[domain_index];
+                       domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+                       if (!domain) {
+                               of_node_put(np);
+                               return -ENOMEM;
+                       }
+                       memcpy(domain, &imx_gpc_domains[domain_index], 
sizeof(*domain));
                        domain->regmap = regmap;
                        domain->ipg_rate_mhz = ipg_rate_mhz;
 
                        pd_pdev = platform_device_alloc("imx-pgc-power-domain",
                                                        domain_index);
                        if (!pd_pdev) {
+                               kfree(domain);
                                of_node_put(np);
                                return -ENOMEM;
                        }
-- 
2.14.3

Reply via email to