如何将新设备添加到主板初始化代码 linux 内核
How to add a new device to board init code linux kernel
您好,我正在使用 2.22.19 版自定义 linux 内核,它不支持设备树。所以我必须使用板初始化代码来描述外围设备。我已经检查了电路板初始化代码中的 "spi node",如下所示:
static struct resource c300v2evm_spi0_resources[] = {
{
.start = COMCERTO_SPI0_BASE,
.end = COMCERTO_SPI0_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
{
.start = IRQ_SPI0,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device c300v2evm_spi0 = {
.name = "comcerto_spi",
.id = 0,
.num_resources = ARRAY_SIZE(c300v2evm_spi0_resources),
.resource = c300v2evm_spi0_resources,
};
并且spi总线与控制器驱动匹配:
static int __init comcerto_spi_probe(struct platform_device *pdev)
{
...// probe function code
}
static struct platform_driver comcerto_spi_driver = {
.driver = {
.name = "comcerto_spi",
.owner = THIS_MODULE,
},
.probe = comcerto_spi_probe,
.remove = __devexit_p(comcerto_spi_remove),
};
现在我有了设备的协议驱动程序(spi 总线上的 eeprom):
static int at25_probe(struct spi_device *spi)
{
... // probe function code
}
static struct spi_driver at25_driver = {
.driver = {
.name = "at25",
.owner = THIS_MODULE,
},
.probe = at25_probe,
.remove = __devexit_p(at25_remove),
};
static int __init at25_init(void)
{
return spi_register_driver(&at25_driver);
}
我查看了日志,看到协议通过初始化函数加载到内核,但我不知道如何在板初始化代码中添加一个节点来匹配协议驱动探测函数。
我已经通过以下操作解决了这个问题:
首先,我在电路板初始化代码文件中定义了一个描述我的 spi 设备的结构:
static struct legerity_platform_data c300v2evm_legerity0_platform_data = {
.type = 5,
.dummy = 0,
};
static struct spi_board_info spi0_info[] = {
{
.modalias = "spi0",
.chip_select = 1,
.max_speed_hz = 1000*1000,
.bus_num = 0,
.irq = -1,
.mode = SPI_MODE_3,
.platform_data = &c300v2evm_legerity0_platform_data,
},
};
有了字段“.bus_num = 0”,内核就会明白这个spi设备属于spi0总线,有"id = 0"。
然后我使用这个函数向内核注册设备:
spi_register_board_info(spi0_info, 1);
我已经用我的板子和与我的设备匹配的协议驱动程序进行了测试,调用了"probe"函数。此方法是在 linux 内核版本 2.x.x 中注册新设备的基本方法,我已经检查过我可以将此方法用于较新版本。
希望这对必须使用旧版本 linux 内核的人有所帮助。
您好,我正在使用 2.22.19 版自定义 linux 内核,它不支持设备树。所以我必须使用板初始化代码来描述外围设备。我已经检查了电路板初始化代码中的 "spi node",如下所示:
static struct resource c300v2evm_spi0_resources[] = {
{
.start = COMCERTO_SPI0_BASE,
.end = COMCERTO_SPI0_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
{
.start = IRQ_SPI0,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device c300v2evm_spi0 = {
.name = "comcerto_spi",
.id = 0,
.num_resources = ARRAY_SIZE(c300v2evm_spi0_resources),
.resource = c300v2evm_spi0_resources,
};
并且spi总线与控制器驱动匹配:
static int __init comcerto_spi_probe(struct platform_device *pdev)
{
...// probe function code
}
static struct platform_driver comcerto_spi_driver = {
.driver = {
.name = "comcerto_spi",
.owner = THIS_MODULE,
},
.probe = comcerto_spi_probe,
.remove = __devexit_p(comcerto_spi_remove),
};
现在我有了设备的协议驱动程序(spi 总线上的 eeprom):
static int at25_probe(struct spi_device *spi)
{
... // probe function code
}
static struct spi_driver at25_driver = {
.driver = {
.name = "at25",
.owner = THIS_MODULE,
},
.probe = at25_probe,
.remove = __devexit_p(at25_remove),
};
static int __init at25_init(void)
{
return spi_register_driver(&at25_driver);
}
我查看了日志,看到协议通过初始化函数加载到内核,但我不知道如何在板初始化代码中添加一个节点来匹配协议驱动探测函数。
我已经通过以下操作解决了这个问题: 首先,我在电路板初始化代码文件中定义了一个描述我的 spi 设备的结构:
static struct legerity_platform_data c300v2evm_legerity0_platform_data = {
.type = 5,
.dummy = 0,
};
static struct spi_board_info spi0_info[] = {
{
.modalias = "spi0",
.chip_select = 1,
.max_speed_hz = 1000*1000,
.bus_num = 0,
.irq = -1,
.mode = SPI_MODE_3,
.platform_data = &c300v2evm_legerity0_platform_data,
},
};
有了字段“.bus_num = 0”,内核就会明白这个spi设备属于spi0总线,有"id = 0"。 然后我使用这个函数向内核注册设备:
spi_register_board_info(spi0_info, 1);
我已经用我的板子和与我的设备匹配的协议驱动程序进行了测试,调用了"probe"函数。此方法是在 linux 内核版本 2.x.x 中注册新设备的基本方法,我已经检查过我可以将此方法用于较新版本。 希望这对必须使用旧版本 linux 内核的人有所帮助。