platform_device+cdev 样例(支持休眠唤醒)

platform_device+cdev 样例(支持休眠唤醒):  

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>

#define DEV_DBG_EN 1
#if(DEV_DBG_EN == 1)
#define rwbuffer_dev_dbg(x,arg...) printk(KERN_INFO"[LS_DEBUG][RWBUFF]"x,##arg)
#else
#define rwbuffer_dev_dbg(x,arg...)
#endif
#define rwbuffer_dev_err(x,arg...) printk(KERN_ERR"[LS_ERR][RWBUFF]"x,##arg)
#define rwbuffer_dev_print(x,arg...) printk(KERN_INFO"[LS_PRINT][RWBUFF]"x,##arg)


#define CHRDEV_NAME "rwbuffer"
#define CLASS_NAME "rwbuffer"
#define DEVICE_NAME "rwbuffer"

static dev_t devid;
static struct cdev* rwbuff_cdev;
static struct class* rwbuff_class;

#define EDOG_POWER_GPIO (GPIOH(07))


static int rwbuff_open(struct inode *inode,struct file *file) {
rwbuffer_dev_dbg("open rwbuffer device!");

return 0;
}

static ssize_t rwbuff_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) {
rwbuffer_dev_dbg("write rwbuffer device!");

return count;
}


static int rwbuff_release(struct inode *inode, struct file *file)
{
rwbuffer_dev_dbg("close rwbuffer device!");

return 0;
}

static int __init edog_power_probe(struct platform_device *pdev) {
rwbuffer_dev_dbg("call %s\n",__func__);

return 0;
}

static int __exit edog_power_remove(struct platform_device *pdev) {
rwbuffer_dev_dbg("call %s\n",__func__);

return 0;
}

static int edog_power_suspend(struct platform_device *pdev, pm_message_t mesg) {
rwbuffer_dev_dbg("call %s\n",__func__);
return 0;
}

static int edog_power_resume(struct platform_device *pdev) {
rwbuffer_dev_dbg("call %s\n",__func__);

return 0;
}

static struct platform_driver rwbuffer_driver = {
.driver = {
.name = "rwbuffer",
.owner = THIS_MODULE,
},
.probe = edog_power_probe,
.remove = __exit_p(edog_power_remove),
.suspend = edog_power_suspend,
.resume = edog_power_resume,
};

static struct platform_device rwbuff_device = {
.name = "rwbuffer",
.id = 0,
};

static struct file_operations fops_rwbuff = {
.owner = THIS_MODULE,
.open = rwbuff_open,
.release = rwbuff_release,
.write = rwbuff_write,
};

/*
* @function:edog_power_init
* This function is a init function of this modules,it such as module_init.
* @return unknown.
*/
static int __init edog_power_init(void) {
int ret;

//get dev number.
ret = alloc_chrdev_region(&devid,0,1,CHRDEV_NAME);
if(ret) {
rwbuffer_dev_err("alloc char driver error!\n");
return ret;
}
//register char dev.
rwbuff_cdev = cdev_alloc();
cdev_init(rwbuff_cdev,&fops_rwbuff);
rwbuff_cdev->owner = THIS_MODULE;
ret = cdev_add(rwbuff_cdev,devid,1);
if(ret) {
rwbuffer_dev_err("cdev create error!\n");
goto regiseter_clean;
}
//create device.
rwbuff_class = class_create(THIS_MODULE,CLASS_NAME);
if(IS_ERR(rwbuff_class)) {
rwbuffer_dev_err("create class error\n");
goto cdev_clean;
}
device_create(rwbuff_class,NULL,devid,NULL,DEVICE_NAME);

ret = platform_device_register(&rwbuff_device);
if (ret) {
rwbuffer_dev_err("platform device register failed\n");
goto device_clean;
}
return platform_driver_probe(&rwbuffer_driver, edog_power_probe);;

device_clean:
device_destroy(rwbuff_class,devid);
class_clean:
class_destroy(rwbuff_class);
cdev_clean:
cdev_del(rwbuff_cdev);
regiseter_clean:
unregister_chrdev_region(devid,1);

return -ENOMEM;
}

/**
* @function:edog_power_exit
* This function is a clean function of this module.
*/
static void __exit edog_power_exit(void) {
rwbuffer_dev_dbg("edog driver exit is ok!\n");

platform_driver_unregister(&rwbuffer_driver);
device_destroy(rwbuff_class,devid);
class_destroy(rwbuff_class);
cdev_del(rwbuff_cdev);
unregister_chrdev_region(devid,1);
}

module_init(edog_power_init);
module_exit(edog_power_exit);

MODULE_AUTHOR("arvinfei@landsem.com.cn");
MODULE_DESCRIPTION("landsem sysconfig driver.");
MODULE_LICENSE("GPL");

上一篇:【神经网络压缩】A GRADIENT FLOW FRAMEWORK FOR ANALYZING NETWORK PRUNING


下一篇:EventBus库传递数据