#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <mach/regs-clock.h>
#include <plat/regs-timer.h>
#include <mach/regs-gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("liuchang");
#define beep_name "beep"
#define MAGIC 'b'
#define START_BEEP _IO(MAGIC,0)
#define STOP_BEEP _IO(MAGIC,1)
//support mdev:make node /dev/* automaticly
static struct class * class;
static struct device * device;
static struct cdev beep_dev;
static struct file_operations fo = {
.owner = THIS_MODULE,
.read = beep_read,
.write = beep_write,
.ioctl = beep_ioctl,
.open = beep_open,
.release = beep_release,
};
static int beep_major = 0;
module_param(beep_major,int,0444);
static int __init beep_init()
{
//alloc dev_t
dev_t dev = MKDEV(beep_major,0);
if(beep_major){
register_chrdev_region(dev,1,beep_name);
} else
{
alloc_chrdev_region(&dev,0,1,beep_name);
beep_major = MAJOR(dev);
}
printk(KERN_EMERG"major is %d\n",beep_major);
//init cdev
cdev_init(&beep_dev,&fo);
beep_dev.owner = THIS_MODULE;
cdev_add(&beep_dev,dev,1);
//mdev
//要实现mdev只要加入以下两句代码
//sys目录结构是 /sys/class/subsystem/device_name/dev
//1.第二个参数对应的是创建的/sys/class/beep_class目录(对应的是subsystem)
class = class_create( THIS_MODULE,"beep_class" );
//2.第四个参数对应的是/sys/class/beep_class/device_name目录,以及/dev/device_name设备名
device = device_create(class,NULL,dev,NULL, "device_name" );
//mknod -m 0666 /dev/device_name c/b 130 1
//dev文件创建在 /sys/class/beep_class/device_name/dev,
//内核在创建完这些sys下的目录及文件后,调用用户进程/sbin/mdev创建名称为device_name,主次设备号是dev内容的设备,
//而创建的设备是c还是b由dev_t参数决定,如果dev_t注册的是字符设备(使用register_chrdev_region或者alloc_chrdev_region函数),那么内核就在/sys/class/中创建subsystem/device_name,而不会在/sys/class/block(对应的是块设备)目录下创建目录及文件,而mdev区分是创建字符设备还是创建块设备就是检查uevent产生的DEVPATH变量中是否包含”/block/“子字符串
return 0;
}
static void __exit beep_exit()
{
cdev_del(&beep_dev);
dev_t dev = MKDEV(beep_major,0);
device_destroy(class,dev );
class_destroy( class );
unregister_chrdev_region(dev,1);
}
module_init(beep_init);
module_exit(beep_exit);