Registration of platform device/driver
Platform_device_register register the device with the system;
Platform_driver_register to the system to register the drive, during which the system looks for the registered device (according to the. Name), locate and then run the. Probe for initialization.
So the platform_device_register must be executed before platform_driver_register.
1. Platform_device_register execution process.
1) All the devices are defined in the zx297520v3-device.c zx29_device_table;
#ifdef CONFIG_MTD_ZXIC_SPIFC static struct resource spi_nand_resource[] = { [0] = { .start = ZX_SPIFC0_BASE, .end = ZX_SPIFC0_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, .name = "spifc_reg", }, [2] = { .start = SPI_FC0_INT, .end = SPI_FC0_INT, .flags = IORESOURCE_IRQ, }, };#endif
#ifdef CONFIG_MTD_ZXIC_SPIFCstruct platform_device zx29_device_spi_nand = { .name = "spi-nand-dt", .id = -1, .num_resources = ARRAY_SIZE(spi_nand_resource), .resource = spi_nand_resource,};#endif
struct platform_device *zx29_device_table[] __initdata={#ifdef CONFIG_SERIAL_ZX29_UART &zx29_uart0_device, &zx29_uart1_device, &zx29_uart2_device,#endif#ifdef CONFIG_MTD_NAND_DENALI &zx29_device_nand,#endif#ifdef CONFIG_DWC_OTG_USB &zx29_usb0_device,#endif#ifdef CONFIG_USB_DWC_OTG_HCD &zx29_usb1_device,#endif#ifdef CONFIG_MTD_ZXIC_SPIFC &zx29_device_spi_nand,#endif#ifdef CONFIG_ZX29_DMA &zx29_dma_device,#endif......}
2) Call Platform_add_devices in the Board_init () function in board-zx297520v3.c;
static void __init board_init(void){ ...... platform_add_devices(zx29_device_table, zx29_device_table_num); ......}
3) platform_add_devices table in the traversal, call Platform_device_register to register;
int platform_add_devices(struct platform_device **devs, int num){ int i, ret = 0; for (i = 0; i < num; i++) { ret = platform_device_register(devs[i]); if (ret) { while (--i >= 0) platform_device_unregister(devs[i]); break; } } return ret;}
4) Platform_device_register call Device_initialize First, then call Platform_device_add;
Device_initialize mainly initializes the device structure, including Kobject, mutex, spin_lock, list, PM initialization, etc., so as to facilitate the use of platform_device_add behind;
Platform_device_add calls Insert_resource (p,r) to add platform resources (resource above) into the kernel, which is managed by the kernel and then called Device_add ().
2. Platform_driver_register execution process.
1) Call Platform_driver_register registration driver;
static const struct of_device_id spifc_nand_dt_ids[] = { { .compatible = "spifc,spifc-nand-dt" }, { /* sentinel */ }};MODULE_DEVICE_TABLE(of, spifc_nand_dt_ids);static struct platform_driver spifc_dt_driver = { .probe = spifc_drv_probe, .remove = spifc_drv_remove, .driver = { .name = "spi-nand-dt", .owner = THIS_MODULE, .of_match_table = spifc_nand_dt_ids, },};module_platform_driver(spifc_dt_driver);
Module_platform_driver (XXX);
After the final expansion is the following form:
static int __init xxx_init (void)
{
? ? ? ? Return Platform_driver_register (&XXX);
}
Module_init (Xxx_init);
static void __exit xxx_init (void)
{
? ? ? ? Return Platform_driver_unregister (&XXX);
}
Module_exit (Xxx_exit);
2) Platform_driver_register (&xx_driver) registers xx_driver This driver with the system, which is based on xx_ The. Name content in the driver, the search system registers the device to have this platform_device, if there is, will execute platform_driver (that is, the type of xx_driver) The. Probe function, which is the Spifc_drv_probe () function above.
I²C Device/Driver Registration
1. Registration of the device
1) zx297520v3-devices.c defined in the need to add the I²C device;
#ifdef CONFIG_MFD_ZX234290_I2Cstatic struct zx234290_board zx234290_platform = { .irq_gpio_num = PIN_PMU_INT, //EX0_INT, .irq_gpio_func = PMU_INT_FUNC_SEL, .pshold_gpio_num = PIN_PMU_PSHOLD, .pshold_gpio_func = PMU_PSHOLD_FUNC_SEL, .irq_base = ENT_ZX234290_IRQ_BASE,};#endif
static struct i2c_board_info zx29_i2c0_devices[] = {#ifdef CONFIG_MFD_ZX234290_I2C [0]={ I2C_BOARD_INFO("zx234290", 0x12), .irq = EX0_INT, .platform_data = &zx234290_platform, },#endif};
2) Call the I2c_add_devices () function in board-zx297520v3.c to add the I²C device;
void __init i2c_add_devices(void){ unsigned devices_num = 0; int ret = 0; /* *i2c devices on bus 0 */ devices_num = ARRAY_SIZE(zx29_i2c0_devices); if (devices_num){ ret = i2c_register_board_info(0,zx29_i2c0_devices, devices_num); if(ret) BUG(); } /* *i2c devices on bus 1 */ devices_num = ARRAY_SIZE(zx29_i2c1_devices); if (devices_num){ ret = i2c_register_board_info(1,zx29_i2c1_devices, devices_num); if(ret) BUG(); }}
3) I2c_add_devices The information of each device into the list of __i2c_board_list;
4) When the I²c driver is initialized, for example I2C-ZX29.C, the driver of the I²C is registered into the platform driver;
static struct platform_driver zx29_i2c_driver = { .probe = zx29_i2c_probe, .remove = zx29_i2c_remove,#ifdef CONFIG_PM .suspend = zx29_i2c_suspend, .resume = zx29_i2c_resume,#endif .driver = { .owner = THIS_MODULE, .name = "zx29_i2c", .of_match_table = zx29_i2c_match, },};static int __init i2c_adap_zx29_init(void){ int ret; ret=platform_driver_register(&zx29_i2c_driver); if (ret<0) { printk(KERN_INFO "zx29 i2c driver register fail\n"); } return ret;}subsys_initcall(i2c_adap_zx29_init);
5) in the platform-driven probe function, by calling I2c_add_numbered_adapter ()-->i2c_register_adapter ()-->i2c_scan_static_board_info ()- ->i2c_new_device ()-->device_register () completes the registration of the device.
2. Registration of the driver
1) Add the corresponding driver by calling I2c_add_driver;
#if 1static struct i2c_driver zx234290_i2c_driver = { .driver = { .name = "zx234290", .owner = THIS_MODULE, }, .probe = zx234290_i2c_probe, .remove = zx234290_i2c_remove, .id_table = zx234290_i2c_id,};#endifstatic int __init zx234290_i2c_init(void){ int ret; ret = i2c_add_driver(&zx234290_i2c_driver); if (ret != 0) pr_err("Failed to register ZX234290 I2C driver: %d\n", ret); return ret;}/* init early so consumer devices can complete system boot */subsys_initcall(zx234290_i2c_init);
2) I2c_add_driver ()-->i2c_register_driver ()-->driver_register () registration driver, which will be the driver and device matching, after the successful match, will be called to the driver registration of the probe function.
SPI device/Driver Registration
- Registration of the device
1) The SPI devices that need to be added are defined in the ZX297520V3-DEVICES.C;
static struct spi_board_info zx29_spi_devices[] = {#ifdef CONFIG_FB_LEADT15DS26 { .modalias = "lead_t15ds26", .bus_num = 0, .chip_select = 0, .max_speed_hz = 13000000, .mode = SPI_MODE_3, .platform_data = &lead_lcd_platform, .controller_data = &lead_lcd_chip_info, },#endif#ifdef CONFIG_TRANSCEIVER_XN297L { .modalias = "xn297l_tx", .bus_num = 0, .chip_select = 0, .max_speed_hz = 1*1000*1000, .mode = SPI_MODE_0, .controller_data = 25, },#endif#ifdef CONFIG_TRANSCEIVER_XN297L { .modalias = "xn297l_rx", .bus_num = 1, .chip_select = 0, .max_speed_hz = 1*1000*1000, .mode = SPI_MODE_0, .controller_data = 87, },#endif};
2) Call the Spi_add_devices () function in board-zx297520v3.c to add the SPI device;
3) spi_add_devices () to register the device by calling Spi_register_board_info;
void __init spi_add_devices(void){ unsigned devices_num = ARRAY_SIZE(zx29_spi_devices); int ret = 0; printk("spi_register_board_info success,devices_num=%d\n",devices_num); if (devices_num){ ret = spi_register_board_info(zx29_spi_devices, devices_num); printk("spi_register_board_info success,ret=%d\n",ret); if(ret) BUG(); }}
4) Traverse all the devices in the SPI device table in Spi_register_board_info and pass the Spi_match_master_to_boardinfo ()-->spi_new_device ()-->spi_add _device ()-->device_add () to register the equipment;
2. Registration of the driver
1) Call Spi_register_driver to register the SPI driver;
static int __init xn297l_init (void) {int ret; int minor = 0; Xn_data ("register char Dev for xn297l."); ret = Spi_register_driver (&xn297l_spi_tx_driver); if (ret! = 0) {Xn_err ("Failed to register Xn297l_tx_spi_driver:%d", ret); return ret; } ret = Spi_register_driver (&xn297l_spi_rx_driver); if (ret! = 0) {Xn_err ("Failed to register Xn297l_rx_spi_driver:%d", ret); return ret; } }
/*spi driver begin*/static const struct spi_device_id xn297l_tx_id[] = { {"xn297l_tx", 0 }, { }};MODULE_DEVICE_TABLE(spi, xn297l_tx_id);static struct spi_driver xn297l_spi_tx_driver = { .driver = { .name = "xn297l_tx", .owner = THIS_MODULE, }, .probe = xn297l_tx_probe, .remove = __devexit_p(xn297l_tx_remove), .id_table = xn297l_tx_id,};static const struct spi_device_id xn297l_rx_id[] = { {"xn297l_rx", 1 }, { }};MODULE_DEVICE_TABLE(spi, xn297l_rx_id);static struct spi_driver xn297l_spi_rx_driver = { .driver = { .name = "xn297l_rx", .owner = THIS_MODULE, }, .probe = xn297l_rx_probe, .remove = __devexit_p(xn297l_rx_remove), .id_table = xn297l_rx_id,};/*spi driver end*/
2) Spi_register_driver inside will call Driver_register to drive the registration, which will be the driver and the device matching, after the successful match, will call to the driver registration of the probe function;
Linux Device/Driver registration