1、dev_t:多此一举的冗余? 
我突然对dev_t 这个有兴趣,之前一直使用但没有认真了解过,查看源码发现,先typedef __kernel_dev_t 然后由__kernel_dev_t 弄个 dev_t,很疑惑为什么不直接dev_t这个别名,感觉多此一举。
查了资料才知道:
核心原因:内核空间与用户空间的类型隔离
Linux 内核和用户应用程序运行在不同的地址空间,有着不同的需求和约束。__kernel_dev_t 和 dev_t 的分离,正是为了优雅地管理这种差异。
AI给出解答如下:

Linux兼容性、移植性强不是没有原因哈;
2、两个同名的spinlock_t?
cpp
#include <linux/spinlock_types_raw.h>
#ifndef CONFIG_PREEMPT_RT
/* Non PREEMPT_RT kernels map spinlock to raw_spinlock */
typedef struct spinlock {
union {
struct raw_spinlock rlock;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
# define LOCK_PADSIZE (offsetof(struct raw_spinlock, dep_map))
struct {
u8 __padding[LOCK_PADSIZE];
struct lockdep_map dep_map;
};
#endif
};
} spinlock_t;
#define ___SPIN_LOCK_INITIALIZER(lockname) \
{ \
.raw_lock = __ARCH_SPIN_LOCK_UNLOCKED, \
SPIN_DEBUG_INIT(lockname) \
SPIN_DEP_MAP_INIT(lockname) }
#define __SPIN_LOCK_INITIALIZER(lockname) \
{ { .rlock = ___SPIN_LOCK_INITIALIZER(lockname) } }
#define __SPIN_LOCK_UNLOCKED(lockname) \
(spinlock_t) __SPIN_LOCK_INITIALIZER(lockname)
#define DEFINE_SPINLOCK(x) spinlock_t x = __SPIN_LOCK_UNLOCKED(x)
#else /* !CONFIG_PREEMPT_RT */
/* PREEMPT_RT kernels map spinlock to rt_mutex */
#include <linux/rtmutex.h>
typedef struct spinlock {
struct rt_mutex_base lock;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
} spinlock_t;
#define __SPIN_LOCK_UNLOCKED(name) \
{ \
.lock = __RT_MUTEX_BASE_INITIALIZER(name.lock), \
SPIN_DEP_MAP_INIT(name) \
}
#define __LOCAL_SPIN_LOCK_UNLOCKED(name) \
{ \
.lock = __RT_MUTEX_BASE_INITIALIZER(name.lock), \
LOCAL_SPIN_DEP_MAP_INIT(name) \
}
#define DEFINE_SPINLOCK(name) \
spinlock_t name = __SPIN_LOCK_UNLOCKED(name)
#endif /* CONFIG_PREEMPT_RT */
#include <linux/rwlock_types.h>
#endif /* __LINUX_SPINLOCK_TYPES_H */
这里看到两个socklock_t结构体,很疑惑
以下是AI给出的参考

再深入应该是内核工程师学的内容了,但可以了解一下两种模式的不同效果
以下是AI给出的参考:

3、强制转换的必要性?
正点原子参考手册804页针对ioctl函数和release函数private_data中的强制转换
总结如图:

release中没有进行强制转换,建议要加都加上,避免小警告。
4、上半部与下半部
目的:

下半部用到软中断,软中断有三种方式:tasklet,工作队列以及中断线程化(将中断放到线程中)