prop = of_find_property(np, name, NULL);
跳转:base.c(driver/of/)
struct property *of_find_property(const struct device_node *np,
const char *name,
int *lenp)
{
struct property *pp;
unsigned long flags;
raw_spin_lock_irqsave(&devtree_lock, flags);
// 1111111111111
pp = __of_find_property(np, name, lenp);
// 22222222222222
raw_spin_unlock_irqrestore(&devtree_lock, flags);
//
33333333333
return pp;
}
EXPORT_SYMBOL(of_find_property);
1111111111111111111111111111111111111111111111111111111
raw_spin_lock_irqsave(&devtree_lock, flags);
跳转:spinlock.h(include/linux/)
#define raw_spin_lock_irqsave(lock, flags)
\
do { \
typecheck(unsigned long, flags);
\
flags = _raw_spin_lock_irqsave(lock);
\
} while (0)
###################################
spinlock.c(kernel/)
unsigned long __lockfunc _raw_spin_lock_irqsave(raw_spinlock_t *lock)
{
return __raw_spin_lock_irqsave(lock);
}
EXPORT_SYMBOL(_raw_spin_lock_irqsave);
###################################
__raw_spin_lock_irqsave(lock)
跳转:spinlock_api_amp.h(include/linux/)
static inline unsigned long __raw_spin_lock_irqsave(raw_spinlock_t *lock)
{
unsigned long flags;
local_irq_save(flags);
preempt_disable();
// #define preempt_disable()
barrier()
// /* Copied from linux/compiler-gcc.h since we can't include it directly */
// #define barrier() __asm__ __volatile__("": : :"memory")
spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
/*
* On lockdep we dont want the hand-coded irq-enable of
* do_raw_spin_lock_flags() code, because lockdep assumes
* that interrupts are not re-enabled during lock-acquire:
*/
#ifdef CONFIG_LOCKDEP
LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
#else
do_raw_spin_lock_flags(lock, &flags);
#endif
return flags;
}
##################
#define local_irq_save(flags)
\
do { \
raw_local_irq_save(flags);
\
trace_hardirqs_off();
\
} while (0)
###################
static inline unsigned long arch_local_irq_save(void)
{
unsigned long flags;
asm volatile(
" mrs
%0, cpsr @ arch_local_irq_save\n"
" cpsid
i" //
cpsid i 就是disable irq; cpsid f 才disable fiq. fast irq硬件上已经自动保存了足够的上下文,这里的操作不会因fiq发生而受影响。
: "=r" (flags) : : "memory", "cc");
return flags;
}
###################
irqflags.h(include/linux/)
# define trace_hardirqs_off()
do { } while (0)
22222222222222222222222222222222222222222222222222222222
__of_find_property(np, name, lenp);
跳转:
static struct property *__of_find_property(const struct device_node *np,
const char *name, int *lenp)
{
struct property *pp;
if (!np)
return NULL;
for (pp = np->properties; pp; pp = pp->next) {
if (of_prop_cmp(pp->name, name) == 0) {
if (lenp)
*lenp = pp->length;
break;
}
}
return pp;
}
##########################
of.h(include/linux/)
#define of_prop_cmp(s1, s2)
strcmp((s1), (s2))
跳转:算了……
3333333333333333333333333333333333333333333333333333333
raw_spin_unlock_irqrestore
跳转:spinlock.h(include/linux/)
#define raw_spin_unlock_irqrestore(lock, flags)
\
do { \
typecheck(unsigned long, flags);
\
_raw_spin_unlock_irqrestore(lock, flags);
\
} while (0)
##################
#define typecheck(type,x) \
({ type __dummy; \
typeof(x) __dummy2; \
// typeof是取变量的类型
(void)(&__dummy == &__dummy2); \
1; \ //
(type一致)正常编译,然后最后的数据1,赋值给调用者
}) // 这个宏定义是一个表达式,不是函数,无所谓返回值,这个值是这个表达式的值,复合表达式,取最后一个表达式的值,作为复杂表达式的值。这里整个表达式的值就是最后一个表达式的值,也就是1
typecheck宏有两个参数,
第一个是一个类型,比如unsigned long,
第二个是一个变量,比如a。
它生成一个unsigned long类型的变量__dummy,
然后利用typeof生成和a同样类型的变量__dummy2,
比较__dummy和__dummy2的地址。
如果它们不是同样类型的指针比较,比如a不是unsigned long,
这时候编译器会有一个警告,让你注意到这个问题。