1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
| #include <linux/types.h> #include <linux/kernel.h> #include <linux/delay.h> #include <linux/ide.h> #include <linux/init.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/gpio.h> #include <linux/cdev.h> #include <linux/device.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_gpio.h> #include <asm/mach/map.h> #include <asm/uaccess.h> #include <asm/io.h> #include <linux/atomic.h>
#define demo_CNT 1 #define demo_NAME "dmeo"
struct demo_dev { dev_t devid; int major; int minor;
struct cdev cdev;
struct class *class; struct device *device; struct device_node *nd; int demo_gpio; };
struct demo_dev demo;
static int demo_open(struct inode *inode, struct file *filp) { filp->private_data = &demo; return 0; } static int demo_release(struct inode *inode,struct file *filp) {
return 0; }
static ssize_t demo_write(struct file *filp,const char __user *buf,size_t count,loff_t *offt) { return 0; }
static ssize_t demo_read(struct file *filp,char __user *buf,size_t count,loff_t *ppos) { return 0; }
static const struct file_operations demo_fops = { .owner = THIS_MODULE, .open = demo_open, .release = demo_release, .write = demo_write, .read = demo_read, };
static int __init demo_init(void) { int ret;
demo.major = 0; if (demo.major) { demo.devid = MKDEV(demo.major, 0); register_chrdev_region(demo.devid,demo_CNT,demo_NAME); } else{ ret = alloc_chrdev_region(&demo.devid,0,demo_CNT,demo_NAME); demo.major = MAJOR(demo.devid); demo.minor = MINOR(demo.devid); } printk("major = %d,minor = %d\r\n",demo.major,demo.minor);
if(ret < 0) { printk("fail devid\r\n"); goto fail_devid; }
demo.cdev.owner = THIS_MODULE; cdev_init(&demo.cdev,&demo_fops);
ret = cdev_add(&demo.cdev,demo.devid,demo_CNT); if (ret < 0) { printk("fail cdevadd\r\n"); goto fail_cdevadd; }
demo.class = class_create(THIS_MODULE,demo_NAME); if (IS_ERR(demo.class)) { printk("fail class\r\n"); ret = PTR_ERR(demo.class); goto fail_class; }
demo.device = device_create(demo.class,NULL,demo.devid,NULL,demo_NAME); if (IS_ERR(demo.device)) { printk("fail device\r\n"); ret = PTR_ERR(demo.device); goto fail_device; } return 0;
fail_device: class_destroy(demo.class); fail_class: cdev_del(&demo.cdev); fail_cdevadd: unregister_chrdev_region(demo.devid,demo_CNT); fail_devid: return ret; }
static void __exit demo_exit(void) { cdev_del(&demo.cdev); unregister_chrdev_region(demo.devid,demo_CNT); device_destroy(demo.class,demo.devid); class_destroy(demo.class);
printk("demo exit!\r\n"); }
module_init(demo_init); module_exit(demo_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("zwl");
|