From 3c81195a04e13833196462ab398d8bcf282701f7 Mon Sep 17 00:00:00 2001 From: Kang Chen Date: Mon, 27 Feb 2023 08:41:16 +0800 Subject: [PATCH 1/5] hwspinlock: add a check of devm_regmap_field_alloc in qcom_hwspinlock_probe devm_regmap_field_alloc may fails, priv field might be error pointer and cause illegal address access later. Signed-off-by: Kang Chen Link: https://lore.kernel.org/r/20230227004116.1273988-1-void0red@gmail.com Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/qcom_hwspinlock.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/hwspinlock/qcom_hwspinlock.c b/drivers/hwspinlock/qcom_hwspinlock.c index 9cf186362ae2f..dee7bb5eae382 100644 --- a/drivers/hwspinlock/qcom_hwspinlock.c +++ b/drivers/hwspinlock/qcom_hwspinlock.c @@ -197,6 +197,8 @@ static int qcom_hwspinlock_probe(struct platform_device *pdev) bank->lock[i].priv = devm_regmap_field_alloc(&pdev->dev, regmap, field); + if (IS_ERR(bank->lock[i].priv)) + return PTR_ERR(bank->lock[i].priv); } return devm_hwspin_lock_register(&pdev->dev, bank, &qcom_hwspinlock_ops, From 72a3a509f992b6bd182b3380913fe7b4f801075f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 14 Mar 2023 19:00:59 +0100 Subject: [PATCH 2/5] hwspinlock: omap: Emit only one error message for errors in .remove() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a remove callback of a platform driver returns a non-zero value, the driver core emits an error message, otherwise ignores the value and completes unbinding the device. As omap_hwspinlock_remove() already emits an error message, suppress the core's error message by returning zero. Signed-off-by: Uwe Kleine-König Acked-by: Baolin Wang Link: https://lore.kernel.org/r/20230314180100.2865801-1-u.kleine-koenig@pengutronix.de Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/omap_hwspinlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c index dfe82952671b1..a2538c67396f4 100644 --- a/drivers/hwspinlock/omap_hwspinlock.c +++ b/drivers/hwspinlock/omap_hwspinlock.c @@ -153,7 +153,7 @@ static int omap_hwspinlock_remove(struct platform_device *pdev) ret = hwspin_lock_unregister(bank); if (ret) { dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret); - return ret; + return 0; } pm_runtime_disable(&pdev->dev); From 4cf16b6b743e0bbe3128cf97a193ee37110d597b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 14 Mar 2023 19:01:00 +0100 Subject: [PATCH 3/5] hwspinlock: omap: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is (mostly) ignored and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new() which already returns void. Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Signed-off-by: Uwe Kleine-König Acked-by: Baolin Wang Link: https://lore.kernel.org/r/20230314180100.2865801-2-u.kleine-koenig@pengutronix.de Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/omap_hwspinlock.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c index a2538c67396f4..a9fd9ca45f2a8 100644 --- a/drivers/hwspinlock/omap_hwspinlock.c +++ b/drivers/hwspinlock/omap_hwspinlock.c @@ -145,7 +145,7 @@ static int omap_hwspinlock_probe(struct platform_device *pdev) return ret; } -static int omap_hwspinlock_remove(struct platform_device *pdev) +static void omap_hwspinlock_remove(struct platform_device *pdev) { struct hwspinlock_device *bank = platform_get_drvdata(pdev); int ret; @@ -153,12 +153,10 @@ static int omap_hwspinlock_remove(struct platform_device *pdev) ret = hwspin_lock_unregister(bank); if (ret) { dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret); - return 0; + return; } pm_runtime_disable(&pdev->dev); - - return 0; } static const struct of_device_id omap_hwspinlock_of_match[] = { @@ -171,7 +169,7 @@ MODULE_DEVICE_TABLE(of, omap_hwspinlock_of_match); static struct platform_driver omap_hwspinlock_driver = { .probe = omap_hwspinlock_probe, - .remove = omap_hwspinlock_remove, + .remove_new = omap_hwspinlock_remove, .driver = { .name = "omap_hwspinlock", .of_match_table = omap_hwspinlock_of_match, From 9519793bb6a731a3dd2453ad8515e8866e84c48e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 14 Mar 2023 19:02:41 +0100 Subject: [PATCH 4/5] hwspinlock: u8500: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is (mostly) ignored and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new() which already returns void. Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Signed-off-by: Uwe Kleine-König Acked-by: Linus Walleij Acked-by: Baolin Wang Link: https://lore.kernel.org/r/20230314180241.2865888-1-u.kleine-koenig@pengutronix.de Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/u8500_hsem.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/hwspinlock/u8500_hsem.c b/drivers/hwspinlock/u8500_hsem.c index 67845c0c97012..1edca1092f29b 100644 --- a/drivers/hwspinlock/u8500_hsem.c +++ b/drivers/hwspinlock/u8500_hsem.c @@ -120,20 +120,18 @@ static int u8500_hsem_probe(struct platform_device *pdev) pdata->base_id, num_locks); } -static int u8500_hsem_remove(struct platform_device *pdev) +static void u8500_hsem_remove(struct platform_device *pdev) { struct hwspinlock_device *bank = platform_get_drvdata(pdev); void __iomem *io_base = bank->lock[0].priv - HSEM_REGISTER_OFFSET; /* clear all interrupts */ writel(0xFFFF, io_base + HSEM_ICRALL); - - return 0; } static struct platform_driver u8500_hsem_driver = { .probe = u8500_hsem_probe, - .remove = u8500_hsem_remove, + .remove_new = u8500_hsem_remove, .driver = { .name = "u8500_hsem", }, From 23316be8a9d450f33a21f1efe7d89570becbec58 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Sun, 16 Jul 2023 04:28:04 +0200 Subject: [PATCH 5/5] hwspinlock: qcom: add missing regmap config for SFPB MMIO implementation Commit 5d4753f741d8 ("hwspinlock: qcom: add support for MMIO on older SoCs") introduced and made regmap_config mandatory in the of_data struct but didn't add the regmap_config for sfpb based devices. SFPB based devices can both use the legacy syscon way to probe or the new MMIO way and currently device that use the MMIO way are broken as they lack the definition of the now required regmap_config and always return -EINVAL (and indirectly makes fail probing everything that depends on it, smem, nandc with smem-parser...) Fix this by correctly adding the missing regmap_config and restore function of hwspinlock on SFPB based devices with MMIO implementation. Cc: stable@vger.kernel.org Fixes: 5d4753f741d8 ("hwspinlock: qcom: add support for MMIO on older SoCs") Signed-off-by: Christian Marangi Link: https://lore.kernel.org/r/20230716022804.21239-1-ansuelsmth@gmail.com Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/qcom_hwspinlock.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/hwspinlock/qcom_hwspinlock.c b/drivers/hwspinlock/qcom_hwspinlock.c index dee7bb5eae382..a0fd67fd29344 100644 --- a/drivers/hwspinlock/qcom_hwspinlock.c +++ b/drivers/hwspinlock/qcom_hwspinlock.c @@ -69,9 +69,18 @@ static const struct hwspinlock_ops qcom_hwspinlock_ops = { .unlock = qcom_hwspinlock_unlock, }; +static const struct regmap_config sfpb_mutex_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x100, + .fast_io = true, +}; + static const struct qcom_hwspinlock_of_data of_sfpb_mutex = { .offset = 0x4, .stride = 0x4, + .regmap_config = &sfpb_mutex_config, }; static const struct regmap_config tcsr_msm8226_mutex_config = {