一、spi_controller 结构体框图


二、spi_register_master() 宏
include/linux/spi/spi.h
- 调用流程
spi_imx_probe
->spi_bitbang_start
->->spi_register_master
#define spi_register_master(_ctlr) spi_register_controller(_ctlr)
spi_register_controller()函数
drivers/spi/spi.c
int spi_register_controller(struct spi_controller *ctlr)
{
struct device *dev = ctlr->dev.parent;
struct boardinfo *bi;
int status = -ENODEV;
int id, first_dynamic;
...
// spi控制器中的device成员设置一个名字
dev_set_name(&ctlr->dev, "spi%u", ctlr->bus_num);
// spi控制器中的device结构体加入到linux设备驱动模型
status = device_add(&ctlr->dev);
...
// 此成员是一个函数指针,此时还未初始化,第一个分支不会执行
if (ctlr->transfer) {
dev_info(dev, "controller is unqueued, this is deprecated\n");
} else if (ctlr->transfer_one || ctlr->transfer_one_message) {
status = spi_controller_initialize_queue(ctlr);// 即将执行
...
}
...
list_add_tail(&ctlr->list, &spi_controller_list);
...
}
spi_controller_initialize_queue()函数
drivers/spi/spi.c
static int spi_controller_initialize_queue(struct spi_controller *ctlr)
{
int ret;
// 初始化一个成员函数指针
ctlr->transfer = spi_queued_transfer;
if (!ctlr->transfer_one_message)
ctlr->transfer_one_message = spi_transfer_one_message;
/* Initialize and start queue */
ret = spi_init_queue(ctlr);
if (ret) {
dev_err(&ctlr->dev, "problem initializing queue\n");
goto err_init_queue;
}
ctlr->queued = true;
ret = spi_start_queue(ctlr);
if (ret) {
dev_err(&ctlr->dev, "problem starting queue\n");
goto err_start_queue;
}
return 0;
err_start_queue:
spi_destroy_queue(ctlr);
err_init_queue:
return ret;
}
spi_init_queue()函数
- 主要内容
初始化内核线程工人
初始化内核具体工作
drivers/spi/spi.c
static int spi_init_queue(struct spi_controller *ctlr)
{
struct sched_param param = {
.sched_priority = MAX_RT_PRIO - 1 };
ctlr->running = false;
ctlr->bus

本文深入解析了SPI控制器的驱动实现,包括spi_controller结构体、注册流程、数据传输机制及同步异步传输函数spi_sync和spi_async的具体实现。通过剖析关键函数如spi_register_controller、spi_controller_initialize_queue等,帮助读者理解SPI设备在Linux系统中的工作原理。
最低0.47元/天 解锁文章
6263

被折叠的 条评论
为什么被折叠?



