spi.c是spi子系统初始化的核心代码,由内核负责初始化
spidev.c是spi用户接口初始化的代码,编译的时候需要选择该模块
spi_sam.c是平台驱动的初始化代码,编译时需要选择spi s3c64xx模块
drivers/spi/spi_test.c 这个文件可以细看,是详细分析spi驱动的好文件。
spi.c也就是spi子系统的核心了,
spi_sam.c是s3c64xx系列芯片的SPI controller驱动,它向更上层的SPI核心层(spi.c)提供接口用来控制芯片的SPI controller,是一个被其他驱动使用的驱动。
spidev.c是在核心层基础之上将SPI controller模拟成一个字符型的驱动,向文件系统提供标准的文件系统接口,用来操作对应的SPI controller
//
/* board_info is normally registered in arch_initcall(),
- but even essential drivers wait till later
- REVISIT only boardinfo really needs static linking. the rest (device and
- driver registration) could be dynamically linked (modular) … costs
- include needing to have boardinfo data structures be much more public.
/
//内核中的xx_initcall初始化标号
postcore_initcall(spi_init);
/-------------------------------------------------------------------------*/
static int __init spi_init(void)
{
int status;
buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);
//总线
status = bus_register(&spi_bus_type);
//类
status = class_register(&spi_master_class);
}
//
spi_bus_type对应SPI中的SPI BUS总线
struct bus_type spi_bus_type = {
.name = “spi”,
.dev_attrs = spi_dev_attrs,
.match = spi_match_device,
.uevent = spi_uevent,
.suspend = spi_suspend,
.resume = spi_resume,
};
//
图片
static struct class spi_master_class = {
.name = “spi_master”,
.owner = THIS_MODULE,
.dev_release = spi_master_release,
};
//
/* modalias support makes “modprobe $MODALIAS” new-style hotplug work,
-
and the sysfs version makes coldplug work too.
*/
//设备与驱动的匹配
static int spi_match_device(struct device *dev, struct device_driver *drv)
{
const struct spi_device *spi = to_spi_device(dev);return strncmp(spi->modalias, drv->name, BUS_ID_SIZE) == 0;
}
//
一般在bus的uevent函数中,都会添加MODALIAS环境变量,设置成dev的名字。这样,uevent传到用户空间后,就可以通过对MODALIAS的匹配自动加载模块
static int spi_uevent(struct device *dev, struct kobj_uevent_env *env)
{
const struct spi_device *spi = to_spi_device(dev);
add_uevent_var(env, "MODALIAS=%s", spi->modalias);
return 0;
}