2019-10-14 07:08:58

by Baolin Wang

[permalink] [raw]
Subject: [PATCH 0/4] Some improvements for hwspinlock

This patch set removes the BUG_ON() from hwspinlock core and changes the
PM runtime support to be optional.

Baolin Wang (4):
hwspinlock: Remove BUG_ON() from the hwspinlock core
hwspinlock: Let the PM runtime can be optional
hwspinlock: sprd: Remove redundant PM runtime implementation
hwspinlock: u8500_hsem: Remove redundant PM runtime implementation

drivers/hwspinlock/hwspinlock_core.c | 16 ++++++++--------
drivers/hwspinlock/sprd_hwspinlock.c | 21 +++------------------
drivers/hwspinlock/u8500_hsem.c | 19 ++++---------------
3 files changed, 15 insertions(+), 41 deletions(-)

--
1.7.9.5


2019-10-14 07:09:05

by Baolin Wang

[permalink] [raw]
Subject: [PATCH 1/4] 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 <[email protected]>
---
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 8862445..a22e252c 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 @@ int __hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int to,
*/
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),
--
1.7.9.5

2019-10-14 07:09:23

by Baolin Wang

[permalink] [raw]
Subject: [PATCH 2/4] 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 <[email protected]>
---
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 a22e252c..fd5f5c5 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),
--
1.7.9.5

2019-10-14 07:10:31

by Baolin Wang

[permalink] [raw]
Subject: [PATCH 3/4] 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 <[email protected]>
---
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 44d69db..36dc803 100644
--- a/drivers/hwspinlock/sprd_hwspinlock.c
+++ b/drivers/hwspinlock/sprd_hwspinlock.c
@@ -15,7 +15,6 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
#include <linux/slab.h>

#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 @@ static int sprd_hwspinlock_remove(struct platform_device *pdev)

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),
--
1.7.9.5

2019-10-14 07:11:38

by Baolin Wang

[permalink] [raw]
Subject: [PATCH 4/4] 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.

Signed-off-by: Baolin Wang <[email protected]>
---
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 b31141a..67845c0 100644
--- a/drivers/hwspinlock/u8500_hsem.c
+++ b/drivers/hwspinlock/u8500_hsem.c
@@ -16,7 +16,6 @@
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/io.h>
-#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/hwspinlock.h>
@@ -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;
}

--
1.7.9.5

2019-10-16 16:00:13

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH 4/4] hwspinlock: u8500_hsem: Remove redundant PM runtime implementation

On Mon, Oct 14, 2019 at 9:08 AM Baolin Wang <[email protected]> wrote:

> Since the hwspinlock core has changed the PM runtime to be optional, thus
> remove the redundant PM runtime implementation in the u8500 HWSEM driver.
>
> Signed-off-by: Baolin Wang <[email protected]>

Reviewed-by: Linus Walleij <[email protected]>

Yours,
Linus Walleij