在驱动文件中,只需在原先基础上再套一层,实现 platform_driver 结构体,如下:
================================================================================================
.c文件:
……(省略部分,和(一)中代码一样)
static struct file_operations light_fops = {
.owner = THIS_MODULE,
.ioctl = light_ioctl,
.open = light_open,
.release = light_release,
};
static int __devinit light_probe (struct platform_device * pdev)
{
int result = 0;
int i, GpioId ;
dev_t dev = 0;
pdeg(" my_led debug message: ");
result = alloc_chrdev_region(&dev,led_minor,1,DEVICE_NAME);
led_major = MAJOR(dev);
if (result < 0){
error(KERN_WARNING "wfet_kb:can`t get major %d\n",led_major);
return result;
}
led_device = kmalloc(sizeof(struct cdev), GFP_KERNEL);
if (!led_device) {
result = -ENOMEM;
unregister_chrdev_region(dev, 1);
return result;
}
memset(led_device, 0, sizeof(struct cdev));
cdev_init(led_device, &light_fops);
led_device->owner = THIS_MODULE;
result = cdev_add(led_device,dev,1);
if (result) {
error(KERN_NOTICE "Error %d adding LED device, major_%d",result, MAJOR(dev));
kfree(led_device);
led_device = NULL;
unregister_chrdev_region(dev, 1);
return result;
}
/*create device file*/
myclass = class_create(THIS_MODULE, DEVICE_NAME);
if (IS_ERR(myclass) ) {
error("Err: failed in in creating class\n");
return -1;
}
device_create(myclass,NULL,MKDEV(led_major,led_minor),DEVICE_NAME);
for (i = 0 ; i <5 ; i++ ) {
GpioId = mfp_to_gpio(led_table[i]);
gpio_direction_output(GpioId,LED_OFF);
}
return 0;
}
static int __devexit light_remove (struct platform_device * pdev)
{
dev_t devno = MKDEV(led_major,led_minor);
pdeg(" my_led debug message: ");
if (led_device){
cdev_del(led_device);
kfree(led_device);
led_device = NULL;
}
device_destroy(myclass,devno);
class_destroy(myclass);
unregister_chrdev_region(devno,1);
// free the kthread
if (led_th ) {
kthread_stop(led_th);
led_th = NULL;
}
return 0;
}
static struct platform_driver light_driver = {
.driver = {
.name = "hyy_led",
.owner = THIS_MODULE,
},
.probe = light_probe,
.remove = light_remove,
};
static int __init light_init(void)
{
pdeg(" my_led debug message: ");
return platform_driver_register(&light_driver);
}
static void __exit light_exit (void)
{
platform_driver_unregister(&light_driver);
pdeg(" my_led debug message: ");
}
module_init(light_init);
module_exit(light_exit);
MODULE_AUTHOR("hyy");
MODULE_LICENSE("GPL");
================================================================================================
在linux内核中,要实现 platform_device 结构体,在device 结构体中的涉及到num_resources 设备所使用各类资源的数量,resource 使用的资源。
将其用 platform_add_device (struct platform_device **pdev, int num) 函数或者 platform_device_register (struct platform_device *pdev) 添加到内核中。
在platform_add_device函数里调用platform_device_register 来实现device的挂载。
以上工作一般都是在linux内核中的平台架构选择的代码中,即在arch/下对应的平台代码中 本例在/arch/arm/mach-pxa/下
================================================================================================
littleton.c中
……
static struct platform_device light_led_device = {
.name = "hyy_led",
.id = -1,
};
static void __init littleton_init(void)
{
……
platform_device_register(&acr320_pmb_device);
}
================================================================================================
特别注意,platform_device 和 platform_driver 是通过结构体内的 name 来匹配的,如果name 不同,则会失败。
阅读(1148) | 评论(0) | 转发(0) |