[新增] 华清 源码

This commit is contained in:
gaoyang3513
2023-12-24 10:29:22 +00:00
commit 3f3b436a9f
149 changed files with 10507 additions and 0 deletions

22
devmodel/ex1/Makefile Executable file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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);
}