[修改] 清空

This commit is contained in:
gaoyang3513
2024-01-16 14:35:50 +00:00
parent 3f3b436a9f
commit 7dc07cf4d7
150 changed files with 12 additions and 10507 deletions

12
.editorconfig Normal file
View File

@ -0,0 +1,12 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
indent_style = tab
indent_size = 8
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := vser.o
endif

View File

@ -1,51 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include "vser.h"
int main(int argc, char *argv[])
{
int fd;
int ret;
unsigned int baud;
struct option opt = {8,1,1};
fd = open("/dev/vser0", O_RDWR);
if (fd == -1)
goto fail;
baud = 9600;
ret = ioctl(fd, VS_SET_BAUD, baud);
if (ret == -1)
goto fail;
ret = ioctl(fd, VS_GET_BAUD, baud);
if (ret == -1)
goto fail;
ret = ioctl(fd, VS_SET_FFMT, &opt);
if (ret == -1)
goto fail;
ret = ioctl(fd, VS_GET_FFMT, &opt);
if (ret == -1)
goto fail;
printf("baud rate: %d\n", baud);
printf("frame format: %d%c%d\n", opt.datab, opt.parity == 0 ? 'N' : \
opt.parity == 1 ? 'O' : 'E', \
opt.stopb);
close(fd);
exit(EXIT_SUCCESS);
fail:
perror("ioctl test");
exit(EXIT_FAILURE);
}

View File

