Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1215098
  • 博文数量: 261
  • 博客积分: 4196
  • 博客等级: 上校
  • 技术积分: 3410
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-17 17:05
文章分类

全部博文(261)

文章存档

2018年(1)

2017年(22)

2016年(2)

2015年(8)

2014年(27)

2013年(40)

2012年(161)

分类: LINUX

2013-03-12 15:01:43

在驱动文件中,只需在原先基础上再套一层,实现 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 不同,则会失败。
阅读(1093) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~