From eecff9a8427a391911accfd077368baeda45c540 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 26 Aug 2019 23:16:44 -0700 Subject: MAINTAINERS: hwspinlock: update git tree location Update the maintainers file to reflect the move of the hwspinlock tree to kernel.org Signed-off-by: Bjorn Andersson --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 296de2b51c83..edecda2be7cf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7234,7 +7234,7 @@ M: Ohad Ben-Cohen M: Bjorn Andersson L: linux-remoteproc@vger.kernel.org S: Maintained -T: git git://git.kernel.org/pub/scm/linux/kernel/git/ohad/hwspinlock.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/andersson/remoteproc.git hwspinlock-next F: Documentation/devicetree/bindings/hwlock/ F: Documentation/hwspinlock.txt F: drivers/hwspinlock/ -- cgit v1.2.3 From 5ee45e0c894636243361fdbaa17828fa00dc7f3a Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Fri, 27 Sep 2019 16:27:41 +0800 Subject: hwspinlock: u8500_hsem: Change to use devm_platform_ioremap_resource() Use the new helper that wraps the calls to platform_get_resource() and devm_ioremap_resource() together, which can simpify the code. Reviewed-by: Linus Walleij Signed-off-by: Baolin Wang Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/u8500_hsem.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/hwspinlock/u8500_hsem.c b/drivers/hwspinlock/u8500_hsem.c index 572ca79d77e8..c247a87fd0b6 100644 --- a/drivers/hwspinlock/u8500_hsem.c +++ b/drivers/hwspinlock/u8500_hsem.c @@ -88,7 +88,6 @@ static int u8500_hsem_probe(struct platform_device *pdev) struct hwspinlock_pdata *pdata = pdev->dev.platform_data; struct hwspinlock_device *bank; struct hwspinlock *hwlock; - struct resource *res; void __iomem *io_base; int i, ret, num_locks = U8500_MAX_SEMAPHORE; ulong val; @@ -96,13 +95,9 @@ static int u8500_hsem_probe(struct platform_device *pdev) if (!pdata) return -ENODEV; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - io_base = ioremap(res->start, resource_size(res)); - if (!io_base) - return -ENOMEM; + io_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(io_base)) + return PTR_ERR(io_base); /* make sure protocol 1 is selected */ val = readl(io_base + HSEM_CTRL_REG); @@ -112,10 +107,8 @@ static int u8500_hsem_probe(struct platform_device *pdev) writel(0xFFFF, io_base + HSEM_ICRALL); bank = kzalloc(struct_size(bank, lock, num_locks), GFP_KERNEL); - if (!bank) { - ret = -ENOMEM; - goto iounmap_base; - } + if (!bank) + return -ENOMEM; platform_set_drvdata(pdev, bank); @@ -135,8 +128,6 @@ static int u8500_hsem_probe(struct platform_device *pdev) reg_fail: pm_runtime_disable(&pdev->dev); kfree(bank); -iounmap_base: - iounmap(io_base); return ret; } @@ -156,7 +147,6 @@ static int u8500_hsem_remove(struct platform_device *pdev) } pm_runtime_disable(&pdev->dev); - iounmap(io_base); kfree(bank); return 0; -- cgit v1.2.3 From 637bcd19beeb9e40b8b64b41e8a8bdf03e918edd Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Fri, 27 Sep 2019 16:27:42 +0800 Subject: hwspinlock: u8500_hsem: Use devm_kzalloc() to allocate memory Use devm_kzalloc() to allocate memory. Reviewed-by: Linus Walleij Signed-off-by: Baolin Wang Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/u8500_hsem.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/hwspinlock/u8500_hsem.c b/drivers/hwspinlock/u8500_hsem.c index c247a87fd0b6..0e8d4ffa867d 100644 --- a/drivers/hwspinlock/u8500_hsem.c +++ b/drivers/hwspinlock/u8500_hsem.c @@ -106,7 +106,8 @@ static int u8500_hsem_probe(struct platform_device *pdev) /* clear all interrupts */ writel(0xFFFF, io_base + HSEM_ICRALL); - bank = kzalloc(struct_size(bank, lock, num_locks), GFP_KERNEL); + bank = devm_kzalloc(&pdev->dev, struct_size(bank, lock, num_locks), + GFP_KERNEL); if (!bank) return -ENOMEM; @@ -120,15 +121,12 @@ static int u8500_hsem_probe(struct platform_device *pdev) ret = hwspin_lock_register(bank, &pdev->dev, &u8500_hwspinlock_ops, pdata->base_id, num_locks); - if (ret) - goto reg_fail; + if (ret) { + pm_runtime_disable(&pdev->dev); + return ret; + } return 0; - -reg_fail: - pm_runtime_disable(&pdev->dev); - kfree(bank); - return ret; } static int u8500_hsem_remove(struct platform_device *pdev) @@ -147,7 +145,6 @@ static int u8500_hsem_remove(struct platform_device *pdev) } pm_runtime_disable(&pdev->dev); - kfree(bank); return 0; } -- cgit v1.2.3 From acc98c1f2a1b4503588d3b1eb35db9cb76abdd89 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Fri, 27 Sep 2019 16:27:43 +0800 Subject: hwspinlock: u8500_hsem: Use devm_hwspin_lock_register() to register hwlock controller Use devm_hwspin_lock_register() to register the hwlock controller instead of unregistering the hwlock controller explicitly when removing the device. Reviewed-by: Linus Walleij Signed-off-by: Baolin Wang Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/u8500_hsem.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/hwspinlock/u8500_hsem.c b/drivers/hwspinlock/u8500_hsem.c index 0e8d4ffa867d..b31141a9b927 100644 --- a/drivers/hwspinlock/u8500_hsem.c +++ b/drivers/hwspinlock/u8500_hsem.c @@ -119,8 +119,8 @@ static int u8500_hsem_probe(struct platform_device *pdev) /* no pm needed for HSem but required to comply with hwspilock core */ pm_runtime_enable(&pdev->dev); - ret = hwspin_lock_register(bank, &pdev->dev, &u8500_hwspinlock_ops, - pdata->base_id, num_locks); + ret = devm_hwspin_lock_register(&pdev->dev, bank, &u8500_hwspinlock_ops, + pdata->base_id, num_locks); if (ret) { pm_runtime_disable(&pdev->dev); return ret; @@ -133,17 +133,10 @@ static int 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; - int ret; /* clear all interrupts */ writel(0xFFFF, io_base + HSEM_ICRALL); - ret = hwspin_lock_unregister(bank); - if (ret) { - dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret); - return ret; - } - pm_runtime_disable(&pdev->dev); return 0; -- cgit v1.2.3 From 74cfa956cbead238cf6c5307be461a087c569c97 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Fri, 27 Sep 2019 15:10:44 +0800 Subject: hwspinlock: sprd: Change to use devm_platform_ioremap_resource() Use the new helper that wraps the calls to platform_get_resource() and devm_ioremap_resource() together, which can simpify the code. Signed-off-by: Baolin Wang Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/sprd_hwspinlock.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/hwspinlock/sprd_hwspinlock.c b/drivers/hwspinlock/sprd_hwspinlock.c index dc42bf51f3e6..7a8534f77737 100644 --- a/drivers/hwspinlock/sprd_hwspinlock.c +++ b/drivers/hwspinlock/sprd_hwspinlock.c @@ -83,7 +83,6 @@ static int sprd_hwspinlock_probe(struct platform_device *pdev) { struct sprd_hwspinlock_dev *sprd_hwlock; struct hwspinlock *lock; - struct resource *res; int i, ret; if (!pdev->dev.of_node) @@ -96,8 +95,7 @@ static int sprd_hwspinlock_probe(struct platform_device *pdev) if (!sprd_hwlock) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - sprd_hwlock->base = devm_ioremap_resource(&pdev->dev, res); + sprd_hwlock->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(sprd_hwlock->base)) return PTR_ERR(sprd_hwlock->base); -- cgit v1.2.3 From 3070c41643609c66d33de3577fc9d8ca15932513 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Fri, 27 Sep 2019 15:10:45 +0800 Subject: hwspinlock: sprd: Check the return value of clk_prepare_enable() We must check the return value of clk_prepare_enable() to make sure the hardware spinlock controller can be enabled successfully, otherwise we should return error. Signed-off-by: Baolin Wang Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/sprd_hwspinlock.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/hwspinlock/sprd_hwspinlock.c b/drivers/hwspinlock/sprd_hwspinlock.c index 7a8534f77737..d2104248013b 100644 --- a/drivers/hwspinlock/sprd_hwspinlock.c +++ b/drivers/hwspinlock/sprd_hwspinlock.c @@ -105,7 +105,9 @@ static int sprd_hwspinlock_probe(struct platform_device *pdev) return PTR_ERR(sprd_hwlock->clk); } - clk_prepare_enable(sprd_hwlock->clk); + ret = clk_prepare_enable(sprd_hwlock->clk); + if (ret) + return ret; /* set the hwspinlock to record user id to identify subsystems */ writel(HWSPINLOCK_USER_BITS, sprd_hwlock->base + HWSPINLOCK_RECCTRL); -- cgit v1.2.3 From b4d64193d41e52a5d35923bc5a0772d9de250092 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Fri, 27 Sep 2019 15:10:46 +0800 Subject: hwspinlock: sprd: Use devm_add_action_or_reset() for calls to clk_disable_unprepare() Use devm_add_action_or_reset() for calls to clk_disable_unprepare(), which can simplify the error handling. Signed-off-by: Baolin Wang Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/sprd_hwspinlock.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/hwspinlock/sprd_hwspinlock.c b/drivers/hwspinlock/sprd_hwspinlock.c index d2104248013b..e76c702f64de 100644 --- a/drivers/hwspinlock/sprd_hwspinlock.c +++ b/drivers/hwspinlock/sprd_hwspinlock.c @@ -79,6 +79,13 @@ static const struct hwspinlock_ops sprd_hwspinlock_ops = { .relax = sprd_hwspinlock_relax, }; +static void sprd_hwspinlock_disable(void *data) +{ + struct sprd_hwspinlock_dev *sprd_hwlock = data; + + clk_disable_unprepare(sprd_hwlock->clk); +} + static int sprd_hwspinlock_probe(struct platform_device *pdev) { struct sprd_hwspinlock_dev *sprd_hwlock; @@ -109,6 +116,14 @@ static int sprd_hwspinlock_probe(struct platform_device *pdev) if (ret) return ret; + ret = devm_add_action_or_reset(&pdev->dev, sprd_hwspinlock_disable, + sprd_hwlock); + if (ret) { + dev_err(&pdev->dev, + "Failed to add hwspinlock disable action\n"); + return ret; + } + /* set the hwspinlock to record user id to identify subsystems */ writel(HWSPINLOCK_USER_BITS, sprd_hwlock->base + HWSPINLOCK_RECCTRL); @@ -124,7 +139,6 @@ static int sprd_hwspinlock_probe(struct platform_device *pdev) &sprd_hwspinlock_ops, 0, SPRD_HWLOCKS_NUM); if (ret) { pm_runtime_disable(&pdev->dev); - clk_disable_unprepare(sprd_hwlock->clk); return ret; } @@ -137,7 +151,6 @@ static int sprd_hwspinlock_remove(struct platform_device *pdev) hwspin_lock_unregister(&sprd_hwlock->bank); pm_runtime_disable(&pdev->dev); - clk_disable_unprepare(sprd_hwlock->clk); return 0; } -- cgit v1.2.3 From b674a30bf8b0edf3b966e32dfcb2e00dfca5a823 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Fri, 27 Sep 2019 15:10:47 +0800 Subject: hwspinlock: sprd: Use devm_hwspin_lock_register() to register hwlock controller Use devm_hwspin_lock_register() to register the hwlock controller instead of unregistering the hwlock controller explicitly when removing the device. Signed-off-by: Baolin Wang Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/sprd_hwspinlock.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/hwspinlock/sprd_hwspinlock.c b/drivers/hwspinlock/sprd_hwspinlock.c index e76c702f64de..44d69db50cbf 100644 --- a/drivers/hwspinlock/sprd_hwspinlock.c +++ b/drivers/hwspinlock/sprd_hwspinlock.c @@ -135,8 +135,9 @@ static int sprd_hwspinlock_probe(struct platform_device *pdev) platform_set_drvdata(pdev, sprd_hwlock); pm_runtime_enable(&pdev->dev); - ret = hwspin_lock_register(&sprd_hwlock->bank, &pdev->dev, - &sprd_hwspinlock_ops, 0, SPRD_HWLOCKS_NUM); + ret = devm_hwspin_lock_register(&pdev->dev, &sprd_hwlock->bank, + &sprd_hwspinlock_ops, 0, + SPRD_HWLOCKS_NUM); if (ret) { pm_runtime_disable(&pdev->dev); return ret; @@ -147,9 +148,6 @@ static int sprd_hwspinlock_probe(struct platform_device *pdev) static int sprd_hwspinlock_remove(struct platform_device *pdev) { - struct sprd_hwspinlock_dev *sprd_hwlock = platform_get_drvdata(pdev); - - hwspin_lock_unregister(&sprd_hwlock->bank); pm_runtime_disable(&pdev->dev); return 0; } -- cgit v1.2.3 From b2547dce4d4a23e8c4a2b0258e3bd31d43dddfad Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Mon, 14 Oct 2019 15:07:43 +0800 Subject: hwspinlock: Remove BUG_ON() from the hwspinlock core The original code use BUG_ON() to validate the parameters when locking or unlocking one hardware lock, but we should not crash the whole kernel though the hwlock parameters are incorrect, instead we can return the error number for users and give some warning. Signed-off-by: Baolin Wang Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/hwspinlock_core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c index 8862445aa858..a22e252c46fc 100644 --- a/drivers/hwspinlock/hwspinlock_core.c +++ b/drivers/hwspinlock/hwspinlock_core.c @@ -92,8 +92,8 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) { int ret; - BUG_ON(!hwlock); - BUG_ON(!flags && mode == HWLOCK_IRQSTATE); + if (WARN_ON(!hwlock || (!flags && mode == HWLOCK_IRQSTATE))) + return -EINVAL; /* * This spin_lock{_irq, _irqsave} serves three purposes: @@ -264,8 +264,8 @@ EXPORT_SYMBOL_GPL(__hwspin_lock_timeout); */ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags) { - BUG_ON(!hwlock); - BUG_ON(!flags && mode == HWLOCK_IRQSTATE); + if (WARN_ON(!hwlock || (!flags && mode == HWLOCK_IRQSTATE))) + return; /* * We must make sure that memory operations (both reads and writes), -- cgit v1.2.3 From a6fc49051cdb847428edf189023b087c1b4fc598 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Mon, 14 Oct 2019 15:07:44 +0800 Subject: hwspinlock: Let the PM runtime can be optional Now some hwspinlock controllers did not have the requirement to implement the PM runtime, but drivers must enable the PM runtime to comply with the hwspinlock core. Thus we can change the PM runtime support to be optional by validating the -EACCES error number which means the PM runtime is not enabled, and removing the return value validating of pm_runtime_put(). So that we can remove some redundant PM runtime code in drivers. Signed-off-by: Baolin Wang Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/hwspinlock_core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c index a22e252c46fc..fd5f5c5a5244 100644 --- a/drivers/hwspinlock/hwspinlock_core.c +++ b/drivers/hwspinlock/hwspinlock_core.c @@ -657,13 +657,15 @@ static int __hwspin_lock_request(struct hwspinlock *hwlock) /* notify PM core that power is now needed */ ret = pm_runtime_get_sync(dev); - if (ret < 0) { + if (ret < 0 && ret != -EACCES) { dev_err(dev, "%s: can't power on device\n", __func__); pm_runtime_put_noidle(dev); module_put(dev->driver->owner); return ret; } + ret = 0; + /* mark hwspinlock as used, should not fail */ tmp = radix_tree_tag_clear(&hwspinlock_tree, hwlock_to_id(hwlock), HWSPINLOCK_UNUSED); @@ -820,9 +822,7 @@ int hwspin_lock_free(struct hwspinlock *hwlock) } /* notify the underlying device that power is not needed */ - ret = pm_runtime_put(dev); - if (ret < 0) - goto out; + pm_runtime_put(dev); /* mark this hwspinlock as available */ tmp = radix_tree_tag_set(&hwspinlock_tree, hwlock_to_id(hwlock), -- cgit v1.2.3 From 4d0c1c57329ac2db987160aa55ffdca479181dbe Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Mon, 14 Oct 2019 15:07:45 +0800 Subject: hwspinlock: sprd: Remove redundant PM runtime implementation Since the hwspinlock core has changed the PM runtime to be optional, thus remove the redundant PM runtime implementation in the Spreadtrum hwlock driver. Signed-off-by: Baolin Wang Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/sprd_hwspinlock.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/drivers/hwspinlock/sprd_hwspinlock.c b/drivers/hwspinlock/sprd_hwspinlock.c index 44d69db50cbf..36dc8038bbb4 100644 --- a/drivers/hwspinlock/sprd_hwspinlock.c +++ b/drivers/hwspinlock/sprd_hwspinlock.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include "hwspinlock_internal.h" @@ -133,23 +132,10 @@ static int sprd_hwspinlock_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, sprd_hwlock); - pm_runtime_enable(&pdev->dev); - ret = devm_hwspin_lock_register(&pdev->dev, &sprd_hwlock->bank, - &sprd_hwspinlock_ops, 0, - SPRD_HWLOCKS_NUM); - if (ret) { - pm_runtime_disable(&pdev->dev); - return ret; - } - - return 0; -} - -static int sprd_hwspinlock_remove(struct platform_device *pdev) -{ - pm_runtime_disable(&pdev->dev); - return 0; + return devm_hwspin_lock_register(&pdev->dev, &sprd_hwlock->bank, + &sprd_hwspinlock_ops, 0, + SPRD_HWLOCKS_NUM); } static const struct of_device_id sprd_hwspinlock_of_match[] = { @@ -160,7 +146,6 @@ MODULE_DEVICE_TABLE(of, sprd_hwspinlock_of_match); static struct platform_driver sprd_hwspinlock_driver = { .probe = sprd_hwspinlock_probe, - .remove = sprd_hwspinlock_remove, .driver = { .name = "sprd_hwspinlock", .of_match_table = of_match_ptr(sprd_hwspinlock_of_match), -- cgit v1.2.3 From 9d399f0c52951c1acf972bf98ea55ba8798fea7a Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Mon, 14 Oct 2019 15:07:46 +0800 Subject: hwspinlock: u8500_hsem: Remove redundant PM runtime implementation Since the hwspinlock core has changed the PM runtime to be optional, thus remove the redundant PM runtime implementation in the u8500 HWSEM driver. Reviewed-by: Linus Walleij Signed-off-by: Baolin Wang Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/u8500_hsem.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/hwspinlock/u8500_hsem.c b/drivers/hwspinlock/u8500_hsem.c index b31141a9b927..67845c0c9701 100644 --- a/drivers/hwspinlock/u8500_hsem.c +++ b/drivers/hwspinlock/u8500_hsem.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -89,7 +88,7 @@ static int u8500_hsem_probe(struct platform_device *pdev) struct hwspinlock_device *bank; struct hwspinlock *hwlock; void __iomem *io_base; - int i, ret, num_locks = U8500_MAX_SEMAPHORE; + int i, num_locks = U8500_MAX_SEMAPHORE; ulong val; if (!pdata) @@ -116,17 +115,9 @@ static int u8500_hsem_probe(struct platform_device *pdev) for (i = 0, hwlock = &bank->lock[0]; i < num_locks; i++, hwlock++) hwlock->priv = io_base + HSEM_REGISTER_OFFSET + sizeof(u32) * i; - /* no pm needed for HSem but required to comply with hwspilock core */ - pm_runtime_enable(&pdev->dev); - - ret = devm_hwspin_lock_register(&pdev->dev, bank, &u8500_hwspinlock_ops, - pdata->base_id, num_locks); - if (ret) { - pm_runtime_disable(&pdev->dev); - return ret; - } - - return 0; + return devm_hwspin_lock_register(&pdev->dev, bank, + &u8500_hwspinlock_ops, + pdata->base_id, num_locks); } static int u8500_hsem_remove(struct platform_device *pdev) @@ -137,8 +128,6 @@ static int u8500_hsem_remove(struct platform_device *pdev) /* clear all interrupts */ writel(0xFFFF, io_base + HSEM_ICRALL); - pm_runtime_disable(&pdev->dev); - return 0; } -- cgit v1.2.3