Files
plant_car/arch/include/armv7-r/spinlock.h
2025-11-08 13:26:19 +08:00

118 lines
2.0 KiB
C

/*
* spinlock.h
*
* Copyright (c) 2020 Semidrive Semiconductor.
* All rights reserved.
*
* Description: ARM spinlock interface.
*
* Revision History:
* -----------------
*/
#ifndef INCLUDE_ARM_SPINLOCK_H
#define INCLUDE_ARM_SPINLOCK_H
#include <armv7-r/barriers.h>
#define SPIN_LOCK_INITIAL_VALUE (0)
#ifndef ASSEMBLY
__BEGIN_CDECLS
/* spin lock type */
typedef unsigned long spin_lock_t;
#ifdef CONFIG_MULTI_CORE_SMP
#else
static inline int __arch_spin_lock_testset(spin_lock_t *spinlock, int value)
{
int result = 0;
__ASM volatile
(
"1:\n"
"\tldrex %0, [%1]\n"
"\tcmp %0, %2\n"
"\tbeq 2f\n"
"\tstrex %0, %2, [%1]\n"
"\tcmp %0, %2\n"
"\tbeq 1b\n"
"\tdmb ish\n"
"2:\n"
: "=&r" (result)
: "r" (spinlock), "r" (value)
: "cc", "memory"
);
return result;
}
#endif
/*
* arch spinlock init.
*
* @spinlock spinlock address.
*/
#ifdef CONFIG_MULTI_CORE_SMP
void arch_spin_lock_init(spin_lock_t *spinlock);
#else
static inline void arch_spin_lock_init(spin_lock_t *spinlock)
{
*spinlock = SPIN_LOCK_INITIAL_VALUE;
}
#endif
/*
* arch spin lock.
*
* @spinlock spinlock address.
*/
#ifdef CONFIG_MULTI_CORE_SMP
void arch_spin_lock(spin_lock_t *spinlock);
#else
static inline void arch_spin_lock(spin_lock_t *spinlock)
{
/* spin until lock is acquired */
while (__arch_spin_lock_testset(spinlock, 1)) {
DSB;
};
}
#endif
/*
* arch spin trylock.
*
* @spinlock spinlock address.
*/
#ifdef CONFIG_MULTI_CORE_SMP
int arch_spin_trylock(spin_lock_t *spinlock);
#else
static inline int arch_spin_trylock(spin_lock_t *spinlock)
{
return __arch_spin_lock_testset(spinlock, 1) == 0;
}
#endif
/*
* arch spin unlock.
*
* @spinlock spinlock address.
*/
#ifdef CONFIG_MULTI_CORE_SMP
void arch_spin_unlock(spin_lock_t *spinlock);
#else
static inline void arch_spin_unlock(spin_lock_t *spinlock)
{
DMB;
*spinlock = 0;
DSB;
}
#endif
__END_CDECLS
#endif
#endif