@ -1,140 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kfifo.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include "vser.h"
#define VSER_MAJOR 256
#define VSER_MINOR 0
#define VSER_DEV_CNT 1
#define VSER_DEV_NAME "vser"
struct vser_dev {
unsigned int baud;
struct option opt;
struct cdev cdev;
};
DEFINE_KFIFO(vsfifo, char, 32);
static struct vser_dev vsdev;
static int vser_open(struct inode *inode, struct file *filp)
{
return 0;
}
static int vser_release(struct inode *inode, struct file *filp)
{
return 0;
}
static ssize_t vser_read(struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
int ret;
unsigned int copied = 0;
ret = kfifo_to_user(&vsfifo, buf, count, &copied);
return ret == 0 ? copied : ret;
}
static ssize_t vser_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos)
{
int ret;
unsigned int copied = 0;
ret = kfifo_from_user(&vsfifo, buf, count, &copied);
return ret == 0 ? copied : ret;
}
static long vser_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
if (_IOC_TYPE(cmd) != VS_MAGIC)
return -ENOTTY;
switch (cmd) {
case VS_SET_BAUD:
vsdev.baud = arg;
break;
case VS_GET_BAUD:
arg = vsdev.baud;
break;
case VS_SET_FFMT:
if (copy_from_user(&vsdev.opt, (struct option __user *)arg, sizeof(struct option)))
return -EFAULT;
break;
case VS_GET_FFMT:
if (copy_to_user((struct option __user *)arg, &vsdev.opt, sizeof(struct option)))
return -EFAULT;
break;
default:
return -ENOTTY;
}
return 0;
}
static struct file_operations vser_ops = {
.owner = THIS_MODULE,
.open = vser_open,
.release = vser_release,
.read = vser_read,
.write = vser_write,
.unlocked_ioctl = vser_ioctl,
};
static int __init vser_init(void)
{
int ret;
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
ret = register_chrdev_region(dev, VSER_DEV_CNT, VSER_DEV_NAME);
if (ret)
goto reg_err;
cdev_init(&vsdev.cdev, &vser_ops);
vsdev.cdev.owner = THIS_MODULE;
vsdev.baud = 115200;
vsdev.opt.datab = 8;
vsdev.opt.parity = 0;
vsdev.opt.stopb = 1;
ret = cdev_add(&vsdev.cdev, dev, VSER_DEV_CNT);
if (ret)
goto add_err;
return 0;
add_err:
unregister_chrdev_region(dev, VSER_DEV_CNT);
reg_err:
return ret;
}
static void __exit vser_exit(void)
{
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
cdev_del(&vsdev.cdev);
unregister_chrdev_region(dev, VSER_DEV_CNT);
}
module_init(vser_init);
module_exit(vser_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple character device driver");
MODULE_ALIAS("virtual-serial");

View File

@ -1,17 +0,0 @@
#ifndef _VSER_H
#define _VSER_H
struct option {
unsigned int datab;
unsigned int parity;
unsigned int stopb;
};
#define VS_MAGIC 's'
#define VS_SET_BAUD _IOW(VS_MAGIC, 0, unsigned int)
#define VS_GET_BAUD _IOW(VS_MAGIC, 1, unsigned int)
#define VS_SET_FFMT _IOW(VS_MAGIC, 2, struct option)
#define VS_GET_FFMT _IOW(VS_MAGIC, 3, struct option)
#endif

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := vfb.o
endif

View File

@ -1,43 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
int main(int argc, char * argv[])
{
int fd;
char *start;
int i;
char buf[32];
fd = open("/dev/vfb0", O_RDWR);
if (fd == -1)
goto fail;
start = mmap(NULL, 32, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (start == MAP_FAILED)
goto fail;
for (i = 0; i < 26; i++)
*(start + i) = 'a' + i;
*(start + i) = '\0';
if(lseek(fd, 3, SEEK_SET) == -1)
goto fail;
if (read(fd, buf, 10) == -1)
goto fail;
buf[10] = '\0';
puts(buf);
munmap(start, 32);
return 0;
fail:
perror("mmap test");
exit(EXIT_FAILURE);
}

View File

@ -1,139 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#define VFB_MAJOR 256
#define VFB_MINOR 1
#define VFB_DEV_CNT 1
#define VFB_DEV_NAME "vfbdev"
struct vfb_dev {
unsigned char *buf;
struct cdev cdev;
};
static struct vfb_dev vfbdev;
static int vfb_open(struct inode * inode, struct file * filp)
{
return 0;
}
static int vfb_release(struct inode *inode, struct file *filp)
{
return 0;
}
static int vfb_mmap(struct file *filp, struct vm_area_struct *vma)
{
if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(vfbdev.buf) >> PAGE_SHIFT, \
vma->vm_end - vma->vm_start, vma->vm_page_prot))
return -EAGAIN;
return 0;
}
ssize_t vfb_read(struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
int ret;
size_t len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
if (*pos + len > PAGE_SIZE)
len = PAGE_SIZE - *pos;
ret = copy_to_user(buf, vfbdev.buf + *pos, len);
*pos += len - ret;
return len - ret;
}
static loff_t vfb_llseek(struct file * filp, loff_t off, int whence)
{
loff_t newpos;
switch (whence) {
case SEEK_SET:
newpos = off;
break;
case SEEK_CUR:
newpos = filp->f_pos + off;
break;
case SEEK_END:
newpos = PAGE_SIZE + off;
break;
default: /* can't happen */
return -EINVAL;
}
if (newpos < 0 || newpos > PAGE_SIZE)
return -EINVAL;
filp->f_pos = newpos;
return newpos;
}
static struct file_operations vfb_fops = {
.owner = THIS_MODULE,
.open = vfb_open,
.release = vfb_release,
.mmap = vfb_mmap,
.read = vfb_read,
.llseek = vfb_llseek,
};
static int __init vfb_init(void)
{
int ret;
dev_t dev;
unsigned long addr;
dev = MKDEV(VFB_MAJOR, VFB_MINOR);
ret = register_chrdev_region(dev, VFB_DEV_CNT, VFB_DEV_NAME);
if (ret)
goto reg_err;
cdev_init(&vfbdev.cdev, &vfb_fops);
vfbdev.cdev.owner = THIS_MODULE;
ret = cdev_add(&vfbdev.cdev, dev, VFB_DEV_CNT);
if (ret)
goto add_err;
addr = __get_free_page(GFP_KERNEL);
if (!addr)
goto get_err;
vfbdev.buf = (unsigned char *)addr;
memset(vfbdev.buf, 0, PAGE_SIZE);
return 0;
get_err:
cdev_del(&vfbdev.cdev);
add_err:
unregister_chrdev_region(dev, VFB_DEV_CNT);
reg_err:
return ret;
}
static void __exit vfb_exit(void)
{
dev_t dev;
dev = MKDEV(VFB_MAJOR, VFB_MINOR);
free_page((unsigned long)vfbdev.buf);
cdev_del(&vfbdev.cdev);
unregister_chrdev_region(dev, VFB_DEV_CNT);
}
module_init(vfb_init);
module_exit(vfb_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("This is an example for mmap");

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := vser.o
endif

View File

@ -1,181 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kfifo.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include "vser.h"
#define VSER_MAJOR 256
#define VSER_MINOR 0
#define VSER_DEV_CNT 1
#define VSER_DEV_NAME "vser"
struct vser_dev {
unsigned int baud;
struct option opt;
struct cdev cdev;
struct proc_dir_entry *pdir;
struct proc_dir_entry *pdat;
};
DEFINE_KFIFO(vsfifo, char, 32);
static struct vser_dev vsdev;
static int vser_open(struct inode *inode, struct file *filp)
{
return 0;
}
static int vser_release(struct inode *inode, struct file *filp)
{
return 0;
}
static ssize_t vser_read(struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
int ret;
unsigned int copied = 0;
ret = kfifo_to_user(&vsfifo, buf, count, &copied);
return ret == 0 ? copied : ret;
}
static ssize_t vser_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos)
{
int ret;
unsigned int copied = 0;
ret = kfifo_from_user(&vsfifo, buf, count, &copied);
return ret == 0 ? copied : ret;
}
static long vser_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
if (_IOC_TYPE(cmd) != VS_MAGIC)
return -ENOTTY;
switch (cmd) {
case VS_SET_BAUD:
vsdev.baud = arg;
break;
case VS_GET_BAUD:
arg = vsdev.baud;
break;
case VS_SET_FFMT:
if (copy_from_user(&vsdev.opt, (struct option __user *)arg, sizeof(struct option)))
return -EFAULT;
break;
case VS_GET_FFMT:
if (copy_to_user((struct option __user *)arg, &vsdev.opt, sizeof(struct option)))
return -EFAULT;
break;
default:
return -ENOTTY;
}
return 0;
}
static struct file_operations vser_ops = {
.owner = THIS_MODULE,
.open = vser_open,
.release = vser_release,
.read = vser_read,
.write = vser_write,
.unlocked_ioctl = vser_ioctl,
};
static int dat_show(struct seq_file *m, void *v)
{
struct vser_dev *dev = m->private;
seq_printf(m, "baudrate: %d\n", dev->baud);
return seq_printf(m, "frame format: %d%c%d\n", dev->opt.datab, \
dev->opt.parity == 0 ? 'N' : dev->opt.parity == 1 ? 'O': 'E', \
dev->opt.stopb);
}
static int proc_open(struct inode *inode, struct file *file)
{
return single_open(file, dat_show, PDE_DATA(inode));
}
static struct file_operations proc_ops = {
.owner = THIS_MODULE,
.open = proc_open,
.release = single_release,
.read = seq_read,
.llseek = seq_lseek,
};
static int __init vser_init(void)
{
int ret;
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
ret = register_chrdev_region(dev, VSER_DEV_CNT, VSER_DEV_NAME);
if (ret)
goto reg_err;
cdev_init(&vsdev.cdev, &vser_ops);
vsdev.cdev.owner = THIS_MODULE;
vsdev.baud = 115200;
vsdev.opt.datab = 8;
vsdev.opt.parity = 0;
vsdev.opt.stopb = 1;
ret = cdev_add(&vsdev.cdev, dev, VSER_DEV_CNT);
if (ret)
goto add_err;
vsdev.pdir = proc_mkdir("vser", NULL);
if (!vsdev.pdir)
goto dir_err;
vsdev.pdat = proc_create_data("info", 0, vsdev.pdir, &proc_ops, &vsdev);
if (!vsdev.pdat)
goto dat_err;
return 0;
dat_err:
remove_proc_entry("vser", NULL);
dir_err:
cdev_del(&vsdev.cdev);
add_err:
unregister_chrdev_region(dev, VSER_DEV_CNT);
reg_err:
return ret;
}
static void __exit vser_exit(void)
{
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
remove_proc_entry("info", vsdev.pdir);
remove_proc_entry("vser", NULL);
cdev_del(&vsdev.cdev);
unregister_chrdev_region(dev, VSER_DEV_CNT);
}
module_init(vser_init);
module_exit(vser_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple character device driver");
MODULE_ALIAS("virtual-serial");

View File

@ -1,17 +0,0 @@
#ifndef _VSER_H
#define _VSER_H
struct option {
unsigned int datab;
unsigned int parity;
unsigned int stopb;
};
#define VS_MAGIC 's'
#define VS_SET_BAUD _IOW(VS_MAGIC, 0, unsigned int)
#define VS_GET_BAUD _IOW(VS_MAGIC, 1, unsigned int)
#define VS_SET_FFMT _IOW(VS_MAGIC, 2, struct option)
#define VS_GET_FFMT _IOW(VS_MAGIC, 3, struct option)
#endif

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := vser.o
endif

View File

@ -1,44 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include "vser.h"
int main(int argc, char *argv[])
{
int fd;
int ret;
unsigned int baud;
struct option opt = {8,1,1};
char rbuf[32] = {0};
char wbuf[32] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
fd = open("/dev/vser0", O_RDWR | O_NONBLOCK);
if (fd == -1)
goto fail;
ret = read(fd, rbuf, sizeof(rbuf));
if (ret < 0)
perror("read");
ret = write(fd, wbuf, sizeof(wbuf));
if (ret < 0)
perror("first write");
ret = write(fd, wbuf, sizeof(wbuf));
if (ret < 0)
perror("second write");
close(fd);
exit(EXIT_SUCCESS);
fail:
perror("ioctl test");
exit(EXIT_FAILURE);
}

View File

@ -1,148 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kfifo.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include "vser.h"
#define VSER_MAJOR 256
#define VSER_MINOR 0
#define VSER_DEV_CNT 1
#define VSER_DEV_NAME "vser"
struct vser_dev {
unsigned int baud;
struct option opt;
struct cdev cdev;
};
DEFINE_KFIFO(vsfifo, char, 32);
static struct vser_dev vsdev;
static int vser_open(struct inode *inode, struct file *filp)
{
return 0;
}
static int vser_release(struct inode *inode, struct file *filp)
{
return 0;
}
static ssize_t vser_read(struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
int ret;
unsigned int copied = 0;
if (kfifo_is_empty(&vsfifo))
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
ret = kfifo_to_user(&vsfifo, buf, count, &copied);
return ret == 0 ? copied : ret;
}
static ssize_t vser_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos)
{
int ret;
unsigned int copied = 0;
if (kfifo_is_full(&vsfifo))
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
ret = kfifo_from_user(&vsfifo, buf, count, &copied);
return ret == 0 ? copied : ret;
}
static long vser_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
if (_IOC_TYPE(cmd) != VS_MAGIC)
return -ENOTTY;
switch (cmd) {
case VS_SET_BAUD:
vsdev.baud = arg;
break;
case VS_GET_BAUD:
arg = vsdev.baud;
break;
case VS_SET_FFMT:
if (copy_from_user(&vsdev.opt, (struct option __user *)arg, sizeof(struct option)))
return -EFAULT;
break;
case VS_GET_FFMT:
if (copy_to_user((struct option __user *)arg, &vsdev.opt, sizeof(struct option)))
return -EFAULT;
break;
default:
return -ENOTTY;
}
return 0;
}
static struct file_operations vser_ops = {
.owner = THIS_MODULE,
.open = vser_open,
.release = vser_release,
.read = vser_read,
.write = vser_write,
.unlocked_ioctl = vser_ioctl,
};
static int __init vser_init(void)
{
int ret;
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
ret = register_chrdev_region(dev, VSER_DEV_CNT, VSER_DEV_NAME);
if (ret)
goto reg_err;
cdev_init(&vsdev.cdev, &vser_ops);
vsdev.cdev.owner = THIS_MODULE;
vsdev.baud = 115200;
vsdev.opt.datab = 8;
vsdev.opt.parity = 0;
vsdev.opt.stopb = 1;
ret = cdev_add(&vsdev.cdev, dev, VSER_DEV_CNT);
if (ret)
goto add_err;
return 0;
add_err:
unregister_chrdev_region(dev, VSER_DEV_CNT);
reg_err:
return ret;
}
static void __exit vser_exit(void)
{
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
cdev_del(&vsdev.cdev);
unregister_chrdev_region(dev, VSER_DEV_CNT);
}
module_init(vser_init);
module_exit(vser_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple character device driver");
MODULE_ALIAS("virtual-serial");

View File

@ -1,17 +0,0 @@
#ifndef _VSER_H
#define _VSER_H
struct option {
unsigned int datab;
unsigned int parity;
unsigned int stopb;
};
#define VS_MAGIC 's'
#define VS_SET_BAUD _IOW(VS_MAGIC, 0, unsigned int)
#define VS_GET_BAUD _IOW(VS_MAGIC, 1, unsigned int)
#define VS_SET_FFMT _IOW(VS_MAGIC, 2, struct option)
#define VS_GET_FFMT _IOW(VS_MAGIC, 3, struct option)
#endif

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := vser.o
endif

View File

@ -1,171 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kfifo.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include "vser.h"
#define VSER_MAJOR 256
#define VSER_MINOR 0
#define VSER_DEV_CNT 1
#define VSER_DEV_NAME "vser"
struct vser_dev {
unsigned int baud;
struct option opt;
struct cdev cdev;
wait_queue_head_t rwqh;
wait_queue_head_t wwqh;
};
DEFINE_KFIFO(vsfifo, char, 32);
static struct vser_dev vsdev;
static int vser_open(struct inode *inode, struct file *filp)
{
return 0;
}
static int vser_release(struct inode *inode, struct file *filp)
{
return 0;
}
static ssize_t vser_read(struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
int ret;
unsigned int copied = 0;
if (kfifo_is_empty(&vsfifo)) {
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
if (wait_event_interruptible(vsdev.rwqh, !kfifo_is_empty(&vsfifo)))
return -ERESTARTSYS;
}
ret = kfifo_to_user(&vsfifo, buf, count, &copied);
if (!kfifo_is_full(&vsfifo))
wake_up_interruptible(&vsdev.wwqh);
return ret == 0 ? copied : ret;
}
static ssize_t vser_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos)
{
int ret;
unsigned int copied = 0;
if (kfifo_is_full(&vsfifo)) {
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
if (wait_event_interruptible(vsdev.wwqh, !kfifo_is_full(&vsfifo)))
return -ERESTARTSYS;
}
ret = kfifo_from_user(&vsfifo, buf, count, &copied);
if (!kfifo_is_empty(&vsfifo))
wake_up_interruptible(&vsdev.rwqh);
return ret == 0 ? copied : ret;
}
static long vser_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
if (_IOC_TYPE(cmd) != VS_MAGIC)
return -ENOTTY;
switch (cmd) {
case VS_SET_BAUD:
vsdev.baud = arg;
break;
case VS_GET_BAUD:
arg = vsdev.baud;
break;
case VS_SET_FFMT:
if (copy_from_user(&vsdev.opt, (struct option __user *)arg, sizeof(struct option)))
return -EFAULT;
break;
case VS_GET_FFMT:
if (copy_to_user((struct option __user *)arg, &vsdev.opt, sizeof(struct option)))
return -EFAULT;
break;
default:
return -ENOTTY;
}
return 0;
}
static struct file_operations vser_ops = {
.owner = THIS_MODULE,
.open = vser_open,
.release = vser_release,
.read = vser_read,
.write = vser_write,
.unlocked_ioctl = vser_ioctl,
};
static int __init vser_init(void)
{
int ret;
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
ret = register_chrdev_region(dev, VSER_DEV_CNT, VSER_DEV_NAME);
if (ret)
goto reg_err;
cdev_init(&vsdev.cdev, &vser_ops);
vsdev.cdev.owner = THIS_MODULE;
vsdev.baud = 115200;
vsdev.opt.datab = 8;
vsdev.opt.parity = 0;
vsdev.opt.stopb = 1;
ret = cdev_add(&vsdev.cdev, dev, VSER_DEV_CNT);
if (ret)
goto add_err;
init_waitqueue_head(&vsdev.rwqh);
init_waitqueue_head(&vsdev.wwqh);
return 0;
add_err:
unregister_chrdev_region(dev, VSER_DEV_CNT);
reg_err:
return ret;
}
static void __exit vser_exit(void)
{
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
cdev_del(&vsdev.cdev);
unregister_chrdev_region(dev, VSER_DEV_CNT);
}
module_init(vser_init);
module_exit(vser_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple character device driver");
MODULE_ALIAS("virtual-serial");

View File

@ -1,17 +0,0 @@
#ifndef _VSER_H
#define _VSER_H
struct option {
unsigned int datab;
unsigned int parity;
unsigned int stopb;
};
#define VS_MAGIC 's'
#define VS_SET_BAUD _IOW(VS_MAGIC, 0, unsigned int)
#define VS_GET_BAUD _IOW(VS_MAGIC, 1, unsigned int)
#define VS_SET_FFMT _IOW(VS_MAGIC, 2, struct option)
#define VS_GET_FFMT _IOW(VS_MAGIC, 3, struct option)
#endif

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := vser.o
endif

View File

@ -1,34 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include "vser.h"
int main(int argc, char *argv[])
{
int fd;
int ret;
unsigned int baud;
struct option opt = {8,1,1};
char rbuf[32] = {0};
fd = open("/dev/vser0", O_RDWR | O_NONBLOCK);
if (fd == -1)
goto fail;
ret = read(fd, rbuf, sizeof(rbuf));
if (ret < 0)
perror("read");
close(fd);
exit(EXIT_SUCCESS);
fail:
perror("ioctl test");
exit(EXIT_FAILURE);
}

View File

@ -1,171 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kfifo.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include "vser.h"
#define VSER_MAJOR 256
#define VSER_MINOR 0
#define VSER_DEV_CNT 1
#define VSER_DEV_NAME "vser"
struct vser_dev {
unsigned int baud;
struct option opt;
struct cdev cdev;
wait_queue_head_t rwqh;
wait_queue_head_t wwqh;
};
DEFINE_KFIFO(vsfifo, char, 32);
static struct vser_dev vsdev;
static int vser_open(struct inode *inode, struct file *filp)
{
return 0;
}
static int vser_release(struct inode *inode, struct file *filp)
{
return 0;
}
static ssize_t vser_read(struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
int ret;
unsigned int copied = 0;
if (kfifo_is_empty(&vsfifo)) {
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
if (wait_event_interruptible_exclusive(vsdev.rwqh, !kfifo_is_empty(&vsfifo)))
return -ERESTARTSYS;
}
ret = kfifo_to_user(&vsfifo, buf, count, &copied);
if (!kfifo_is_full(&vsfifo))
wake_up_interruptible(&vsdev.wwqh);
return ret == 0 ? copied : ret;
}
static ssize_t vser_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos)
{
int ret;
unsigned int copied = 0;
if (kfifo_is_full(&vsfifo)) {
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
if (wait_event_interruptible_exclusive(vsdev.wwqh, !kfifo_is_full(&vsfifo)))
return -ERESTARTSYS;
}
ret = kfifo_from_user(&vsfifo, buf, count, &copied);
if (!kfifo_is_empty(&vsfifo))
wake_up_interruptible(&vsdev.rwqh);
return ret == 0 ? copied : ret;
}
static long vser_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
if (_IOC_TYPE(cmd) != VS_MAGIC)
return -ENOTTY;
switch (cmd) {
case VS_SET_BAUD:
vsdev.baud = arg;
break;
case VS_GET_BAUD:
arg = vsdev.baud;
break;
case VS_SET_FFMT:
if (copy_from_user(&vsdev.opt, (struct option __user *)arg, sizeof(struct option)))
return -EFAULT;
break;
case VS_GET_FFMT:
if (copy_to_user((struct option __user *)arg, &vsdev.opt, sizeof(struct option)))
return -EFAULT;
break;
default:
return -ENOTTY;
}
return 0;
}
static struct file_operations vser_ops = {
.owner = THIS_MODULE,
.open = vser_open,
.release = vser_release,
.read = vser_read,
.write = vser_write,
.unlocked_ioctl = vser_ioctl,
};
static int __init vser_init(void)
{
int ret;
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
ret = register_chrdev_region(dev, VSER_DEV_CNT, VSER_DEV_NAME);
if (ret)
goto reg_err;
cdev_init(&vsdev.cdev, &vser_ops);
vsdev.cdev.owner = THIS_MODULE;
vsdev.baud = 115200;
vsdev.opt.datab = 8;
vsdev.opt.parity = 0;
vsdev.opt.stopb = 1;
ret = cdev_add(&vsdev.cdev, dev, VSER_DEV_CNT);
if (ret)
goto add_err;
init_waitqueue_head(&vsdev.rwqh);
init_waitqueue_head(&vsdev.wwqh);
return 0;
add_err:
unregister_chrdev_region(dev, VSER_DEV_CNT);
reg_err:
return ret;
}
static void __exit vser_exit(void)
{
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
cdev_del(&vsdev.cdev);
unregister_chrdev_region(dev, VSER_DEV_CNT);
}
module_init(vser_init);
module_exit(vser_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple character device driver");
MODULE_ALIAS("virtual-serial");

View File

@ -1,17 +0,0 @@
#ifndef _VSER_H
#define _VSER_H
struct option {
unsigned int datab;
unsigned int parity;
unsigned int stopb;
};
#define VS_MAGIC 's'
#define VS_SET_BAUD _IOW(VS_MAGIC, 0, unsigned int)
#define VS_GET_BAUD _IOW(VS_MAGIC, 1, unsigned int)
#define VS_SET_FFMT _IOW(VS_MAGIC, 2, struct option)
#define VS_GET_FFMT _IOW(VS_MAGIC, 3, struct option)
#endif

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := vser.o
endif

View File

@ -1,63 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <poll.h>
#include <linux/input.h>
#include "vser.h"
int main(int argc, char *argv[])
{
int ret;
struct pollfd fds[2];
char rbuf[32];
char wbuf[32];
struct input_event key;
fds[0].fd = open("/dev/vser0", O_RDWR | O_NONBLOCK);
if (fds[0].fd == -1)
goto fail;
fds[0].events = POLLIN;
fds[0].revents = 0;
fds[1].fd = open("/dev/input/event1", O_RDWR | O_NONBLOCK);
if (fds[1].fd == -1)
goto fail;
fds[1].events = POLLIN;
fds[1].revents = 0;
while (1) {
ret = poll(fds, 2, -1);
if (ret == -1)
goto fail;
if (fds[0].revents & POLLIN) {
ret = read(fds[0].fd, rbuf, sizeof(rbuf));
if (ret < 0)
goto fail;
puts(rbuf);
}
if (fds[1].revents & POLLIN) {
ret = read(fds[1].fd, &key, sizeof(key));
if (ret < 0)
goto fail;
if (key.type == EV_KEY) {
sprintf(wbuf, "%#x\n", key.code);
ret = write(fds[0].fd, wbuf, strlen(wbuf) + 1);
if (ret < 0)
goto fail;
}
}
}
fail:
perror("poll test");
exit(EXIT_FAILURE);
}

View File

@ -1,188 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kfifo.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include "vser.h"
#define VSER_MAJOR 256
#define VSER_MINOR 0
#define VSER_DEV_CNT 1
#define VSER_DEV_NAME "vser"
struct vser_dev {
unsigned int baud;
struct option opt;
struct cdev cdev;
wait_queue_head_t rwqh;
wait_queue_head_t wwqh;
};
DEFINE_KFIFO(vsfifo, char, 32);
static struct vser_dev vsdev;
static int vser_open(struct inode *inode, struct file *filp)
{
return 0;
}
static int vser_release(struct inode *inode, struct file *filp)
{
return 0;
}
static ssize_t vser_read(struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
int ret;
unsigned int copied = 0;
if (kfifo_is_empty(&vsfifo)) {
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
if (wait_event_interruptible_exclusive(vsdev.rwqh, !kfifo_is_empty(&vsfifo)))
return -ERESTARTSYS;
}
ret = kfifo_to_user(&vsfifo, buf, count, &copied);
if (!kfifo_is_full(&vsfifo))
wake_up_interruptible(&vsdev.wwqh);
return ret == 0 ? copied : ret;
}
static ssize_t vser_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos)
{
int ret;
unsigned int copied = 0;
if (kfifo_is_full(&vsfifo)) {
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
if (wait_event_interruptible_exclusive(vsdev.wwqh, !kfifo_is_full(&vsfifo)))
return -ERESTARTSYS;
}
ret = kfifo_from_user(&vsfifo, buf, count, &copied);
if (!kfifo_is_empty(&vsfifo))
wake_up_interruptible(&vsdev.rwqh);
return ret == 0 ? copied : ret;
}
static long vser_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
if (_IOC_TYPE(cmd) != VS_MAGIC)
return -ENOTTY;
switch (cmd) {
case VS_SET_BAUD:
vsdev.baud = arg;
break;
case VS_GET_BAUD:
arg = vsdev.baud;
break;
case VS_SET_FFMT:
if (copy_from_user(&vsdev.opt, (struct option __user *)arg, sizeof(struct option)))
return -EFAULT;
break;
case VS_GET_FFMT:
if (copy_to_user((struct option __user *)arg, &vsdev.opt, sizeof(struct option)))
return -EFAULT;
break;
default:
return -ENOTTY;
}
return 0;
}
unsigned int vser_poll(struct file *filp, struct poll_table_struct *p)
{
int mask = 0;
poll_wait(filp, &vsdev.rwqh, p);
poll_wait(filp, &vsdev.wwqh, p);
if (!kfifo_is_empty(&vsfifo))
mask |= POLLIN | POLLRDNORM;
if (!kfifo_is_full(&vsfifo))
mask |= POLLOUT | POLLWRNORM;
return mask;
}
static struct file_operations vser_ops = {
.owner = THIS_MODULE,
.open = vser_open,
.release = vser_release,
.read = vser_read,
.write = vser_write,
.unlocked_ioctl = vser_ioctl,
.poll = vser_poll,
};
static int __init vser_init(void)
{
int ret;
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
ret = register_chrdev_region(dev, VSER_DEV_CNT, VSER_DEV_NAME);
if (ret)
goto reg_err;
cdev_init(&vsdev.cdev, &vser_ops);
vsdev.cdev.owner = THIS_MODULE;
vsdev.baud = 115200;
vsdev.opt.datab = 8;
vsdev.opt.parity = 0;
vsdev.opt.stopb = 1;
ret = cdev_add(&vsdev.cdev, dev, VSER_DEV_CNT);
if (ret)
goto add_err;
init_waitqueue_head(&vsdev.rwqh);
init_waitqueue_head(&vsdev.wwqh);
return 0;
add_err:
unregister_chrdev_region(dev, VSER_DEV_CNT);
reg_err:
return ret;
}
static void __exit vser_exit(void)
{
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
cdev_del(&vsdev.cdev);
unregister_chrdev_region(dev, VSER_DEV_CNT);
}
module_init(vser_init);
module_exit(vser_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple character device driver");
MODULE_ALIAS("virtual-serial");

View File

@ -1,17 +0,0 @@
#ifndef _VSER_H
#define _VSER_H
struct option {
unsigned int datab;
unsigned int parity;
unsigned int stopb;
};
#define VS_MAGIC 's'
#define VS_SET_BAUD _IOW(VS_MAGIC, 0, unsigned int)
#define VS_GET_BAUD _IOW(VS_MAGIC, 1, unsigned int)
#define VS_SET_FFMT _IOW(VS_MAGIC, 2, struct option)
#define VS_GET_FFMT _IOW(VS_MAGIC, 3, struct option)
#endif

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := vser.o
endif

View File

@ -1,89 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <poll.h>
#include <linux/input.h>
#include <aio.h>
#include "vser.h"
void aiow_completion_handler(sigval_t sigval)
{
int ret;
struct aiocb *req;
req = (struct aiocb *)sigval.sival_ptr;
if (aio_error(req) == 0) {
ret = aio_return(req);
printf("aio write %d bytes\n", ret);
}
return;
}
void aior_completion_handler(sigval_t sigval)
{
int ret;
struct aiocb *req;
req = (struct aiocb *)sigval.sival_ptr;
if (aio_error(req) == 0) {
ret = aio_return(req);
if (ret)
printf("aio read: %s\n", (char *)req->aio_buf);
}
return;
}
int main(int argc, char *argv[])
{
int ret;
int fd;
struct aiocb aiow, aior;
fd = open("/dev/vser0", O_RDWR);
if (fd == -1)
goto fail;
memset(&aiow, 0, sizeof(aiow));
memset(&aior, 0, sizeof(aior));
aiow.aio_fildes = fd;
aiow.aio_buf = malloc(32);
strcpy((char *)aiow.aio_buf, "aio test");
aiow.aio_nbytes = strlen((char *)aiow.aio_buf) + 1;
aiow.aio_offset = 0;
aiow.aio_sigevent.sigev_notify = SIGEV_THREAD;
aiow.aio_sigevent.sigev_notify_function = aiow_completion_handler;
aiow.aio_sigevent.sigev_notify_attributes = NULL;
aiow.aio_sigevent.sigev_value.sival_ptr = &aiow;
aior.aio_fildes = fd;
aior.aio_buf = malloc(32);
aior.aio_nbytes = 32;
aior.aio_offset = 0;
aior.aio_sigevent.sigev_notify = SIGEV_THREAD;
aior.aio_sigevent.sigev_notify_function = aior_completion_handler;
aior.aio_sigevent.sigev_notify_attributes = NULL;
aior.aio_sigevent.sigev_value.sival_ptr = &aior;
while (1) {
if (aio_write(&aiow) == -1)
goto fail;
if (aio_read(&aior) == -1)
goto fail;
sleep(1);
}
fail:
perror("aio test");
exit(EXIT_FAILURE);
}

View File

@ -1,223 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kfifo.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/aio.h>
#include "vser.h"
#define VSER_MAJOR 256
#define VSER_MINOR 0
#define VSER_DEV_CNT 1
#define VSER_DEV_NAME "vser"
struct vser_dev {
unsigned int baud;
struct option opt;
struct cdev cdev;
wait_queue_head_t rwqh;
wait_queue_head_t wwqh;
};
DEFINE_KFIFO(vsfifo, char, 32);
static struct vser_dev vsdev;
static int vser_open(struct inode *inode, struct file *filp)
{
return 0;
}
static int vser_release(struct inode *inode, struct file *filp)
{
return 0;
}
static ssize_t vser_read(struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
int ret;
unsigned int copied = 0;
if (kfifo_is_empty(&vsfifo)) {
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
if (wait_event_interruptible_exclusive(vsdev.rwqh, !kfifo_is_empty(&vsfifo)))
return -ERESTARTSYS;
}
ret = kfifo_to_user(&vsfifo, buf, count, &copied);
if (!kfifo_is_full(&vsfifo))
wake_up_interruptible(&vsdev.wwqh);
return ret == 0 ? copied : ret;
}
static ssize_t vser_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos)
{
int ret;
unsigned int copied = 0;
if (kfifo_is_full(&vsfifo)) {
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
if (wait_event_interruptible_exclusive(vsdev.wwqh, !kfifo_is_full(&vsfifo)))
return -ERESTARTSYS;
}
ret = kfifo_from_user(&vsfifo, buf, count, &copied);
if (!kfifo_is_empty(&vsfifo))
wake_up_interruptible(&vsdev.rwqh);
return ret == 0 ? copied : ret;
}
static long vser_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
if (_IOC_TYPE(cmd) != VS_MAGIC)
return -ENOTTY;
switch (cmd) {
case VS_SET_BAUD:
vsdev.baud = arg;
break;
case VS_GET_BAUD:
arg = vsdev.baud;
break;
case VS_SET_FFMT:
if (copy_from_user(&vsdev.opt, (struct option __user *)arg, sizeof(struct option)))
return -EFAULT;
break;
case VS_GET_FFMT:
if (copy_to_user((struct option __user *)arg, &vsdev.opt, sizeof(struct option)))
return -EFAULT;
break;
default:
return -ENOTTY;
}
return 0;
}
static unsigned int vser_poll(struct file *filp, struct poll_table_struct *p)
{
int mask = 0;
poll_wait(filp, &vsdev.rwqh, p);
poll_wait(filp, &vsdev.wwqh, p);
if (!kfifo_is_empty(&vsfifo))
mask |= POLLIN | POLLRDNORM;
if (!kfifo_is_full(&vsfifo))
mask |= POLLOUT | POLLWRNORM;
return mask;
}
static ssize_t vser_aio_read(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos)
{
size_t read = 0;
unsigned long i;
ssize_t ret;
for (i = 0; i < nr_segs; i++) {
ret = vser_read(iocb->ki_filp, iov[i].iov_base, iov[i].iov_len, &pos);
if (ret < 0)
break;
read += ret;
}
return read ? read : -EFAULT;
}
static ssize_t vser_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos)
{
size_t written = 0;
unsigned long i;
ssize_t ret;
for (i = 0; i < nr_segs; i++) {
ret = vser_write(iocb->ki_filp, iov[i].iov_base, iov[i].iov_len, &pos);
if (ret < 0)
break;
written += ret;
}
return written ? written : -EFAULT;
}
static struct file_operations vser_ops = {
.owner = THIS_MODULE,
.open = vser_open,
.release = vser_release,
.read = vser_read,
.write = vser_write,
.unlocked_ioctl = vser_ioctl,
.poll = vser_poll,
.aio_read = vser_aio_read,
.aio_write = vser_aio_write,
};
static int __init vser_init(void)
{
int ret;
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
ret = register_chrdev_region(dev, VSER_DEV_CNT, VSER_DEV_NAME);
if (ret)
goto reg_err;
cdev_init(&vsdev.cdev, &vser_ops);
vsdev.cdev.owner = THIS_MODULE;
vsdev.baud = 115200;
vsdev.opt.datab = 8;
vsdev.opt.parity = 0;
vsdev.opt.stopb = 1;
ret = cdev_add(&vsdev.cdev, dev, VSER_DEV_CNT);
if (ret)
goto add_err;
init_waitqueue_head(&vsdev.rwqh);
init_waitqueue_head(&vsdev.wwqh);
return 0;
add_err:
unregister_chrdev_region(dev, VSER_DEV_CNT);
reg_err:
return ret;
}
static void __exit vser_exit(void)
{
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
cdev_del(&vsdev.cdev);
unregister_chrdev_region(dev, VSER_DEV_CNT);
}
module_init(vser_init);
module_exit(vser_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple character device driver");
MODULE_ALIAS("virtual-serial");

View File

@ -1,17 +0,0 @@
#ifndef _VSER_H
#define _VSER_H
struct option {
unsigned int datab;
unsigned int parity;
unsigned int stopb;
};
#define VS_MAGIC 's'
#define VS_SET_BAUD _IOW(VS_MAGIC, 0, unsigned int)
#define VS_GET_BAUD _IOW(VS_MAGIC, 1, unsigned int)
#define VS_SET_FFMT _IOW(VS_MAGIC, 2, struct option)
#define VS_GET_FFMT _IOW(VS_MAGIC, 3, struct option)
#endif

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := vser.o
endif

View File

@ -1,67 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <poll.h>
#include <signal.h>
#include "vser.h"
int fd;
void sigio_handler(int signum, siginfo_t *siginfo, void *act)
{
int ret;
char buf[32];
if (signum == SIGIO) {
if (siginfo->si_band & POLLIN) {
printf("FIFO is not empty\n");
if ((ret = read(fd, buf, sizeof(buf))) != -1) {
buf[ret] = '\0';
puts(buf);
}
}
if (siginfo->si_band & POLLOUT)
printf("FIFO is not full\n");
}
}
int main(int argc, char *argv[])
{
int ret;
int flag;
struct sigaction act, oldact;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask, SIGIO);
act.sa_flags = SA_SIGINFO;
act.sa_sigaction = sigio_handler;
if (sigaction(SIGIO, &act, &oldact) == -1)
goto fail;
fd = open("/dev/vser0", O_RDWR | O_NONBLOCK);
if (fd == -1)
goto fail;
if (fcntl(fd, F_SETOWN, getpid()) == -1)
goto fail;
if (fcntl(fd, F_SETSIG, SIGIO) == -1)
goto fail;
if ((flag = fcntl(fd, F_GETFL)) == -1)
goto fail;
if (fcntl(fd, F_SETFL, flag | FASYNC) == -1)
goto fail;
while (1)
sleep(1);
fail:
perror("fasync test");
exit(EXIT_FAILURE);
}

