These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / staging / most / hdm-dim2 / dim2_sysfs.c
1 /*
2  * dim2_sysfs.c - MediaLB sysfs information
3  *
4  * Copyright (C) 2015, Microchip Technology Germany II GmbH & Co. KG
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9  * GNU General Public License for more details.
10  *
11  * This file is licensed under GPLv2.
12  */
13
14 /* Author: Andrey Shvetsov <andrey.shvetsov@k2l.de> */
15
16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17
18 #include <linux/kernel.h>
19 #include "dim2_sysfs.h"
20
21 struct bus_attr {
22         struct attribute attr;
23         ssize_t (*show)(struct medialb_bus *bus, char *buf);
24         ssize_t (*store)(struct medialb_bus *bus, const char *buf,
25                          size_t count);
26 };
27
28 static ssize_t state_show(struct medialb_bus *bus, char *buf)
29 {
30         bool state = dim2_sysfs_get_state_cb();
31
32         return sprintf(buf, "%s\n", state ? "locked" : "");
33 }
34
35 static struct bus_attr state_attr = __ATTR_RO(state);
36
37 static struct attribute *bus_default_attrs[] = {
38         &state_attr.attr,
39         NULL,
40 };
41
42 static struct attribute_group bus_attr_group = {
43         .attrs = bus_default_attrs,
44 };
45
46 static void bus_kobj_release(struct kobject *kobj)
47 {
48 }
49
50 static ssize_t bus_kobj_attr_show(struct kobject *kobj, struct attribute *attr,
51                                   char *buf)
52 {
53         struct medialb_bus *bus =
54                 container_of(kobj, struct medialb_bus, kobj_group);
55         struct bus_attr *xattr = container_of(attr, struct bus_attr, attr);
56
57         if (!xattr->show)
58                 return -EIO;
59
60         return xattr->show(bus, buf);
61 }
62
63 static ssize_t bus_kobj_attr_store(struct kobject *kobj, struct attribute *attr,
64                                    const char *buf, size_t count)
65 {
66         ssize_t ret;
67         struct medialb_bus *bus =
68                 container_of(kobj, struct medialb_bus, kobj_group);
69         struct bus_attr *xattr = container_of(attr, struct bus_attr, attr);
70
71         if (!xattr->store)
72                 return -EIO;
73
74         ret = xattr->store(bus, buf, count);
75         return ret;
76 }
77
78 static struct sysfs_ops const bus_kobj_sysfs_ops = {
79         .show = bus_kobj_attr_show,
80         .store = bus_kobj_attr_store,
81 };
82
83 static struct kobj_type bus_ktype = {
84         .release = bus_kobj_release,
85         .sysfs_ops = &bus_kobj_sysfs_ops,
86 };
87
88 int dim2_sysfs_probe(struct medialb_bus *bus, struct kobject *parent_kobj)
89 {
90         int err;
91
92         kobject_init(&bus->kobj_group, &bus_ktype);
93         err = kobject_add(&bus->kobj_group, parent_kobj, "bus");
94         if (err) {
95                 pr_err("kobject_add() failed: %d\n", err);
96                 goto err_kobject_add;
97         }
98
99         err = sysfs_create_group(&bus->kobj_group, &bus_attr_group);
100         if (err) {
101                 pr_err("sysfs_create_group() failed: %d\n", err);
102                 goto err_create_group;
103         }
104
105         return 0;
106
107 err_create_group:
108         kobject_put(&bus->kobj_group);
109
110 err_kobject_add:
111         return err;
112 }
113
114 void dim2_sysfs_destroy(struct medialb_bus *bus)
115 {
116         kobject_put(&bus->kobj_group);
117 }