drivers/hwspinlock/hwspinlock_core.c
Source file repositories/reference/linux-study-clean/drivers/hwspinlock/hwspinlock_core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/hwspinlock/hwspinlock_core.c- Extension
.c- Size
- 26229 bytes
- Lines
- 893
- Domain
- Driver Families
- Bucket
- drivers/hwspinlock
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/delay.hlinux/kernel.hlinux/module.hlinux/spinlock.hlinux/types.hlinux/err.hlinux/jiffies.hlinux/radix-tree.hlinux/hwspinlock.hlinux/pm_runtime.hlinux/mutex.hlinux/of.hhwspinlock_internal.h
Detected Declarations
function __hwspin_trylockfunction usagefunction __hwspin_lock_timeoutfunction __hwspin_unlockfunction hwspin_lock_bustfunction of_hwspin_lock_simple_xlatefunction of_hwspin_lock_get_idfunction of_hwspin_lock_get_id_bynamefunction hwspin_lock_register_singlefunction hwspin_lock_registerfunction hwspin_lock_unregisterfunction devm_hwspin_lock_unregfunction devm_hwspin_lock_device_matchfunction devm_hwspin_lock_unregisterfunction devm_hwspin_lock_registerfunction __hwspin_lock_requestfunction hwspin_lock_request_specificfunction hwspin_lock_freefunction devm_hwspin_lock_matchfunction devm_hwspin_lock_releasefunction devm_hwspin_lock_freefunction devm_hwspin_lock_request_specificexport __hwspin_trylockexport __hwspin_lock_timeoutexport __hwspin_unlockexport hwspin_lock_bustexport of_hwspin_lock_get_idexport of_hwspin_lock_get_id_bynameexport hwspin_lock_registerexport hwspin_lock_unregisterexport devm_hwspin_lock_unregisterexport devm_hwspin_lock_registerexport hwspin_lock_request_specificexport hwspin_lock_freeexport devm_hwspin_lock_freeexport devm_hwspin_lock_request_specific
Annotated Snippet
switch (mode) {
case HWLOCK_IRQSTATE:
spin_unlock_irqrestore(&hwlock->lock, *flags);
break;
case HWLOCK_IRQ:
spin_unlock_irq(&hwlock->lock);
break;
case HWLOCK_RAW:
case HWLOCK_IN_ATOMIC:
/* Nothing to do */
break;
default:
spin_unlock(&hwlock->lock);
break;
}
return -EBUSY;
}
/*
* We can be sure the other core's memory operations
* are observable to us only _after_ we successfully take
* the hwspinlock, and we must make sure that subsequent memory
* operations (both reads and writes) will not be reordered before
* we actually took the hwspinlock.
*
* Note: the implicit memory barrier of the spinlock above is too
* early, so we need this additional explicit memory barrier.
*/
mb();
return 0;
}
EXPORT_SYMBOL_GPL(__hwspin_trylock);
/**
* __hwspin_lock_timeout() - lock an hwspinlock with timeout limit
* @hwlock: the hwspinlock to be locked
* @to: timeout value in msecs
* @mode: mode which controls whether local interrupts are disabled or not
* @flags: a pointer to where the caller's interrupt state will be saved at (if
* requested)
*
* This function locks the given @hwlock. If the @hwlock
* is already taken, the function will busy loop waiting for it to
* be released, but give up after @timeout msecs have elapsed.
*
* 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 HWLOCK_IN_ATOMIC (called from an atomic context) the timeout
* is handled with busy-waiting delays, hence shall not exceed few msecs.
*
* If the mode is neither HWLOCK_IN_ATOMIC nor 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
* to choose the appropriate @mode of operation, exactly the same way users
* should decide between spin_lock, spin_lock_irq and spin_lock_irqsave.
*
* Returns: %0 when the @hwlock was successfully taken, and an appropriate
* error code otherwise (most notably -ETIMEDOUT if the @hwlock is still
* busy after @timeout msecs).
*
* The function will never sleep.
*/
int __hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int to,
int mode, unsigned long *flags)
{
int ret;
unsigned long expire, atomic_delay = 0;
expire = msecs_to_jiffies(to) + jiffies;
for (;;) {
/* Try to take the hwspinlock */
ret = __hwspin_trylock(hwlock, mode, flags);
if (ret != -EBUSY)
break;
/*
* The lock is already taken, let's check if the user wants
* us to try again
*/
Annotation
- Immediate include surface: `linux/delay.h`, `linux/kernel.h`, `linux/module.h`, `linux/spinlock.h`, `linux/types.h`, `linux/err.h`, `linux/jiffies.h`, `linux/radix-tree.h`.
- Detected declarations: `function __hwspin_trylock`, `function usage`, `function __hwspin_lock_timeout`, `function __hwspin_unlock`, `function hwspin_lock_bust`, `function of_hwspin_lock_simple_xlate`, `function of_hwspin_lock_get_id`, `function of_hwspin_lock_get_id_byname`, `function hwspin_lock_register_single`, `function hwspin_lock_register`.
- Atlas domain: Driver Families / drivers/hwspinlock.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.