diff options
Diffstat (limited to 'meta-rtmod1/model_answer/files/rt-demo-kmod.c')
-rw-r--r-- | meta-rtmod1/model_answer/files/rt-demo-kmod.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/meta-rtmod1/model_answer/files/rt-demo-kmod.c b/meta-rtmod1/model_answer/files/rt-demo-kmod.c new file mode 100644 index 0000000000..2342b9c35e --- /dev/null +++ b/meta-rtmod1/model_answer/files/rt-demo-kmod.c @@ -0,0 +1,98 @@ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/fs.h> +#include <linux/slab.h> + +struct demo_attr { + struct attribute attr; + int value; +}; + +static struct demo_attr notify = { + .attr.name="notify", + .attr.mode = 0644, + .value = 0, +}; + +static struct demo_attr trigger = { + .attr.name="trigger", + .attr.mode = 0644, + .value = 0, +}; + +static struct attribute *demoattr[] = { + ¬ify.attr, + &trigger.attr, + NULL +}; + +static struct kobject *demo_kobj; + +static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) +{ + struct demo_attr *a = container_of(attr, struct demo_attr, attr); + + pr_debug("RT demo kmod: show called (%s)\n", a->attr.name); + + return scnprintf(buf, PAGE_SIZE, "%s: %d\n", a->attr.name, a->value); +} + +static ssize_t store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t len) +{ + struct demo_attr *a = container_of(attr, struct demo_attr, attr); + + if (!strncmp(a->attr.name, "notify", sizeof("notify"))) + return len; + + sscanf(buf, "%d", &a->value); + notify.value = a->value; + pr_debug("RT demo kmod: sysfs_notify store %s = %d\n", a->attr.name, + a->value); + sysfs_notify(demo_kobj, NULL, "notify"); + + return len; +} + +static struct sysfs_ops demoops = { + .show = show, + .store = store, +}; + +static struct kobj_type mytype = { + .sysfs_ops = &demoops, + .default_attrs = demoattr, +}; + +static int __init demo_module_init(void) +{ + int err = -1; + + pr_debug("RT demo kmod: init\n"); + demo_kobj = kzalloc(sizeof(*demo_kobj), GFP_KERNEL); + if (demo_kobj) { + kobject_init(demo_kobj, &mytype); + if (kobject_add(demo_kobj, NULL, "%s", "demo-poll")) { + err = -1; + pr_err("RT demo kmod: kobject_add() failed\n"); + kobject_put(demo_kobj); + demo_kobj = NULL; + } + err = 0; + } + return err; +} + +static void __exit demo_module_exit(void) +{ + if (demo_kobj) { + kobject_put(demo_kobj); + kfree(demo_kobj); + } + pr_debug("RT demo kmod: exit\n"); +} + +module_init(demo_module_init); +module_exit(demo_module_exit); +MODULE_LICENSE("GPL"); |