View File

@ -1,237 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kfifo.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/aio.h>
#include "vser.h"
#define VSER_MAJOR 256
#define VSER_MINOR 0
#define VSER_DEV_CNT 1
#define VSER_DEV_NAME "vser"
struct vser_dev {
unsigned int baud;
struct option opt;
struct cdev cdev;
wait_queue_head_t rwqh;
wait_queue_head_t wwqh;
struct fasync_struct *fapp;
};
DEFINE_KFIFO(vsfifo, char, 32);
static struct vser_dev vsdev;
static int vser_fasync(int fd, struct file *filp, int on);
static int vser_open(struct inode *inode, struct file *filp)
{
return 0;
}
static int vser_release(struct inode *inode, struct file *filp)
{
vser_fasync(-1, filp, 0);
return 0;
}
static ssize_t vser_read(struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
int ret;
unsigned int copied = 0;
if (kfifo_is_empty(&vsfifo)) {
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
if (wait_event_interruptible_exclusive(vsdev.rwqh, !kfifo_is_empty(&vsfifo)))
return -ERESTARTSYS;
}
ret = kfifo_to_user(&vsfifo, buf, count, &copied);
if (!kfifo_is_full(&vsfifo)) {
wake_up_interruptible(&vsdev.wwqh);
kill_fasync(&vsdev.fapp, SIGIO, POLL_OUT);
}
return ret == 0 ? copied : ret;
}
static ssize_t vser_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos)
{
int ret;
unsigned int copied = 0;
if (kfifo_is_full(&vsfifo)) {
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
if (wait_event_interruptible_exclusive(vsdev.wwqh, !kfifo_is_full(&vsfifo)))
return -ERESTARTSYS;
}
ret = kfifo_from_user(&vsfifo, buf, count, &copied);
if (!kfifo_is_empty(&vsfifo)) {
wake_up_interruptible(&vsdev.rwqh);
kill_fasync(&vsdev.fapp, SIGIO, POLL_IN);
}
return ret == 0 ? copied : ret;
}
static long vser_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
if (_IOC_TYPE(cmd) != VS_MAGIC)
return -ENOTTY;
switch (cmd) {
case VS_SET_BAUD:
vsdev.baud = arg;
break;
case VS_GET_BAUD:
arg = vsdev.baud;
break;
case VS_SET_FFMT:
if (copy_from_user(&vsdev.opt, (struct option __user *)arg, sizeof(struct option)))
return -EFAULT;
break;
case VS_GET_FFMT:
if (copy_to_user((struct option __user *)arg, &vsdev.opt, sizeof(struct option)))
return -EFAULT;
break;
default:
return -ENOTTY;
}
return 0;
}
static unsigned int vser_poll(struct file *filp, struct poll_table_struct *p)
{
int mask = 0;
poll_wait(filp, &vsdev.rwqh, p);
poll_wait(filp, &vsdev.wwqh, p);
if (!kfifo_is_empty(&vsfifo))
mask |= POLLIN | POLLRDNORM;
if (!kfifo_is_full(&vsfifo))
mask |= POLLOUT | POLLWRNORM;
return mask;
}
static ssize_t vser_aio_read(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos)
{
size_t read = 0;
unsigned long i;
ssize_t ret;
for (i = 0; i < nr_segs; i++) {
ret = vser_read(iocb->ki_filp, iov[i].iov_base, iov[i].iov_len, &pos);
if (ret < 0)
break;
read += ret;
}
return read ? read : -EFAULT;
}
static ssize_t vser_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos)
{
size_t written = 0;
unsigned long i;
ssize_t ret;
for (i = 0; i < nr_segs; i++) {
ret = vser_write(iocb->ki_filp, iov[i].iov_base, iov[i].iov_len, &pos);
if (ret < 0)
break;
written += ret;
}
return written ? written : -EFAULT;
}
static int vser_fasync(int fd, struct file *filp, int on)
{
return fasync_helper(fd, filp, on, &vsdev.fapp);
}
static struct file_operations vser_ops = {
.owner = THIS_MODULE,
.open = vser_open,
.release = vser_release,
.read = vser_read,
.write = vser_write,
.unlocked_ioctl = vser_ioctl,
.poll = vser_poll,
.aio_read = vser_aio_read,
.aio_write = vser_aio_write,
.fasync = vser_fasync,
};
static int __init vser_init(void)
{
int ret;
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
ret = register_chrdev_region(dev, VSER_DEV_CNT, VSER_DEV_NAME);
if (ret)
goto reg_err;
cdev_init(&vsdev.cdev, &vser_ops);
vsdev.cdev.owner = THIS_MODULE;
vsdev.baud = 115200;
vsdev.opt.datab = 8;
vsdev.opt.parity = 0;
vsdev.opt.stopb = 1;
ret = cdev_add(&vsdev.cdev, dev, VSER_DEV_CNT);
if (ret)
goto add_err;
init_waitqueue_head(&vsdev.rwqh);
init_waitqueue_head(&vsdev.wwqh);
return 0;
add_err:
unregister_chrdev_region(dev, VSER_DEV_CNT);
reg_err:
return ret;
}
static void __exit vser_exit(void)
{
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
cdev_del(&vsdev.cdev);
unregister_chrdev_region(dev, VSER_DEV_CNT);
}
module_init(vser_init);
module_exit(vser_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple character device driver");
MODULE_ALIAS("virtual-serial");

View File

@ -1,17 +0,0 @@
#ifndef _VSER_H
#define _VSER_H
struct option {
unsigned int datab;
unsigned int parity;
unsigned int stopb;
};
#define VS_MAGIC 's'
#define VS_SET_BAUD _IOW(VS_MAGIC, 0, unsigned int)
#define VS_GET_BAUD _IOW(VS_MAGIC, 1, unsigned int)
#define VS_SET_FFMT _IOW(VS_MAGIC, 2, struct option)
#define VS_GET_FFMT _IOW(VS_MAGIC, 3, struct option)
#endif

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := vfb.o
endif

View File

@ -1,39 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
int main(int argc, char * argv[])
{
int fd;
char *start;
int i;
char buf[32];
fd = open("/dev/vfb0", O_RDWR);
if (fd == -1)
goto fail;
start = mmap(NULL, 32, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (start == MAP_FAILED)
goto fail;
for (i = 0; i < 26; i++)
*(start + i) = 'a' + i;
*(start + i) = '\0';
if (read(fd, buf, 27) == -1)
goto fail;
puts(buf);
munmap(start, 32);
return 0;
fail:
perror("mmap test");
exit(EXIT_FAILURE);
}

View File

@ -1,108 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#define VFB_MAJOR 256
#define VFB_MINOR 1
#define VFB_DEV_CNT 1
#define VFB_DEV_NAME "vfbdev"
struct vfb_dev {
unsigned char *buf;
struct cdev cdev;
};
static struct vfb_dev vfbdev;
static int vfb_open(struct inode * inode, struct file * filp)
{
return 0;
}
static int vfb_release(struct inode *inode, struct file *filp)
{
return 0;
}
static int vfb_mmap(struct file *filp, struct vm_area_struct *vma)
{
if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(vfbdev.buf) >> PAGE_SHIFT, \
vma->vm_end - vma->vm_start, vma->vm_page_prot))
return -EAGAIN;
return 0;
}
ssize_t vfb_read(struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
int ret;
size_t len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
ret = copy_to_user(buf, vfbdev.buf, len);
return len - ret;
}
static struct file_operations vfb_fops = {
.owner = THIS_MODULE,
.open = vfb_open,
.release = vfb_release,
.mmap = vfb_mmap,
.read = vfb_read,
};
static int __init vfb_init(void)
{
int ret;
dev_t dev;
unsigned long addr;
dev = MKDEV(VFB_MAJOR, VFB_MINOR);
ret = register_chrdev_region(dev, VFB_DEV_CNT, VFB_DEV_NAME);
if (ret)
goto reg_err;
cdev_init(&vfbdev.cdev, &vfb_fops);
vfbdev.cdev.owner = THIS_MODULE;
ret = cdev_add(&vfbdev.cdev, dev, VFB_DEV_CNT);
if (ret)
goto add_err;
addr = __get_free_page(GFP_KERNEL);
if (!addr)
goto get_err;
vfbdev.buf = (unsigned char *)addr;
memset(vfbdev.buf, 0, PAGE_SIZE);
return 0;
get_err:
cdev_del(&vfbdev.cdev);
add_err:
unregister_chrdev_region(dev, VFB_DEV_CNT);
reg_err:
return ret;
}
static void __exit vfb_exit(void)
{
dev_t dev;
dev = MKDEV(VFB_MAJOR, VFB_MINOR);
free_page((unsigned long)vfbdev.buf);
cdev_del(&vfbdev.cdev);
unregister_chrdev_region(dev, VFB_DEV_CNT);
}
module_init(vfb_init);
module_exit(vfb_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("This is an example for mmap");

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := vdsk.o
endif

View File

@ -1,161 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/genhd.h>
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/vmalloc.h>
#define VDSK_MINORS 4
#define VDSK_HEADS 4
#define VDSK_SECTORS 16
#define VDSK_CYLINDERS 256
#define VDSK_SECTOR_SIZE 512
#define VDSK_SECTOR_TOTAL (VDSK_HEADS * VDSK_SECTORS * VDSK_CYLINDERS)
#define VDSK_SIZE (VDSK_SECTOR_TOTAL * VDSK_SECTOR_SIZE)
static int vdsk_major = 0;
static char vdsk_name[] = "vdsk";
struct vdsk_dev
{
u8 *data;
int size;
spinlock_t lock;
struct gendisk *gd;
struct request_queue *queue;
};
struct vdsk_dev *vdsk = NULL;
static int vdsk_open(struct block_device *bdev, fmode_t mode)
{
return 0;
}
static void vdsk_release(struct gendisk *gd, fmode_t mode)
{
}
static int vdsk_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg)
{
return 0;
}
static int vdsk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
geo->cylinders = VDSK_CYLINDERS;
geo->heads = VDSK_HEADS;
geo->sectors = VDSK_SECTORS;
geo->start = 0;
return 0;
}
static void vdsk_make_request(struct request_queue *q, struct bio *bio)
{
struct vdsk_dev *vdsk;
struct bio_vec bvec;
struct bvec_iter iter;
unsigned long offset;
unsigned long nbytes;
char *buffer;
vdsk = q->queuedata;
bio_for_each_segment(bvec, bio, iter) {
buffer = __bio_kmap_atomic(bio, iter);
offset = iter.bi_sector * VDSK_SECTOR_SIZE;
nbytes = bvec.bv_len;
if ((offset + nbytes) > get_capacity(vdsk->gd) * VDSK_SECTOR_SIZE) {
bio_endio(bio, -EINVAL);
return;
}
if (bio_data_dir(bio) == WRITE)
memcpy(vdsk->data + offset, buffer, nbytes);
else
memcpy(buffer, vdsk->data + offset, nbytes);
__bio_kunmap_atomic(bio);
}
bio_endio(bio, 0);
}
static struct block_device_operations vdsk_fops = {
.owner = THIS_MODULE,
.open = vdsk_open,
.release = vdsk_release,
.ioctl = vdsk_ioctl,
.getgeo = vdsk_getgeo,
};
static int __init vdsk_init(void)
{
vdsk_major = register_blkdev(vdsk_major, vdsk_name);
if (vdsk_major <= 0)
return -EBUSY;
vdsk = kzalloc(sizeof(struct vdsk_dev), GFP_KERNEL);
if (!vdsk)
goto unreg_dev;
vdsk->size = VDSK_SIZE;
vdsk->data = vmalloc(vdsk->size);
if (!vdsk->data)
goto free_dev;
spin_lock_init(&vdsk->lock);
vdsk->queue = blk_alloc_queue(GFP_KERNEL);
if (vdsk->queue == NULL)
goto free_data;
blk_queue_make_request(vdsk->queue, vdsk_make_request);
blk_queue_logical_block_size(vdsk->queue, VDSK_SECTOR_SIZE);
vdsk->queue->queuedata = vdsk;
vdsk->gd = alloc_disk(VDSK_MINORS);
if (!vdsk->gd)
goto free_queue;
vdsk->gd->major = vdsk_major;
vdsk->gd->first_minor = 0;
vdsk->gd->fops = &vdsk_fops;
vdsk->gd->queue = vdsk->queue;
vdsk->gd->private_data = vdsk;
snprintf(vdsk->gd->disk_name, 32, "vdsk%c", 'a');
set_capacity(vdsk->gd, VDSK_SECTOR_TOTAL);
add_disk(vdsk->gd);
return 0;
free_queue:
blk_cleanup_queue(vdsk->queue);
free_data:
vfree(vdsk->data);
free_dev:
kfree(vdsk);
unreg_dev:
unregister_blkdev(vdsk_major, vdsk_name);
return -ENOMEM;
}
static void __exit vdsk_exit(void)
{
del_gendisk(vdsk->gd);
put_disk(vdsk->gd);
blk_cleanup_queue(vdsk->queue);
vfree(vdsk->data);
kfree(vdsk);
unregister_blkdev(vdsk_major, vdsk_name);
}
module_init(vdsk_init);
module_exit(vdsk_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("This is an example for Linux block device driver");

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := vdsk.o
endif

View File

@ -1,162 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/genhd.h>
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/vmalloc.h>
#define VDSK_MINORS 4
#define VDSK_HEADS 4
#define VDSK_SECTORS 16
#define VDSK_CYLINDERS 256
#define VDSK_SECTOR_SIZE 512
#define VDSK_SECTOR_TOTAL (VDSK_HEADS * VDSK_SECTORS * VDSK_CYLINDERS)
#define VDSK_SIZE (VDSK_SECTOR_TOTAL * VDSK_SECTOR_SIZE)
static int vdsk_major = 0;
static char vdsk_name[] = "vdsk";
struct vdsk_dev
{
int size;
u8 *data;
spinlock_t lock;
struct gendisk *gd;
struct request_queue *queue;
};
static struct vdsk_dev *vdsk = NULL;
static int vdsk_open(struct block_device *bdev, fmode_t mode)
{
return 0;
}
static void vdsk_release(struct gendisk *gd, fmode_t mode)
{
}
static int vdsk_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg)
{
return 0;
}
static int vdsk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
geo->cylinders = VDSK_CYLINDERS;
geo->heads = VDSK_HEADS;
geo->sectors = VDSK_SECTORS;
geo->start = 0;
return 0;
}
static void vdsk_request(struct request_queue *q)
{
struct vdsk_dev *vdsk;
struct request *req;
struct bio *bio;
struct bio_vec bvec;
struct bvec_iter iter;
unsigned long offset;
unsigned long nbytes;
char *buffer;
vdsk = q->queuedata;
req = blk_fetch_request(q);
while (req != NULL) {
__rq_for_each_bio(bio, req) {
bio_for_each_segment(bvec, bio, iter) {
buffer = __bio_kmap_atomic(bio, iter);
offset = iter.bi_sector * VDSK_SECTOR_SIZE;
nbytes = bvec.bv_len;
if ((offset + nbytes) > get_capacity(vdsk->gd) * VDSK_SECTOR_SIZE)
return;
if (bio_data_dir(bio) == WRITE)
memcpy(vdsk->data + offset, buffer, nbytes);
else
memcpy(buffer, vdsk->data + offset, nbytes);
__bio_kunmap_atomic(bio);
}
}
if (!__blk_end_request_cur(req, 0))
req = blk_fetch_request(q);
}
}
static struct block_device_operations vdsk_fops = {
.owner = THIS_MODULE,
.open = vdsk_open,
.release = vdsk_release,
.ioctl = vdsk_ioctl,
.getgeo = vdsk_getgeo,
};
static int __init vdsk_init(void)
{
vdsk_major = register_blkdev(vdsk_major, vdsk_name);
if (vdsk_major <= 0)
return -EBUSY;
vdsk = kzalloc(sizeof(struct vdsk_dev), GFP_KERNEL);
if (!vdsk)
goto unreg_dev;
vdsk->size = VDSK_SIZE;
vdsk->data = vmalloc(vdsk->size);
if (!vdsk->data)
goto free_dev;
spin_lock_init(&vdsk->lock);
vdsk->queue = blk_init_queue(vdsk_request, &vdsk->lock);
blk_queue_logical_block_size(vdsk->queue, VDSK_SECTOR_SIZE);
vdsk->queue->queuedata = vdsk;
vdsk->gd = alloc_disk(VDSK_MINORS);
if (!vdsk->gd)
goto free_data;
vdsk->gd->major = vdsk_major;
vdsk->gd->first_minor = 0;
vdsk->gd->fops = &vdsk_fops;
vdsk->gd->queue = vdsk->queue;
vdsk->gd->private_data = vdsk;
snprintf(vdsk->gd->disk_name, 32, "vdsk%c", 'a');
set_capacity(vdsk->gd, VDSK_SECTOR_TOTAL);
add_disk(vdsk->gd);
return 0;
free_data:
blk_cleanup_queue(vdsk->queue);
vfree(vdsk->data);
free_dev:
kfree(vdsk);
unreg_dev:
unregister_blkdev(vdsk_major, vdsk_name);
return -ENOMEM;
}
static void __exit vdsk_exit(void)
{
del_gendisk(vdsk->gd);
put_disk(vdsk->gd);
blk_cleanup_queue(vdsk->queue);
vfree(vdsk->data);
kfree(vdsk);
unregister_blkdev(vdsk_major, vdsk_name);
}
module_init(vdsk_init);
module_exit(vdsk_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("This is an example for Linux block device driver");

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := vser.o
endif

View File

@ -1,42 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#define VSER_MAJOR 256
#define VSER_MINOR 0
#define VSER_DEV_CNT 1
#define VSER_DEV_NAME "vser"
static int __init vser_init(void)
{
int ret;
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
ret = register_chrdev_region(dev, VSER_DEV_CNT, VSER_DEV_NAME);
if (ret)
goto reg_err;
return 0;
reg_err:
return ret;
}
static void __exit vser_exit(void)
{
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
unregister_chrdev_region(dev, VSER_DEV_CNT);
}
module_init(vser_init);
module_exit(vser_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple character device driver");
MODULE_ALIAS("virtual-serial");

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := vser.o
endif

View File

@ -1,61 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#define VSER_MAJOR 256
#define VSER_MINOR 0
#define VSER_DEV_CNT 1
#define VSER_DEV_NAME "vser"
static struct cdev vsdev;
static struct file_operations vser_ops = {
.owner = THIS_MODULE,
};
static int __init vser_init(void)
{
int ret;
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
ret = register_chrdev_region(dev, VSER_DEV_CNT, VSER_DEV_NAME);
if (ret)
goto reg_err;
cdev_init(&vsdev, &vser_ops);
vsdev.owner = THIS_MODULE;
ret = cdev_add(&vsdev, dev, VSER_DEV_CNT);
if (ret)
goto add_err;
return 0;
add_err:
unregister_chrdev_region(dev, VSER_DEV_CNT);
reg_err:
return ret;
}
static void __exit vser_exit(void)
{
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
cdev_del(&vsdev);
unregister_chrdev_region(dev, VSER_DEV_CNT);
}
module_init(vser_init);
module_exit(vser_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple character device driver");
MODULE_ALIAS("virtual-serial");

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := vser.o
endif

View File

@ -1,95 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kfifo.h>
#define VSER_MAJOR 256
#define VSER_MINOR 0
#define VSER_DEV_CNT 1
#define VSER_DEV_NAME "vser"
static struct cdev vsdev;
DEFINE_KFIFO(vsfifo, char, 32);
static int vser_open(struct inode *inode, struct file *filp)
{
return 0;
}
static int vser_release(struct inode *inode, struct file *filp)
{
return 0;
}
static ssize_t vser_read(struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
unsigned int copied = 0;
kfifo_to_user(&vsfifo, buf, count, &copied);
return copied;
}
static ssize_t vser_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos)
{
unsigned int copied = 0;
kfifo_from_user(&vsfifo, buf, count, &copied);
return copied;
}
static struct file_operations vser_ops = {
.owner = THIS_MODULE,
.open = vser_open,
.release = vser_release,
.read = vser_read,
.write = vser_write,
};
static int __init vser_init(void)
{
int ret;
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
ret = register_chrdev_region(dev, VSER_DEV_CNT, VSER_DEV_NAME);
if (ret)
goto reg_err;
cdev_init(&vsdev, &vser_ops);
vsdev.owner = THIS_MODULE;
ret = cdev_add(&vsdev, dev, VSER_DEV_CNT);
if (ret)
goto add_err;
return 0;
add_err:
unregister_chrdev_region(dev, VSER_DEV_CNT);
reg_err:
return ret;
}
static void __exit vser_exit(void)
{
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
cdev_del(&vsdev);
unregister_chrdev_region(dev, VSER_DEV_CNT);
}
module_init(vser_init);
module_exit(vser_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple character device driver");
MODULE_ALIAS("virtual-serial");

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := vser.o
endif

View File

@ -1,107 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kfifo.h>
#define VSER_MAJOR 256
#define VSER_MINOR 0
#define VSER_DEV_CNT 2
#define VSER_DEV_NAME "vser"
static struct cdev vsdev;
static DEFINE_KFIFO(vsfifo0, char, 32);
static DEFINE_KFIFO(vsfifo1, char, 32);
static int vser_open(struct inode *inode, struct file *filp)
{
switch (MINOR(inode->i_rdev)) {
default:
case 0:
filp->private_data = &vsfifo0;
break;
case 1:
filp->private_data = &vsfifo1;
break;
}
return 0;
}
static int vser_release(struct inode *inode, struct file *filp)
{
return 0;
}
static ssize_t vser_read(struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
unsigned int copied = 0;
struct kfifo *vsfifo = filp->private_data;
kfifo_to_user(vsfifo, buf, count, &copied);
return copied;
}
static ssize_t vser_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos)
{
unsigned int copied = 0;
struct kfifo *vsfifo = filp->private_data;
kfifo_from_user(vsfifo, buf, count, &copied);
return copied;
}
static struct file_operations vser_ops = {
.owner = THIS_MODULE,
.open = vser_open,
.release = vser_release,
.read = vser_read,
.write = vser_write,
};
static int __init vser_init(void)
{
int ret;
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
ret = register_chrdev_region(dev, VSER_DEV_CNT, VSER_DEV_NAME);
if (ret)
goto reg_err;
cdev_init(&vsdev, &vser_ops);
vsdev.owner = THIS_MODULE;
ret = cdev_add(&vsdev, dev, VSER_DEV_CNT);
if (ret)
goto add_err;
return 0;
add_err:
unregister_chrdev_region(dev, VSER_DEV_CNT);
reg_err:
return ret;
}
static void __exit vser_exit(void)
{
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
cdev_del(&vsdev);
unregister_chrdev_region(dev, VSER_DEV_CNT);
}
module_init(vser_init);
module_exit(vser_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple character device driver");
MODULE_ALIAS("virtual-serial");

View File

@ -1,112 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kfifo.h>
#define VSER_MAJOR 256
#define VSER_MINOR 0
#define VSER_DEV_CNT 2
#define VSER_DEV_NAME "vser"
static DEFINE_KFIFO(vsfifo0, char, 32);
static DEFINE_KFIFO(vsfifo1, char, 32);
struct vser_dev {
struct kfifo *fifo;
struct cdev cdev;
};
static struct vser_dev vsdev[2];
static int vser_open(struct inode *inode, struct file *filp)
{
filp->private_data = container_of(inode->i_cdev, struct vser_dev, cdev);
return 0;
}
static int vser_release(struct inode *inode, struct file *filp)
{
return 0;
}
static ssize_t vser_read(struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
unsigned int copied = 0;
struct vser_dev *dev = filp->private_data;
kfifo_to_user(dev->fifo, buf, count, &copied);
return copied;
}
static ssize_t vser_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos)
{
unsigned int copied = 0;
struct vser_dev *dev = filp->private_data;
kfifo_from_user(dev->fifo, buf, count, &copied);
return copied;
}
static struct file_operations vser_ops = {
.owner = THIS_MODULE,
.open = vser_open,
.release = vser_release,
.read = vser_read,
.write = vser_write,
};
static int __init vser_init(void)
{
int i;
int ret;
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
ret = register_chrdev_region(dev, VSER_DEV_CNT, VSER_DEV_NAME);
if (ret)
goto reg_err;
for (i = 0; i < VSER_DEV_CNT; i++) {
cdev_init(&vsdev[i].cdev, &vser_ops);
vsdev[i].cdev.owner = THIS_MODULE;
vsdev[i].fifo = i == 0 ? (struct kfifo *) &vsfifo0 : (struct kfifo*)&vsfifo1;
ret = cdev_add(&vsdev[i].cdev, dev + i, 1);
if (ret)
goto add_err;
}
return 0;
add_err:
for (--i; i > 0; --i)
cdev_del(&vsdev[i].cdev);
unregister_chrdev_region(dev, VSER_DEV_CNT);
reg_err:
return ret;
}
static void __exit vser_exit(void)
{
int i;
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
for (i = 0; i < VSER_DEV_CNT; i++)
cdev_del(&vsdev[i].cdev);
unregister_chrdev_region(dev, VSER_DEV_CNT);
}
module_init(vser_init);
module_exit(vser_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple character device driver");
MODULE_ALIAS("virtual-serial");

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := vser.o
endif

View File

@ -1,277 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kfifo.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/aio.h>
#include <linux/interrupt.h>
#include <linux/random.h>
#include "vser.h"
#define VSER_MAJOR 256
#define VSER_MINOR 0
#define VSER_DEV_CNT 1
#define VSER_DEV_NAME "vser"
#define VSER_FIFO_SIZE 32
struct vser_dev {
wait_queue_head_t rwqh;
struct fasync_struct *fapp;
atomic_t available;
unsigned int baud;
struct option opt;
struct cdev cdev;
};
DEFINE_KFIFO(vsfifo, char, VSER_FIFO_SIZE);
static struct vser_dev vsdev;
static void vser_work(struct work_struct *work);
DECLARE_WORK(vswork, vser_work);
static int vser_fasync(int fd, struct file *filp, int on);
static int vser_open(struct inode *inode, struct file *filp)
{
if (atomic_dec_and_test(&vsdev.available))
return 0;
else {
atomic_inc(&vsdev.available);
return -EBUSY;
}
}
static int vser_release(struct inode *inode, struct file *filp)
{
vser_fasync(-1, filp, 0);
atomic_inc(&vsdev.available);
return 0;
}
static ssize_t vser_read(struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
int ret;
int len;
char tbuf[VSER_FIFO_SIZE];
len = count > sizeof(tbuf) ? sizeof(tbuf) : count;
spin_lock(&vsdev.rwqh.lock);
if (kfifo_is_empty(&vsfifo)) {
if (filp->f_flags & O_NONBLOCK) {
spin_unlock(&vsdev.rwqh.lock);
return -EAGAIN;
}
if (wait_event_interruptible_locked(vsdev.rwqh, !kfifo_is_empty(&vsfifo))) {
spin_unlock(&vsdev.rwqh.lock);
return -ERESTARTSYS;
}
}
len = kfifo_out(&vsfifo, tbuf, len);
spin_unlock(&vsdev.rwqh.lock);
ret = copy_to_user(buf, tbuf, len);
return len - ret;
}
static ssize_t vser_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos)
{
int ret;
int len;
char *tbuf[VSER_FIFO_SIZE];
len = count > sizeof(tbuf) ? sizeof(tbuf) : count;
ret = copy_from_user(tbuf, buf, len);
return len - ret;
}
static long vser_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
if (_IOC_TYPE(cmd) != VS_MAGIC)
return -ENOTTY;
switch (cmd) {
case VS_SET_BAUD:
vsdev.baud = arg;
break;
case VS_GET_BAUD:
arg = vsdev.baud;
break;
case VS_SET_FFMT:
if (copy_from_user(&vsdev.opt, (struct option __user *)arg, sizeof(struct option)))
return -EFAULT;
break;
case VS_GET_FFMT:
if (copy_to_user((struct option __user *)arg, &vsdev.opt, sizeof(struct option)))
return -EFAULT;
break;
default:
return -ENOTTY;
}
return 0;
}
static unsigned int vser_poll(struct file *filp, struct poll_table_struct *p)
{
int mask = POLLOUT | POLLWRNORM;
poll_wait(filp, &vsdev.rwqh, p);
spin_lock(&vsdev.rwqh.lock);
if (!kfifo_is_empty(&vsfifo))
mask |= POLLIN | POLLRDNORM;
spin_unlock(&vsdev.rwqh.lock);
return mask;
}
static ssize_t vser_aio_read(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos)
{
size_t read = 0;
unsigned long i;
ssize_t ret;
for (i = 0; i < nr_segs; i++) {
ret = vser_read(iocb->ki_filp, iov[i].iov_base, iov[i].iov_len, &pos);
if (ret < 0)
break;
read += ret;
}
return read ? read : -EFAULT;
}
static ssize_t vser_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos)
{
size_t written = 0;
unsigned long i;
ssize_t ret;
for (i = 0; i < nr_segs; i++) {
ret = vser_write(iocb->ki_filp, iov[i].iov_base, iov[i].iov_len, &pos);
if (ret < 0)
break;
written += ret;
}
return written ? written : -EFAULT;
}
static int vser_fasync(int fd, struct file *filp, int on)
{
return fasync_helper(fd, filp, on, &vsdev.fapp);
}
static irqreturn_t vser_handler(int irq, void *dev_id)
{
schedule_work(&vswork);
return IRQ_HANDLED;
}
static void vser_work(struct work_struct *work)
{
char data;
get_random_bytes(&data, sizeof(data));
data %= 26;
data += 'A';
spin_lock(&vsdev.rwqh.lock);
if (!kfifo_is_full(&vsfifo))
if(!kfifo_in(&vsfifo, &data, sizeof(data)))
printk(KERN_ERR "vser: kfifo_in failure\n");
if (!kfifo_is_empty(&vsfifo)) {
spin_unlock(&vsdev.rwqh.lock);
wake_up_interruptible(&vsdev.rwqh);
kill_fasync(&vsdev.fapp, SIGIO, POLL_IN);
} else
spin_unlock(&vsdev.rwqh.lock);
}
static struct file_operations vser_ops = {
.owner = THIS_MODULE,
.open = vser_open,
.release = vser_release,
.read = vser_read,
.write = vser_write,
.unlocked_ioctl = vser_ioctl,
.poll = vser_poll,
.aio_read = vser_aio_read,
.aio_write = vser_aio_write,
.fasync = vser_fasync,
};
static int __init vser_init(void)
{
int ret;
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
ret = register_chrdev_region(dev, VSER_DEV_CNT, VSER_DEV_NAME);
if (ret)
goto reg_err;
cdev_init(&vsdev.cdev, &vser_ops);
vsdev.cdev.owner = THIS_MODULE;
vsdev.baud = 115200;
vsdev.opt.datab = 8;
vsdev.opt.parity = 0;
vsdev.opt.stopb = 1;
ret = cdev_add(&vsdev.cdev, dev, VSER_DEV_CNT);
if (ret)
goto add_err;
init_waitqueue_head(&vsdev.rwqh);
ret = request_irq(167, vser_handler, IRQF_TRIGGER_HIGH | IRQF_SHARED, "vser", &vsdev);
if (ret)
goto irq_err;
atomic_set(&vsdev.available, 1);
return 0;
irq_err:
cdev_del(&vsdev.cdev);
add_err:
unregister_chrdev_region(dev, VSER_DEV_CNT);
reg_err:
return ret;
}
static void __exit vser_exit(void)
{
dev_t dev;
dev = MKDEV(VSER_MAJOR, VSER_MINOR);
free_irq(167, &vsdev);
cdev_del(&vsdev.cdev);
unregister_chrdev_region(dev, VSER_DEV_CNT);
}
module_init(vser_init);
module_exit(vser_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple character device driver");
MODULE_ALIAS("virtual-serial");

View File

@ -1,17 +0,0 @@
#ifndef _VSER_H
#define _VSER_H
struct option {
unsigned int datab;
unsigned int parity;
unsigned int stopb;
};
#define VS_MAGIC 's'
#define VS_SET_BAUD _IOW(VS_MAGIC, 0, unsigned int)
#define VS_GET_BAUD _IOW(VS_MAGIC, 1, unsigned int)
#define VS_SET_FFMT _IOW(VS_MAGIC, 2, struct option)
#define VS_GET_FFMT _IOW(VS_MAGIC, 3, struct option)
#endif

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := model.o
endif

View File

@ -1,66 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/kobject.h>
static struct kset *kset;
static struct kobject *kobj1;
static struct kobject *kobj2;
static unsigned int val = 0;
static ssize_t val_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", val);
}
static ssize_t val_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
char *endp;
printk("size = %d\n", count);
val = simple_strtoul(buf, &endp, 10);
return count;
}
static struct kobj_attribute kobj1_val_attr = __ATTR(val, 0666, val_show, val_store);
static struct attribute *kobj1_attrs[] = {
&kobj1_val_attr.attr,
NULL,
};
static struct attribute_group kobj1_attr_group = {
.attrs = kobj1_attrs,
};
static int __init model_init(void)
{
int ret;
kset = kset_create_and_add("kset", NULL, NULL);
kobj1 = kobject_create_and_add("kobj1", &kset->kobj);
kobj2 = kobject_create_and_add("kobj2", &kset->kobj);
ret = sysfs_create_group(kobj1, &kobj1_attr_group);
ret = sysfs_create_link(kobj2, kobj1, "kobj1");
return 0;
}
static void __exit model_exit(void)
{
sysfs_remove_link(kobj2, "kobj1");
sysfs_remove_group(kobj1, &kobj1_attr_group);
kobject_del(kobj2);
kobject_del(kobj1);
kset_unregister(kset);
}
module_init(model_init);
module_exit(model_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple module for device model");

View File

@ -1,21 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := vbus.o vdrv.o vdev.o
endif

View File

@ -1,34 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
static int vbus_match(struct device *dev, struct device_driver *drv)
{
return 1;
}
static struct bus_type vbus = {
.name = "vbus",
.match = vbus_match,
};
EXPORT_SYMBOL(vbus);
static int __init vbus_init(void)
{
return bus_register(&vbus);
}
static void __exit vbus_exit(void)
{
bus_unregister(&vbus);
}
module_init(vbus_init);
module_exit(vbus_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A virtual bus");

View File

@ -1,34 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
extern struct bus_type vbus;
static void vdev_release(struct device *dev)
{
}
static struct device vdev = {
.init_name = "vdev",
.bus = &vbus,
.release = vdev_release,
};
static int __init vdev_init(void)
{
return device_register(&vdev);
}
static void __exit vdev_exit(void)
{
device_unregister(&vdev);
}
module_init(vdev_init);
module_exit(vdev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A virtual device");

View File

@ -1,29 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
extern struct bus_type vbus;
static struct device_driver vdrv = {
.name = "vdrv",
.bus = &vbus,
};
static int __init vdrv_init(void)
{
return driver_register(&vdrv);
}
static void __exit vdrv_exit(void)
{
driver_unregister(&vdrv);
}
module_init(vdrv_init);
module_exit(vdrv_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A virtual device driver");

View File

@ -1,21 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := pltdev.o pltdrv.o
endif

View File

@ -1,50 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
static void pdev_release(struct device *dev)
{
}
struct platform_device pdev0 = {
.name = "pdev",
.id = 0,
.num_resources = 0,
.resource = NULL,
.dev = {
.release = pdev_release,
},
};
struct platform_device pdev1 = {
.name = "pdev",
.id = 1,
.num_resources = 0,
.resource = NULL,
.dev = {
.release = pdev_release,
},
};
static int __init pltdev_init(void)
{
platform_device_register(&pdev0);
platform_device_register(&pdev1);
return 0;
}
static void __exit pltdev_exit(void)
{
platform_device_unregister(&pdev1);
platform_device_unregister(&pdev0);
}
module_init(pltdev_init);
module_exit(pltdev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("register a platfom device");

View File

@ -1,49 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
static int pdrv_suspend(struct device *dev)
{
printk("pdev: suspend\n");
return 0;
}
static int pdrv_resume(struct device *dev)
{
printk("pdev: resume\n");
return 0;
}
static const struct dev_pm_ops pdrv_pm_ops = {
.suspend = pdrv_suspend,
.resume = pdrv_resume,
};
static int pdrv_probe(struct platform_device *pdev)
{
return 0;
}
static int pdrv_remove(struct platform_device *pdev)
{
return 0;
}
struct platform_driver pdrv = {
.driver = {
.name = "pdev",
.owner = THIS_MODULE,
.pm = &pdrv_pm_ops,
},
.probe = pdrv_probe,
.remove = pdrv_remove,
};
module_platform_driver(pdrv);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple platform driver");
MODULE_ALIAS("platform:pdev");

View File

@ -1,23 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := fsled.o
obj-m += fsdev.o
endif

View File

@ -1,101 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
static void fsdev_release(struct device *dev)
{
}
static struct resource led2_resources[] = {
[0] = DEFINE_RES_MEM(0x11000C40, 4),
};
static struct resource led3_resources[] = {
[0] = DEFINE_RES_MEM(0x11000C20, 4),
};
static struct resource led4_resources[] = {
[0] = DEFINE_RES_MEM(0x114001E0, 4),
};
static struct resource led5_resources[] = {
[0] = DEFINE_RES_MEM(0x114001E0, 4),
};
unsigned int led2pin = 7;
unsigned int led3pin = 0;
unsigned int led4pin = 4;
unsigned int led5pin = 5;
struct platform_device fsled2 = {
.name = "fsled",
.id = 2,
.num_resources = ARRAY_SIZE(led2_resources),
.resource = led2_resources,
.dev = {
.release = fsdev_release,
.platform_data = &led2pin,
},
};
struct platform_device fsled3 = {
.name = "fsled",
.id = 3,
.num_resources = ARRAY_SIZE(led3_resources),
.resource = led3_resources,
.dev = {
.release = fsdev_release,
.platform_data = &led3pin,
},
};
struct platform_device fsled4 = {
.name = "fsled",
.id = 4,
.num_resources = ARRAY_SIZE(led4_resources),
.resource = led4_resources,
.dev = {
.release = fsdev_release,
.platform_data = &led4pin,
},
};
struct platform_device fsled5 = {
.name = "fsled",
.id = 5,
.num_resources = ARRAY_SIZE(led5_resources),
.resource = led5_resources,
.dev = {
.release = fsdev_release,
.platform_data = &led5pin,
},
};
static struct platform_device *fsled_devices[] = {
&fsled2,
&fsled3,
&fsled4,
&fsled5,
};
static int __init fsdev_init(void)
{
return platform_add_devices(fsled_devices, ARRAY_SIZE(fsled_devices));
}
static void __exit fsdev_exit(void)
{
platform_device_unregister(&fsled5);
platform_device_unregister(&fsled4);
platform_device_unregister(&fsled3);
platform_device_unregister(&fsled2);
}
module_init(fsdev_init);
module_exit(fsdev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("register LED devices");

View File

@ -1,165 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include "fsled.h"
#define FSLED_MAJOR 256
#define FSLED_DEV_NAME "fsled"
struct fsled_dev {
unsigned int __iomem *con;
unsigned int __iomem *dat;
unsigned int pin;
atomic_t available;
struct cdev cdev;
};
static int fsled_open(struct inode *inode, struct file *filp)
{
struct fsled_dev *fsled = container_of(inode->i_cdev, struct fsled_dev, cdev);
filp->private_data = fsled;
if (atomic_dec_and_test(&fsled->available))
return 0;
else {
atomic_inc(&fsled->available);
return -EBUSY;
}
}
static int fsled_release(struct inode *inode, struct file *filp)
{
struct fsled_dev *fsled = filp->private_data;
writel(readl(fsled->dat) & ~(0x1 << fsled->pin), fsled->dat);
atomic_inc(&fsled->available);
return 0;
}
static long fsled_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct fsled_dev *fsled = filp->private_data;
if (_IOC_TYPE(cmd) != FSLED_MAGIC)
return -ENOTTY;
switch (cmd) {
case FSLED_ON:
writel(readl(fsled->dat) | (0x1 << fsled->pin), fsled->dat);
break;
case FSLED_OFF:
writel(readl(fsled->dat) & ~(0x1 << fsled->pin), fsled->dat);
break;
default:
return -ENOTTY;
}
return 0;
}
static struct file_operations fsled_ops = {
.owner = THIS_MODULE,
.open = fsled_open,
.release = fsled_release,
.unlocked_ioctl = fsled_ioctl,
};
static int fsled_probe(struct platform_device *pdev)
{
int ret;
dev_t dev;
struct fsled_dev *fsled;
struct resource *res;
unsigned int pin = *(unsigned int*)pdev->dev.platform_data;
dev = MKDEV(FSLED_MAJOR, pdev->id);
ret = register_chrdev_region(dev, 1, FSLED_DEV_NAME);
if (ret)
goto reg_err;
fsled = kzalloc(sizeof(struct fsled_dev), GFP_KERNEL);
if (!fsled) {
ret = -ENOMEM;
goto mem_err;
}
cdev_init(&fsled->cdev, &fsled_ops);
fsled->cdev.owner = THIS_MODULE;
ret = cdev_add(&fsled->cdev, dev, 1);
if (ret)
goto add_err;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
ret = -ENOENT;
goto res_err;
}
fsled->con = ioremap(res->start, resource_size(res));
if (!fsled->con) {
ret = -EBUSY;
goto map_err;
}
fsled->dat = fsled->con + 1;
fsled->pin = pin;
atomic_set(&fsled->available, 1);
writel((readl(fsled->con) & ~(0xF << 4 * fsled->pin)) | (0x1 << 4 * fsled->pin), fsled->con);
writel(readl(fsled->dat) & ~(0x1 << fsled->pin), fsled->dat);
platform_set_drvdata(pdev, fsled);
return 0;
map_err:
res_err:
cdev_del(&fsled->cdev);
add_err:
kfree(fsled);
mem_err:
unregister_chrdev_region(dev, 1);
reg_err:
return ret;
}
static int fsled_remove(struct platform_device *pdev)
{
dev_t dev;
struct fsled_dev *fsled = platform_get_drvdata(pdev);
dev = MKDEV(FSLED_MAJOR, pdev->id);
iounmap(fsled->con);
cdev_del(&fsled->cdev);
kfree(fsled);
unregister_chrdev_region(dev, 1);
return 0;
}
struct platform_driver fsled_drv = {
.driver = {
.name = "fsled",
.owner = THIS_MODULE,
},
.probe = fsled_probe,
.remove = fsled_remove,
};
module_platform_driver(fsled_drv);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple character device driver for LEDs on FS4412 board");

View File

@ -1,9 +0,0 @@
#ifndef _FSLED_H
#define _FSLED_H
#define FSLED_MAGIC 'f'
#define FSLED_ON _IO(FSLED_MAGIC, 0)
#define FSLED_OFF _IO(FSLED_MAGIC, 1)
#endif

View File

@ -1,46 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include "fsled.h"
int main(int argc, char *argv[])
{
int fd[4];
int ret;
int num = 0;
fd[0] = open("/dev/led2", O_RDWR);
if (fd[0] == -1)
goto fail;
fd[1] = open("/dev/led3", O_RDWR);
if (fd[1] == -1)
goto fail;
fd[2] = open("/dev/led4", O_RDWR);
if (fd[2] == -1)
goto fail;
fd[3] = open("/dev/led5", O_RDWR);
if (fd[3] == -1)
goto fail;
while (1) {
ret = ioctl(fd[num], FSLED_ON);
if (ret == -1)
goto fail;
usleep(500000);
ret = ioctl(fd[num], FSLED_OFF);
if (ret == -1)
goto fail;
usleep(500000);
num = (num + 1) % 4;
}
fail:
perror("led test");
exit(EXIT_FAILURE);
}

View File

@ -1,23 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := fsled.o
obj-m += fsdev.o
endif

View File

@ -1,101 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
static void fsdev_release(struct device *dev)
{
}
static struct resource led2_resources[] = {
[0] = DEFINE_RES_MEM(0x11000C40, 4),
};
static struct resource led3_resources[] = {
[0] = DEFINE_RES_MEM(0x11000C20, 4),
};
static struct resource led4_resources[] = {
[0] = DEFINE_RES_MEM(0x114001E0, 4),
};
static struct resource led5_resources[] = {
[0] = DEFINE_RES_MEM(0x114001E0, 4),
};
unsigned int led2pin = 7;
unsigned int led3pin = 0;
unsigned int led4pin = 4;
unsigned int led5pin = 5;
struct platform_device fsled2 = {
.name = "fsled",
.id = 2,
.num_resources = ARRAY_SIZE(led2_resources),
.resource = led2_resources,
.dev = {
.release = fsdev_release,
.platform_data = &led2pin,
},
};
struct platform_device fsled3 = {
.name = "fsled",
.id = 3,
.num_resources = ARRAY_SIZE(led3_resources),
.resource = led3_resources,
.dev = {
.release = fsdev_release,
.platform_data = &led3pin,
},
};
struct platform_device fsled4 = {
.name = "fsled",
.id = 4,
.num_resources = ARRAY_SIZE(led4_resources),
.resource = led4_resources,
.dev = {
.release = fsdev_release,
.platform_data = &led4pin,
},
};
struct platform_device fsled5 = {
.name = "fsled",
.id = 5,
.num_resources = ARRAY_SIZE(led5_resources),
.resource = led5_resources,
.dev = {
.release = fsdev_release,
.platform_data = &led5pin,
},
};
static struct platform_device *fsled_devices[] = {
&fsled2,
&fsled3,
&fsled4,
&fsled5,
};
static int __init fsdev_init(void)
{
return platform_add_devices(fsled_devices, ARRAY_SIZE(fsled_devices));
}
static void __exit fsdev_exit(void)
{
platform_device_unregister(&fsled5);
platform_device_unregister(&fsled4);
platform_device_unregister(&fsled3);
platform_device_unregister(&fsled2);
}
module_init(fsdev_init);
module_exit(fsdev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("register LED devices");

View File

@ -1,199 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include "fsled.h"
#define FSLED_MAJOR 256
#define FSLED_DEV_NAME "fsled"
struct fsled_dev {
unsigned int __iomem *con;
unsigned int __iomem *dat;
unsigned int pin;
atomic_t available;
struct cdev cdev;
struct device *dev;
};
struct class *fsled_cls;
static int fsled_open(struct inode *inode, struct file *filp)
{
struct fsled_dev *fsled = container_of(inode->i_cdev, struct fsled_dev, cdev);
filp->private_data = fsled;
if (atomic_dec_and_test(&fsled->available))
return 0;
else {
atomic_inc(&fsled->available);
return -EBUSY;
}
}
static int fsled_release(struct inode *inode, struct file *filp)
{
struct fsled_dev *fsled = filp->private_data;
writel(readl(fsled->dat) & ~(0x1 << fsled->pin), fsled->dat);
atomic_inc(&fsled->available);
return 0;
}
static long fsled_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct fsled_dev *fsled = filp->private_data;
if (_IOC_TYPE(cmd) != FSLED_MAGIC)
return -ENOTTY;
switch (cmd) {
case FSLED_ON:
writel(readl(fsled->dat) | (0x1 << fsled->pin), fsled->dat);
break;
case FSLED_OFF:
writel(readl(fsled->dat) & ~(0x1 << fsled->pin), fsled->dat);
break;
default:
return -ENOTTY;
}
return 0;
}
static struct file_operations fsled_ops = {
.owner = THIS_MODULE,
.open = fsled_open,
.release = fsled_release,
.unlocked_ioctl = fsled_ioctl,
};
static int fsled_probe(struct platform_device *pdev)
{
int ret;
dev_t dev;
struct fsled_dev *fsled;
struct resource *res;
unsigned int pin = *(unsigned int*)pdev->dev.platform_data;
dev = MKDEV(FSLED_MAJOR, pdev->id);
ret = register_chrdev_region(dev, 1, FSLED_DEV_NAME);
if (ret)
goto reg_err;
fsled = kzalloc(sizeof(struct fsled_dev), GFP_KERNEL);
if (!fsled) {
ret = -ENOMEM;
goto mem_err;
}
cdev_init(&fsled->cdev, &fsled_ops);
fsled->cdev.owner = THIS_MODULE;
ret = cdev_add(&fsled->cdev, dev, 1);
if (ret)
goto add_err;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
ret = -ENOENT;
goto res_err;
}
fsled->con = ioremap(res->start, resource_size(res));
if (!fsled->con) {
ret = -EBUSY;
goto map_err;
}
fsled->dat = fsled->con + 1;
fsled->pin = pin;
atomic_set(&fsled->available, 1);
writel((readl(fsled->con) & ~(0xF << 4 * fsled->pin)) | (0x1 << 4 * fsled->pin), fsled->con);
writel(readl(fsled->dat) & ~(0x1 << fsled->pin), fsled->dat);
platform_set_drvdata(pdev, fsled);
fsled->dev = device_create(fsled_cls, NULL, dev, NULL, "led%d", pdev->id);
if (IS_ERR(fsled->dev)) {
ret = PTR_ERR(fsled->dev);
goto dev_err;
}
return 0;
dev_err:
iounmap(fsled->con);
map_err:
res_err:
cdev_del(&fsled->cdev);
add_err:
kfree(fsled);
mem_err:
unregister_chrdev_region(dev, 1);
reg_err:
return ret;
}
static int fsled_remove(struct platform_device *pdev)
{
dev_t dev;
struct fsled_dev *fsled = platform_get_drvdata(pdev);
dev = MKDEV(FSLED_MAJOR, pdev->id);
device_destroy(fsled_cls, dev);
iounmap(fsled->con);
cdev_del(&fsled->cdev);
kfree(fsled);
unregister_chrdev_region(dev, 1);
return 0;
}
struct platform_driver fsled_drv = {
.driver = {
.name = "fsled",
.owner = THIS_MODULE,
},
.probe = fsled_probe,
.remove = fsled_remove,
};
static int __init fsled_init(void)
{
int ret;
fsled_cls = class_create(THIS_MODULE, "fsled");
if (IS_ERR(fsled_cls))
return PTR_ERR(fsled_cls);
ret = platform_driver_register(&fsled_drv);
if (ret)
class_destroy(fsled_cls);
return ret;
}
static void __exit fsled_exit(void)
{
platform_driver_unregister(&fsled_drv);
class_destroy(fsled_cls);
}
module_init(fsled_init);
module_exit(fsled_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple character device driver for LEDs on FS4412 board");

View File

@ -1,9 +0,0 @@
#ifndef _FSLED_H
#define _FSLED_H
#define FSLED_MAGIC 'f'
#define FSLED_ON _IO(FSLED_MAGIC, 0)
#define FSLED_OFF _IO(FSLED_MAGIC, 1)
#endif

View File

@ -1,46 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include "fsled.h"
int main(int argc, char *argv[])
{
int fd[4];
int ret;
int num = 0;
fd[0] = open("/dev/led2", O_RDWR);
if (fd[0] == -1)
goto fail;
fd[1] = open("/dev/led3", O_RDWR);
if (fd[1] == -1)
goto fail;
fd[2] = open("/dev/led4", O_RDWR);
if (fd[2] == -1)
goto fail;
fd[3] = open("/dev/led5", O_RDWR);
if (fd[3] == -1)
goto fail;
while (1) {
ret = ioctl(fd[num], FSLED_ON);
if (ret == -1)
goto fail;
usleep(500000);
ret = ioctl(fd[num], FSLED_OFF);
if (ret == -1)
goto fail;
usleep(500000);
num = (num + 1) % 4;
}
fail:
perror("led test");
exit(EXIT_FAILURE);
}

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := fsled.o
endif

View File

@ -1,183 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include "fsled.h"
#define FSLED_MAJOR 256
#define FSLED_DEV_NAME "fsled"
struct fsled_dev {
unsigned int __iomem *con;
unsigned int __iomem *dat;
unsigned int pin;
atomic_t available;
struct cdev cdev;
};
static int fsled_open(struct inode *inode, struct file *filp)
{
struct fsled_dev *fsled = container_of(inode->i_cdev, struct fsled_dev, cdev);
filp->private_data = fsled;
if (atomic_dec_and_test(&fsled->available))
return 0;
else {
atomic_inc(&fsled->available);
return -EBUSY;
}
}
static int fsled_release(struct inode *inode, struct file *filp)
{
struct fsled_dev *fsled = filp->private_data;
writel(readl(fsled->dat) & ~(0x1 << fsled->pin), fsled->dat);
atomic_inc(&fsled->available);
return 0;
}
static long fsled_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct fsled_dev *fsled = filp->private_data;
if (_IOC_TYPE(cmd) != FSLED_MAGIC)
return -ENOTTY;
switch (cmd) {
case FSLED_ON:
writel(readl(fsled->dat) | (0x1 << fsled->pin), fsled->dat);
break;
case FSLED_OFF:
writel(readl(fsled->dat) & ~(0x1 << fsled->pin), fsled->dat);
break;
default:
return -ENOTTY;
}
return 0;
}
static struct file_operations fsled_ops = {
.owner = THIS_MODULE,
.open = fsled_open,
.release = fsled_release,
.unlocked_ioctl = fsled_ioctl,
};
static int fsled_probe(struct platform_device *pdev)
{
int ret;
dev_t dev;
struct fsled_dev *fsled;
struct resource *res;
ret = of_property_read_u32(pdev->dev.of_node, "id", &pdev->id);
if (ret)
goto id_err;
dev = MKDEV(FSLED_MAJOR, pdev->id);
ret = register_chrdev_region(dev, 1, FSLED_DEV_NAME);
if (ret)
goto reg_err;
fsled = kzalloc(sizeof(struct fsled_dev), GFP_KERNEL);
if (!fsled) {
ret = -ENOMEM;
goto mem_err;
}
cdev_init(&fsled->cdev, &fsled_ops);
fsled->cdev.owner = THIS_MODULE;
ret = cdev_add(&fsled->cdev, dev, 1);
if (ret)
goto add_err;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
ret = -ENOENT;
goto res_err;
}
fsled->con = ioremap(res->start, resource_size(res));
if (!fsled->con) {
ret = -EBUSY;
goto map_err;
}
fsled->dat = fsled->con + 1;
ret = of_property_read_u32(pdev->dev.of_node, "pin", &fsled->pin);
if (ret)
goto pin_err;
atomic_set(&fsled->available, 1);
writel((readl(fsled->con) & ~(0xF << 4 * fsled->pin)) | (0x1 << 4 * fsled->pin), fsled->con);
writel(readl(fsled->dat) & ~(0x1 << fsled->pin), fsled->dat);
platform_set_drvdata(pdev, fsled);
return 0;
pin_err:
iounmap(fsled->con);
map_err:
res_err:
cdev_del(&fsled->cdev);
add_err:
kfree(fsled);
mem_err:
unregister_chrdev_region(dev, 1);
reg_err:
id_err:
return ret;
}
static int fsled_remove(struct platform_device *pdev)
{
dev_t dev;
struct fsled_dev *fsled = platform_get_drvdata(pdev);
dev = MKDEV(FSLED_MAJOR, pdev->id);
iounmap(fsled->con);
cdev_del(&fsled->cdev);
kfree(fsled);
unregister_chrdev_region(dev, 1);
return 0;
}
static const struct of_device_id fsled_of_matches[] = {
{ .compatible = "fs4412,fsled", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fsled_of_matches);
struct platform_driver pdrv = {
.driver = {
.name = "fsled",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(fsled_of_matches),
},
.probe = fsled_probe,
.remove = fsled_remove,
};
module_platform_driver(pdrv);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple character device driver for LEDs on FS4412 board");

View File

@ -1,9 +0,0 @@
#ifndef _FSLED_H
#define _FSLED_H
#define FSLED_MAGIC 'f'
#define FSLED_ON _IO(FSLED_MAGIC, 0)
#define FSLED_OFF _IO(FSLED_MAGIC, 1)
#endif

View File

@ -1,46 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include "fsled.h"
int main(int argc, char *argv[])
{
int fd[4];
int ret;
int num = 0;
fd[0] = open("/dev/led2", O_RDWR);
if (fd[0] == -1)
goto fail;
fd[1] = open("/dev/led3", O_RDWR);
if (fd[1] == -1)
goto fail;
fd[2] = open("/dev/led4", O_RDWR);
if (fd[2] == -1)
goto fail;
fd[3] = open("/dev/led5", O_RDWR);
if (fd[3] == -1)
goto fail;
while (1) {
ret = ioctl(fd[num], FSLED_ON);
if (ret == -1)
goto fail;
usleep(500000);
ret = ioctl(fd[num], FSLED_OFF);
if (ret == -1)
goto fail;
usleep(500000);
num = (num + 1) % 4;
}
fail:
perror("led test");
exit(EXIT_FAILURE);
}

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := memcpy.o
endif

View File

@ -1,96 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
struct dma_chan *chan;
unsigned int *txbuf;
unsigned int *rxbuf;
dma_addr_t txaddr;
dma_addr_t rxaddr;
static void dma_callback(void *data)
{
int i;
unsigned int *p = rxbuf;
printk("dma complete\n");
for (i = 0; i < PAGE_SIZE / sizeof(unsigned int); i++)
printk("%d ", *p++);
printk("\n");
}
static bool filter(struct dma_chan *chan, void *filter_param)
{
printk("%s\n", dma_chan_name(chan));
return strcmp(dma_chan_name(chan), filter_param) == 0;
}
static int __init memcpy_init(void)
{
int i;
dma_cap_mask_t mask;
struct dma_async_tx_descriptor *desc;
char name[] = "dma2chan0";
unsigned int *p;
dma_cap_zero(mask);
dma_cap_set(DMA_MEMCPY, mask);
chan = dma_request_channel(mask, filter, name);
if (!chan) {
printk("dma_request_channel failure\n");
return -ENODEV;
}
txbuf = dma_alloc_coherent(chan->device->dev, PAGE_SIZE, &txaddr, GFP_KERNEL);
if (!txbuf) {
printk("dma_alloc_coherent failure\n");
dma_release_channel(chan);
return -ENOMEM;
}
rxbuf = dma_alloc_coherent(chan->device->dev, PAGE_SIZE, &rxaddr, GFP_KERNEL);
if (!rxbuf) {
printk("dma_alloc_coherent failure\n");
dma_free_coherent(chan->device->dev, PAGE_SIZE, txbuf, txaddr);
dma_release_channel(chan);
return -ENOMEM;
}
for (i = 0, p = txbuf; i < PAGE_SIZE / sizeof(unsigned int); i++)
*p++ = i;
for (i = 0, p = txbuf; i < PAGE_SIZE / sizeof(unsigned int); i++)
printk("%d ", *p++);
printk("\n");
memset(rxbuf, 0, PAGE_SIZE);
for (i = 0, p = rxbuf; i < PAGE_SIZE / sizeof(unsigned int); i++)
printk("%d ", *p++);
printk("\n");
desc = chan->device->device_prep_dma_memcpy(chan, rxaddr, txaddr, PAGE_SIZE, DMA_CTRL_ACK | DMA_PREP_INTERRUPT);
desc->callback = dma_callback;
desc->callback_param = NULL;
dmaengine_submit(desc);
dma_async_issue_pending(chan);
return 0;
}
static void __exit memcpy_exit(void)
{
dma_free_coherent(chan->device->dev, PAGE_SIZE, txbuf, txaddr);
dma_free_coherent(chan->device->dev, PAGE_SIZE, rxbuf, rxaddr);
dma_release_channel(chan);
}
module_init(memcpy_init);
module_exit(memcpy_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("simple driver using dmaengine");

View File

@ -1,61 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#define LED_DEV_PATH "/sys/class/leds/led%d/brightness"
#define ON 1
#define OFF 0
int fs4412_set_led(unsigned int lednum, unsigned int mode)
{
int fd;
int ret;
char devpath[128];
char *on = "1\n";
char *off = "0\n";
char *m = NULL;
snprintf(devpath, sizeof(devpath), LED_DEV_PATH, lednum);
fd = open(devpath, O_WRONLY);
if (fd == -1) {
perror("fsled->open");
return -1;
}
if (mode == ON)
m = on;
else
m = off;
ret = write(fd, m, strlen(m));
if (ret == -1) {
perror("fsled->write");
close(fd);
return -1;
}
close(fd);
return 0;
}
int main(int argc, char *argv[])
{
unsigned int lednum = 2;
while (1) {
fs4412_set_led(lednum, ON);
usleep(500000);
fs4412_set_led(lednum, OFF);
usleep(500000);
lednum++;
if (lednum > 5)
lednum = 2;
}
}

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := fskey.o
endif

View File

@ -1,85 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/of.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
struct resource *key2_res;
struct resource *key3_res;
static irqreturn_t fskey_handler(int irq, void *dev_id)
{
if (irq == key2_res->start)
printk("K2 pressed\n");
else
printk("K3 pressed\n");
return IRQ_HANDLED;
}
static int fskey_probe(struct platform_device *pdev)
{
int ret;
key2_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
key3_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
if (!key2_res || !key3_res) {
ret = -ENOENT;
goto res_err;
}
ret = request_irq(key2_res->start, fskey_handler, key2_res->flags & IRQF_TRIGGER_MASK, "key2", NULL);
if (ret)
goto key2_err;
ret = request_irq(key3_res->start, fskey_handler, key3_res->flags & IRQF_TRIGGER_MASK, "key3", NULL);
if (ret)
goto key3_err;
return 0;
key3_err:
free_irq(key2_res->start, NULL);
key2_err:
res_err:
return ret;
}
static int fskey_remove(struct platform_device *pdev)
{
free_irq(key3_res->start, NULL);
free_irq(key2_res->start, NULL);
return 0;
}
static const struct of_device_id fskey_of_matches[] = {
{ .compatible = "fs4412,fskey", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fskey_of_matches);
struct platform_driver fskey_drv = {
.driver = {
.name = "fskey",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(fskey_of_matches),
},
.probe = fskey_probe,
.remove = fskey_remove,
};
module_platform_driver(fskey_drv);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple device driver for Keys on FS4412 board");

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := fskey.o
endif

View File

@ -1,168 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/platform_device.h>
#define MAX_KEYS_NUM (8)
#define SCAN_INTERVAL (50) /* ms */
#define KB_ACTIVATE_DELAY (20) /* us */
#define KBDSCAN_STABLE_COUNT (3)
struct fskey_dev {
unsigned int count;
unsigned int kstate[MAX_KEYS_NUM];
unsigned int kcount[MAX_KEYS_NUM];
unsigned char keycode[MAX_KEYS_NUM];
int gpio[MAX_KEYS_NUM];
struct input_polled_dev *polldev;
};
static void fskey_poll(struct input_polled_dev *dev)
{
unsigned int index;
unsigned int kstate;
struct fskey_dev *fskey = dev->private;
for (index = 0; index < fskey->count; index++)
fskey->kcount[index] = 0;
index = 0;
do {
udelay(KB_ACTIVATE_DELAY);
kstate = gpio_get_value(fskey->gpio[index]);
if (kstate != fskey->kstate[index]) {
fskey->kstate[index] = kstate;
fskey->kcount[index] = 0;
} else {
if (++fskey->kcount[index] >= KBDSCAN_STABLE_COUNT) {
input_report_key(dev->input, fskey->keycode[index], !kstate);
index++;
}
}
} while (index < fskey->count);
input_sync(dev->input);
}
static int fskey_probe(struct platform_device *pdev)
{
int ret;
int index;
struct fskey_dev *fskey;
fskey = kzalloc(sizeof(struct fskey_dev), GFP_KERNEL);
if (!fskey)
return -ENOMEM;
platform_set_drvdata(pdev, fskey);
for (index = 0; index < MAX_KEYS_NUM; index++) {
ret = of_get_gpio(pdev->dev.of_node, index);
if (ret < 0)
break;
else
fskey->gpio[index] = ret;
}
if (!index)
goto gpio_err;
else
fskey->count = index;
for (index = 0; index < fskey->count; index++) {
ret = gpio_request(fskey->gpio[index], "KEY");
if (ret)
goto req_err;
gpio_direction_input(fskey->gpio[index]);
fskey->keycode[index] = KEY_2 + index;
fskey->kstate[index] = 1;
}
fskey->polldev = input_allocate_polled_device();
if (!fskey->polldev) {
ret = -ENOMEM;
goto req_err;
}
fskey->polldev->private = fskey;
fskey->polldev->poll = fskey_poll;
fskey->polldev->poll_interval = SCAN_INTERVAL;
fskey->polldev->input->name = "FS4412 Keyboard";
fskey->polldev->input->phys = "fskbd/input0";
fskey->polldev->input->id.bustype = BUS_HOST;
fskey->polldev->input->id.vendor = 0x0001;
fskey->polldev->input->id.product = 0x0001;
fskey->polldev->input->id.version = 0x0100;
fskey->polldev->input->dev.parent = &pdev->dev;
fskey->polldev->input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
fskey->polldev->input->keycode = fskey->keycode;
fskey->polldev->input->keycodesize = sizeof(unsigned char);
fskey->polldev->input->keycodemax = index;
for (index = 0; index < fskey->count; index++)
__set_bit(fskey->keycode[index], fskey->polldev->input->keybit);
__clear_bit(KEY_RESERVED, fskey->polldev->input->keybit);
ret = input_register_polled_device(fskey->polldev);
if (ret)
goto reg_err;
return 0;
reg_err:
input_free_polled_device(fskey->polldev);
req_err:
for (index--; index >= 0; index--)
gpio_free(fskey->gpio[index]);
gpio_err:
kfree(fskey);
return ret;
}
static int fskey_remove(struct platform_device *pdev)
{
unsigned int index;
struct fskey_dev *fskey = platform_get_drvdata(pdev);
input_unregister_polled_device(fskey->polldev);
input_free_polled_device(fskey->polldev);
for (index = 0; index < fskey->count; index++)
gpio_free(fskey->gpio[index]);
kfree(fskey);
return 0;
}
static const struct of_device_id fskey_of_matches[] = {
{ .compatible = "fs4412,fskey", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fskey_of_matches);
struct platform_driver fskey_drv = {
.driver = {
.name = "fskey",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(fskey_of_matches),
},
.probe = fskey_probe,
.remove = fskey_remove,
};
module_platform_driver(fskey_drv);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("A simple device driver for Keys on FS4412 board");

View File

@ -1,46 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <linux/input.h>
#define KEY_DEV_PATH "/dev/input/event0"
int fs4412_get_key(void)
{
int fd;
struct input_event event;
fd = open(KEY_DEV_PATH, O_RDONLY);
if(fd == -1) {
perror("fskey->open");
return -1;
}
while (1) {
if(read(fd, &event, sizeof(event)) == sizeof(event)) {
if (event.type == EV_KEY && event.value == 1) {
close(fd);
return event.code;
} else
continue;
} else {
close(fd);
fprintf(stderr, "fskey->read: read failed\n");
return -1;
}
}
}
int main(int argc, char *argv[])
{
while (1)
printf("key value: %d\n", fs4412_get_key());
}

Binary file not shown.

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := fsadc.o
endif

View File

@ -1,211 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/interrupt.h>
#include "fsadc.h"
#define FSADC_MAJOR 256
#define FSADC_MINOR 6
#define FSADC_DEV_NAME "fsadc"
struct fsadc_dev {
unsigned int __iomem *adccon;
unsigned int __iomem *adcdat;
unsigned int __iomem *clrint;
unsigned int __iomem *adcmux;
unsigned int adcval;
struct completion completion;
atomic_t available;
unsigned int irq;
struct cdev cdev;
};
static int fsadc_open(struct inode *inode, struct file *filp)
{
struct fsadc_dev *fsadc = container_of(inode->i_cdev, struct fsadc_dev, cdev);
filp->private_data = fsadc;
if (atomic_dec_and_test(&fsadc->available))
return 0;
else {
atomic_inc(&fsadc->available);
return -EBUSY;
}
}
static int fsadc_release(struct inode *inode, struct file *filp)
{
struct fsadc_dev *fsadc = filp->private_data;
atomic_inc(&fsadc->available);
return 0;
}
static long fsadc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct fsadc_dev *fsadc = filp->private_data;
union chan_val cv;
if (_IOC_TYPE(cmd) != FSADC_MAGIC)
return -ENOTTY;
switch (cmd) {
case FSADC_GET_VAL:
if (copy_from_user(&cv, (union chan_val __user *)arg, sizeof(union chan_val)))
return -EFAULT;
if (cv.chan > AIN3)
return -ENOTTY;
writel(cv.chan, fsadc->adcmux);
writel(readl(fsadc->adccon) | 1, fsadc->adccon);
if (wait_for_completion_interruptible(&fsadc->completion))
return -ERESTARTSYS;
cv.val = fsadc->adcval & 0xFFF;
if (copy_to_user( (union chan_val __user *)arg, &cv, sizeof(union chan_val)))
return -EFAULT;
break;
default:
return -ENOTTY;
}
return 0;
}
static irqreturn_t fsadc_isr(int irq, void *dev_id)
{
struct fsadc_dev *fsadc = dev_id;
fsadc->adcval = readl(fsadc->adcdat);
writel(1, fsadc->clrint);
complete(&fsadc->completion);
return IRQ_HANDLED;
}
static struct file_operations fsadc_ops = {
.owner = THIS_MODULE,
.open = fsadc_open,
.release = fsadc_release,
.unlocked_ioctl = fsadc_ioctl,
};
static int fsadc_probe(struct platform_device *pdev)
{
int ret;
dev_t dev;
struct fsadc_dev *fsadc;
struct resource *res;
dev = MKDEV(FSADC_MAJOR, FSADC_MINOR);
ret = register_chrdev_region(dev, 1, FSADC_DEV_NAME);
if (ret)
goto reg_err;
fsadc = kzalloc(sizeof(struct fsadc_dev), GFP_KERNEL);
if (!fsadc) {
ret = -ENOMEM;
goto mem_err;
}
platform_set_drvdata(pdev, fsadc);
cdev_init(&fsadc->cdev, &fsadc_ops);
fsadc->cdev.owner = THIS_MODULE;
ret = cdev_add(&fsadc->cdev, dev, 1);
if (ret)
goto add_err;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
ret = -ENOENT;
goto res_err;
}
fsadc->adccon = ioremap(res->start, resource_size(res));
if (!fsadc->adccon) {
ret = -EBUSY;
goto map_err;
}
fsadc->adcdat = fsadc->adccon + 3;
fsadc->clrint = fsadc->adccon + 6;
fsadc->adcmux = fsadc->adccon + 7;
fsadc->irq = platform_get_irq(pdev, 0);
if (fsadc->irq < 0) {
ret = fsadc->irq;
goto irq_err;
}
ret = request_irq(fsadc->irq, fsadc_isr, 0, "adc", fsadc);
if (ret)
goto irq_err;
writel((1 << 16) | (1 << 14) | (19 << 6), fsadc->adccon);
init_completion(&fsadc->completion);
atomic_set(&fsadc->available, 1);
return 0;
irq_err:
iounmap(fsadc->adccon);
map_err:
res_err:
cdev_del(&fsadc->cdev);
add_err:
kfree(fsadc);
mem_err:
unregister_chrdev_region(dev, 1);
reg_err:
return ret;
}
static int fsadc_remove(struct platform_device *pdev)
{
dev_t dev;
struct fsadc_dev *fsadc = platform_get_drvdata(pdev);
dev = MKDEV(FSADC_MAJOR, FSADC_MINOR);
writel((readl(fsadc->adccon) & ~(1 << 16)) | (1 << 2), fsadc->adccon);
free_irq(fsadc->irq, fsadc);
iounmap(fsadc->adccon);
cdev_del(&fsadc->cdev);
kfree(fsadc);
unregister_chrdev_region(dev, 1);
return 0;
}
static const struct of_device_id fsadc_of_matches[] = {
{ .compatible = "fs4412,fsadc", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fsadc_of_matches);
struct platform_driver fsadc_drv = {
.driver = {
.name = "fsadc",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(fsadc_of_matches),
},
.probe = fsadc_probe,
.remove = fsadc_remove,
};
module_platform_driver(fsadc_drv);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("ADC driver");

View File

@ -1,18 +0,0 @@
#ifndef _FSADC_H
#define _FSADC_H
#define FSADC_MAGIC 'f'
union chan_val {
unsigned int chan;
unsigned int val;
};
#define FSADC_GET_VAL _IOWR(FSADC_MAGIC, 0, union chan_val)
#define AIN0 0
#define AIN1 1
#define AIN2 2
#define AIN3 3
#endif

View File

@ -1,33 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include "fsadc.h"
int main(int argc, char *argv[])
{
int fd;
int ret;
union chan_val cv;
fd = open("/dev/adc", O_RDWR);
if (fd == -1)
goto fail;
while (1) {
cv.chan = 3;
ret = ioctl(fd, FSADC_GET_VAL, &cv);
if (ret == -1)
goto fail;
printf("current volatage is: %.2fV\n", 1.8 * cv.val / 4095.0);
sleep(1);
}
fail:
perror("adc test");
exit(EXIT_FAILURE);
}

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := fspwm.o
endif

View File

@ -1,215 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/clk.h>
#include <linux/pinctrl/consumer.h>
#include "fspwm.h"
#define FSPWM_MAJOR 256
#define FSPWM_MINOR 7
#define FSPWM_DEV_NAME "fspwm"
struct fspwm_dev {
unsigned int __iomem *tcfg0;
unsigned int __iomem *tcfg1;
unsigned int __iomem *tcon;
unsigned int __iomem *tcntb0;
unsigned int __iomem *tcmpb0;
unsigned int __iomem *tcnto0;
struct clk *clk;
unsigned long freq;
struct pinctrl *pctrl;
atomic_t available;
struct cdev cdev;
};
static int fspwm_open(struct inode *inode, struct file *filp)
{
struct fspwm_dev *fspwm = container_of(inode->i_cdev, struct fspwm_dev, cdev);
filp->private_data = fspwm;
if (atomic_dec_and_test(&fspwm->available))
return 0;
else {
atomic_inc(&fspwm->available);
return -EBUSY;
}
}
static int fspwm_release(struct inode *inode, struct file *filp)
{
struct fspwm_dev *fspwm = filp->private_data;
atomic_inc(&fspwm->available);
return 0;
}
static long fspwm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct fspwm_dev *fspwm = filp->private_data;
unsigned int div;
if (_IOC_TYPE(cmd) != FSPWM_MAGIC)
return -ENOTTY;
switch (cmd) {
case FSPWM_START:
writel(readl(fspwm->tcon) | 0x1, fspwm->tcon);
break;
case FSPWM_STOP:
writel(readl(fspwm->tcon) & ~0x1, fspwm->tcon);
break;
case FSPWM_SET_FREQ:
if (arg > fspwm->freq || arg == 0)
return -ENOTTY;
div = fspwm->freq / arg - 1;
writel(div, fspwm->tcntb0);
writel(div / 2, fspwm->tcmpb0);
writel(readl(fspwm->tcon) | 0x2, fspwm->tcon);
writel(readl(fspwm->tcon) & ~0x2, fspwm->tcon);
break;
default:
return -ENOTTY;
}
return 0;
}
static struct file_operations fspwm_ops = {
.owner = THIS_MODULE,
.open = fspwm_open,
.release = fspwm_release,
.unlocked_ioctl = fspwm_ioctl,
};
static int fspwm_probe(struct platform_device *pdev)
{
int ret;
dev_t dev;
struct fspwm_dev *fspwm;
struct resource *res;
unsigned int prescaler0;
dev = MKDEV(FSPWM_MAJOR, FSPWM_MINOR);
ret = register_chrdev_region(dev, 1, FSPWM_DEV_NAME);
if (ret)
goto reg_err;
fspwm = kzalloc(sizeof(struct fspwm_dev), GFP_KERNEL);
if (!fspwm) {
ret = -ENOMEM;
goto mem_err;
}
platform_set_drvdata(pdev, fspwm);
cdev_init(&fspwm->cdev, &fspwm_ops);
fspwm->cdev.owner = THIS_MODULE;
ret = cdev_add(&fspwm->cdev, dev, 1);
if (ret)
goto add_err;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
ret = -ENOENT;
goto res_err;
}
fspwm->tcfg0 = ioremap(res->start, resource_size(res));
if (!fspwm->tcfg0) {
ret = -EBUSY;
goto map_err;
}
fspwm->tcfg1 = fspwm->tcfg0 + 1;
fspwm->tcon = fspwm->tcfg0 + 2;
fspwm->tcntb0 = fspwm->tcfg0 + 3;
fspwm->tcmpb0 = fspwm->tcfg0 + 4;
fspwm->tcnto0 = fspwm->tcfg0 + 5;
fspwm->clk = clk_get(&pdev->dev, "timers");
if (IS_ERR(fspwm->clk)) {
ret = PTR_ERR(fspwm->clk);
goto get_clk_err;
}
ret = clk_prepare_enable(fspwm->clk);
if (ret < 0)
goto enable_clk_err;
fspwm->freq = clk_get_rate(fspwm->clk);
prescaler0 = readl(fspwm->tcfg0) & 0xFF;
writel((readl(fspwm->tcfg1) & ~0xF) | 0x4, fspwm->tcfg1); /* 1/16 */
fspwm->freq /= (prescaler0 + 1) * 16; /* 3125000 */
writel((readl(fspwm->tcon) & ~0xF) | 0x8, fspwm->tcon); /* auto-reload */
fspwm->pctrl = devm_pinctrl_get_select_default(&pdev->dev);
atomic_set(&fspwm->available, 1);
return 0;
enable_clk_err:
clk_put(fspwm->clk);
get_clk_err:
iounmap(fspwm->tcfg0);
map_err:
res_err:
cdev_del(&fspwm->cdev);
add_err:
kfree(fspwm);
mem_err:
unregister_chrdev_region(dev, 1);
reg_err:
return ret;
}
static int fspwm_remove(struct platform_device *pdev)
{
dev_t dev;
struct fspwm_dev *fspwm = platform_get_drvdata(pdev);
dev = MKDEV(FSPWM_MAJOR, FSPWM_MINOR);
clk_disable_unprepare(fspwm->clk);
clk_put(fspwm->clk);
iounmap(fspwm->tcfg0);
cdev_del(&fspwm->cdev);
kfree(fspwm);
unregister_chrdev_region(dev, 1);
return 0;
}
static const struct of_device_id fspwm_of_matches[] = {
{ .compatible = "fs4412,fspwm", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fspwm_of_matches);
struct platform_driver fspwm_drv = {
.driver = {
.name = "fspwm",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(fspwm_of_matches),
},
.probe = fspwm_probe,
.remove = fspwm_remove,
};
module_platform_driver(fspwm_drv);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("PWM driver");

View File

@ -1,10 +0,0 @@
#ifndef _FSPWM_H
#define _FSPWM_H
#define FSPWM_MAGIC 'f'
#define FSPWM_START _IO(FSPWM_MAGIC, 0)
#define FSPWM_STOP _IO(FSPWM_MAGIC, 1)
#define FSPWM_SET_FREQ _IOW(FSPWM_MAGIC, 2, unsigned int)
#endif

View File

@ -1,36 +0,0 @@
#ifndef _MUSIC_H
#define _MUSIC_H
typedef struct
{
int pitch;
int dimation;
} note;
// 1 2 3 4 5 6 7
// C D E F G A B
// 261.6256 293.6648 329.6276 349.2282 391.9954 440 493.8833
// C调
#define DO 262
#define RE 294
#define MI 330
#define FA 349
#define SOL 392
#define LA 440
#define SI 494
#define BEAT (60000000 / 120)
const note HappyNewYear[] = {
{DO, BEAT/2}, {DO, BEAT/2}, {DO, BEAT}, {SOL/2, BEAT},
{MI, BEAT/2}, {MI, BEAT/2}, {MI, BEAT}, {DO, BEAT},
{DO, BEAT/2}, {MI, BEAT/2}, {SOL, BEAT}, {SOL, BEAT},
{FA, BEAT/2}, {MI, BEAT/2}, {RE, BEAT}, {RE, BEAT},
{RE, BEAT/2}, {MI, BEAT/2}, {FA, BEAT}, {FA, BEAT},
{MI, BEAT/2}, {RE, BEAT/2}, {MI, BEAT}, {DO, BEAT},
{DO, BEAT/2}, {MI, BEAT/2}, {RE, BEAT}, {SOL/2, BEAT},
{SI/2, BEAT/2}, {RE, BEAT/2}, {DO, BEAT}, {DO, BEAT},
};
#endif

View File

@ -1,45 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include "fspwm.h"
#include "music.h"
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
int main(int argc, char *argv[])
{
int i;
int fd;
int ret;
unsigned int freq;
fd = open("/dev/pwm", O_RDWR);
if (fd == -1)
goto fail;
ret = ioctl(fd, FSPWM_START);
if (ret == -1)
goto fail;
for (i = 0; i < ARRAY_SIZE(HappyNewYear); i++) {
ret = ioctl(fd, FSPWM_SET_FREQ, HappyNewYear[i].pitch);
if (ret == -1)
goto fail;
usleep(HappyNewYear[i].dimation);
}
ret = ioctl(fd, FSPWM_STOP);
if (ret == -1)
goto fail;
exit(EXIT_SUCCESS);
fail:
perror("pwm test");
exit(EXIT_FAILURE);
}

View File

@ -1,22 +0,0 @@
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH),arm)
KERNELDIR ?= /home/farsight/fs4412/linux-3.14.25-fs4412
ROOTFS ?= /nfs/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_install
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m := fsrtc.o
endif

View File

@ -1,221 +0,0 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/clk.h>
#include <linux/pinctrl/consumer.h>
#include <linux/bcd.h>
#include "fsrtc.h"
#define FSRTC_MAJOR 256
#define FSRTC_MINOR 8
#define FSRTC_DEV_NAME "fsrtc"
struct fsrtc_dev {
unsigned int __iomem *rtccon;
unsigned int __iomem *bcdsec;
unsigned int __iomem *bcdmin;
unsigned int __iomem *bcdhour;
unsigned int __iomem *bcdday;
unsigned int __iomem *bcdmon;
unsigned int __iomem *bcdyear;
struct clk *clk;
atomic_t available;
struct cdev cdev;
};
static int fsrtc_open(struct inode *inode, struct file *filp)
{
struct fsrtc_dev *fsrtc = container_of(inode->i_cdev, struct fsrtc_dev, cdev);
filp->private_data = fsrtc;
if (atomic_dec_and_test(&fsrtc->available))
return 0;
else {
atomic_inc(&fsrtc->available);
return -EBUSY;
}
}
static int fsrtc_release(struct inode *inode, struct file *filp)
{
struct fsrtc_dev *fsrtc = filp->private_data;
atomic_inc(&fsrtc->available);
return 0;
}
static long fsrtc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct fsrtc_dev *fsrtc = filp->private_data;
struct rtc_time time;
if (_IOC_TYPE(cmd) != FSRTC_MAGIC)
return -ENOTTY;
switch (cmd) {
case FSRTC_SET:
if (copy_from_user(&time, (struct rtc_time __user *)arg, sizeof(struct rtc_time)))
return -ENOTTY;
writel(readl(fsrtc->rtccon) | 0x1, fsrtc->rtccon);
writel(bin2bcd(time.tm_sec ), fsrtc->bcdsec);
writel(bin2bcd(time.tm_min ), fsrtc->bcdmin);
writel(bin2bcd(time.tm_hour), fsrtc->bcdhour);
writel(bin2bcd(time.tm_mday), fsrtc->bcdday);
writel(bin2bcd(time.tm_mon ), fsrtc->bcdmon);
writel(bin2bcd(time.tm_year - 2000), fsrtc->bcdyear);
writel(readl(fsrtc->rtccon) & ~0x1, fsrtc->rtccon);
break;
case FSRTC_GET:
time.tm_sec = bcd2bin(readl(fsrtc->bcdsec));
time.tm_min = bcd2bin(readl(fsrtc->bcdmin));
time.tm_hour = bcd2bin(readl(fsrtc->bcdhour));
time.tm_mday = bcd2bin(readl(fsrtc->bcdday));
time.tm_mon = bcd2bin(readl(fsrtc->bcdmon));
time.tm_year = bcd2bin(readl(fsrtc->bcdyear)) + 2000;
if (copy_to_user((struct rtc_time __user *)arg, &time, sizeof(struct rtc_time)))
return -ENOTTY;
break;
default:
return -ENOTTY;
}
return 0;
}
static struct file_operations fsrtc_ops = {
.owner = THIS_MODULE,
.open = fsrtc_open,
.release = fsrtc_release,
.unlocked_ioctl = fsrtc_ioctl,
};
static int fsrtc_probe(struct platform_device *pdev)
{
int ret;
dev_t dev;
struct fsrtc_dev *fsrtc;
struct resource *res;
unsigned int __iomem *regbase;
dev = MKDEV(FSRTC_MAJOR, FSRTC_MINOR);
ret = register_chrdev_region(dev, 1, FSRTC_DEV_NAME);
if (ret)
goto reg_err;
fsrtc = kzalloc(sizeof(struct fsrtc_dev), GFP_KERNEL);
if (!fsrtc) {
ret = -ENOMEM;
goto mem_err;
}
platform_set_drvdata(pdev, fsrtc);
cdev_init(&fsrtc->cdev, &fsrtc_ops);
fsrtc->cdev.owner = THIS_MODULE;
ret = cdev_add(&fsrtc->cdev, dev, 1);
if (ret)
goto add_err;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
ret = -ENOENT;
goto res_err;
}
regbase = ioremap(res->start, resource_size(res));
if (!regbase) {
ret = -EBUSY;
goto map_err;
}
fsrtc->rtccon = regbase + 16;
fsrtc->bcdsec = regbase + 28;
fsrtc->bcdmin = regbase + 29;
fsrtc->bcdhour = regbase + 30;
fsrtc->bcdday = regbase + 31;
fsrtc->bcdmon = regbase + 33;
fsrtc->bcdyear = regbase + 34;
fsrtc->clk = clk_get(&pdev->dev, "rtc");
if (IS_ERR(fsrtc->clk)) {
ret = PTR_ERR(fsrtc->clk);
goto get_clk_err;
}
ret = clk_prepare_enable(fsrtc->clk);
if (ret < 0)
goto enable_clk_err;
writel(0, fsrtc->rtccon);
atomic_set(&fsrtc->available, 1);
return 0;
enable_clk_err:
clk_put(fsrtc->clk);
get_clk_err:
iounmap(fsrtc->rtccon - 16);
map_err:
res_err:
cdev_del(&fsrtc->cdev);
add_err:
kfree(fsrtc);
mem_err:
unregister_chrdev_region(dev, 1);
reg_err:
return ret;
}
static int fsrtc_remove(struct platform_device *pdev)
{
dev_t dev;
struct fsrtc_dev *fsrtc = platform_get_drvdata(pdev);
dev = MKDEV(FSRTC_MAJOR, FSRTC_MINOR);
clk_disable_unprepare(fsrtc->clk);
clk_put(fsrtc->clk);
iounmap(fsrtc->rtccon - 16);
cdev_del(&fsrtc->cdev);
kfree(fsrtc);
unregister_chrdev_region(dev, 1);
return 0;
}
static const struct of_device_id fsrtc_of_matches[] = {
{ .compatible = "fs4412,fsrtc", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fsrtc_of_matches);
struct platform_driver fsrtc_drv = {
.driver = {
.name = "fsrtc",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(fsrtc_of_matches),
},
.probe = fsrtc_probe,
.remove = fsrtc_remove,
};
module_platform_driver(fsrtc_drv);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kevin Jiang <jiangxg@farsight.com.cn>");
MODULE_DESCRIPTION("RTC driver");

View File

@ -1,20 +0,0 @@
#ifndef _FSRTC_H
#define _FSRTC_H
struct rtc_time {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
};
#define FSRTC_MAGIC 'f'
#define FSRTC_SET _IOW(FSRTC_MAGIC, 0, struct rtc_time)
#define FSRTC_GET _IOR(FSRTC_MAGIC, 1, struct rtc_time)
#endif

View File

@ -1,36 +0,0 @@
#ifndef _MUSIC_H
#define _MUSIC_H
typedef struct
{
int pitch;
int dimation;
} note;
// 1 2 3 4 5 6 7
// C D E F G A B
// 261.6256 293.6648 329.6276 349.2282 391.9954 440 493.8833
// C调
#define DO 262
#define RE 294
#define MI 330
#define FA 349
#define SOL 392
#define LA 440
#define SI 494
#define BEAT (60000000 / 120)
const note HappyNewYear[] = {
{DO, BEAT/2}, {DO, BEAT/2}, {DO, BEAT}, {SOL/2, BEAT},
{MI, BEAT/2}, {MI, BEAT/2}, {MI, BEAT}, {DO, BEAT},
{DO, BEAT/2}, {MI, BEAT/2}, {SOL, BEAT}, {SOL, BEAT},
{FA, BEAT/2}, {MI, BEAT/2}, {RE, BEAT}, {RE, BEAT},
{RE, BEAT/2}, {MI, BEAT/2}, {FA, BEAT}, {FA, BEAT},
{MI, BEAT/2}, {RE, BEAT/2}, {MI, BEAT}, {DO, BEAT},
{DO, BEAT/2}, {MI, BEAT/2}, {RE, BEAT}, {SOL/2, BEAT},
{SI/2, BEAT/2}, {RE, BEAT/2}, {DO, BEAT}, {DO, BEAT},
};
#endif

View File

@ -1,47 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include "fsrtc.h"
int main(int argc, char *argv[])
{
int fd;
int ret;
struct rtc_time time;
fd = open("/dev/rtc", O_RDWR);
if (fd == -1)
goto fail;
time.tm_sec = 59;
time.tm_min = 59;
time.tm_hour = 23;
time.tm_mday = 8;
time.tm_mon = 8;
time.tm_year = 2016;
ret = ioctl(fd, FSRTC_SET, &time);
if (ret == -1)
goto fail;
while (1) {
ret = ioctl(fd, FSRTC_GET, &time);
if (ret == -1)
goto fail;
printf("%d-%d-%d %d:%d:%d\n", time.tm_year, time.tm_mon, time.tm_mday,\
time.tm_hour, time.tm_min, time.tm_sec);
sleep(1);
}
exit(EXIT_SUCCESS);
fail:
perror("adc test");
exit(EXIT_FAILURE);
}

View File

@ -1,334 +0,0 @@
/*
i2c-dev.h - i2c-bus driver, char device interface
Copyright (C) 1995-97 Simon G. Vogl
Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
/* $Id: i2c-dev.h 5361 2008-10-19 09:47:02Z khali $ */
#ifndef LIB_I2CDEV_H
#define LIB_I2CDEV_H
#include <linux/types.h>
#include <sys/ioctl.h>
/* -- i2c.h -- */
/*
* I2C Message - used for pure i2c transaction, also from /dev interface
*/
struct i2c_msg {
__u16 addr; /* slave address */
unsigned short flags;
#define I2C_M_TEN 0x10 /* we have a ten bit chip address */
#define I2C_M_RD 0x01
#define I2C_M_NOSTART 0x4000
#define I2C_M_REV_DIR_ADDR 0x2000
#define I2C_M_IGNORE_NAK 0x1000
#define I2C_M_NO_RD_ACK 0x0800
short len; /* msg length */
char *buf; /* pointer to msg data */
};
/* To determine what functionality is present */
#define I2C_FUNC_I2C 0x00000001
#define I2C_FUNC_10BIT_ADDR 0x00000002
#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */
#define I2C_FUNC_SMBUS_PEC 0x00000008
#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */
#define I2C_FUNC_SMBUS_QUICK 0x00010000
#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000
#define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000
#define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000
#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000
#define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000
#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000
#define I2C_FUNC_SMBUS_PROC_CALL 0x00800000
#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000
#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */
#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */
#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \
I2C_FUNC_SMBUS_WRITE_BYTE)
#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \
I2C_FUNC_SMBUS_WRITE_BYTE_DATA)
#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \
I2C_FUNC_SMBUS_WRITE_WORD_DATA)
#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \
I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)
#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \
I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
/* Old name, for compatibility */
#define I2C_FUNC_SMBUS_HWPEC_CALC I2C_FUNC_SMBUS_PEC
/*
* Data for SMBus Messages
*/
#define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */
#define I2C_SMBUS_I2C_BLOCK_MAX 32 /* Not specified but we use same structure */
union i2c_smbus_data {
__u8 byte;
__u16 word;
__u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */
/* and one more for PEC */
};
/* smbus_access read or write markers */
#define I2C_SMBUS_READ 1
#define I2C_SMBUS_WRITE 0
/* SMBus transaction types (size parameter in the above functions)
Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */
#define I2C_SMBUS_QUICK 0
#define I2C_SMBUS_BYTE 1
#define I2C_SMBUS_BYTE_DATA 2
#define I2C_SMBUS_WORD_DATA 3
#define I2C_SMBUS_PROC_CALL 4
#define I2C_SMBUS_BLOCK_DATA 5
#define I2C_SMBUS_I2C_BLOCK_BROKEN 6
#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */
#define I2C_SMBUS_I2C_BLOCK_DATA 8
/* ----- commands for the ioctl like i2c_command call:
* note that additional calls are defined in the algorithm and hw
* dependent layers - these can be listed here, or see the
* corresponding header files.
*/
/* -> bit-adapter specific ioctls */
#define I2C_RETRIES 0x0701 /* number of times a device address */
/* should be polled when not */
/* acknowledging */
#define I2C_TIMEOUT 0x0702 /* set timeout - call with int */
/* this is for i2c-dev.c */
#define I2C_SLAVE 0x0703 /* Change slave address */
/* Attn.: Slave address is 7 or 10 bits */
#define I2C_SLAVE_FORCE 0x0706 /* Change slave address */
/* Attn.: Slave address is 7 or 10 bits */
/* This changes the address, even if it */
/* is already taken! */
#define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */
#define I2C_FUNCS 0x0705 /* Get the adapter functionality */
#define I2C_RDWR 0x0707 /* Combined R/W transfer (one stop only)*/
#define I2C_PEC 0x0708 /* != 0 for SMBus PEC */
#define I2C_SMBUS 0x0720 /* SMBus-level access */
/* -- i2c.h -- */
/* Note: 10-bit addresses are NOT supported! */
/* This is the structure as used in the I2C_SMBUS ioctl call */
struct i2c_smbus_ioctl_data {
char read_write;
__u8 command;
int size;
union i2c_smbus_data *data;
};
/* This is the structure as used in the I2C_RDWR ioctl call */
struct i2c_rdwr_ioctl_data {
struct i2c_msg *msgs; /* pointers to i2c_msgs */
int nmsgs; /* number of i2c_msgs */
};
static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command,
int size, union i2c_smbus_data *data)
{
struct i2c_smbus_ioctl_data args;
args.read_write = read_write;
args.command = command;
args.size = size;
args.data = data;
return ioctl(file,I2C_SMBUS,&args);
}
static inline __s32 i2c_smbus_write_quick(int file, __u8 value)
{
return i2c_smbus_access(file,value,0,I2C_SMBUS_QUICK,NULL);
}
static inline __s32 i2c_smbus_read_byte(int file)
{
union i2c_smbus_data data;
if (i2c_smbus_access(file,I2C_SMBUS_READ,0,I2C_SMBUS_BYTE,&data))
return -1;
else
return 0x0FF & data.byte;
}
static inline __s32 i2c_smbus_write_byte(int file, __u8 value)
{
return i2c_smbus_access(file,I2C_SMBUS_WRITE,value,
I2C_SMBUS_BYTE,NULL);
}
static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command)
{
union i2c_smbus_data data;
if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
I2C_SMBUS_BYTE_DATA,&data))
return -1;
else
return 0x0FF & data.byte;
}
static inline __s32 i2c_smbus_write_byte_data(int file, __u8 command,
__u8 value)
{
union i2c_smbus_data data;
data.byte = value;
return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
I2C_SMBUS_BYTE_DATA, &data);
}
static inline __s32 i2c_smbus_read_word_data(int file, __u8 command)
{
union i2c_smbus_data data;
if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
I2C_SMBUS_WORD_DATA,&data))
return -1;
else
return 0x0FFFF & data.word;
}
static inline __s32 i2c_smbus_write_word_data(int file, __u8 command,
__u16 value)
{
union i2c_smbus_data data;
data.word = value;
return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
I2C_SMBUS_WORD_DATA, &data);
}
static inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value)
{
union i2c_smbus_data data;
data.word = value;
if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
I2C_SMBUS_PROC_CALL,&data))
return -1;
else
return 0x0FFFF & data.word;
}
/* Returns the number of read bytes */
static inline __s32 i2c_smbus_read_block_data(int file, __u8 command,
__u8 *values)
{
union i2c_smbus_data data;
int i;
if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
I2C_SMBUS_BLOCK_DATA,&data))
return -1;
else {
for (i = 1; i <= data.block[0]; i++)
values[i-1] = data.block[i];
return data.block[0];
}
}
static inline __s32 i2c_smbus_write_block_data(int file, __u8 command,
__u8 length, __u8 *values)
{
union i2c_smbus_data data;
int i;
if (length > 32)
length = 32;
for (i = 1; i <= length; i++)
data.block[i] = values[i-1];
data.block[0] = length;
return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
I2C_SMBUS_BLOCK_DATA, &data);
}
/* Returns the number of read bytes */
/* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
ask for less than 32 bytes, your code will only work with kernels
2.6.23 and later. */
static inline __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command,
__u8 length, __u8 *values)
{
union i2c_smbus_data data;
int i;
if (length > 32)
length = 32;
data.block[0] = length;
if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
length == 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN :
I2C_SMBUS_I2C_BLOCK_DATA,&data))
return -1;
else {
for (i = 1; i <= data.block[0]; i++)
values[i-1] = data.block[i];
return data.block[0];
}
}
static inline __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command,
__u8 length, __u8 *values)
{
union i2c_smbus_data data;
int i;
if (length > 32)
length = 32;
for (i = 1; i <= length; i++)
data.block[i] = values[i-1];
data.block[0] = length;
return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
I2C_SMBUS_I2C_BLOCK_BROKEN, &data);
}
/* Returns the number of read bytes */
static inline __s32 i2c_smbus_block_process_call(int file, __u8 command,
__u8 length, __u8 *values)
{
union i2c_smbus_data data;
int i;
if (length > 32)
length = 32;
for (i = 1; i <= length; i++)
data.block[i] = values[i-1];
data.block[0] = length;
if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
I2C_SMBUS_BLOCK_PROC_CALL,&data))
return -1;
else {
for (i = 1; i <= data.block[0]; i++)
values[i-1] = data.block[i];
return data.block[0];
}
}
#endif /* LIB_I2CDEV_H */

Some files were not shown because too many files have changed in this diff Show More