其他分享
首页 > 其他分享> > platform_device

platform_device

作者:互联网

platform_device:

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/blkdev.h>
#include <linux/module.h>  
#include <linux/fs.h>  
#include <linux/errno.h>  
#include <linux/mm.h>  
#include <linux/cdev.h>  
#include <linux/platform_device.h>  
 
static int chrdev_open(struct inode *inode, struct file *file) 
{  
    printk(KERN_ALERT "chrdev open!\n");  
    return 0;  
}  
  
static int chrdev_release(struct inode *inode, struct file *file) 
{  
    printk(KERN_ALERT "chrdev release!\n");  
    return 0;  
}  
  
int temp_data = 0;
static int chrdev_ioctl(struct inode *inode, struct file *file,  unsigned int cmd, unsigned long arg) 
{    
    switch(cmd)
    {
        case 0x100:
            if(copy_from_user(&temp_data,  (int *)arg, sizeof(int))) 
                return -EFAULT;
            break;
        
        case 0x101:
            if(copy_to_user( (int *)arg, &temp_data, sizeof(int))) 
                return -EFAULT;
            break;
    }
 
    printk(KERN_ALERT "chrdev_ioctl: 0x%x temp_data=%d\n", cmd, temp_data);  
    return 0;
}  
  
// Kernel interface  
static struct file_operations chrdev_fops = {  
    .owner      =   THIS_MODULE,  
    .unlocked_ioctl      =   chrdev_ioctl,  
    .open       =   chrdev_open,  
    .release    =   chrdev_release,  
};  
  
#define CHRDEV_NAME     "miscdriver"  
 
static struct class *chrdev_class = NULL;  
static struct device *chrdev_device = NULL;  
static dev_t chrdev_devno;  
static struct cdev chrdev_cdev;  
  
static int chrdev_probe(struct platform_device *dev) 
{  
    int ret = 0, err = 0;  
      
    printk(KERN_ALERT "chrdev probe!\n");  
      
    // alloc character device number  
    ret = alloc_chrdev_region(&chrdev_devno, 0, 1, CHRDEV_NAME);  
    if (ret) {  
        printk(KERN_ALERT " alloc_chrdev_region failed!\n");  
        goto PROBE_ERR;  
    }  
    printk(KERN_ALERT " major:%d minor:%d\n", MAJOR(chrdev_devno), MINOR(chrdev_devno));  
      
    // add a character device  
    cdev_init(&chrdev_cdev, &chrdev_fops);  
    chrdev_cdev.owner = THIS_MODULE;  
    err = cdev_add(&chrdev_cdev, chrdev_devno, 1);  
    if (err) {  
        printk(KERN_ALERT " cdev_add failed!\n");  
        goto PROBE_ERR;  
    }  
      
    // create the device class  
    chrdev_class = class_create(THIS_MODULE, CHRDEV_NAME);  
    if (IS_ERR(chrdev_class)) {  
        printk(KERN_ALERT " class_create failed!\n");  
        goto PROBE_ERR;  
    }  
      
    // create the device node in /dev  
    chrdev_device = device_create(chrdev_class, NULL, chrdev_devno,  
        NULL, CHRDEV_NAME);  
    if (NULL == chrdev_device) {  
        printk(KERN_ALERT " device_create failed!\n");  
        goto PROBE_ERR;  
    }  
      
    printk(KERN_ALERT " chrdev probe ok!\n");  
    return 0;  
      
PROBE_ERR:  
    if (err)  
        cdev_del(&chrdev_cdev);  
    if (ret)   
        unregister_chrdev_region(chrdev_devno, 1);  
    return -1;  
}  
  
static int chrdev_remove (struct platform_device *dev) 
{  
    printk(KERN_ALERT " chrdev remove!\n");  
      
    cdev_del(&chrdev_cdev);  
    unregister_chrdev_region(chrdev_devno, 1);  
      
    device_destroy(chrdev_class, chrdev_devno);  
    class_destroy(chrdev_class);  
    return 0;  
}  
  
// platform_device and platform_driver must has a same name!  
// or it will not work normally  
static struct platform_driver chrdev_platform_driver = {  
    .probe  =   chrdev_probe,  
    .remove =   chrdev_remove,  
    .driver =   {  
        .name   =   CHRDEV_NAME,  
        .owner  =   THIS_MODULE,  
    },  
};  
  
static struct platform_device chrdev_platform_device = {  
    .name   =   CHRDEV_NAME,  
    .id     =   0,  
    .dev    =   {  
    }  
};  
  
  
static __init int chrdev_init(void) 
{  
    int ret = 0;  
    printk(KERN_ALERT "chrdev init!\n");  
      
    ret = platform_device_register(&chrdev_platform_device);  
    if (ret) {  
        printk(KERN_ALERT " platform_device_register failed!\n");  
        return ret;  
    }  
      
    ret = platform_driver_register(&chrdev_platform_driver);  
    if (ret) {  
        printk(KERN_ALERT " platform_driver_register failed!\n");  
        return ret;  
    }  
    printk(KERN_ALERT " chrdev_init ok!\n");  
    return ret;  
}  
  
static __exit void chrdev_exit(void) 
{  
    printk(KERN_ALERT "chrdev exit!\n");  
    platform_driver_unregister(&chrdev_platform_driver);  
}  
  
module_init(chrdev_init);  
module_exit(chrdev_exit); 
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Decly");

  

 

标签:chrdev,ALERT,KERN,platform,device,printk
来源: https://www.cnblogs.com/alone153/p/16128200.html