[新增] 华清 源码
This commit is contained in:
22
devmodel/ex1/Makefile
Executable file
22
devmodel/ex1/Makefile
Executable file
@ -0,0 +1,22 @@
|
||||
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
|
||||
|
||||
66
devmodel/ex1/model.c
Executable file
66
devmodel/ex1/model.c
Executable file
@ -0,0 +1,66 @@
|
||||
#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");
|
||||
21
devmodel/ex2/Makefile
Executable file
21
devmodel/ex2/Makefile
Executable file
@ -0,0 +1,21 @@
|
||||
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
|
||||
34
devmodel/ex2/vbus.c
Executable file
34
devmodel/ex2/vbus.c
Executable file
@ -0,0 +1,34 @@
|
||||
#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");
|
||||
34
devmodel/ex2/vdev.c
Executable file
34
devmodel/ex2/vdev.c
Executable file
@ -0,0 +1,34 @@
|
||||
#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");
|
||||
29
devmodel/ex2/vdrv.c
Executable file
29
devmodel/ex2/vdrv.c
Executable file
@ -0,0 +1,29 @@
|
||||
#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");
|
||||
21
devmodel/ex3/Makefile
Executable file
21
devmodel/ex3/Makefile
Executable file
@ -0,0 +1,21 @@
|
||||
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
|
||||
50
devmodel/ex3/pltdev.c
Executable file
50
devmodel/ex3/pltdev.c
Executable file
@ -0,0 +1,50 @@
|
||||
#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");
|
||||
49
devmodel/ex3/pltdrv.c
Executable file
49
devmodel/ex3/pltdrv.c
Executable file
@ -0,0 +1,49 @@
|
||||
#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");
|
||||
23
devmodel/ex4/Makefile
Executable file
23
devmodel/ex4/Makefile
Executable file
@ -0,0 +1,23 @@
|
||||
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
|
||||
|
||||
101
devmodel/ex4/fsdev.c
Executable file
101
devmodel/ex4/fsdev.c
Executable file
@ -0,0 +1,101 @@
|
||||
#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");
|
||||
165
devmodel/ex4/fsled.c
Executable file
165
devmodel/ex4/fsled.c
Executable file
@ -0,0 +1,165 @@
|
||||
#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");
|
||||
9
devmodel/ex4/fsled.h
Executable file
9
devmodel/ex4/fsled.h
Executable file
@ -0,0 +1,9 @@
|
||||
#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
|
||||
46
devmodel/ex4/test.c
Executable file
46
devmodel/ex4/test.c
Executable file
@ -0,0 +1,46 @@
|
||||
#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);
|
||||
}
|
||||
|
||||
23
devmodel/ex5/Makefile
Executable file
23
devmodel/ex5/Makefile
Executable file
@ -0,0 +1,23 @@
|
||||
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
|
||||
|
||||
101
devmodel/ex5/fsdev.c
Executable file
101
devmodel/ex5/fsdev.c
Executable file
@ -0,0 +1,101 @@
|
||||
#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");
|
||||
199
devmodel/ex5/fsled.c
Executable file
199
devmodel/ex5/fsled.c
Executable file
@ -0,0 +1,199 @@
|
||||
#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");
|
||||
9
devmodel/ex5/fsled.h
Executable file
9
devmodel/ex5/fsled.h
Executable file
@ -0,0 +1,9 @@
|
||||
#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
|
||||
46
devmodel/ex5/test.c
Executable file
46
devmodel/ex5/test.c
Executable file
@ -0,0 +1,46 @@
|
||||
#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);
|
||||
}
|
||||
|
||||
22
devmodel/ex6/Makefile
Executable file
22
devmodel/ex6/Makefile
Executable file
@ -0,0 +1,22 @@
|
||||
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
|
||||
|
||||
183
devmodel/ex6/fsled.c
Executable file
183
devmodel/ex6/fsled.c
Executable file
@ -0,0 +1,183 @@
|
||||
#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");
|
||||
9
devmodel/ex6/fsled.h
Executable file
9
devmodel/ex6/fsled.h
Executable file
@ -0,0 +1,9 @@
|
||||
#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
|
||||
46
devmodel/ex6/test.c
Executable file
46
devmodel/ex6/test.c
Executable file
@ -0,0 +1,46 @@
|
||||
#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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user