승철이가 만든 것.
#include <linux/module.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/miscdevice.h>
#include <asm/uaccess.h>
int init_TEMPLATE(void);
void exit_TEMPLATE(void);
static int TEMPLATE_open(struct inode *inode, struct file *file);
static int TEMPLATE_release(struct inode *inode, struct file *file);
static ssize_t TEMPLATE_read(struct file *file, char __user *buf, size_t count, loff_t *pos);
static ssize_t TEMPLATE_write(struct file *file, const char __user *buf, size_t count, loff_t *pos);
static int TEMPLATE_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
static struct file_operations TEMPLATE_fops = {
.owner = THIS_MODULE,
.read = TEMPLATE_read,
.write = TEMPLATE_write,
.open = TEMPLATE_open,
.release= TEMPLATE_release,
.ioctl = TEMPLATE_ioctl,
};
static struct miscdevice TEMPLATE_miscdev = {
.minor = TEMPLATE_MINOR, /* set it to include/linux/miscdevice.h */
.name = "TEMPLATE",
.fops = &TEMPLATE_fops,
.devfs_name = "tmp/TEMPLATE",
};
static void TEMPLATE_tasklet_handler(unsigned long data) {
printk("Tasklet is scheduled\n");
}
static void TEMPLATE_worker(void *data) {
printk("Worker is called\n");
}
static DECLARE_TASKLET(TEMPLATE_tasklet, TEMPLATE_tasklet_handler, 0);
static DECLARE_WORK(TEMPLATE_work, TEMPLATE_worker, 0);
irqreturn_t TEMPLATE_irq_handler(int irq, void *dev_id, struct pt_regs *regs) {
tasklet_schedule(&TEMPLATE_tasklet); /* on bottom half: interrupt context */
schedule_work(&TEMPLATE_work); /* on running keventd: process context */
return IRQ_HANDLED;
}
#define TEMPLATE_IRQ 1
static int TEMPLATE_open(struct inode *inode, struct file *file){
int ret;
if (!try_module_get(THIS_MODULE)) return -EBUSY;
ret = request_irq(TEMPLATE_IRQ, /* The number of the IRQ*/
TEMPLATE_irq_handler, /* our handler */
SA_SHIRQ, /* SA_SHIRQ or SA_INTERRUPT */
"TEMPLATE_irq_handler",
(void *)(TEMPLATE_irq_handler));
if (!ret) return -ENODEV;
printk("Template Open\n");
return 0;
}
static int TEMPLATE_release(struct inode *inode, struct file *file){
module_put(THIS_MODULE);
printk("Template Release\n");
}
static ssize_t TEMPLATE_read(struct file *file, char __user *buf, size_t count, loff_t *pos){
printk("Template Read\n");
}
static ssize_t TEMPLATE_write(struct file *file, const char __user *buf, size_t count, loff_t *pos){
printk("Template Write\n");
}
static int TEMPLATE_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) {
printk("Template IOctl\n");
}
int __init init_TEMPLATE(void) {
int ret;
ret = misc_register(&TEMPLATE_miscdev);
printk("Template Module Init\n");
return ret;
}
void __exit exit_TEMPLATE(void) {
misc_deregister(&TEMPLATE_miscdev);
printk(KERN_ALERT "Template Module Exit\n");
}
module_init(init_TEMPLATE);
module_exit(exit_TEMPLATE);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jackson Kang<ohmylove@mail.co.kr");
MODULE_DESCRIPTION("A template driver");
MODULE_SUPPORTED_DEVICE("none");