Linux设备驱动剖析之SPI(二)

957至962行,一个SPI控制器用一个master来描述。这里使用SPI核心的spi_alloc_master函数请求分配master。它在drivers/spi/spi.c文件中定义:

00000471 struct spi_master *spi_alloc_master(struct device *dev, unsigned size)
00000472 {
00000473     struct spi_master    *master;
00000474 
00000475     if (!dev)
00000476         return NULL;
00000477 
00000478     master = kzalloc(size + sizeof *master, GFP_KERNEL);
00000479     if (!master)
00000480         return NULL;
00000481 
00000482     device_initialize(&master->dev);
00000483     master->dev.class = &spi_master_class;
00000484     master->dev.parent = get_device(dev);
00000485     spi_master_set_devdata(master, &master[1]);
00000486 
00000487     return master;
00000488 }

478至480行,这里分配的内存大小是*master加size,包含了两部分内存。

482行,设备模型中的初始设备函数,不说。

483行,spi_master_class在SPI子系统初始化的时候就已经注册好了。

484行,设置当前设备的父设备,关于设备模型的。

485行,&master[1]就是master之后的另一部分内存的起始地址。

回到s3c64xx_spi_probe函数,966行,就是取出刚才申请的第二部分内存的起始地址。

966至980行,根据预先定义的变量、函数进行填充。

983行,有点意思,说明该驱动支持哪些SPI模式。

985至997行,写过Linux驱动都应该知道,IO内存映射。

999至1003行,SPI IO管脚配置,将相应的IO管脚设置为SPI功能。

1006至1032行,使能SPI时钟。

1034至1040行,创建单个线程的工作队列,用于数据收发操作。

1043行,硬件初始化,初始化SPI控制器寄存器。

1045至1048行,锁,工作队列等初始化。

1050至1054行,spi_register_master在drivers/spi/spi.c文件中定义:

00000511 int spi_register_master(struct spi_master *master)
00000512 {
00000513     static atomic_t        dyn_bus_id = ATOMIC_INIT((1<<15) - 1);
00000514     struct device        *dev = master->dev.parent;
00000515     int            status = -ENODEV;
00000516     int            dynamic = 0;
00000517 
00000518     if (!dev)
00000519         return -ENODEV;
00000520 
00000521     /* even if it's just one always-selected device, there must
00000522      * be at least one chipselect
00000523      */
00000524     if (master->num_chipselect == 0)
00000525         return -EINVAL;
00000526 
00000527     /* convention:  dynamically assigned bus IDs count down from the max */
00000528     if (master->bus_num < 0) {
00000529         /* FIXME switch to an IDR based scheme, something like
00000530          * I2C now uses, so we can't run out of "dynamic" IDs
00000531          */
00000532         master->bus_num = atomic_dec_return(&dyn_bus_id);
00000533         dynamic = 1;
00000534     }
00000535 
00000536     spin_lock_init(&master->bus_lock_spinlock);
00000537     mutex_init(&master->bus_lock_mutex);
00000538     master->bus_lock_flag = 0;
00000539 
00000540     /* register the device, then userspace will see it.
00000541      * registration fails if the bus ID is in use.
00000542      */
00000543     dev_set_name(&master->dev, "spi%u", master->bus_num);
00000544     status = device_add(&master->dev);
00000545     if (status < 0)
00000546         goto done;
00000547     dev_dbg(dev, "registered master %s%s\n", dev_name(&master->dev),
00000548             dynamic ? " (dynamic)" : "");
00000549 
00000550     /* populate children from any spi device tables */
00000551     scan_boardinfo(master);
00000552     status = 0;
00000553 
00000554     /* Register devices from the device tree */
00000555     of_register_spi_devices(master);
00000556 done:
00000557     return status;
00000558 }

524行,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值