Skip to content

Commit 5489913

Browse files
authored
The Sensor driver framework module complies with s3ip sysfs specification (#12890) (#13219)
1 parent 29e7348 commit 5489913

File tree

6 files changed

+1270
-0
lines changed

6 files changed

+1270
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,391 @@
1+
/*
2+
* curr_sensor_sysfs.c
3+
*
4+
* This module create curr sensor kobjects and attributes in /sys/s3ip/curr_sensor
5+
*
6+
* History
7+
* [Version] [Date] [Description]
8+
* * v1.0 2021-08-31 S3IP sysfs
9+
*/
10+
11+
#include <linux/slab.h>
12+
13+
#include "switch.h"
14+
#include "curr_sensor_sysfs.h"
15+
16+
static int g_curr_sensor_loglevel = 0;
17+
18+
#define CURR_SENSOR_INFO(fmt, args...) do { \
19+
if (g_curr_sensor_loglevel & INFO) { \
20+
printk(KERN_INFO "[CURR_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \
21+
} \
22+
} while (0)
23+
24+
#define CURR_SENSOR_ERR(fmt, args...) do { \
25+
if (g_curr_sensor_loglevel & ERR) { \
26+
printk(KERN_ERR "[CURR_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \
27+
} \
28+
} while (0)
29+
30+
#define CURR_SENSOR_DBG(fmt, args...) do { \
31+
if (g_curr_sensor_loglevel & DBG) { \
32+
printk(KERN_DEBUG "[CURR_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \
33+
} \
34+
} while (0)
35+
36+
struct curr_sensor_obj_s {
37+
struct switch_obj *obj;
38+
};
39+
40+
struct curr_sensor_s {
41+
unsigned int curr_number;
42+
struct curr_sensor_obj_s *curr;
43+
};
44+
45+
static struct s3ip_sysfs_curr_sensor_drivers_s *g_curr_sensor_drv = NULL;
46+
static struct curr_sensor_s g_curr_sensor;
47+
static struct switch_obj *g_curr_sensor_obj = NULL;
48+
49+
static ssize_t curr_sensor_number_show(struct switch_obj *obj, struct switch_attribute *attr,
50+
char *buf)
51+
{
52+
return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_curr_sensor.curr_number);
53+
}
54+
55+
static ssize_t curr_sensor_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
56+
{
57+
unsigned int curr_index;
58+
int ret;
59+
60+
check_p(g_curr_sensor_drv);
61+
check_p(g_curr_sensor_drv->get_main_board_curr_value);
62+
63+
curr_index = obj->index;
64+
CURR_SENSOR_DBG("curr index: %u\n", curr_index);
65+
ret = g_curr_sensor_drv->get_main_board_curr_value(curr_index, buf, PAGE_SIZE);
66+
if (ret < 0) {
67+
CURR_SENSOR_ERR("get curr%u value failed, ret: %d\n", curr_index, ret);
68+
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
69+
}
70+
return ret;
71+
}
72+
73+
static ssize_t curr_sensor_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
74+
{
75+
unsigned int curr_index;
76+
int ret;
77+
78+
check_p(g_curr_sensor_drv);
79+
check_p(g_curr_sensor_drv->get_main_board_curr_alias);
80+
81+
curr_index = obj->index;
82+
CURR_SENSOR_DBG("curr index: %u\n", curr_index);
83+
ret = g_curr_sensor_drv->get_main_board_curr_alias(curr_index, buf, PAGE_SIZE);
84+
if (ret < 0) {
85+
CURR_SENSOR_ERR("get curr%u alias failed, ret: %d\n", curr_index, ret);
86+
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
87+
}
88+
return ret;
89+
}
90+
91+
static ssize_t curr_sensor_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
92+
{
93+
unsigned int curr_index;
94+
int ret;
95+
96+
check_p(g_curr_sensor_drv);
97+
check_p(g_curr_sensor_drv->get_main_board_curr_type);
98+
99+
curr_index = obj->index;
100+
CURR_SENSOR_DBG("curr index: %u\n", curr_index);
101+
ret = g_curr_sensor_drv->get_main_board_curr_type(curr_index, buf, PAGE_SIZE);
102+
if (ret < 0) {
103+
CURR_SENSOR_ERR("get curr%u type failed, ret: %d\n", curr_index, ret);
104+
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
105+
}
106+
return ret;
107+
}
108+
109+
static ssize_t curr_sensor_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
110+
{
111+
unsigned int curr_index;
112+
int ret;
113+
114+
check_p(g_curr_sensor_drv);
115+
check_p(g_curr_sensor_drv->get_main_board_curr_max);
116+
117+
curr_index = obj->index;
118+
CURR_SENSOR_DBG("curr index: %u\n", curr_index);
119+
ret = g_curr_sensor_drv->get_main_board_curr_max(curr_index, buf, PAGE_SIZE);
120+
if (ret < 0) {
121+
CURR_SENSOR_ERR("get curr%u max threshold failed, ret: %d\n", curr_index, ret);
122+
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
123+
}
124+
return ret;
125+
}
126+
127+
static ssize_t curr_sensor_max_store(struct switch_obj *obj, struct switch_attribute *attr,
128+
const char* buf, size_t count)
129+
{
130+
unsigned int curr_index;
131+
int ret;
132+
133+
check_p(g_curr_sensor_drv);
134+
check_p(g_curr_sensor_drv->set_main_board_curr_max);
135+
136+
curr_index = obj->index;
137+
CURR_SENSOR_DBG("curr index: %u\n", curr_index);
138+
ret = g_curr_sensor_drv->set_main_board_curr_max(curr_index, buf, count);
139+
if (ret < 0) {
140+
CURR_SENSOR_ERR("set curr%u max threshold failed, value: %s, count: %lu, ret: %d\n",
141+
curr_index, buf, count, ret);
142+
return -EIO;
143+
}
144+
CURR_SENSOR_DBG("set curr%u max threshold success, value: %s, count: %lu, ret: %d\n",
145+
curr_index, buf, count, ret);
146+
return count;
147+
}
148+
149+
static ssize_t curr_sensor_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
150+
{
151+
unsigned int curr_index;
152+
int ret;
153+
154+
check_p(g_curr_sensor_drv);
155+
check_p(g_curr_sensor_drv->get_main_board_curr_min);
156+
157+
curr_index = obj->index;
158+
CURR_SENSOR_DBG("curr index: %u\n", curr_index);
159+
ret = g_curr_sensor_drv->get_main_board_curr_min(curr_index, buf, PAGE_SIZE);
160+
if (ret < 0) {
161+
CURR_SENSOR_ERR("get curr%u min threshold failed, ret: %d\n", curr_index, ret);
162+
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
163+
}
164+
return ret;
165+
}
166+
167+
static ssize_t curr_sensor_min_store(struct switch_obj *obj, struct switch_attribute *attr,
168+
const char* buf, size_t count)
169+
{
170+
unsigned int curr_index;
171+
int ret;
172+
173+
check_p(g_curr_sensor_drv);
174+
check_p(g_curr_sensor_drv->set_main_board_curr_min);
175+
176+
curr_index = obj->index;
177+
CURR_SENSOR_DBG("curr index: %u\n", curr_index);
178+
ret = g_curr_sensor_drv->set_main_board_curr_min(curr_index, buf, count);
179+
if (ret < 0) {
180+
CURR_SENSOR_ERR("set curr%u min threshold failed, value: %s, count: %lu, ret: %d\n",
181+
curr_index, buf, count, ret);
182+
return -EIO;
183+
}
184+
CURR_SENSOR_DBG("set curr%u min threshold success, value: %s, count: %lu, ret: %d\n",
185+
curr_index, buf, count, ret);
186+
return count;
187+
}
188+
189+
/************************************curr_sensor dir and attrs*******************************************/
190+
static struct switch_attribute num_curr_att = __ATTR(number, S_IRUGO, curr_sensor_number_show, NULL);
191+
192+
static struct attribute *curr_sensor_dir_attrs[] = {
193+
&num_curr_att.attr,
194+
NULL,
195+
};
196+
197+
static struct attribute_group curr_sensor_root_attr_group = {
198+
.attrs = curr_sensor_dir_attrs,
199+
};
200+
201+
/*******************************curr1 curr2 dir and attrs*******************************************/
202+
static struct switch_attribute curr_value_attr = __ATTR(value, S_IRUGO, curr_sensor_value_show, NULL);
203+
static struct switch_attribute curr_alias_attr = __ATTR(alias, S_IRUGO, curr_sensor_alias_show, NULL);
204+
static struct switch_attribute curr_type_attr = __ATTR(type, S_IRUGO, curr_sensor_type_show, NULL);
205+
static struct switch_attribute curr_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, curr_sensor_max_show, curr_sensor_max_store);
206+
static struct switch_attribute curr_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, curr_sensor_min_show, curr_sensor_min_store);
207+
208+
static struct attribute *curr_sensor_attrs[] = {
209+
&curr_value_attr.attr,
210+
&curr_alias_attr.attr,
211+
&curr_type_attr.attr,
212+
&curr_max_attr.attr,
213+
&curr_min_attr.attr,
214+
NULL,
215+
};
216+
217+
static struct attribute_group curr_sensor_attr_group = {
218+
.attrs = curr_sensor_attrs,
219+
};
220+
221+
static int curr_sensor_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index)
222+
{
223+
char name[DIR_NAME_MAX_LEN];
224+
struct curr_sensor_obj_s *curr_sensor;
225+
226+
curr_sensor = &g_curr_sensor.curr[index - 1];
227+
memset(name, 0, sizeof(name));
228+
snprintf(name, sizeof(name), "curr%u", index);
229+
curr_sensor->obj = switch_kobject_create(name, parent);
230+
if (!curr_sensor->obj) {
231+
CURR_SENSOR_ERR("create %s object error.\n", name);
232+
return -ENOMEM;
233+
}
234+
curr_sensor->obj->index = index;
235+
if (sysfs_create_group(&curr_sensor->obj->kobj, &curr_sensor_attr_group) != 0) {
236+
CURR_SENSOR_ERR("create %s attrs error.\n", name);
237+
switch_kobject_delete(&curr_sensor->obj);
238+
return -EBADRQC;
239+
}
240+
CURR_SENSOR_DBG("create %s dir and attrs success.\n", name);
241+
return 0;
242+
}
243+
244+
static void curr_sensor_sub_single_remove_kobj_and_attrs(unsigned int index)
245+
{
246+
struct curr_sensor_obj_s *curr_sensor;
247+
248+
curr_sensor = &g_curr_sensor.curr[index - 1];
249+
if (curr_sensor->obj) {
250+
sysfs_remove_group(&curr_sensor->obj->kobj, &curr_sensor_attr_group);
251+
switch_kobject_delete(&curr_sensor->obj);
252+
CURR_SENSOR_DBG("delete curr%u dir and attrs success.\n", index);
253+
}
254+
255+
return;
256+
}
257+
258+
static int curr_sensor_sub_create_kobj_and_attrs(struct kobject *parent, int curr_num)
259+
{
260+
unsigned int curr_index, i;
261+
262+
g_curr_sensor.curr = kzalloc(sizeof(struct curr_sensor_obj_s) * curr_num, GFP_KERNEL);
263+
if (!g_curr_sensor.curr) {
264+
CURR_SENSOR_ERR("kzalloc g_curr_sensor.curr error, curr number: %d.\n", curr_num);
265+
return -ENOMEM;
266+
}
267+
268+
for (curr_index = 1; curr_index <= curr_num; curr_index++) {
269+
if (curr_sensor_sub_single_create_kobj_and_attrs(parent, curr_index) != 0) {
270+
goto error;
271+
}
272+
}
273+
return 0;
274+
error:
275+
for (i = curr_index; i > 0; i--) {
276+
curr_sensor_sub_single_remove_kobj_and_attrs(i);
277+
}
278+
kfree(g_curr_sensor.curr);
279+
g_curr_sensor.curr = NULL;
280+
return -EBADRQC;
281+
}
282+
283+
/* create curr[1-n] directory and attributes*/
284+
static int curr_sensor_sub_create(void)
285+
{
286+
int ret;
287+
288+
ret = curr_sensor_sub_create_kobj_and_attrs(&g_curr_sensor_obj->kobj,
289+
g_curr_sensor.curr_number);
290+
return ret;
291+
}
292+
293+
/* delete curr[1-n] directory and attributes*/
294+
static void curr_sensor_sub_remove(void)
295+
{
296+
unsigned int curr_index;
297+
298+
if (g_curr_sensor.curr) {
299+
for (curr_index = g_curr_sensor.curr_number; curr_index > 0; curr_index--) {
300+
curr_sensor_sub_single_remove_kobj_and_attrs(curr_index);
301+
}
302+
kfree(g_curr_sensor.curr);
303+
g_curr_sensor.curr = NULL;
304+
}
305+
g_curr_sensor.curr_number = 0;
306+
return;
307+
}
308+
309+
/* create curr_sensor directory and number attributes */
310+
static int curr_sensor_root_create(void)
311+
{
312+
g_curr_sensor_obj = switch_kobject_create("curr_sensor", NULL);
313+
if (!g_curr_sensor_obj) {
314+
CURR_SENSOR_ERR("switch_kobject_create curr_sensor error!\n");
315+
return -ENOMEM;
316+
}
317+
318+
if (sysfs_create_group(&g_curr_sensor_obj->kobj, &curr_sensor_root_attr_group) != 0) {
319+
switch_kobject_delete(&g_curr_sensor_obj);
320+
CURR_SENSOR_ERR("create curr_sensor dir attrs error!\n");
321+
return -EBADRQC;
322+
}
323+
return 0;
324+
}
325+
326+
/* delete curr_sensor directory and number attributes */
327+
static void curr_sensor_root_remove(void)
328+
{
329+
if (g_curr_sensor_obj) {
330+
sysfs_remove_group(&g_curr_sensor_obj->kobj, &curr_sensor_root_attr_group);
331+
switch_kobject_delete(&g_curr_sensor_obj);
332+
}
333+
334+
return;
335+
}
336+
337+
int s3ip_sysfs_curr_sensor_drivers_register(struct s3ip_sysfs_curr_sensor_drivers_s *drv)
338+
{
339+
int ret, curr_num;
340+
341+
CURR_SENSOR_INFO("s3ip_sysfs_curr_sensor_drivers_register...\n");
342+
if (g_curr_sensor_drv) {
343+
CURR_SENSOR_ERR("g_curr_sensor_drv is not NULL, can't register\n");
344+
return -EPERM;
345+
}
346+
347+
check_p(drv);
348+
check_p(drv->get_main_board_curr_number);
349+
g_curr_sensor_drv = drv;
350+
351+
curr_num = g_curr_sensor_drv->get_main_board_curr_number();
352+
if (curr_num <= 0) {
353+
CURR_SENSOR_ERR("curr sensor number: %d, don't need to create curr_sensor dirs and attrs.\n",
354+
curr_num);
355+
return -EINVAL;
356+
}
357+
memset(&g_curr_sensor, 0, sizeof(struct curr_sensor_s));
358+
g_curr_sensor.curr_number = curr_num;
359+
ret = curr_sensor_root_create();
360+
if (ret < 0) {
361+
CURR_SENSOR_ERR("create curr_sensor root dir and attrs failed, ret: %d\n", ret);
362+
g_curr_sensor_drv = NULL;
363+
return ret;
364+
}
365+
366+
ret = curr_sensor_sub_create();
367+
if (ret < 0) {
368+
CURR_SENSOR_ERR("create curr_sensor sub dir and attrs failed, ret: %d\n", ret);
369+
curr_sensor_root_remove();
370+
g_curr_sensor_drv = NULL;
371+
return ret;
372+
}
373+
CURR_SENSOR_INFO("s3ip_sysfs_curr_sensor_drivers_register success\n");
374+
return ret;
375+
}
376+
377+
void s3ip_sysfs_curr_sensor_drivers_unregister(void)
378+
{
379+
if (g_curr_sensor_drv) {
380+
curr_sensor_sub_remove();
381+
curr_sensor_root_remove();
382+
g_curr_sensor_drv = NULL;
383+
CURR_SENSOR_DBG("s3ip_sysfs_curr_sensor_drivers_unregister success.\n");
384+
}
385+
return;
386+
}
387+
388+
EXPORT_SYMBOL(s3ip_sysfs_curr_sensor_drivers_register);
389+
EXPORT_SYMBOL(s3ip_sysfs_curr_sensor_drivers_unregister);
390+
module_param(g_curr_sensor_loglevel, int, 0644);
391+
MODULE_PARM_DESC(g_curr_sensor_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n");

0 commit comments

Comments
 (0)