summaryrefslogtreecommitdiff
path: root/meta-rtmod1/model_answer/files/rt-demo-kmod.c
diff options
context:
space:
mode:
Diffstat (limited to 'meta-rtmod1/model_answer/files/rt-demo-kmod.c')
-rw-r--r--meta-rtmod1/model_answer/files/rt-demo-kmod.c98
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[] = {
+ &notify.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");