aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-11 15:09:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-11 15:09:19 -0400
commit6f75edeadd0dd3d58017bc3bcdc2b80879a7cfd3 (patch)
treee75729deec3343feec7a19820fba633df4aea9b0
parentd2b2250c3e565038a746b5db1de2af20a6468f02 (diff)
parente759176c7f6b6d84a31276e11d687f232f6e4ecf (diff)
Merge tag 'hwlock-v4.18' of git://github.com/andersson/remoteproc
Pull hwspinlock updates from Bjorn Andersson: "In addition to migrating the files to use SPDX license headers this introduces the ability for clients to operate a hwlock without the framework taking any additional locks" * tag 'hwlock-v4.18' of git://github.com/andersson/remoteproc: hwspinlock/u8500: Switch to SPDX license identifier hwspinlock: sprd: Switch to SPDX license identifier hwspinlock/sirf: Switch to SPDX license identifier hwspinlock: qcom: Switch to SPDX license identifier hwspinlock/omap: Switch to SPDX license identifier hwspinlock/core: Switch to SPDX license identifier hwspinlock: Introduce one new mode for hwspinlock hwspinlock: Convert to use 'switch' statement
-rw-r--r--drivers/hwspinlock/Kconfig1
-rw-r--r--drivers/hwspinlock/hwspinlock_core.c77
-rw-r--r--drivers/hwspinlock/hwspinlock_internal.h10
-rw-r--r--drivers/hwspinlock/omap_hwspinlock.c10
-rw-r--r--drivers/hwspinlock/qcom_hwspinlock.c10
-rw-r--r--drivers/hwspinlock/sirf_hwspinlock.c3
-rw-r--r--drivers/hwspinlock/sprd_hwspinlock.c10
-rw-r--r--drivers/hwspinlock/u8500_hsem.c10
-rw-r--r--include/linux/hwspinlock.h68
9 files changed, 118 insertions, 81 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 @@
1# SPDX-License-Identifier: GPL-2.0
1# 2#
2# Generic HWSPINLOCK framework 3# Generic HWSPINLOCK framework
3# 4#
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
index 4074441444fe..d16e6a3d38e8 100644
--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -1,18 +1,10 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Hardware spinlock framework 3 * Hardware spinlock framework
3 * 4 *
4 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com 5 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com
5 * 6 *
6 * Contact: Ohad Ben-Cohen <ohad@wizery.com> 7 * Contact: Ohad Ben-Cohen <ohad@wizery.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */ 8 */
17 9
18#define pr_fmt(fmt) "%s: " fmt, __func__ 10#define pr_fmt(fmt) "%s: " fmt, __func__
@@ -71,10 +63,16 @@ static DEFINE_MUTEX(hwspinlock_tree_lock);
71 * This function attempts to lock an hwspinlock, and will immediately 63 * This function attempts to lock an hwspinlock, and will immediately
72 * fail if the hwspinlock is already taken. 64 * fail if the hwspinlock is already taken.
73 * 65 *
74 * Upon a successful return from this function, preemption (and possibly 66 * Caution: If the mode is HWLOCK_RAW, that means user must protect the routine
75 * interrupts) is disabled, so the caller must not sleep, and is advised to 67 * of getting hardware lock with mutex or spinlock. Since in some scenarios,
76 * release the hwspinlock as soon as possible. This is required in order to 68 * user need some time-consuming or sleepable operations under the hardware
77 * minimize remote cores polling on the hardware interconnect. 69 * lock, they need one sleepable lock (like mutex) to protect the operations.
70 *
71 * If the mode is not HWLOCK_RAW, upon a successful return from this function,
72 * preemption (and possibly interrupts) is disabled, so the caller must not
73 * sleep, and is advised to release the hwspinlock as soon as possible. This is
74 * required in order to minimize remote cores polling on the hardware
75 * interconnect.
78 * 76 *
79 * The user decides whether local interrupts are disabled or not, and if yes, 77 * The user decides whether local interrupts are disabled or not, and if yes,
80 * whether he wants their previous state to be saved. It is up to the user 78 * whether he wants their previous state to be saved. It is up to the user
@@ -106,12 +104,20 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
106 * problems with hwspinlock usage (e.g. scheduler checks like 104 * problems with hwspinlock usage (e.g. scheduler checks like
107 * 'scheduling while atomic' etc.) 105 * 'scheduling while atomic' etc.)
108 */ 106 */
109 if (mode == HWLOCK_IRQSTATE) 107 switch (mode) {
108 case HWLOCK_IRQSTATE:
110 ret = spin_trylock_irqsave(&hwlock->lock, *flags); 109 ret = spin_trylock_irqsave(&hwlock->lock, *flags);
111 else if (mode == HWLOCK_IRQ) 110 break;
111 case HWLOCK_IRQ:
112 ret = spin_trylock_irq(&hwlock->lock); 112 ret = spin_trylock_irq(&hwlock->lock);
113 else 113 break;
114 case HWLOCK_RAW:
115 ret = 1;
116 break;
117 default:
114 ret = spin_trylock(&hwlock->lock); 118 ret = spin_trylock(&hwlock->lock);
119 break;
120 }
115 121
116 /* is lock already taken by another context on the local cpu ? */ 122 /* is lock already taken by another context on the local cpu ? */
117 if (!ret) 123 if (!ret)
@@ -122,12 +128,20 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
122 128
123 /* if hwlock is already taken, undo spin_trylock_* and exit */ 129 /* if hwlock is already taken, undo spin_trylock_* and exit */
124 if (!ret) { 130 if (!ret) {
125 if (mode == HWLOCK_IRQSTATE) 131 switch (mode) {
132 case HWLOCK_IRQSTATE:
126 spin_unlock_irqrestore(&hwlock->lock, *flags); 133 spin_unlock_irqrestore(&hwlock->lock, *flags);
127 else if (mode == HWLOCK_IRQ) 134 break;
135 case HWLOCK_IRQ:
128 spin_unlock_irq(&hwlock->lock); 136 spin_unlock_irq(&hwlock->lock);
129 else 137 break;
138 case HWLOCK_RAW:
139 /* Nothing to do */
140 break;
141 default:
130 spin_unlock(&hwlock->lock); 142 spin_unlock(&hwlock->lock);
143 break;
144 }
131 145
132 return -EBUSY; 146 return -EBUSY;
133 } 147 }
@@ -160,9 +174,14 @@ EXPORT_SYMBOL_GPL(__hwspin_trylock);
160 * is already taken, the function will busy loop waiting for it to 174 * is already taken, the function will busy loop waiting for it to
161 * be released, but give up after @timeout msecs have elapsed. 175 * be released, but give up after @timeout msecs have elapsed.
162 * 176 *
163 * Upon a successful return from this function, preemption is disabled 177 * Caution: If the mode is HWLOCK_RAW, that means user must protect the routine
164 * (and possibly local interrupts, too), so the caller must not sleep, 178 * of getting hardware lock with mutex or spinlock. Since in some scenarios,
165 * and is advised to release the hwspinlock as soon as possible. 179 * user need some time-consuming or sleepable operations under the hardware
180 * lock, they need one sleepable lock (like mutex) to protect the operations.
181 *
182 * If the mode is not HWLOCK_RAW, upon a successful return from this function,
183 * preemption is disabled (and possibly local interrupts, too), so the caller
184 * must not sleep, and is advised to release the hwspinlock as soon as possible.
166 * This is required in order to minimize remote cores polling on the 185 * This is required in order to minimize remote cores polling on the
167 * hardware interconnect. 186 * hardware interconnect.
168 * 187 *
@@ -249,12 +268,20 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
249 hwlock->bank->ops->unlock(hwlock); 268 hwlock->bank->ops->unlock(hwlock);
250 269
251 /* Undo the spin_trylock{_irq, _irqsave} called while locking */ 270 /* Undo the spin_trylock{_irq, _irqsave} called while locking */
252 if (mode == HWLOCK_IRQSTATE) 271 switch (mode) {
272 case HWLOCK_IRQSTATE:
253 spin_unlock_irqrestore(&hwlock->lock, *flags); 273 spin_unlock_irqrestore(&hwlock->lock, *flags);
254 else if (mode == HWLOCK_IRQ) 274 break;
275 case HWLOCK_IRQ:
255 spin_unlock_irq(&hwlock->lock); 276 spin_unlock_irq(&hwlock->lock);
256 else 277 break;
278 case HWLOCK_RAW:
279 /* Nothing to do */
280 break;
281 default:
257 spin_unlock(&hwlock->lock); 282 spin_unlock(&hwlock->lock);
283 break;
284 }
258} 285}
259EXPORT_SYMBOL_GPL(__hwspin_unlock); 286EXPORT_SYMBOL_GPL(__hwspin_unlock);
260 287
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 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * Hardware spinlocks internal header 3 * Hardware spinlocks internal header
3 * 4 *
4 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com 5 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com
5 * 6 *
6 * Contact: Ohad Ben-Cohen <ohad@wizery.com> 7 * Contact: Ohad Ben-Cohen <ohad@wizery.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */ 8 */
17 9
18#ifndef __HWSPINLOCK_HWSPINLOCK_H 10#ifndef __HWSPINLOCK_HWSPINLOCK_H
diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c
index d897e5251c36..625844e0abef 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * OMAP hardware spinlock driver 3 * OMAP hardware spinlock driver
3 * 4 *
@@ -6,15 +7,6 @@
6 * Contact: Simon Que <sque@ti.com> 7 * Contact: Simon Que <sque@ti.com>
7 * Hari Kanigeri <h-kanigeri2@ti.com> 8 * Hari Kanigeri <h-kanigeri2@ti.com>
8 * Ohad Ben-Cohen <ohad@wizery.com> 9 * Ohad Ben-Cohen <ohad@wizery.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 */ 10 */
19 11
20#include <linux/kernel.h> 12#include <linux/kernel.h>
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 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (c) 2013, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
3 * Copyright (c) 2015, Sony Mobile Communications AB 4 * Copyright (c) 2015, Sony Mobile Communications AB
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */ 5 */
14 6
15#include <linux/hwspinlock.h> 7#include <linux/hwspinlock.h>
diff --git a/drivers/hwspinlock/sirf_hwspinlock.c b/drivers/hwspinlock/sirf_hwspinlock.c
index cb38e487c6c4..1f625cd68c50 100644
--- a/drivers/hwspinlock/sirf_hwspinlock.c
+++ b/drivers/hwspinlock/sirf_hwspinlock.c
@@ -1,9 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * SIRF hardware spinlock driver 3 * SIRF hardware spinlock driver
3 * 4 *
4 * Copyright (c) 2015 Cambridge Silicon Radio Limited, a CSR plc group company. 5 * Copyright (c) 2015 Cambridge Silicon Radio Limited, a CSR plc group company.
5 *
6 * Licensed under GPLv2.
7 */ 6 */
8 7
9#include <linux/kernel.h> 8#include <linux/kernel.h>
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 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Spreadtrum hardware spinlock driver 3 * Spreadtrum hardware spinlock driver
3 * Copyright (C) 2017 Spreadtrum - http://www.spreadtrum.com 4 * Copyright (C) 2017 Spreadtrum - http://www.spreadtrum.com
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 */ 5 */
14 6
15#include <linux/bitops.h> 7#include <linux/bitops.h>
diff --git a/drivers/hwspinlock/u8500_hsem.c b/drivers/hwspinlock/u8500_hsem.c
index 0128d8fb905e..572ca79d77e8 100644
--- a/drivers/hwspinlock/u8500_hsem.c
+++ b/drivers/hwspinlock/u8500_hsem.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * u8500 HWSEM driver 3 * u8500 HWSEM driver
3 * 4 *
@@ -10,15 +11,6 @@
10 * Simon Que <sque@ti.com> 11 * Simon Que <sque@ti.com>
11 * Hari Kanigeri <h-kanigeri2@ti.com> 12 * Hari Kanigeri <h-kanigeri2@ti.com>
12 * Ohad Ben-Cohen <ohad@wizery.com> 13 * Ohad Ben-Cohen <ohad@wizery.com>
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * version 2 as published by the Free Software Foundation.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
22 */ 14 */
23 15
24#include <linux/module.h> 16#include <linux/module.h>
diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h
index 859d673d98c8..57537e67b468 100644
--- a/include/linux/hwspinlock.h
+++ b/include/linux/hwspinlock.h
@@ -1,18 +1,10 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * Hardware spinlock public header 3 * Hardware spinlock public header
3 * 4 *
4 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com 5 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com
5 * 6 *
6 * Contact: Ohad Ben-Cohen <ohad@wizery.com> 7 * Contact: Ohad Ben-Cohen <ohad@wizery.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */ 8 */
17 9
18#ifndef __LINUX_HWSPINLOCK_H 10#ifndef __LINUX_HWSPINLOCK_H
@@ -24,6 +16,7 @@
24/* hwspinlock mode argument */ 16/* hwspinlock mode argument */
25#define HWLOCK_IRQSTATE 0x01 /* Disable interrupts, save state */ 17#define HWLOCK_IRQSTATE 0x01 /* Disable interrupts, save state */
26#define HWLOCK_IRQ 0x02 /* Disable interrupts, don't save state */ 18#define HWLOCK_IRQ 0x02 /* Disable interrupts, don't save state */
19#define HWLOCK_RAW 0x03
27 20
28struct device; 21struct device;
29struct device_node; 22struct device_node;
@@ -176,6 +169,25 @@ static inline int hwspin_trylock_irq(struct hwspinlock *hwlock)
176} 169}
177 170
178/** 171/**
172 * hwspin_trylock_raw() - attempt to lock a specific hwspinlock
173 * @hwlock: an hwspinlock which we want to trylock
174 *
175 * This function attempts to lock an hwspinlock, and will immediately fail
176 * if the hwspinlock is already taken.
177 *
178 * Caution: User must protect the routine of getting hardware lock with mutex
179 * or spinlock to avoid dead-lock, that will let user can do some time-consuming
180 * or sleepable operations under the hardware lock.
181 *
182 * Returns 0 if we successfully locked the hwspinlock, -EBUSY if
183 * the hwspinlock was already taken, and -EINVAL if @hwlock is invalid.
184 */
185static inline int hwspin_trylock_raw(struct hwspinlock *hwlock)
186{
187 return __hwspin_trylock(hwlock, HWLOCK_RAW, NULL);
188}
189
190/**
179 * hwspin_trylock() - attempt to lock a specific hwspinlock 191 * hwspin_trylock() - attempt to lock a specific hwspinlock
180 * @hwlock: an hwspinlock which we want to trylock 192 * @hwlock: an hwspinlock which we want to trylock
181 * 193 *
@@ -243,6 +255,29 @@ int hwspin_lock_timeout_irq(struct hwspinlock *hwlock, unsigned int to)
243} 255}
244 256
245/** 257/**
258 * hwspin_lock_timeout_raw() - lock an hwspinlock with timeout limit
259 * @hwlock: the hwspinlock to be locked
260 * @to: timeout value in msecs
261 *
262 * This function locks the underlying @hwlock. If the @hwlock
263 * is already taken, the function will busy loop waiting for it to
264 * be released, but give up when @timeout msecs have elapsed.
265 *
266 * Caution: User must protect the routine of getting hardware lock with mutex
267 * or spinlock to avoid dead-lock, that will let user can do some time-consuming
268 * or sleepable operations under the hardware lock.
269 *
270 * Returns 0 when the @hwlock was successfully taken, and an appropriate
271 * error code otherwise (most notably an -ETIMEDOUT if the @hwlock is still
272 * busy after @timeout msecs). The function will never sleep.
273 */
274static inline
275int hwspin_lock_timeout_raw(struct hwspinlock *hwlock, unsigned int to)
276{
277 return __hwspin_lock_timeout(hwlock, to, HWLOCK_RAW, NULL);
278}
279
280/**
246 * hwspin_lock_timeout() - lock an hwspinlock with timeout limit 281 * hwspin_lock_timeout() - lock an hwspinlock with timeout limit
247 * @hwlock: the hwspinlock to be locked 282 * @hwlock: the hwspinlock to be locked
248 * @to: timeout value in msecs 283 * @to: timeout value in msecs
@@ -302,6 +337,21 @@ static inline void hwspin_unlock_irq(struct hwspinlock *hwlock)
302} 337}
303 338
304/** 339/**
340 * hwspin_unlock_raw() - unlock hwspinlock
341 * @hwlock: a previously-acquired hwspinlock which we want to unlock
342 *
343 * This function will unlock a specific hwspinlock.
344 *
345 * @hwlock must be already locked (e.g. by hwspin_trylock()) before calling
346 * this function: it is a bug to call unlock on a @hwlock that is already
347 * unlocked.
348 */
349static inline void hwspin_unlock_raw(struct hwspinlock *hwlock)
350{
351 __hwspin_unlock(hwlock, HWLOCK_RAW, NULL);
352}
353
354/**
305 * hwspin_unlock() - unlock hwspinlock 355 * hwspin_unlock() - unlock hwspinlock
306 * @hwlock: a previously-acquired hwspinlock which we want to unlock 356 * @hwlock: a previously-acquired hwspinlock which we want to unlock
307 * 357 *