Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+118 -81
+1
drivers/hwspinlock/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0 1 2 # 2 3 # Generic HWSPINLOCK framework 3 4 #
+52 -25
drivers/hwspinlock/hwspinlock_core.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * Hardware spinlock framework 3 4 * 4 5 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com 5 6 * 6 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 10 #define pr_fmt(fmt) "%s: " fmt, __func__ ··· 63 71 * This function attempts to lock an hwspinlock, and will immediately 64 72 * fail if the hwspinlock is already taken. 65 73 * 66 - * Upon a successful return from this function, preemption (and possibly 67 - * interrupts) is disabled, so the caller must not sleep, and is advised to 68 - * release the hwspinlock as soon as possible. This is required in order to 69 - * minimize remote cores polling on the hardware interconnect. 74 + * Caution: If the mode is HWLOCK_RAW, that means user must protect the routine 75 + * of getting hardware lock with mutex or spinlock. Since in some scenarios, 76 + * user need some time-consuming or sleepable operations under the hardware 77 + * lock, they need one sleepable lock (like mutex) to protect the operations. 78 + * 79 + * If the mode is not HWLOCK_RAW, upon a successful return from this function, 80 + * preemption (and possibly interrupts) is disabled, so the caller must not 81 + * sleep, and is advised to release the hwspinlock as soon as possible. This is 82 + * required in order to minimize remote cores polling on the hardware 83 + * interconnect. 70 84 * 71 85 * The user decides whether local interrupts are disabled or not, and if yes, 72 86 * whether he wants their previous state to be saved. It is up to the user ··· 104 106 * problems with hwspinlock usage (e.g. scheduler checks like 105 107 * 'scheduling while atomic' etc.) 106 108 */ 107 - if (mode == HWLOCK_IRQSTATE) 109 + switch (mode) { 110 + case HWLOCK_IRQSTATE: 108 111 ret = spin_trylock_irqsave(&hwlock->lock, *flags); 109 - else if (mode == HWLOCK_IRQ) 112 + break; 113 + case HWLOCK_IRQ: 110 114 ret = spin_trylock_irq(&hwlock->lock); 111 - else 115 + break; 116 + case HWLOCK_RAW: 117 + ret = 1; 118 + break; 119 + default: 112 120 ret = spin_trylock(&hwlock->lock); 121 + break; 122 + } 113 123 114 124 /* is lock already taken by another context on the local cpu ? */ 115 125 if (!ret) ··· 128 122 129 123 /* if hwlock is already taken, undo spin_trylock_* and exit */ 130 124 if (!ret) { 131 - if (mode == HWLOCK_IRQSTATE) 125 + switch (mode) { 126 + case HWLOCK_IRQSTATE: 132 127 spin_unlock_irqrestore(&hwlock->lock, *flags); 133 - else if (mode == HWLOCK_IRQ) 128 + break; 129 + case HWLOCK_IRQ: 134 130 spin_unlock_irq(&hwlock->lock); 135 - else 131 + break; 132 + case HWLOCK_RAW: 133 + /* Nothing to do */ 134 + break; 135 + default: 136 136 spin_unlock(&hwlock->lock); 137 + break; 138 + } 137 139 138 140 return -EBUSY; 139 141 } ··· 174 160 * is already taken, the function will busy loop waiting for it to 175 161 * be released, but give up after @timeout msecs have elapsed. 176 162 * 177 - * Upon a successful return from this function, preemption is disabled 178 - * (and possibly local interrupts, too), so the caller must not sleep, 179 - * and is advised to release the hwspinlock as soon as possible. 163 + * Caution: If the mode is HWLOCK_RAW, that means user must protect the routine 164 + * of getting hardware lock with mutex or spinlock. Since in some scenarios, 165 + * user need some time-consuming or sleepable operations under the hardware 166 + * lock, they need one sleepable lock (like mutex) to protect the operations. 167 + * 168 + * If the mode is not HWLOCK_RAW, upon a successful return from this function, 169 + * preemption is disabled (and possibly local interrupts, too), so the caller 170 + * must not sleep, and is advised to release the hwspinlock as soon as possible. 180 171 * This is required in order to minimize remote cores polling on the 181 172 * hardware interconnect. 182 173 * ··· 268 249 hwlock->bank->ops->unlock(hwlock); 269 250 270 251 /* Undo the spin_trylock{_irq, _irqsave} called while locking */ 271 - if (mode == HWLOCK_IRQSTATE) 252 + switch (mode) { 253 + case HWLOCK_IRQSTATE: 272 254 spin_unlock_irqrestore(&hwlock->lock, *flags); 273 - else if (mode == HWLOCK_IRQ) 255 + break; 256 + case HWLOCK_IRQ: 274 257 spin_unlock_irq(&hwlock->lock); 275 - else 258 + break; 259 + case HWLOCK_RAW: 260 + /* Nothing to do */ 261 + break; 262 + default: 276 263 spin_unlock(&hwlock->lock); 264 + break; 265 + } 277 266 } 278 267 EXPORT_SYMBOL_GPL(__hwspin_unlock); 279 268
+1 -9
drivers/hwspinlock/hwspinlock_internal.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 1 2 /* 2 3 * Hardware spinlocks internal header 3 4 * 4 5 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com 5 6 * 6 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 10 #ifndef __HWSPINLOCK_HWSPINLOCK_H
+1 -9
drivers/hwspinlock/omap_hwspinlock.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * OMAP hardware spinlock driver 3 4 * ··· 7 6 * Contact: Simon Que <sque@ti.com> 8 7 * Hari Kanigeri <h-kanigeri2@ti.com> 9 8 * Ohad Ben-Cohen <ohad@wizery.com> 10 - * 11 - * This program is free software; you can redistribute it and/or 12 - * modify it under the terms of the GNU General Public License 13 - * version 2 as published by the Free Software Foundation. 14 - * 15 - * This program is distributed in the hope that it will be useful, but 16 - * WITHOUT ANY WARRANTY; without even the implied warranty of 17 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 - * General Public License for more details. 19 9 */ 20 10 21 11 #include <linux/kernel.h>
+1 -9
drivers/hwspinlock/qcom_hwspinlock.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * Copyright (c) 2013, The Linux Foundation. All rights reserved. 3 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 7 #include <linux/hwspinlock.h>
+1 -2
drivers/hwspinlock/sirf_hwspinlock.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * SIRF hardware spinlock driver 3 4 * 4 5 * Copyright (c) 2015 Cambridge Silicon Radio Limited, a CSR plc group company. 5 - * 6 - * Licensed under GPLv2. 7 6 */ 8 7 9 8 #include <linux/kernel.h>
+1 -9
drivers/hwspinlock/sprd_hwspinlock.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * Spreadtrum hardware spinlock driver 3 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 7 #include <linux/bitops.h>
+1 -9
drivers/hwspinlock/u8500_hsem.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * u8500 HWSEM driver 3 4 * ··· 11 10 * Simon Que <sque@ti.com> 12 11 * Hari Kanigeri <h-kanigeri2@ti.com> 13 12 * Ohad Ben-Cohen <ohad@wizery.com> 14 - * 15 - * This program is free software; you can redistribute it and/or 16 - * modify it under the terms of the GNU General Public License 17 - * version 2 as published by the Free Software Foundation. 18 - * 19 - * This program is distributed in the hope that it will be useful, but 20 - * WITHOUT ANY WARRANTY; without even the implied warranty of 21 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 - * General Public License for more details. 23 13 */ 24 14 25 15 #include <linux/module.h>
+59 -9
include/linux/hwspinlock.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 1 2 /* 2 3 * Hardware spinlock public header 3 4 * 4 5 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com 5 6 * 6 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 10 #ifndef __LINUX_HWSPINLOCK_H ··· 16 24 /* hwspinlock mode argument */ 17 25 #define HWLOCK_IRQSTATE 0x01 /* Disable interrupts, save state */ 18 26 #define HWLOCK_IRQ 0x02 /* Disable interrupts, don't save state */ 27 + #define HWLOCK_RAW 0x03 19 28 20 29 struct device; 21 30 struct device_node; ··· 169 176 } 170 177 171 178 /** 179 + * hwspin_trylock_raw() - attempt to lock a specific hwspinlock 180 + * @hwlock: an hwspinlock which we want to trylock 181 + * 182 + * This function attempts to lock an hwspinlock, and will immediately fail 183 + * if the hwspinlock is already taken. 184 + * 185 + * Caution: User must protect the routine of getting hardware lock with mutex 186 + * or spinlock to avoid dead-lock, that will let user can do some time-consuming 187 + * or sleepable operations under the hardware lock. 188 + * 189 + * Returns 0 if we successfully locked the hwspinlock, -EBUSY if 190 + * the hwspinlock was already taken, and -EINVAL if @hwlock is invalid. 191 + */ 192 + static inline int hwspin_trylock_raw(struct hwspinlock *hwlock) 193 + { 194 + return __hwspin_trylock(hwlock, HWLOCK_RAW, NULL); 195 + } 196 + 197 + /** 172 198 * hwspin_trylock() - attempt to lock a specific hwspinlock 173 199 * @hwlock: an hwspinlock which we want to trylock 174 200 * ··· 255 243 } 256 244 257 245 /** 246 + * hwspin_lock_timeout_raw() - lock an hwspinlock with timeout limit 247 + * @hwlock: the hwspinlock to be locked 248 + * @to: timeout value in msecs 249 + * 250 + * This function locks the underlying @hwlock. If the @hwlock 251 + * is already taken, the function will busy loop waiting for it to 252 + * be released, but give up when @timeout msecs have elapsed. 253 + * 254 + * Caution: User must protect the routine of getting hardware lock with mutex 255 + * or spinlock to avoid dead-lock, that will let user can do some time-consuming 256 + * or sleepable operations under the hardware lock. 257 + * 258 + * Returns 0 when the @hwlock was successfully taken, and an appropriate 259 + * error code otherwise (most notably an -ETIMEDOUT if the @hwlock is still 260 + * busy after @timeout msecs). The function will never sleep. 261 + */ 262 + static inline 263 + int hwspin_lock_timeout_raw(struct hwspinlock *hwlock, unsigned int to) 264 + { 265 + return __hwspin_lock_timeout(hwlock, to, HWLOCK_RAW, NULL); 266 + } 267 + 268 + /** 258 269 * hwspin_lock_timeout() - lock an hwspinlock with timeout limit 259 270 * @hwlock: the hwspinlock to be locked 260 271 * @to: timeout value in msecs ··· 334 299 static inline void hwspin_unlock_irq(struct hwspinlock *hwlock) 335 300 { 336 301 __hwspin_unlock(hwlock, HWLOCK_IRQ, NULL); 302 + } 303 + 304 + /** 305 + * hwspin_unlock_raw() - unlock hwspinlock 306 + * @hwlock: a previously-acquired hwspinlock which we want to unlock 307 + * 308 + * This function will unlock a specific hwspinlock. 309 + * 310 + * @hwlock must be already locked (e.g. by hwspin_trylock()) before calling 311 + * this function: it is a bug to call unlock on a @hwlock that is already 312 + * unlocked. 313 + */ 314 + static inline void hwspin_unlock_raw(struct hwspinlock *hwlock) 315 + { 316 + __hwspin_unlock(hwlock, HWLOCK_RAW, NULL); 337 317 } 338 318 339 319 /**