Platform Driver for Linux drivers

Source: Internet
Author: User
Tags driver manager

# Platform Driver
All device drivers in Linux must be registered to the system platform. This operation is completed by a set of functions defined in platform_device.h. Let's take a look at the struct platform_driver:
View plaincopy to clipboardprint? Struct platform_driver {
Int (* probe) (struct platform_device *);
Int (* remove) (struct platform_device *);
Void (* shutdown) (struct platform_device *);
Int (* suspend) (struct platform_device *, pm_message_t state );
Int (* resume) (struct platform_device *);
Struct device_driver driver;
Const struct platform_device_id * id_table;
};
Struct platform_driver {
Int (* probe) (struct platform_device *);
Int (* remove) (struct platform_device *);
Void (* shutdown) (struct platform_device *);
Int (* suspend) (struct platform_device *, pm_message_t state );
Int (* resume) (struct platform_device *);
Struct device_driver driver;
Const struct platform_device_id * id_table;
};
This structure contains a set of operation functions and a pair of struct device_driver images. in our own driver, the first thing we need to do is to define the functions in platform_driver, create an object instance of this structure, and then call platform_driver_register () in the init () function () register our driver with the system.
For example, the definition of platform_driver in the leds-s3c24xx.c of kernel-3.0 is:
View plaincopy to clipboardprint? Static struct platform_driver s3c24xx_led_driver = {
. Probe = s3c24xx_led_probe,
. Remove = s3c24xx_led_remove,
. Driver = {
. Name = "s3c24xx_led ",
. Owner = THIS_MODULE,
},
};
Static struct platform_driver s3c24xx_led_driver = {
. Probe = s3c24xx_led_probe,
. Remove = s3c24xx_led_remove,
. Driver = {
. Name = "s3c24xx_led ",
. Owner = THIS_MODULE,
},
};
The. driver name and owner. when platform_driver_register () is called to register a driver, platform first specifies that the device is under the system's platform_bus main bus. This is just a virtual bus driver. then, when the platform driver calls driver_register () and driver_register calls bus_add_driver (), it registers the driver with the system bus manager. if the scan succeeds, the device is scanned. driver_attach () in c. actually, _ driver_attach () is called. driver_probe_device () and driver_probe_device () are called to call the bus probe specified during driver registration and the probe function of the driver, that is, the s3c24xx_led_probe () function registered above. The bus probe function is set in platform_driver_register () and the default Driver operation function is also set.
In our probe function, we mainly perform Device Detection and initialization. Here, the 2410 LEDs are connected to gpio, so they always exist, but if they are peripherals like usb, we need to first check whether external peripherals exist. in sc324xx_led_probe, we mainly do the following three things.
1. create a private data object and call platform_set_drvdata () to attach it to the device object. the parameter passed to the probe function is the image of the platform device of a struct platform_device (where was it created ?),
Struct platform_device is defined as follows:
View plaincopy to clipboardprint? Struct platform_device {
Const char * name;
Int id;
Struct device dev;
U32 num_resources;
Struct resource * resource;
 
Const struct platform_device_id * id_entry;
 
/* MFD cell pointer */
Struct mfd_cell * mfd_cell;
 
/* Arch specific additions */
Struct pdev_archdata archdata;
};
Struct platform_device {
Const char * name;
Int id;
Struct device dev;
U32 num_resources;
Struct resource * resource;

Const struct platform_device_id * id_entry;

/* MFD cell pointer */
Struct mfd_cell * mfd_cell;

/* Arch specific additions */
Struct pdev_archdata archdata;
};

There is a struct device object, which stores information about a specific device in the system. driver_data is generally used to save private information related to the device. For example, here, it is used to save the struct s3c24xx_gpio_led instance, but we should use the platform_set_drvdata () function instead of directly operating it.
2. initialize the specific gpio
3. Call led_classdev_register to register an led driver with the kernel.
Section: In this process, we can see what needs to be done and the basic process in a driver.
1. Define a platform_driver object to describe the driver information.
2. Implement the necessary functions defined in platform_driver
3. register the driver with the Platform driver manager.
4. The driver manager will call the. probe function to detect the device. You need to initialize the device here.
5. the kernel calls the corresponding functions of the driver according to the operation request, such as open and close.

# Platform Device
In the platform driver, the kernel calls back our registered. probe function, the parameter is a platform_device Object Pointer, but this from then on it, the s3c2410 smdk Board as an example, the corresponding mach for the mach-s3c2410, the specific use depends on the platform and mach we selected When configuring the kernel. how to configure or add mach is not in the scope of this article. open arch/arm/mach-s3c2410/mach-smdk2410.c now and there is a MACHINE_START struct at the end of the file:
View plaincopy to clipboardprint? MACHINE_START (SMDK2410, "SMDK2410 ")
. Phys_io = S3C2410_PA_UART,
. Io_pg_offst = (u32) S3C24XX_VA_UART)> 18) & 0 xfffc,
. Boot_params = S3C2410_SDRAM_PA + 0x100,
. Map_io = smdk2410_map_io,
. Init_irq = s3c24xx_init_irq,
. Init_machine = smdk_machine_init,
. Timer = & s3c24xx_timer,
MACHINE_END
MACHINE_START (SMDK2410, "SMDK2410 ")
. Phys_io = S3C2410_PA_UART,
. Io_pg_offst = (u32) S3C24XX_VA_UART)> 18) & 0 xfffc,
. Boot_params = S3C2410_SDRAM_PA + 0x100,
. Map_io = smdk2410_map_io,
. Init_irq = s3c24xx_init_irq,
. Init_machine = smdk_machine_init,
. Timer = & s3c24xx_timer,
MACHINE_END
This struct describes system resources related to this mach. During kernel initialization, the initialization operation is performed based on the content of this struct. find the specified smdk_machine_init function, which does not have much content. Now we only care about:
Platform_add_devices (smdk_devs, ARRAY_SIZE (smdk_devs ));
This call enters platform_add_devices. You can see that there is a for loop in this function to traverse the platform_device In the devs parameter, and then call platform_device_register to register the device. In this way, the platform_device received by our s3c24xx_led_probe.
The main devs came back to the previous layer. We can see that the input is a static-defined platform_device array, the configuration information is defined based on our mach, which is a bit good for pc bios. therefore, you need to modify the hardware configuration from here.

Author: "Welcome to cowshed"

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.