From 43b240d41b5173eaebb825f19c423b4278435d2c Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Thu, 9 Jun 2022 13:17:07 +0200 Subject: soc: imx: gpcv2: print errno for regulator errors Make debugging of power management issues easier by printing the reason why a regulator fails to be enabled or disabled. Signed-off-by: Martin Kepplinger Signed-off-by: Shawn Guo --- drivers/soc/imx/gpcv2.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index 85aa86e1338a..6383a4edc360 100644 --- a/drivers/soc/imx/gpcv2.c +++ b/drivers/soc/imx/gpcv2.c @@ -328,7 +328,9 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd) if (!IS_ERR(domain->regulator)) { ret = regulator_enable(domain->regulator); if (ret) { - dev_err(domain->dev, "failed to enable regulator\n"); + dev_err(domain->dev, + "failed to enable regulator: %pe\n", + ERR_PTR(ret)); goto out_put_pm; } } @@ -467,7 +469,9 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd) if (!IS_ERR(domain->regulator)) { ret = regulator_disable(domain->regulator); if (ret) { - dev_err(domain->dev, "failed to disable regulator\n"); + dev_err(domain->dev, + "failed to disable regulator: %pe\n", + ERR_PTR(ret)); return ret; } } -- cgit v1.2.3 From ab3f045774f704c4e7b6a878102f4e9d4ae7bc74 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Mon, 4 Apr 2022 11:56:03 +0200 Subject: soc: fsl: guts: machine variable might be unset If both the model and the compatible properties are missing, then machine will not be set. Initialize it with NULL. Fixes: 34c1c21e94ac ("soc: fsl: fix section mismatch build warnings") Signed-off-by: Michael Walle Acked-by: Arnd Bergmann Signed-off-by: Shawn Guo --- drivers/soc/fsl/guts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/soc') diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c index 5ed2fc1c53a0..be18d46c7b0f 100644 --- a/drivers/soc/fsl/guts.c +++ b/drivers/soc/fsl/guts.c @@ -140,7 +140,7 @@ static int fsl_guts_probe(struct platform_device *pdev) struct device_node *root, *np = pdev->dev.of_node; struct device *dev = &pdev->dev; const struct fsl_soc_die_attr *soc_die; - const char *machine; + const char *machine = NULL; u32 svr; /* Initialize guts */ -- cgit v1.2.3 From 6de6cb89fc031cf95cb759bbf9fa00b139e0281a Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Mon, 4 Apr 2022 11:56:04 +0200 Subject: soc: fsl: guts: remove module_exit() and fsl_guts_remove() This driver will never be unloaded. Firstly, it is not available as a module, but more importantly, other drivers will depend on this one to apply possible chip errata. Signed-off-by: Michael Walle Acked-by: Arnd Bergmann Signed-off-by: Shawn Guo --- drivers/soc/fsl/guts.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c index be18d46c7b0f..0bea43770d51 100644 --- a/drivers/soc/fsl/guts.c +++ b/drivers/soc/fsl/guts.c @@ -27,7 +27,6 @@ struct fsl_soc_die_attr { static struct guts *guts; static struct soc_device_attribute soc_dev_attr; -static struct soc_device *soc_dev; /* SoC die attribute definition for QorIQ platform */ @@ -138,6 +137,7 @@ static u32 fsl_guts_get_svr(void) static int fsl_guts_probe(struct platform_device *pdev) { struct device_node *root, *np = pdev->dev.of_node; + static struct soc_device *soc_dev; struct device *dev = &pdev->dev; const struct fsl_soc_die_attr *soc_die; const char *machine = NULL; @@ -197,12 +197,6 @@ static int fsl_guts_probe(struct platform_device *pdev) return 0; } -static int fsl_guts_remove(struct platform_device *dev) -{ - soc_device_unregister(soc_dev); - return 0; -} - /* * Table for matching compatible strings, for device tree * guts node, for Freescale QorIQ SOCs. @@ -242,7 +236,6 @@ static struct platform_driver fsl_guts_driver = { .of_match_table = fsl_guts_of_match, }, .probe = fsl_guts_probe, - .remove = fsl_guts_remove, }; static int __init fsl_guts_init(void) @@ -250,9 +243,3 @@ static int __init fsl_guts_init(void) return platform_driver_register(&fsl_guts_driver); } core_initcall(fsl_guts_init); - -static void __exit fsl_guts_exit(void) -{ - platform_driver_unregister(&fsl_guts_driver); -} -module_exit(fsl_guts_exit); -- cgit v1.2.3 From ab4988d6a39348dd8c031ef6db946afb9a543f0f Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Mon, 4 Apr 2022 11:56:05 +0200 Subject: soc: fsl: guts: embed fsl_guts_get_svr() in probe() Move the reading of the SVR into the probe function as fsl_guts_get_svr() is the only user of the static guts variable and this lets us drop that as well as the malloc() for this variable. Also, we can unmap the memory region after we accessed it, which will simplify error handling later. Signed-off-by: Michael Walle Acked-by: Arnd Bergmann Signed-off-by: Shawn Guo --- drivers/soc/fsl/guts.c | 42 +++++++++++------------------------------- 1 file changed, 11 insertions(+), 31 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c index 0bea43770d51..4e5675ab5f73 100644 --- a/drivers/soc/fsl/guts.c +++ b/drivers/soc/fsl/guts.c @@ -14,18 +14,12 @@ #include #include -struct guts { - struct ccsr_guts __iomem *regs; - bool little_endian; -}; - struct fsl_soc_die_attr { char *die; u32 svr; u32 mask; }; -static struct guts *guts; static struct soc_device_attribute soc_dev_attr; @@ -119,40 +113,27 @@ static const struct fsl_soc_die_attr *fsl_soc_die_match( return NULL; } -static u32 fsl_guts_get_svr(void) -{ - u32 svr = 0; - - if (!guts || !guts->regs) - return svr; - - if (guts->little_endian) - svr = ioread32(&guts->regs->svr); - else - svr = ioread32be(&guts->regs->svr); - - return svr; -} - static int fsl_guts_probe(struct platform_device *pdev) { struct device_node *root, *np = pdev->dev.of_node; static struct soc_device *soc_dev; struct device *dev = &pdev->dev; const struct fsl_soc_die_attr *soc_die; + struct ccsr_guts __iomem *regs; const char *machine = NULL; + bool little_endian; u32 svr; - /* Initialize guts */ - guts = devm_kzalloc(dev, sizeof(*guts), GFP_KERNEL); - if (!guts) - return -ENOMEM; - - guts->little_endian = of_property_read_bool(np, "little-endian"); + regs = of_iomap(np, 0); + if (IS_ERR(regs)) + return PTR_ERR(regs); - guts->regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(guts->regs)) - return PTR_ERR(guts->regs); + little_endian = of_property_read_bool(np, "little-endian"); + if (little_endian) + svr = ioread32(®s->svr); + else + svr = ioread32be(®s->svr); + iounmap(regs); /* Register soc device */ root = of_find_node_by_path("/"); @@ -167,7 +148,6 @@ static int fsl_guts_probe(struct platform_device *pdev) } of_node_put(root); - svr = fsl_guts_get_svr(); soc_die = fsl_soc_die_match(svr, fsl_soc_die); if (soc_die) { soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, -- cgit v1.2.3 From 5d707e4e3fb5185b24a41d72f75599cc77afab61 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Mon, 4 Apr 2022 11:56:06 +0200 Subject: soc: fsl: guts: allocate soc_dev_attr on the heap This is the last global static variable. Drop it and allocate the memory on the heap instead. Signed-off-by: Michael Walle Acked-by: Arnd Bergmann Signed-off-by: Shawn Guo --- drivers/soc/fsl/guts.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c index 4e5675ab5f73..44e7a9bf6392 100644 --- a/drivers/soc/fsl/guts.c +++ b/drivers/soc/fsl/guts.c @@ -20,9 +20,6 @@ struct fsl_soc_die_attr { u32 mask; }; -static struct soc_device_attribute soc_dev_attr; - - /* SoC die attribute definition for QorIQ platform */ static const struct fsl_soc_die_attr fsl_soc_die[] = { /* @@ -116,6 +113,7 @@ static const struct fsl_soc_die_attr *fsl_soc_die_match( static int fsl_guts_probe(struct platform_device *pdev) { struct device_node *root, *np = pdev->dev.of_node; + struct soc_device_attribute *soc_dev_attr; static struct soc_device *soc_dev; struct device *dev = &pdev->dev; const struct fsl_soc_die_attr *soc_die; @@ -136,12 +134,16 @@ static int fsl_guts_probe(struct platform_device *pdev) iounmap(regs); /* Register soc device */ + soc_dev_attr = devm_kzalloc(dev, sizeof(*soc_dev_attr), GFP_KERNEL); + if (!soc_dev_attr) + return -ENOMEM; + root = of_find_node_by_path("/"); if (of_property_read_string(root, "model", &machine)) of_property_read_string_index(root, "compatible", 0, &machine); if (machine) { - soc_dev_attr.machine = devm_kstrdup(dev, machine, GFP_KERNEL); - if (!soc_dev_attr.machine) { + soc_dev_attr->machine = devm_kstrdup(dev, machine, GFP_KERNEL); + if (!soc_dev_attr->machine) { of_node_put(root); return -ENOMEM; } @@ -150,30 +152,30 @@ static int fsl_guts_probe(struct platform_device *pdev) soc_die = fsl_soc_die_match(svr, fsl_soc_die); if (soc_die) { - soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, - "QorIQ %s", soc_die->die); + soc_dev_attr->family = devm_kasprintf(dev, GFP_KERNEL, + "QorIQ %s", soc_die->die); } else { - soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, "QorIQ"); + soc_dev_attr->family = devm_kasprintf(dev, GFP_KERNEL, "QorIQ"); } - if (!soc_dev_attr.family) + if (!soc_dev_attr->family) return -ENOMEM; - soc_dev_attr.soc_id = devm_kasprintf(dev, GFP_KERNEL, - "svr:0x%08x", svr); - if (!soc_dev_attr.soc_id) + soc_dev_attr->soc_id = devm_kasprintf(dev, GFP_KERNEL, + "svr:0x%08x", svr); + if (!soc_dev_attr->soc_id) return -ENOMEM; - soc_dev_attr.revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d", - (svr >> 4) & 0xf, svr & 0xf); - if (!soc_dev_attr.revision) + soc_dev_attr->revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d", + (svr >> 4) & 0xf, svr & 0xf); + if (!soc_dev_attr->revision) return -ENOMEM; - soc_dev = soc_device_register(&soc_dev_attr); + soc_dev = soc_device_register(soc_dev_attr); if (IS_ERR(soc_dev)) return PTR_ERR(soc_dev); - pr_info("Machine: %s\n", soc_dev_attr.machine); - pr_info("SoC family: %s\n", soc_dev_attr.family); + pr_info("Machine: %s\n", soc_dev_attr->machine); + pr_info("SoC family: %s\n", soc_dev_attr->family); pr_info("SoC ID: %s, Revision: %s\n", - soc_dev_attr.soc_id, soc_dev_attr.revision); + soc_dev_attr->soc_id, soc_dev_attr->revision); return 0; } -- cgit v1.2.3 From b46dd0cb93decf58c43db0a39c1c047fc5315901 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Mon, 4 Apr 2022 11:56:07 +0200 Subject: soc: fsl: guts: use of_root instead of own reference There is already a global of_root reference. Use that instead of getting one on our own. We don't need to care about the reference count either this way. Signed-off-by: Michael Walle Acked-by: Arnd Bergmann Signed-off-by: Shawn Guo --- drivers/soc/fsl/guts.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c index 44e7a9bf6392..585cbd9d8224 100644 --- a/drivers/soc/fsl/guts.c +++ b/drivers/soc/fsl/guts.c @@ -112,7 +112,7 @@ static const struct fsl_soc_die_attr *fsl_soc_die_match( static int fsl_guts_probe(struct platform_device *pdev) { - struct device_node *root, *np = pdev->dev.of_node; + struct device_node *np = pdev->dev.of_node; struct soc_device_attribute *soc_dev_attr; static struct soc_device *soc_dev; struct device *dev = &pdev->dev; @@ -138,17 +138,13 @@ static int fsl_guts_probe(struct platform_device *pdev) if (!soc_dev_attr) return -ENOMEM; - root = of_find_node_by_path("/"); - if (of_property_read_string(root, "model", &machine)) - of_property_read_string_index(root, "compatible", 0, &machine); + if (of_property_read_string(of_root, "model", &machine)) + of_property_read_string_index(of_root, "compatible", 0, &machine); if (machine) { soc_dev_attr->machine = devm_kstrdup(dev, machine, GFP_KERNEL); - if (!soc_dev_attr->machine) { - of_node_put(root); + if (!soc_dev_attr->machine) return -ENOMEM; - } } - of_node_put(root); soc_die = fsl_soc_die_match(svr, fsl_soc_die); if (soc_die) { -- cgit v1.2.3 From 55488c90b392d74a6a8bbd358b7129aab0b19aee Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Mon, 4 Apr 2022 11:56:08 +0200 Subject: soc: fsl: guts: drop platform driver This driver cannot be unloaded and it will be needed very early in the boot process because other driver (weakly) depend on it (eg. for chip errata handling). Drop all the platform driver and devres stuff and simply make it a core_initcall. Signed-off-by: Michael Walle Acked-by: Arnd Bergmann Signed-off-by: Shawn Guo --- drivers/soc/fsl/guts.c | 134 ++++++++++++++++++++++++++----------------------- 1 file changed, 71 insertions(+), 63 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c index 585cbd9d8224..370be923aa0f 100644 --- a/drivers/soc/fsl/guts.c +++ b/drivers/soc/fsl/guts.c @@ -110,21 +110,59 @@ static const struct fsl_soc_die_attr *fsl_soc_die_match( return NULL; } -static int fsl_guts_probe(struct platform_device *pdev) +/* + * Table for matching compatible strings, for device tree + * guts node, for Freescale QorIQ SOCs. + */ +static const struct of_device_id fsl_guts_of_match[] = { + { .compatible = "fsl,qoriq-device-config-1.0", }, + { .compatible = "fsl,qoriq-device-config-2.0", }, + { .compatible = "fsl,p1010-guts", }, + { .compatible = "fsl,p1020-guts", }, + { .compatible = "fsl,p1021-guts", }, + { .compatible = "fsl,p1022-guts", }, + { .compatible = "fsl,p1023-guts", }, + { .compatible = "fsl,p2020-guts", }, + { .compatible = "fsl,bsc9131-guts", }, + { .compatible = "fsl,bsc9132-guts", }, + { .compatible = "fsl,mpc8536-guts", }, + { .compatible = "fsl,mpc8544-guts", }, + { .compatible = "fsl,mpc8548-guts", }, + { .compatible = "fsl,mpc8568-guts", }, + { .compatible = "fsl,mpc8569-guts", }, + { .compatible = "fsl,mpc8572-guts", }, + { .compatible = "fsl,ls1021a-dcfg", }, + { .compatible = "fsl,ls1043a-dcfg", }, + { .compatible = "fsl,ls2080a-dcfg", }, + { .compatible = "fsl,ls1088a-dcfg", }, + { .compatible = "fsl,ls1012a-dcfg", }, + { .compatible = "fsl,ls1046a-dcfg", }, + { .compatible = "fsl,lx2160a-dcfg", }, + { .compatible = "fsl,ls1028a-dcfg", }, + {} +}; + +static int __init fsl_guts_init(void) { - struct device_node *np = pdev->dev.of_node; struct soc_device_attribute *soc_dev_attr; static struct soc_device *soc_dev; - struct device *dev = &pdev->dev; const struct fsl_soc_die_attr *soc_die; struct ccsr_guts __iomem *regs; const char *machine = NULL; + struct device_node *np; bool little_endian; u32 svr; + int ret; + + np = of_find_matching_node_and_match(NULL, fsl_guts_of_match, NULL); + if (!np) + return 0; regs = of_iomap(np, 0); - if (IS_ERR(regs)) + if (IS_ERR(regs)) { + of_node_put(np); return PTR_ERR(regs); + } little_endian = of_property_read_bool(np, "little-endian"); if (little_endian) @@ -132,92 +170,62 @@ static int fsl_guts_probe(struct platform_device *pdev) else svr = ioread32be(®s->svr); iounmap(regs); + of_node_put(np); /* Register soc device */ - soc_dev_attr = devm_kzalloc(dev, sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); if (!soc_dev_attr) return -ENOMEM; if (of_property_read_string(of_root, "model", &machine)) of_property_read_string_index(of_root, "compatible", 0, &machine); if (machine) { - soc_dev_attr->machine = devm_kstrdup(dev, machine, GFP_KERNEL); + soc_dev_attr->machine = kstrdup(machine, GFP_KERNEL); if (!soc_dev_attr->machine) - return -ENOMEM; + goto err_nomem; } soc_die = fsl_soc_die_match(svr, fsl_soc_die); if (soc_die) { - soc_dev_attr->family = devm_kasprintf(dev, GFP_KERNEL, - "QorIQ %s", soc_die->die); + soc_dev_attr->family = kasprintf(GFP_KERNEL, "QorIQ %s", + soc_die->die); } else { - soc_dev_attr->family = devm_kasprintf(dev, GFP_KERNEL, "QorIQ"); + soc_dev_attr->family = kasprintf(GFP_KERNEL, "QorIQ"); } if (!soc_dev_attr->family) - return -ENOMEM; - soc_dev_attr->soc_id = devm_kasprintf(dev, GFP_KERNEL, - "svr:0x%08x", svr); + goto err_nomem; + + soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "svr:0x%08x", svr); if (!soc_dev_attr->soc_id) - return -ENOMEM; - soc_dev_attr->revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d", - (svr >> 4) & 0xf, svr & 0xf); + goto err_nomem; + + soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d.%d", + (svr >> 4) & 0xf, svr & 0xf); if (!soc_dev_attr->revision) - return -ENOMEM; + goto err_nomem; soc_dev = soc_device_register(soc_dev_attr); - if (IS_ERR(soc_dev)) - return PTR_ERR(soc_dev); + if (IS_ERR(soc_dev)) { + ret = PTR_ERR(soc_dev); + goto err; + } pr_info("Machine: %s\n", soc_dev_attr->machine); pr_info("SoC family: %s\n", soc_dev_attr->family); pr_info("SoC ID: %s, Revision: %s\n", soc_dev_attr->soc_id, soc_dev_attr->revision); - return 0; -} -/* - * Table for matching compatible strings, for device tree - * guts node, for Freescale QorIQ SOCs. - */ -static const struct of_device_id fsl_guts_of_match[] = { - { .compatible = "fsl,qoriq-device-config-1.0", }, - { .compatible = "fsl,qoriq-device-config-2.0", }, - { .compatible = "fsl,p1010-guts", }, - { .compatible = "fsl,p1020-guts", }, - { .compatible = "fsl,p1021-guts", }, - { .compatible = "fsl,p1022-guts", }, - { .compatible = "fsl,p1023-guts", }, - { .compatible = "fsl,p2020-guts", }, - { .compatible = "fsl,bsc9131-guts", }, - { .compatible = "fsl,bsc9132-guts", }, - { .compatible = "fsl,mpc8536-guts", }, - { .compatible = "fsl,mpc8544-guts", }, - { .compatible = "fsl,mpc8548-guts", }, - { .compatible = "fsl,mpc8568-guts", }, - { .compatible = "fsl,mpc8569-guts", }, - { .compatible = "fsl,mpc8572-guts", }, - { .compatible = "fsl,ls1021a-dcfg", }, - { .compatible = "fsl,ls1043a-dcfg", }, - { .compatible = "fsl,ls2080a-dcfg", }, - { .compatible = "fsl,ls1088a-dcfg", }, - { .compatible = "fsl,ls1012a-dcfg", }, - { .compatible = "fsl,ls1046a-dcfg", }, - { .compatible = "fsl,lx2160a-dcfg", }, - { .compatible = "fsl,ls1028a-dcfg", }, - {} -}; -MODULE_DEVICE_TABLE(of, fsl_guts_of_match); + return 0; -static struct platform_driver fsl_guts_driver = { - .driver = { - .name = "fsl-guts", - .of_match_table = fsl_guts_of_match, - }, - .probe = fsl_guts_probe, -}; +err_nomem: + ret = -ENOMEM; +err: + kfree(soc_dev_attr->machine); + kfree(soc_dev_attr->family); + kfree(soc_dev_attr->soc_id); + kfree(soc_dev_attr->revision); + kfree(soc_dev_attr); -static int __init fsl_guts_init(void) -{ - return platform_driver_register(&fsl_guts_driver); + return ret; } core_initcall(fsl_guts_init); -- cgit v1.2.3 From 786dde1e59d7122f55e42f5ab1167bc10ad87a41 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Mon, 4 Apr 2022 11:56:09 +0200 Subject: soc: fsl: guts: add serial_number support Most layerscapes provide a security fuse processor where the vendor will store a unique id per part. Unfortunately, we cannot use the corresponding efuse driver because this driver needs to be ready early during the boot phase. To get the unique identifier, we just need to access two registers. Thus we just search the device tree for the corresponding device, map its memory to read the id and then unmap it again. Because it is likely that the offset within the fuses is dependent on the SoC, we need a per SoC data. Also, the compatible string is different among the SoCs. For now, this add support for the LS1028A SoC. Signed-off-by: Michael Walle Acked-by: Arnd Bergmann Signed-off-by: Shawn Guo --- drivers/soc/fsl/guts.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c index 370be923aa0f..27035de062f8 100644 --- a/drivers/soc/fsl/guts.c +++ b/drivers/soc/fsl/guts.c @@ -20,6 +20,11 @@ struct fsl_soc_die_attr { u32 mask; }; +struct fsl_soc_data { + const char *sfp_compat; + u32 uid_offset; +}; + /* SoC die attribute definition for QorIQ platform */ static const struct fsl_soc_die_attr fsl_soc_die[] = { /* @@ -110,6 +115,33 @@ static const struct fsl_soc_die_attr *fsl_soc_die_match( return NULL; } +static u64 fsl_guts_get_soc_uid(const char *compat, unsigned int offset) +{ + struct device_node *np; + void __iomem *sfp_base; + u64 uid; + + np = of_find_compatible_node(NULL, NULL, compat); + if (!np) + return 0; + + sfp_base = of_iomap(np, 0); + + uid = ioread32(sfp_base + offset); + uid <<= 32; + uid |= ioread32(sfp_base + offset + 4); + + iounmap(sfp_base); + of_node_put(np); + + return uid; +} + +static const struct fsl_soc_data ls1028a_data = { + .sfp_compat = "fsl,ls1028a-sfp", + .uid_offset = 0x21c, +}; + /* * Table for matching compatible strings, for device tree * guts node, for Freescale QorIQ SOCs. @@ -138,7 +170,7 @@ static const struct of_device_id fsl_guts_of_match[] = { { .compatible = "fsl,ls1012a-dcfg", }, { .compatible = "fsl,ls1046a-dcfg", }, { .compatible = "fsl,lx2160a-dcfg", }, - { .compatible = "fsl,ls1028a-dcfg", }, + { .compatible = "fsl,ls1028a-dcfg", .data = &ls1028a_data}, {} }; @@ -147,16 +179,20 @@ static int __init fsl_guts_init(void) struct soc_device_attribute *soc_dev_attr; static struct soc_device *soc_dev; const struct fsl_soc_die_attr *soc_die; + const struct fsl_soc_data *soc_data; + const struct of_device_id *match; struct ccsr_guts __iomem *regs; const char *machine = NULL; struct device_node *np; bool little_endian; + u64 soc_uid = 0; u32 svr; int ret; - np = of_find_matching_node_and_match(NULL, fsl_guts_of_match, NULL); + np = of_find_matching_node_and_match(NULL, fsl_guts_of_match, &match); if (!np) return 0; + soc_data = match->data; regs = of_iomap(np, 0); if (IS_ERR(regs)) { @@ -204,6 +240,13 @@ static int __init fsl_guts_init(void) if (!soc_dev_attr->revision) goto err_nomem; + if (soc_data) + soc_uid = fsl_guts_get_soc_uid(soc_data->sfp_compat, + soc_data->uid_offset); + if (soc_uid) + soc_dev_attr->serial_number = kasprintf(GFP_KERNEL, "%016llX", + soc_uid); + soc_dev = soc_device_register(soc_dev_attr); if (IS_ERR(soc_dev)) { ret = PTR_ERR(soc_dev); @@ -224,6 +267,7 @@ err: kfree(soc_dev_attr->family); kfree(soc_dev_attr->soc_id); kfree(soc_dev_attr->revision); + kfree(soc_dev_attr->serial_number); kfree(soc_dev_attr); return ret; -- cgit v1.2.3 From 1ec32a4f1c694b5424f6fab1a977d3e556c539bf Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 24 Jun 2022 20:29:39 +0200 Subject: soc: imx: imx8m-blk-ctrl: Make error prints useful Print the name of the power domain which failed to make the error prints actually useful for finding the error. Signed-off-by: Marek Vasut Cc: Alexander Stein Cc: Lucas Stach Cc: Martyn Welch Cc: Paul Elder Cc: Shawn Guo Acked-by: Alexander Stein Signed-off-by: Shawn Guo --- drivers/soc/imx/imx8m-blk-ctrl.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/imx/imx8m-blk-ctrl.c b/drivers/soc/imx/imx8m-blk-ctrl.c index 7f49385ed2f8..2a1a47d06eab 100644 --- a/drivers/soc/imx/imx8m-blk-ctrl.c +++ b/drivers/soc/imx/imx8m-blk-ctrl.c @@ -216,7 +216,7 @@ static int imx8m_blk_ctrl_probe(struct platform_device *pdev) bc->bus_power_dev = genpd_dev_pm_attach_by_name(dev, "bus"); if (IS_ERR(bc->bus_power_dev)) return dev_err_probe(dev, PTR_ERR(bc->bus_power_dev), - "failed to attach power domain\n"); + "failed to attach power domain \"bus\"\n"); for (i = 0; i < bc_data->num_domains; i++) { const struct imx8m_blk_ctrl_domain_data *data = &bc_data->domains[i]; @@ -238,7 +238,8 @@ static int imx8m_blk_ctrl_probe(struct platform_device *pdev) dev_pm_domain_attach_by_name(dev, data->gpc_name); if (IS_ERR(domain->power_dev)) { dev_err_probe(dev, PTR_ERR(domain->power_dev), - "failed to attach power domain\n"); + "failed to attach power domain \"%s\"\n", + data->gpc_name); ret = PTR_ERR(domain->power_dev); goto cleanup_pds; } @@ -251,7 +252,9 @@ static int imx8m_blk_ctrl_probe(struct platform_device *pdev) ret = pm_genpd_init(&domain->genpd, NULL, true); if (ret) { - dev_err_probe(dev, ret, "failed to init power domain\n"); + dev_err_probe(dev, ret, + "failed to init power domain \"%s\"\n", + data->gpc_name); dev_pm_domain_detach(domain->power_dev, true); goto cleanup_pds; } -- cgit v1.2.3 From edf12b913abb69abce4cd6996398a4ce23e5b047 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 28 Jun 2022 22:02:48 +0800 Subject: soc: fsl: guts: fix return value check in fsl_guts_init() In case of error, of_iomap() returns NULL pointer not ERR_PTR(). The IS_ERR() test in the return value check should be replaced with NULL test and return -ENOMEM as error value. Reported-by: Hulk Robot Signed-off-by: Yang Yingliang Reviewed-by: Michael Walle Signed-off-by: Shawn Guo --- drivers/soc/fsl/guts.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c index 27035de062f8..8038c599ad83 100644 --- a/drivers/soc/fsl/guts.c +++ b/drivers/soc/fsl/guts.c @@ -195,9 +195,9 @@ static int __init fsl_guts_init(void) soc_data = match->data; regs = of_iomap(np, 0); - if (IS_ERR(regs)) { + if (!regs) { of_node_put(np); - return PTR_ERR(regs); + return -ENOMEM; } little_endian = of_property_read_bool(np, "little-endian"); -- cgit v1.2.3 From 63f98153075167a6c88d8ac90bfd26f1887c670c Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 28 Jun 2022 22:02:49 +0800 Subject: soc: fsl: guts: check return value after calling of_iomap() in fsl_guts_get_soc_uid() of_iomap() may return NULL, so we need check the return value. Reported-by: Hulk Robot Signed-off-by: Yang Yingliang Reviewed-by: Michael Walle Signed-off-by: Shawn Guo --- drivers/soc/fsl/guts.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/soc') diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c index 8038c599ad83..6bf3e6a980ff 100644 --- a/drivers/soc/fsl/guts.c +++ b/drivers/soc/fsl/guts.c @@ -126,6 +126,10 @@ static u64 fsl_guts_get_soc_uid(const char *compat, unsigned int offset) return 0; sfp_base = of_iomap(np, 0); + if (!sfp_base) { + of_node_put(np); + return 0; + } uid = ioread32(sfp_base + offset); uid <<= 32; -- cgit v1.2.3