一、驱动程序结构
1、platform_device
文件:/arch/arm/mach-omap2/device.c
static struct omap2_mcspi_platform_config omap2_mcspi1_config = { .num_cs = 4, }; static struct resource omap2_mcspi1_resources[] = { { .start = OMAP2_MCSPI1_BASE, .end = OMAP2_MCSPI1_BASE + 0xff, .flags = IORESOURCE_MEM, }, }; static struct platform_device omap2_mcspi1 = { .name = "omap2_mcspi", .id = 1, /* 用于platform_driver probe函数中识别不同的设备 */ .num_resources = ARRAY_SIZE(omap2_mcspi1_resources), .resource = omap2_mcspi1_resources, .dev = { .platform_data = &omap2_mcspi1_config, }, }; static inline void ti81xx_mcspi_fixup(void) { omap2_mcspi1_resources[0].start = TI81XX_MCSPI1_BASE; omap2_mcspi1_resources[0].end = TI81XX_MCSPI1_BASE + 0xff; } static void omap_init_mcspi(void) { if (cpu_is_ti81xx()) ti81xx_mcspi_fixup() platform_device_register(&omap2_mcspi1); }
2、dev_devices
文件:/arch/arm/mach-omap2/board-ti8148ipnc.c
static struct spi_board_info dm8127_spi1_board[] = { [0] = { .modalias = "spidev", .bus_num = 1, .chip_select = 0, .irq = -1, .max_speed_hz = 20*1000*1000, .mode = SPI_MODE_0, }, }; void __init ti8148_spi_init(void) { spi_register_board_info(dm8127_spi1_board, ARRAY_SIZE(dm8127_spi1_board)); } int __init spi_register_board_info(struct spi_board_info const *info, unsigned n) { struct boardinfo *bi; int i; bi = kzalloc(n * sizeof(*bi), GFP_KERNEL); if (!bi) return -ENOMEM; for (i = 0; i < n; i++, bi++, info++) { struct spi_master *master; memcpy(&bi->board_info, info, sizeof(*info)); mutex_lock(&board_lock); list_add_tail(&bi->list, &board_list); /*加入board_list全局链表*/ list_for_each_entry(master, &spi_master_list, list) spi_match_master_to_boardinfo(master, &bi->board_info); mutex_unlock(&board_lock); } return 0; }
1、platform_driver
文件:/driver/spi/omap2_mcspi.c
static const struct dev_pm_ops omap2_mcspi_pm_ops = { .resume = omap2_mcspi_resume, }; static struct platform_driver omap2_mcspi_driver = { .driver = { .name = "omap2_mcspi", .owner = THIS_MODULE, .pm = &omap2_mcspi_pm_ops }, .remove = __exit_p(omap2_mcspi_remove), }; static int __init omap2_mcspi_init(void) { omap2_mcspi_wq = create_singlethread_workqueue( /* 创建工作队列 */ omap2_mcspi_driver.driver.name); if (omap2_mcspi_wq == NULL) return -1; return platform_driver_probe(&omap2_mcspi_driver, omap2_mcspi_probe); }
1、dev_driver
文件:/driver/spi/spidev.c
static struct spi_driver spidev_spi_driver = { .driver = { .name = "spidev", .owner = THIS_MODULE, }, .probe = spidev_probe, .remove = __devexit_p(spidev_remove), };