From 66742b19e5e0d01297d355cc445d4920b648821b Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Sun, 8 Apr 2018 11:06:56 +0800 Subject: [PATCH 1/8] hwspinlock: Convert to use 'switch' statement We have different hwspinlock modes to select, thus it will be more readable to handle different modes with using 'switch' statement instead of 'if' statement. Signed-off-by: Baolin Wang Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/hwspinlock_core.c | 33 ++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c index 4074441444fe..f4a59f5631e4 100644 --- a/drivers/hwspinlock/hwspinlock_core.c +++ b/drivers/hwspinlock/hwspinlock_core.c @@ -106,12 +106,17 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) * problems with hwspinlock usage (e.g. scheduler checks like * 'scheduling while atomic' etc.) */ - if (mode == HWLOCK_IRQSTATE) + switch (mode) { + case HWLOCK_IRQSTATE: ret = spin_trylock_irqsave(&hwlock->lock, *flags); - else if (mode == HWLOCK_IRQ) + break; + case HWLOCK_IRQ: ret = spin_trylock_irq(&hwlock->lock); - else + break; + default: ret = spin_trylock(&hwlock->lock); + break; + } /* is lock already taken by another context on the local cpu ? */ if (!ret) @@ -122,12 +127,17 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) /* if hwlock is already taken, undo spin_trylock_* and exit */ if (!ret) { - if (mode == HWLOCK_IRQSTATE) + switch (mode) { + case HWLOCK_IRQSTATE: spin_unlock_irqrestore(&hwlock->lock, *flags); - else if (mode == HWLOCK_IRQ) + break; + case HWLOCK_IRQ: spin_unlock_irq(&hwlock->lock); - else + break; + default: spin_unlock(&hwlock->lock); + break; + } return -EBUSY; } @@ -249,12 +259,17 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags) hwlock->bank->ops->unlock(hwlock); /* Undo the spin_trylock{_irq, _irqsave} called while locking */ - if (mode == HWLOCK_IRQSTATE) + switch (mode) { + case HWLOCK_IRQSTATE: spin_unlock_irqrestore(&hwlock->lock, *flags); - else if (mode == HWLOCK_IRQ) + break; + case HWLOCK_IRQ: spin_unlock_irq(&hwlock->lock); - else + break; + default: spin_unlock(&hwlock->lock); + break; + } } EXPORT_SYMBOL_GPL(__hwspin_unlock); From 1e6c06a7e88c251d8a30271ad5206fbd967a4576 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Sun, 8 Apr 2018 11:06:57 +0800 Subject: [PATCH 2/8] hwspinlock: Introduce one new mode for hwspinlock In some scenarios, user need do some time-consuming or sleepable operations under the hardware spinlock protection for synchronization between the multiple subsystems. For example, there is one PMIC efuse on Spreadtrum platform, which need to be accessed under one hardware lock. But during the hardware lock protection, the efuse operation is time-consuming to almost 5 ms, so we can not disable the interrupts or preemption so long in this case. Thus we can introduce one new mode to indicate that we just acquire the hardware lock and do not disable interrupts or preemption, meanwhile we should force user to protect the hardware lock with mutex or spinlock to avoid dead-lock. Signed-off-by: Baolin Wang Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/hwspinlock_core.c | 34 ++++++++++++---- include/linux/hwspinlock.h | 58 ++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 7 deletions(-) diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c index f4a59f5631e4..5278d0560a4a 100644 --- a/drivers/hwspinlock/hwspinlock_core.c +++ b/drivers/hwspinlock/hwspinlock_core.c @@ -71,10 +71,16 @@ static DEFINE_MUTEX(hwspinlock_tree_lock); * This function attempts to lock an hwspinlock, and will immediately * fail if the hwspinlock is already taken. * - * Upon a successful return from this function, preemption (and possibly - * interrupts) is disabled, so the caller must not sleep, and is advised to - * release the hwspinlock as soon as possible. This is required in order to - * minimize remote cores polling on the hardware interconnect. + * Caution: If the mode is HWLOCK_RAW, that means user must protect the routine + * of getting hardware lock with mutex or spinlock. Since in some scenarios, + * user need some time-consuming or sleepable operations under the hardware + * lock, they need one sleepable lock (like mutex) to protect the operations. + * + * If the mode is not HWLOCK_RAW, upon a successful return from this function, + * preemption (and possibly interrupts) is disabled, so the caller must not + * sleep, and is advised to release the hwspinlock as soon as possible. This is + * required in order to minimize remote cores polling on the hardware + * interconnect. * * The user decides whether local interrupts are disabled or not, and if yes, * whether he wants their previous state to be saved. It is up to the user @@ -113,6 +119,9 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) case HWLOCK_IRQ: ret = spin_trylock_irq(&hwlock->lock); break; + case HWLOCK_RAW: + ret = 1; + break; default: ret = spin_trylock(&hwlock->lock); break; @@ -134,6 +143,9 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) case HWLOCK_IRQ: spin_unlock_irq(&hwlock->lock); break; + case HWLOCK_RAW: + /* Nothing to do */ + break; default: spin_unlock(&hwlock->lock); break; @@ -170,9 +182,14 @@ EXPORT_SYMBOL_GPL(__hwspin_trylock); * is already taken, the function will busy loop waiting for it to * be released, but give up after @timeout msecs have elapsed. * - * Upon a successful return from this function, preemption is disabled - * (and possibly local interrupts, too), so the caller must not sleep, - * and is advised to release the hwspinlock as soon as possible. + * Caution: If the mode is HWLOCK_RAW, that means user must protect the routine + * of getting hardware lock with mutex or spinlock. Since in some scenarios, + * user need some time-consuming or sleepable operations under the hardware + * lock, they need one sleepable lock (like mutex) to protect the operations. + * + * If the mode is not HWLOCK_RAW, upon a successful return from this function, + * preemption is disabled (and possibly local interrupts, too), so the caller + * must not sleep, and is advised to release the hwspinlock as soon as possible. * This is required in order to minimize remote cores polling on the * hardware interconnect. * @@ -266,6 +283,9 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags) case HWLOCK_IRQ: spin_unlock_irq(&hwlock->lock); break; + case HWLOCK_RAW: + /* Nothing to do */ + break; default: spin_unlock(&hwlock->lock); break; diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h index 859d673d98c8..fe450ee58d55 100644 --- a/include/linux/hwspinlock.h +++ b/include/linux/hwspinlock.h @@ -24,6 +24,7 @@ /* hwspinlock mode argument */ #define HWLOCK_IRQSTATE 0x01 /* Disable interrupts, save state */ #define HWLOCK_IRQ 0x02 /* Disable interrupts, don't save state */ +#define HWLOCK_RAW 0x03 struct device; struct device_node; @@ -175,6 +176,25 @@ static inline int hwspin_trylock_irq(struct hwspinlock *hwlock) return __hwspin_trylock(hwlock, HWLOCK_IRQ, NULL); } +/** + * hwspin_trylock_raw() - attempt to lock a specific hwspinlock + * @hwlock: an hwspinlock which we want to trylock + * + * This function attempts to lock an hwspinlock, and will immediately fail + * if the hwspinlock is already taken. + * + * Caution: User must protect the routine of getting hardware lock with mutex + * or spinlock to avoid dead-lock, that will let user can do some time-consuming + * or sleepable operations under the hardware lock. + * + * Returns 0 if we successfully locked the hwspinlock, -EBUSY if + * the hwspinlock was already taken, and -EINVAL if @hwlock is invalid. + */ +static inline int hwspin_trylock_raw(struct hwspinlock *hwlock) +{ + return __hwspin_trylock(hwlock, HWLOCK_RAW, NULL); +} + /** * hwspin_trylock() - attempt to lock a specific hwspinlock * @hwlock: an hwspinlock which we want to trylock @@ -242,6 +262,29 @@ int hwspin_lock_timeout_irq(struct hwspinlock *hwlock, unsigned int to) return __hwspin_lock_timeout(hwlock, to, HWLOCK_IRQ, NULL); } +/** + * hwspin_lock_timeout_raw() - lock an hwspinlock with timeout limit + * @hwlock: the hwspinlock to be locked + * @to: timeout value in msecs + * + * This function locks the underlying @hwlock. If the @hwlock + * is already taken, the function will busy loop waiting for it to + * be released, but give up when @timeout msecs have elapsed. + * + * Caution: User must protect the routine of getting hardware lock with mutex + * or spinlock to avoid dead-lock, that will let user can do some time-consuming + * or sleepable operations under the hardware lock. + * + * Returns 0 when the @hwlock was successfully taken, and an appropriate + * error code otherwise (most notably an -ETIMEDOUT if the @hwlock is still + * busy after @timeout msecs). The function will never sleep. + */ +static inline +int hwspin_lock_timeout_raw(struct hwspinlock *hwlock, unsigned int to) +{ + return __hwspin_lock_timeout(hwlock, to, HWLOCK_RAW, NULL); +} + /** * hwspin_lock_timeout() - lock an hwspinlock with timeout limit * @hwlock: the hwspinlock to be locked @@ -301,6 +344,21 @@ static inline void hwspin_unlock_irq(struct hwspinlock *hwlock) __hwspin_unlock(hwlock, HWLOCK_IRQ, NULL); } +/** + * hwspin_unlock_raw() - unlock hwspinlock + * @hwlock: a previously-acquired hwspinlock which we want to unlock + * + * This function will unlock a specific hwspinlock. + * + * @hwlock must be already locked (e.g. by hwspin_trylock()) before calling + * this function: it is a bug to call unlock on a @hwlock that is already + * unlocked. + */ +static inline void hwspin_unlock_raw(struct hwspinlock *hwlock) +{ + __hwspin_unlock(hwlock, HWLOCK_RAW, NULL); +} + /** * hwspin_unlock() - unlock hwspinlock * @hwlock: a previously-acquired hwspinlock which we want to unlock From eebba71e1cb4f3464645c4b106f8ccc31bc5cd11 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Fri, 11 May 2018 12:03:16 -0500 Subject: [PATCH 3/8] hwspinlock/core: Switch to SPDX license identifier Use the appropriate SPDX license identifier in the Hwspinlock core driver source files and drop the previous boilerplate license text. Signed-off-by: Suman Anna Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/Kconfig | 1 + drivers/hwspinlock/hwspinlock_core.c | 10 +--------- drivers/hwspinlock/hwspinlock_internal.h | 10 +--------- include/linux/hwspinlock.h | 10 +--------- 4 files changed, 4 insertions(+), 27 deletions(-) diff --git a/drivers/hwspinlock/Kconfig b/drivers/hwspinlock/Kconfig index f0f467983960..e895d29500ee 100644 --- a/drivers/hwspinlock/Kconfig +++ b/drivers/hwspinlock/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Generic HWSPINLOCK framework # diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c index 5278d0560a4a..d16e6a3d38e8 100644 --- a/drivers/hwspinlock/hwspinlock_core.c +++ b/drivers/hwspinlock/hwspinlock_core.c @@ -1,18 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Hardware spinlock framework * * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com * * Contact: Ohad Ben-Cohen - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #define pr_fmt(fmt) "%s: " fmt, __func__ diff --git a/drivers/hwspinlock/hwspinlock_internal.h b/drivers/hwspinlock/hwspinlock_internal.h index d26f78b8f214..9eb6bd020dc7 100644 --- a/drivers/hwspinlock/hwspinlock_internal.h +++ b/drivers/hwspinlock/hwspinlock_internal.h @@ -1,18 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Hardware spinlocks internal header * * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com * * Contact: Ohad Ben-Cohen - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __HWSPINLOCK_HWSPINLOCK_H diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h index fe450ee58d55..57537e67b468 100644 --- a/include/linux/hwspinlock.h +++ b/include/linux/hwspinlock.h @@ -1,18 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Hardware spinlock public header * * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com * * Contact: Ohad Ben-Cohen - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __LINUX_HWSPINLOCK_H From 357ace03f0abceabd5fa7ec9fe7bcc1482c87e51 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Fri, 11 May 2018 12:03:17 -0500 Subject: [PATCH 4/8] hwspinlock/omap: Switch to SPDX license identifier Use the appropriate SPDX license identifier in the OMAP hwspinlock driver source file and drop the previous boilerplate license text. Signed-off-by: Suman Anna Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/omap_hwspinlock.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c index ad2f8cac8487..79a4030e89d8 100644 --- a/drivers/hwspinlock/omap_hwspinlock.c +++ b/drivers/hwspinlock/omap_hwspinlock.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * OMAP hardware spinlock driver * @@ -6,15 +7,6 @@ * Contact: Simon Que * Hari Kanigeri * Ohad Ben-Cohen - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. */ #include From 8ba01caeec59a2f379aa94fcd133b417a3431bcb Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Fri, 11 May 2018 12:03:18 -0500 Subject: [PATCH 5/8] hwspinlock: qcom: Switch to SPDX license identifier Use the appropriate SPDX license identifier in the Qualcomm Hwspinlock driver source file and drop the previous boilerplate license text. Signed-off-by: Suman Anna Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/qcom_hwspinlock.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/hwspinlock/qcom_hwspinlock.c b/drivers/hwspinlock/qcom_hwspinlock.c index fa6880b8060a..6da7447d277d 100644 --- a/drivers/hwspinlock/qcom_hwspinlock.c +++ b/drivers/hwspinlock/qcom_hwspinlock.c @@ -1,15 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2013, The Linux Foundation. All rights reserved. * Copyright (c) 2015, Sony Mobile Communications AB - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include From 50a522805ef00dbca3f84373dca9ca0d1e4b9752 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Fri, 11 May 2018 12:03:19 -0500 Subject: [PATCH 6/8] hwspinlock/sirf: Switch to SPDX license identifier Use the appropriate SPDX license identifier in the CSR's SIRF hardware spinlock driver source file and drop the previous boilerplate license text. Cc: Wei Chen Cc: Barry Song Signed-off-by: Suman Anna Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/sirf_hwspinlock.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/hwspinlock/sirf_hwspinlock.c b/drivers/hwspinlock/sirf_hwspinlock.c index 16018544d431..02ef6e543cd1 100644 --- a/drivers/hwspinlock/sirf_hwspinlock.c +++ b/drivers/hwspinlock/sirf_hwspinlock.c @@ -1,9 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * SIRF hardware spinlock driver * * Copyright (c) 2015 Cambridge Silicon Radio Limited, a CSR plc group company. - * - * Licensed under GPLv2. */ #include From 0c3e890b1ef31e0de2a6b35493c7f32d18588ab4 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Fri, 11 May 2018 12:03:21 -0500 Subject: [PATCH 7/8] hwspinlock: sprd: Switch to SPDX license identifier Use the appropriate SPDX license identifiers in the Spreadtrum hardware spinlock driver source file and drop the previous boilerplate license text. Cc: Baolin Wang Signed-off-by: Suman Anna Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/sprd_hwspinlock.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/hwspinlock/sprd_hwspinlock.c b/drivers/hwspinlock/sprd_hwspinlock.c index 638e64ac18f5..dc42bf51f3e6 100644 --- a/drivers/hwspinlock/sprd_hwspinlock.c +++ b/drivers/hwspinlock/sprd_hwspinlock.c @@ -1,15 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Spreadtrum hardware spinlock driver * Copyright (C) 2017 Spreadtrum - http://www.spreadtrum.com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. */ #include From e759176c7f6b6d84a31276e11d687f232f6e4ecf Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Fri, 11 May 2018 12:03:20 -0500 Subject: [PATCH 8/8] hwspinlock/u8500: Switch to SPDX license identifier Use the appropriate SPDX license identifier in the U8500 HWSEM driver source file and drop the previous boilerplate license text. Cc: Mathieu J. Poirier Reviewed-by: Linus Walleij Signed-off-by: Suman Anna Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/u8500_hsem.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/hwspinlock/u8500_hsem.c b/drivers/hwspinlock/u8500_hsem.c index e93eabbd660f..84a92d424e8d 100644 --- a/drivers/hwspinlock/u8500_hsem.c +++ b/drivers/hwspinlock/u8500_hsem.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * u8500 HWSEM driver * @@ -10,15 +11,6 @@ * Simon Que * Hari Kanigeri * Ohad Ben-Cohen - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. */ #include