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

hwspinlock.txt: standardize document format

Each text file under Documentation follows a different
format. Some doesn't even have titles!

Change its representation to follow the adopted standard,
using ReST markups for it to be parseable by Sphinx:

- Adjust title markups;
- remove explicit numeration from titles;
- mark literal blocks as such;
- replace _foo_ by **foo** for emphasis;
- adjust whitespaces and add blank lines where needed.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>

authored by

Mauro Carvalho Chehab and committed by
Jonathan Corbet
e2862b25 440e4f6d

+292 -205
+292 -205
Documentation/hwspinlock.txt
··· 1 + =========================== 1 2 Hardware Spinlock Framework 3 + =========================== 2 4 3 - 1. Introduction 5 + Introduction 6 + ============ 4 7 5 8 Hardware spinlock modules provide hardware assistance for synchronization 6 9 and mutual exclusion between heterogeneous processors and those not operating ··· 35 32 A common hwspinlock interface makes it possible to have generic, platform- 36 33 independent, drivers. 37 34 38 - 2. User API 35 + User API 36 + ======== 37 + 38 + :: 39 39 40 40 struct hwspinlock *hwspin_lock_request(void); 41 - - dynamically assign an hwspinlock and return its address, or NULL 42 - in case an unused hwspinlock isn't available. Users of this 43 - API will usually want to communicate the lock's id to the remote core 44 - before it can be used to achieve synchronization. 45 - Should be called from a process context (might sleep). 41 + 42 + Dynamically assign an hwspinlock and return its address, or NULL 43 + in case an unused hwspinlock isn't available. Users of this 44 + API will usually want to communicate the lock's id to the remote core 45 + before it can be used to achieve synchronization. 46 + 47 + Should be called from a process context (might sleep). 48 + 49 + :: 46 50 47 51 struct hwspinlock *hwspin_lock_request_specific(unsigned int id); 48 - - assign a specific hwspinlock id and return its address, or NULL 49 - if that hwspinlock is already in use. Usually board code will 50 - be calling this function in order to reserve specific hwspinlock 51 - ids for predefined purposes. 52 - Should be called from a process context (might sleep). 52 + 53 + Assign a specific hwspinlock id and return its address, or NULL 54 + if that hwspinlock is already in use. Usually board code will 55 + be calling this function in order to reserve specific hwspinlock 56 + ids for predefined purposes. 57 + 58 + Should be called from a process context (might sleep). 59 + 60 + :: 53 61 54 62 int of_hwspin_lock_get_id(struct device_node *np, int index); 55 - - retrieve the global lock id for an OF phandle-based specific lock. 56 - This function provides a means for DT users of a hwspinlock module 57 - to get the global lock id of a specific hwspinlock, so that it can 58 - be requested using the normal hwspin_lock_request_specific() API. 59 - The function returns a lock id number on success, -EPROBE_DEFER if 60 - the hwspinlock device is not yet registered with the core, or other 61 - error values. 62 - Should be called from a process context (might sleep). 63 + 64 + Retrieve the global lock id for an OF phandle-based specific lock. 65 + This function provides a means for DT users of a hwspinlock module 66 + to get the global lock id of a specific hwspinlock, so that it can 67 + be requested using the normal hwspin_lock_request_specific() API. 68 + 69 + The function returns a lock id number on success, -EPROBE_DEFER if 70 + the hwspinlock device is not yet registered with the core, or other 71 + error values. 72 + 73 + Should be called from a process context (might sleep). 74 + 75 + :: 63 76 64 77 int hwspin_lock_free(struct hwspinlock *hwlock); 65 - - free a previously-assigned hwspinlock; returns 0 on success, or an 66 - appropriate error code on failure (e.g. -EINVAL if the hwspinlock 67 - is already free). 68 - Should be called from a process context (might sleep). 78 + 79 + Free a previously-assigned hwspinlock; returns 0 on success, or an 80 + appropriate error code on failure (e.g. -EINVAL if the hwspinlock 81 + is already free). 82 + 83 + Should be called from a process context (might sleep). 84 + 85 + :: 69 86 70 87 int hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int timeout); 71 - - lock a previously-assigned hwspinlock with a timeout limit (specified in 72 - msecs). If the hwspinlock is already taken, the function will busy loop 73 - waiting for it to be released, but give up when the timeout elapses. 74 - Upon a successful return from this function, preemption is disabled so 75 - the caller must not sleep, and is advised to release the hwspinlock as 76 - soon as possible, in order to minimize remote cores polling on the 77 - hardware interconnect. 78 - Returns 0 when successful and an appropriate error code otherwise (most 79 - notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs). 80 - The function will never sleep. 88 + 89 + Lock a previously-assigned hwspinlock with a timeout limit (specified in 90 + msecs). If the hwspinlock is already taken, the function will busy loop 91 + waiting for it to be released, but give up when the timeout elapses. 92 + Upon a successful return from this function, preemption is disabled so 93 + the caller must not sleep, and is advised to release the hwspinlock as 94 + soon as possible, in order to minimize remote cores polling on the 95 + hardware interconnect. 96 + 97 + Returns 0 when successful and an appropriate error code otherwise (most 98 + notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs). 99 + The function will never sleep. 100 + 101 + :: 81 102 82 103 int hwspin_lock_timeout_irq(struct hwspinlock *hwlock, unsigned int timeout); 83 - - lock a previously-assigned hwspinlock with a timeout limit (specified in 84 - msecs). If the hwspinlock is already taken, the function will busy loop 85 - waiting for it to be released, but give up when the timeout elapses. 86 - Upon a successful return from this function, preemption and the local 87 - interrupts are disabled, so the caller must not sleep, and is advised to 88 - release the hwspinlock as soon as possible. 89 - Returns 0 when successful and an appropriate error code otherwise (most 90 - notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs). 91 - The function will never sleep. 104 + 105 + Lock a previously-assigned hwspinlock with a timeout limit (specified in 106 + msecs). If the hwspinlock is already taken, the function will busy loop 107 + waiting for it to be released, but give up when the timeout elapses. 108 + Upon a successful return from this function, preemption and the local 109 + interrupts are disabled, so the caller must not sleep, and is advised to 110 + release the hwspinlock as soon as possible. 111 + 112 + Returns 0 when successful and an appropriate error code otherwise (most 113 + notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs). 114 + The function will never sleep. 115 + 116 + :: 92 117 93 118 int hwspin_lock_timeout_irqsave(struct hwspinlock *hwlock, unsigned int to, 94 - unsigned long *flags); 95 - - lock a previously-assigned hwspinlock with a timeout limit (specified in 96 - msecs). If the hwspinlock is already taken, the function will busy loop 97 - waiting for it to be released, but give up when the timeout elapses. 98 - Upon a successful return from this function, preemption is disabled, 99 - local interrupts are disabled and their previous state is saved at the 100 - given flags placeholder. The caller must not sleep, and is advised to 101 - release the hwspinlock as soon as possible. 102 - Returns 0 when successful and an appropriate error code otherwise (most 103 - notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs). 104 - The function will never sleep. 119 + unsigned long *flags); 120 + 121 + Lock a previously-assigned hwspinlock with a timeout limit (specified in 122 + msecs). If the hwspinlock is already taken, the function will busy loop 123 + waiting for it to be released, but give up when the timeout elapses. 124 + Upon a successful return from this function, preemption is disabled, 125 + local interrupts are disabled and their previous state is saved at the 126 + given flags placeholder. The caller must not sleep, and is advised to 127 + release the hwspinlock as soon as possible. 128 + 129 + Returns 0 when successful and an appropriate error code otherwise (most 130 + notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs). 131 + 132 + The function will never sleep. 133 + 134 + :: 105 135 106 136 int hwspin_trylock(struct hwspinlock *hwlock); 107 - - attempt to lock a previously-assigned hwspinlock, but immediately fail if 108 - it is already taken. 109 - Upon a successful return from this function, preemption is disabled so 110 - caller must not sleep, and is advised to release the hwspinlock as soon as 111 - possible, in order to minimize remote cores polling on the hardware 112 - interconnect. 113 - Returns 0 on success and an appropriate error code otherwise (most 114 - notably -EBUSY if the hwspinlock was already taken). 115 - The function will never sleep. 137 + 138 + 139 + Attempt to lock a previously-assigned hwspinlock, but immediately fail if 140 + it is already taken. 141 + 142 + Upon a successful return from this function, preemption is disabled so 143 + caller must not sleep, and is advised to release the hwspinlock as soon as 144 + possible, in order to minimize remote cores polling on the hardware 145 + interconnect. 146 + 147 + Returns 0 on success and an appropriate error code otherwise (most 148 + notably -EBUSY if the hwspinlock was already taken). 149 + The function will never sleep. 150 + 151 + :: 116 152 117 153 int hwspin_trylock_irq(struct hwspinlock *hwlock); 118 - - attempt to lock a previously-assigned hwspinlock, but immediately fail if 119 - it is already taken. 120 - Upon a successful return from this function, preemption and the local 121 - interrupts are disabled so caller must not sleep, and is advised to 122 - release the hwspinlock as soon as possible. 123 - Returns 0 on success and an appropriate error code otherwise (most 124 - notably -EBUSY if the hwspinlock was already taken). 125 - The function will never sleep. 154 + 155 + 156 + Attempt to lock a previously-assigned hwspinlock, but immediately fail if 157 + it is already taken. 158 + 159 + Upon a successful return from this function, preemption and the local 160 + interrupts are disabled so caller must not sleep, and is advised to 161 + release the hwspinlock as soon as possible. 162 + 163 + Returns 0 on success and an appropriate error code otherwise (most 164 + notably -EBUSY if the hwspinlock was already taken). 165 + 166 + The function will never sleep. 167 + 168 + :: 126 169 127 170 int hwspin_trylock_irqsave(struct hwspinlock *hwlock, unsigned long *flags); 128 - - attempt to lock a previously-assigned hwspinlock, but immediately fail if 129 - it is already taken. 130 - Upon a successful return from this function, preemption is disabled, 131 - the local interrupts are disabled and their previous state is saved 132 - at the given flags placeholder. The caller must not sleep, and is advised 133 - to release the hwspinlock as soon as possible. 134 - Returns 0 on success and an appropriate error code otherwise (most 135 - notably -EBUSY if the hwspinlock was already taken). 136 - The function will never sleep. 171 + 172 + Attempt to lock a previously-assigned hwspinlock, but immediately fail if 173 + it is already taken. 174 + 175 + Upon a successful return from this function, preemption is disabled, 176 + the local interrupts are disabled and their previous state is saved 177 + at the given flags placeholder. The caller must not sleep, and is advised 178 + to release the hwspinlock as soon as possible. 179 + 180 + Returns 0 on success and an appropriate error code otherwise (most 181 + notably -EBUSY if the hwspinlock was already taken). 182 + The function will never sleep. 183 + 184 + :: 137 185 138 186 void hwspin_unlock(struct hwspinlock *hwlock); 139 - - unlock a previously-locked hwspinlock. Always succeed, and can be called 140 - from any context (the function never sleeps). Note: code should _never_ 141 - unlock an hwspinlock which is already unlocked (there is no protection 142 - against this). 187 + 188 + Unlock a previously-locked hwspinlock. Always succeed, and can be called 189 + from any context (the function never sleeps). 190 + 191 + .. note:: 192 + 193 + code should **never** unlock an hwspinlock which is already unlocked 194 + (there is no protection against this). 195 + 196 + :: 143 197 144 198 void hwspin_unlock_irq(struct hwspinlock *hwlock); 145 - - unlock a previously-locked hwspinlock and enable local interrupts. 146 - The caller should _never_ unlock an hwspinlock which is already unlocked. 147 - Doing so is considered a bug (there is no protection against this). 148 - Upon a successful return from this function, preemption and local 149 - interrupts are enabled. This function will never sleep. 199 + 200 + Unlock a previously-locked hwspinlock and enable local interrupts. 201 + The caller should **never** unlock an hwspinlock which is already unlocked. 202 + 203 + Doing so is considered a bug (there is no protection against this). 204 + Upon a successful return from this function, preemption and local 205 + interrupts are enabled. This function will never sleep. 206 + 207 + :: 150 208 151 209 void 152 210 hwspin_unlock_irqrestore(struct hwspinlock *hwlock, unsigned long *flags); 153 - - unlock a previously-locked hwspinlock. 154 - The caller should _never_ unlock an hwspinlock which is already unlocked. 155 - Doing so is considered a bug (there is no protection against this). 156 - Upon a successful return from this function, preemption is reenabled, 157 - and the state of the local interrupts is restored to the state saved at 158 - the given flags. This function will never sleep. 211 + 212 + Unlock a previously-locked hwspinlock. 213 + 214 + The caller should **never** unlock an hwspinlock which is already unlocked. 215 + Doing so is considered a bug (there is no protection against this). 216 + Upon a successful return from this function, preemption is reenabled, 217 + and the state of the local interrupts is restored to the state saved at 218 + the given flags. This function will never sleep. 219 + 220 + :: 159 221 160 222 int hwspin_lock_get_id(struct hwspinlock *hwlock); 161 - - retrieve id number of a given hwspinlock. This is needed when an 162 - hwspinlock is dynamically assigned: before it can be used to achieve 163 - mutual exclusion with a remote cpu, the id number should be communicated 164 - to the remote task with which we want to synchronize. 165 - Returns the hwspinlock id number, or -EINVAL if hwlock is null. 166 223 167 - 3. Typical usage 224 + Retrieve id number of a given hwspinlock. This is needed when an 225 + hwspinlock is dynamically assigned: before it can be used to achieve 226 + mutual exclusion with a remote cpu, the id number should be communicated 227 + to the remote task with which we want to synchronize. 168 228 169 - #include <linux/hwspinlock.h> 170 - #include <linux/err.h> 229 + Returns the hwspinlock id number, or -EINVAL if hwlock is null. 171 230 172 - int hwspinlock_example1(void) 173 - { 174 - struct hwspinlock *hwlock; 175 - int ret; 231 + Typical usage 232 + ============= 176 233 177 - /* dynamically assign a hwspinlock */ 178 - hwlock = hwspin_lock_request(); 179 - if (!hwlock) 180 - ... 234 + :: 181 235 182 - id = hwspin_lock_get_id(hwlock); 183 - /* probably need to communicate id to a remote processor now */ 236 + #include <linux/hwspinlock.h> 237 + #include <linux/err.h> 184 238 185 - /* take the lock, spin for 1 sec if it's already taken */ 186 - ret = hwspin_lock_timeout(hwlock, 1000); 187 - if (ret) 188 - ... 239 + int hwspinlock_example1(void) 240 + { 241 + struct hwspinlock *hwlock; 242 + int ret; 189 243 190 - /* 191 - * we took the lock, do our thing now, but do NOT sleep 192 - */ 244 + /* dynamically assign a hwspinlock */ 245 + hwlock = hwspin_lock_request(); 246 + if (!hwlock) 247 + ... 193 248 194 - /* release the lock */ 195 - hwspin_unlock(hwlock); 249 + id = hwspin_lock_get_id(hwlock); 250 + /* probably need to communicate id to a remote processor now */ 196 251 197 - /* free the lock */ 198 - ret = hwspin_lock_free(hwlock); 199 - if (ret) 200 - ... 252 + /* take the lock, spin for 1 sec if it's already taken */ 253 + ret = hwspin_lock_timeout(hwlock, 1000); 254 + if (ret) 255 + ... 201 256 202 - return ret; 203 - } 257 + /* 258 + * we took the lock, do our thing now, but do NOT sleep 259 + */ 204 260 205 - int hwspinlock_example2(void) 206 - { 207 - struct hwspinlock *hwlock; 208 - int ret; 261 + /* release the lock */ 262 + hwspin_unlock(hwlock); 209 263 210 - /* 211 - * assign a specific hwspinlock id - this should be called early 212 - * by board init code. 213 - */ 214 - hwlock = hwspin_lock_request_specific(PREDEFINED_LOCK_ID); 215 - if (!hwlock) 216 - ... 264 + /* free the lock */ 265 + ret = hwspin_lock_free(hwlock); 266 + if (ret) 267 + ... 217 268 218 - /* try to take it, but don't spin on it */ 219 - ret = hwspin_trylock(hwlock); 220 - if (!ret) { 221 - pr_info("lock is already taken\n"); 222 - return -EBUSY; 269 + return ret; 223 270 } 224 271 225 - /* 226 - * we took the lock, do our thing now, but do NOT sleep 227 - */ 272 + int hwspinlock_example2(void) 273 + { 274 + struct hwspinlock *hwlock; 275 + int ret; 228 276 229 - /* release the lock */ 230 - hwspin_unlock(hwlock); 277 + /* 278 + * assign a specific hwspinlock id - this should be called early 279 + * by board init code. 280 + */ 281 + hwlock = hwspin_lock_request_specific(PREDEFINED_LOCK_ID); 282 + if (!hwlock) 283 + ... 231 284 232 - /* free the lock */ 233 - ret = hwspin_lock_free(hwlock); 234 - if (ret) 235 - ... 285 + /* try to take it, but don't spin on it */ 286 + ret = hwspin_trylock(hwlock); 287 + if (!ret) { 288 + pr_info("lock is already taken\n"); 289 + return -EBUSY; 290 + } 236 291 237 - return ret; 238 - } 292 + /* 293 + * we took the lock, do our thing now, but do NOT sleep 294 + */ 295 + 296 + /* release the lock */ 297 + hwspin_unlock(hwlock); 298 + 299 + /* free the lock */ 300 + ret = hwspin_lock_free(hwlock); 301 + if (ret) 302 + ... 303 + 304 + return ret; 305 + } 239 306 240 307 241 - 4. API for implementors 308 + API for implementors 309 + ==================== 310 + 311 + :: 242 312 243 313 int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev, 244 314 const struct hwspinlock_ops *ops, int base_id, int num_locks); 245 - - to be called from the underlying platform-specific implementation, in 246 - order to register a new hwspinlock device (which is usually a bank of 247 - numerous locks). Should be called from a process context (this function 248 - might sleep). 249 - Returns 0 on success, or appropriate error code on failure. 315 + 316 + To be called from the underlying platform-specific implementation, in 317 + order to register a new hwspinlock device (which is usually a bank of 318 + numerous locks). Should be called from a process context (this function 319 + might sleep). 320 + 321 + Returns 0 on success, or appropriate error code on failure. 322 + 323 + :: 250 324 251 325 int hwspin_lock_unregister(struct hwspinlock_device *bank); 252 - - to be called from the underlying vendor-specific implementation, in order 253 - to unregister an hwspinlock device (which is usually a bank of numerous 254 - locks). 255 - Should be called from a process context (this function might sleep). 256 - Returns the address of hwspinlock on success, or NULL on error (e.g. 257 - if the hwspinlock is still in use). 258 326 259 - 5. Important structs 327 + To be called from the underlying vendor-specific implementation, in order 328 + to unregister an hwspinlock device (which is usually a bank of numerous 329 + locks). 330 + 331 + Should be called from a process context (this function might sleep). 332 + 333 + Returns the address of hwspinlock on success, or NULL on error (e.g. 334 + if the hwspinlock is still in use). 335 + 336 + Important structs 337 + ================= 260 338 261 339 struct hwspinlock_device is a device which usually contains a bank 262 340 of hardware locks. It is registered by the underlying hwspinlock 263 341 implementation using the hwspin_lock_register() API. 264 342 265 - /** 266 - * struct hwspinlock_device - a device which usually spans numerous hwspinlocks 267 - * @dev: underlying device, will be used to invoke runtime PM api 268 - * @ops: platform-specific hwspinlock handlers 269 - * @base_id: id index of the first lock in this device 270 - * @num_locks: number of locks in this device 271 - * @lock: dynamically allocated array of 'struct hwspinlock' 272 - */ 273 - struct hwspinlock_device { 274 - struct device *dev; 275 - const struct hwspinlock_ops *ops; 276 - int base_id; 277 - int num_locks; 278 - struct hwspinlock lock[0]; 279 - }; 343 + :: 344 + 345 + /** 346 + * struct hwspinlock_device - a device which usually spans numerous hwspinlocks 347 + * @dev: underlying device, will be used to invoke runtime PM api 348 + * @ops: platform-specific hwspinlock handlers 349 + * @base_id: id index of the first lock in this device 350 + * @num_locks: number of locks in this device 351 + * @lock: dynamically allocated array of 'struct hwspinlock' 352 + */ 353 + struct hwspinlock_device { 354 + struct device *dev; 355 + const struct hwspinlock_ops *ops; 356 + int base_id; 357 + int num_locks; 358 + struct hwspinlock lock[0]; 359 + }; 280 360 281 361 struct hwspinlock_device contains an array of hwspinlock structs, each 282 - of which represents a single hardware lock: 362 + of which represents a single hardware lock:: 283 363 284 - /** 285 - * struct hwspinlock - this struct represents a single hwspinlock instance 286 - * @bank: the hwspinlock_device structure which owns this lock 287 - * @lock: initialized and used by hwspinlock core 288 - * @priv: private data, owned by the underlying platform-specific hwspinlock drv 289 - */ 290 - struct hwspinlock { 291 - struct hwspinlock_device *bank; 292 - spinlock_t lock; 293 - void *priv; 294 - }; 364 + /** 365 + * struct hwspinlock - this struct represents a single hwspinlock instance 366 + * @bank: the hwspinlock_device structure which owns this lock 367 + * @lock: initialized and used by hwspinlock core 368 + * @priv: private data, owned by the underlying platform-specific hwspinlock drv 369 + */ 370 + struct hwspinlock { 371 + struct hwspinlock_device *bank; 372 + spinlock_t lock; 373 + void *priv; 374 + }; 295 375 296 376 When registering a bank of locks, the hwspinlock driver only needs to 297 377 set the priv members of the locks. The rest of the members are set and 298 378 initialized by the hwspinlock core itself. 299 379 300 - 6. Implementation callbacks 380 + Implementation callbacks 381 + ======================== 301 382 302 - There are three possible callbacks defined in 'struct hwspinlock_ops': 383 + There are three possible callbacks defined in 'struct hwspinlock_ops':: 303 384 304 - struct hwspinlock_ops { 305 - int (*trylock)(struct hwspinlock *lock); 306 - void (*unlock)(struct hwspinlock *lock); 307 - void (*relax)(struct hwspinlock *lock); 308 - }; 385 + struct hwspinlock_ops { 386 + int (*trylock)(struct hwspinlock *lock); 387 + void (*unlock)(struct hwspinlock *lock); 388 + void (*relax)(struct hwspinlock *lock); 389 + }; 309 390 310 391 The first two callbacks are mandatory: 311 392 312 393 The ->trylock() callback should make a single attempt to take the lock, and 313 - return 0 on failure and 1 on success. This callback may _not_ sleep. 394 + return 0 on failure and 1 on success. This callback may **not** sleep. 314 395 315 396 The ->unlock() callback releases the lock. It always succeed, and it, too, 316 - may _not_ sleep. 397 + may **not** sleep. 317 398 318 399 The ->relax() callback is optional. It is called by hwspinlock core while 319 400 spinning on a lock, and can be used by the underlying implementation to force 320 - a delay between two successive invocations of ->trylock(). It may _not_ sleep. 401 + a delay between two successive invocations of ->trylock(). It may **not** sleep.