This commit is contained in:
parent
29e7348c7b
commit
5489913baf
391
platform/s3ip-sysfs/s3ip_sysfs_frame/curr_sensor_sysfs.c
Normal file
391
platform/s3ip-sysfs/s3ip_sysfs_frame/curr_sensor_sysfs.c
Normal file
@ -0,0 +1,391 @@
|
|||||||
|
/*
|
||||||
|
* curr_sensor_sysfs.c
|
||||||
|
*
|
||||||
|
* This module create curr sensor kobjects and attributes in /sys/s3ip/curr_sensor
|
||||||
|
*
|
||||||
|
* History
|
||||||
|
* [Version] [Date] [Description]
|
||||||
|
* * v1.0 2021-08-31 S3IP sysfs
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
#include "switch.h"
|
||||||
|
#include "curr_sensor_sysfs.h"
|
||||||
|
|
||||||
|
static int g_curr_sensor_loglevel = 0;
|
||||||
|
|
||||||
|
#define CURR_SENSOR_INFO(fmt, args...) do { \
|
||||||
|
if (g_curr_sensor_loglevel & INFO) { \
|
||||||
|
printk(KERN_INFO "[CURR_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CURR_SENSOR_ERR(fmt, args...) do { \
|
||||||
|
if (g_curr_sensor_loglevel & ERR) { \
|
||||||
|
printk(KERN_ERR "[CURR_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CURR_SENSOR_DBG(fmt, args...) do { \
|
||||||
|
if (g_curr_sensor_loglevel & DBG) { \
|
||||||
|
printk(KERN_DEBUG "[CURR_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
struct curr_sensor_obj_s {
|
||||||
|
struct switch_obj *obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct curr_sensor_s {
|
||||||
|
unsigned int curr_number;
|
||||||
|
struct curr_sensor_obj_s *curr;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct s3ip_sysfs_curr_sensor_drivers_s *g_curr_sensor_drv = NULL;
|
||||||
|
static struct curr_sensor_s g_curr_sensor;
|
||||||
|
static struct switch_obj *g_curr_sensor_obj = NULL;
|
||||||
|
|
||||||
|
static ssize_t curr_sensor_number_show(struct switch_obj *obj, struct switch_attribute *attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_curr_sensor.curr_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t curr_sensor_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
unsigned int curr_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_curr_sensor_drv);
|
||||||
|
check_p(g_curr_sensor_drv->get_main_board_curr_value);
|
||||||
|
|
||||||
|
curr_index = obj->index;
|
||||||
|
CURR_SENSOR_DBG("curr index: %u\n", curr_index);
|
||||||
|
ret = g_curr_sensor_drv->get_main_board_curr_value(curr_index, buf, PAGE_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
CURR_SENSOR_ERR("get curr%u value failed, ret: %d\n", curr_index, ret);
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t curr_sensor_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
unsigned int curr_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_curr_sensor_drv);
|
||||||
|
check_p(g_curr_sensor_drv->get_main_board_curr_alias);
|
||||||
|
|
||||||
|
curr_index = obj->index;
|
||||||
|
CURR_SENSOR_DBG("curr index: %u\n", curr_index);
|
||||||
|
ret = g_curr_sensor_drv->get_main_board_curr_alias(curr_index, buf, PAGE_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
CURR_SENSOR_ERR("get curr%u alias failed, ret: %d\n", curr_index, ret);
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t curr_sensor_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
unsigned int curr_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_curr_sensor_drv);
|
||||||
|
check_p(g_curr_sensor_drv->get_main_board_curr_type);
|
||||||
|
|
||||||
|
curr_index = obj->index;
|
||||||
|
CURR_SENSOR_DBG("curr index: %u\n", curr_index);
|
||||||
|
ret = g_curr_sensor_drv->get_main_board_curr_type(curr_index, buf, PAGE_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
CURR_SENSOR_ERR("get curr%u type failed, ret: %d\n", curr_index, ret);
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t curr_sensor_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
unsigned int curr_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_curr_sensor_drv);
|
||||||
|
check_p(g_curr_sensor_drv->get_main_board_curr_max);
|
||||||
|
|
||||||
|
curr_index = obj->index;
|
||||||
|
CURR_SENSOR_DBG("curr index: %u\n", curr_index);
|
||||||
|
ret = g_curr_sensor_drv->get_main_board_curr_max(curr_index, buf, PAGE_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
CURR_SENSOR_ERR("get curr%u max threshold failed, ret: %d\n", curr_index, ret);
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t curr_sensor_max_store(struct switch_obj *obj, struct switch_attribute *attr,
|
||||||
|
const char* buf, size_t count)
|
||||||
|
{
|
||||||
|
unsigned int curr_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_curr_sensor_drv);
|
||||||
|
check_p(g_curr_sensor_drv->set_main_board_curr_max);
|
||||||
|
|
||||||
|
curr_index = obj->index;
|
||||||
|
CURR_SENSOR_DBG("curr index: %u\n", curr_index);
|
||||||
|
ret = g_curr_sensor_drv->set_main_board_curr_max(curr_index, buf, count);
|
||||||
|
if (ret < 0) {
|
||||||
|
CURR_SENSOR_ERR("set curr%u max threshold failed, value: %s, count: %lu, ret: %d\n",
|
||||||
|
curr_index, buf, count, ret);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
CURR_SENSOR_DBG("set curr%u max threshold success, value: %s, count: %lu, ret: %d\n",
|
||||||
|
curr_index, buf, count, ret);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t curr_sensor_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
unsigned int curr_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_curr_sensor_drv);
|
||||||
|
check_p(g_curr_sensor_drv->get_main_board_curr_min);
|
||||||
|
|
||||||
|
curr_index = obj->index;
|
||||||
|
CURR_SENSOR_DBG("curr index: %u\n", curr_index);
|
||||||
|
ret = g_curr_sensor_drv->get_main_board_curr_min(curr_index, buf, PAGE_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
CURR_SENSOR_ERR("get curr%u min threshold failed, ret: %d\n", curr_index, ret);
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t curr_sensor_min_store(struct switch_obj *obj, struct switch_attribute *attr,
|
||||||
|
const char* buf, size_t count)
|
||||||
|
{
|
||||||
|
unsigned int curr_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_curr_sensor_drv);
|
||||||
|
check_p(g_curr_sensor_drv->set_main_board_curr_min);
|
||||||
|
|
||||||
|
curr_index = obj->index;
|
||||||
|
CURR_SENSOR_DBG("curr index: %u\n", curr_index);
|
||||||
|
ret = g_curr_sensor_drv->set_main_board_curr_min(curr_index, buf, count);
|
||||||
|
if (ret < 0) {
|
||||||
|
CURR_SENSOR_ERR("set curr%u min threshold failed, value: %s, count: %lu, ret: %d\n",
|
||||||
|
curr_index, buf, count, ret);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
CURR_SENSOR_DBG("set curr%u min threshold success, value: %s, count: %lu, ret: %d\n",
|
||||||
|
curr_index, buf, count, ret);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************curr_sensor dir and attrs*******************************************/
|
||||||
|
static struct switch_attribute num_curr_att = __ATTR(number, S_IRUGO, curr_sensor_number_show, NULL);
|
||||||
|
|
||||||
|
static struct attribute *curr_sensor_dir_attrs[] = {
|
||||||
|
&num_curr_att.attr,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct attribute_group curr_sensor_root_attr_group = {
|
||||||
|
.attrs = curr_sensor_dir_attrs,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************curr1 curr2 dir and attrs*******************************************/
|
||||||
|
static struct switch_attribute curr_value_attr = __ATTR(value, S_IRUGO, curr_sensor_value_show, NULL);
|
||||||
|
static struct switch_attribute curr_alias_attr = __ATTR(alias, S_IRUGO, curr_sensor_alias_show, NULL);
|
||||||
|
static struct switch_attribute curr_type_attr = __ATTR(type, S_IRUGO, curr_sensor_type_show, NULL);
|
||||||
|
static struct switch_attribute curr_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, curr_sensor_max_show, curr_sensor_max_store);
|
||||||
|
static struct switch_attribute curr_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, curr_sensor_min_show, curr_sensor_min_store);
|
||||||
|
|
||||||
|
static struct attribute *curr_sensor_attrs[] = {
|
||||||
|
&curr_value_attr.attr,
|
||||||
|
&curr_alias_attr.attr,
|
||||||
|
&curr_type_attr.attr,
|
||||||
|
&curr_max_attr.attr,
|
||||||
|
&curr_min_attr.attr,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct attribute_group curr_sensor_attr_group = {
|
||||||
|
.attrs = curr_sensor_attrs,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int curr_sensor_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index)
|
||||||
|
{
|
||||||
|
char name[DIR_NAME_MAX_LEN];
|
||||||
|
struct curr_sensor_obj_s *curr_sensor;
|
||||||
|
|
||||||
|
curr_sensor = &g_curr_sensor.curr[index - 1];
|
||||||
|
memset(name, 0, sizeof(name));
|
||||||
|
snprintf(name, sizeof(name), "curr%u", index);
|
||||||
|
curr_sensor->obj = switch_kobject_create(name, parent);
|
||||||
|
if (!curr_sensor->obj) {
|
||||||
|
CURR_SENSOR_ERR("create %s object error.\n", name);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
curr_sensor->obj->index = index;
|
||||||
|
if (sysfs_create_group(&curr_sensor->obj->kobj, &curr_sensor_attr_group) != 0) {
|
||||||
|
CURR_SENSOR_ERR("create %s attrs error.\n", name);
|
||||||
|
switch_kobject_delete(&curr_sensor->obj);
|
||||||
|
return -EBADRQC;
|
||||||
|
}
|
||||||
|
CURR_SENSOR_DBG("create %s dir and attrs success.\n", name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void curr_sensor_sub_single_remove_kobj_and_attrs(unsigned int index)
|
||||||
|
{
|
||||||
|
struct curr_sensor_obj_s *curr_sensor;
|
||||||
|
|
||||||
|
curr_sensor = &g_curr_sensor.curr[index - 1];
|
||||||
|
if (curr_sensor->obj) {
|
||||||
|
sysfs_remove_group(&curr_sensor->obj->kobj, &curr_sensor_attr_group);
|
||||||
|
switch_kobject_delete(&curr_sensor->obj);
|
||||||
|
CURR_SENSOR_DBG("delete curr%u dir and attrs success.\n", index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int curr_sensor_sub_create_kobj_and_attrs(struct kobject *parent, int curr_num)
|
||||||
|
{
|
||||||
|
unsigned int curr_index, i;
|
||||||
|
|
||||||
|
g_curr_sensor.curr = kzalloc(sizeof(struct curr_sensor_obj_s) * curr_num, GFP_KERNEL);
|
||||||
|
if (!g_curr_sensor.curr) {
|
||||||
|
CURR_SENSOR_ERR("kzalloc g_curr_sensor.curr error, curr number: %d.\n", curr_num);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (curr_index = 1; curr_index <= curr_num; curr_index++) {
|
||||||
|
if (curr_sensor_sub_single_create_kobj_and_attrs(parent, curr_index) != 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
for (i = curr_index; i > 0; i--) {
|
||||||
|
curr_sensor_sub_single_remove_kobj_and_attrs(i);
|
||||||
|
}
|
||||||
|
kfree(g_curr_sensor.curr);
|
||||||
|
g_curr_sensor.curr = NULL;
|
||||||
|
return -EBADRQC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create curr[1-n] directory and attributes*/
|
||||||
|
static int curr_sensor_sub_create(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = curr_sensor_sub_create_kobj_and_attrs(&g_curr_sensor_obj->kobj,
|
||||||
|
g_curr_sensor.curr_number);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* delete curr[1-n] directory and attributes*/
|
||||||
|
static void curr_sensor_sub_remove(void)
|
||||||
|
{
|
||||||
|
unsigned int curr_index;
|
||||||
|
|
||||||
|
if (g_curr_sensor.curr) {
|
||||||
|
for (curr_index = g_curr_sensor.curr_number; curr_index > 0; curr_index--) {
|
||||||
|
curr_sensor_sub_single_remove_kobj_and_attrs(curr_index);
|
||||||
|
}
|
||||||
|
kfree(g_curr_sensor.curr);
|
||||||
|
g_curr_sensor.curr = NULL;
|
||||||
|
}
|
||||||
|
g_curr_sensor.curr_number = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create curr_sensor directory and number attributes */
|
||||||
|
static int curr_sensor_root_create(void)
|
||||||
|
{
|
||||||
|
g_curr_sensor_obj = switch_kobject_create("curr_sensor", NULL);
|
||||||
|
if (!g_curr_sensor_obj) {
|
||||||
|
CURR_SENSOR_ERR("switch_kobject_create curr_sensor error!\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sysfs_create_group(&g_curr_sensor_obj->kobj, &curr_sensor_root_attr_group) != 0) {
|
||||||
|
switch_kobject_delete(&g_curr_sensor_obj);
|
||||||
|
CURR_SENSOR_ERR("create curr_sensor dir attrs error!\n");
|
||||||
|
return -EBADRQC;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* delete curr_sensor directory and number attributes */
|
||||||
|
static void curr_sensor_root_remove(void)
|
||||||
|
{
|
||||||
|
if (g_curr_sensor_obj) {
|
||||||
|
sysfs_remove_group(&g_curr_sensor_obj->kobj, &curr_sensor_root_attr_group);
|
||||||
|
switch_kobject_delete(&g_curr_sensor_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int s3ip_sysfs_curr_sensor_drivers_register(struct s3ip_sysfs_curr_sensor_drivers_s *drv)
|
||||||
|
{
|
||||||
|
int ret, curr_num;
|
||||||
|
|
||||||
|
CURR_SENSOR_INFO("s3ip_sysfs_curr_sensor_drivers_register...\n");
|
||||||
|
if (g_curr_sensor_drv) {
|
||||||
|
CURR_SENSOR_ERR("g_curr_sensor_drv is not NULL, can't register\n");
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
check_p(drv);
|
||||||
|
check_p(drv->get_main_board_curr_number);
|
||||||
|
g_curr_sensor_drv = drv;
|
||||||
|
|
||||||
|
curr_num = g_curr_sensor_drv->get_main_board_curr_number();
|
||||||
|
if (curr_num <= 0) {
|
||||||
|
CURR_SENSOR_ERR("curr sensor number: %d, don't need to create curr_sensor dirs and attrs.\n",
|
||||||
|
curr_num);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
memset(&g_curr_sensor, 0, sizeof(struct curr_sensor_s));
|
||||||
|
g_curr_sensor.curr_number = curr_num;
|
||||||
|
ret = curr_sensor_root_create();
|
||||||
|
if (ret < 0) {
|
||||||
|
CURR_SENSOR_ERR("create curr_sensor root dir and attrs failed, ret: %d\n", ret);
|
||||||
|
g_curr_sensor_drv = NULL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = curr_sensor_sub_create();
|
||||||
|
if (ret < 0) {
|
||||||
|
CURR_SENSOR_ERR("create curr_sensor sub dir and attrs failed, ret: %d\n", ret);
|
||||||
|
curr_sensor_root_remove();
|
||||||
|
g_curr_sensor_drv = NULL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
CURR_SENSOR_INFO("s3ip_sysfs_curr_sensor_drivers_register success\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void s3ip_sysfs_curr_sensor_drivers_unregister(void)
|
||||||
|
{
|
||||||
|
if (g_curr_sensor_drv) {
|
||||||
|
curr_sensor_sub_remove();
|
||||||
|
curr_sensor_root_remove();
|
||||||
|
g_curr_sensor_drv = NULL;
|
||||||
|
CURR_SENSOR_DBG("s3ip_sysfs_curr_sensor_drivers_unregister success.\n");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(s3ip_sysfs_curr_sensor_drivers_register);
|
||||||
|
EXPORT_SYMBOL(s3ip_sysfs_curr_sensor_drivers_unregister);
|
||||||
|
module_param(g_curr_sensor_loglevel, int, 0644);
|
||||||
|
MODULE_PARM_DESC(g_curr_sensor_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n");
|
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef _CURR_SENSOR_SYSFS_H_
|
||||||
|
#define _CURR_SENSOR_SYSFS_H_
|
||||||
|
|
||||||
|
struct s3ip_sysfs_curr_sensor_drivers_s {
|
||||||
|
int (*get_main_board_curr_number)(void);
|
||||||
|
ssize_t (*get_main_board_curr_alias)(unsigned int curr_index, char *buf, size_t count);
|
||||||
|
ssize_t (*get_main_board_curr_type)(unsigned int curr_index, char *buf, size_t count);
|
||||||
|
ssize_t (*get_main_board_curr_max)(unsigned int curr_index, char *buf, size_t count);
|
||||||
|
int (*set_main_board_curr_max)(unsigned int curr_index, const char *buf, size_t count);
|
||||||
|
ssize_t (*get_main_board_curr_min)(unsigned int curr_index, char *buf, size_t count);
|
||||||
|
int (*set_main_board_curr_min)(unsigned int curr_index, const char *buf, size_t count);
|
||||||
|
ssize_t (*get_main_board_curr_value)(unsigned int curr_index, char *buf, size_t count);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int s3ip_sysfs_curr_sensor_drivers_register(struct s3ip_sysfs_curr_sensor_drivers_s *drv);
|
||||||
|
extern void s3ip_sysfs_curr_sensor_drivers_unregister(void);
|
||||||
|
#endif /*_CURR_SENSOR_SYSFS_H_ */
|
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef _TEMP_SENSOR_SYSFS_H_
|
||||||
|
#define _TEMP_SENSOR_SYSFS_H_
|
||||||
|
|
||||||
|
struct s3ip_sysfs_temp_sensor_drivers_s {
|
||||||
|
int (*get_main_board_temp_number)(void);
|
||||||
|
ssize_t (*get_main_board_temp_alias)(unsigned int temp_index, char *buf, size_t count);
|
||||||
|
ssize_t (*get_main_board_temp_type)(unsigned int temp_index, char *buf, size_t count);
|
||||||
|
ssize_t (*get_main_board_temp_max)(unsigned int temp_index, char *buf, size_t count);
|
||||||
|
int (*set_main_board_temp_max)(unsigned int temp_index, const char *buf, size_t count);
|
||||||
|
ssize_t (*get_main_board_temp_min)(unsigned int temp_index, char *buf, size_t count);
|
||||||
|
int (*set_main_board_temp_min)(unsigned int temp_index, const char *buf, size_t count);
|
||||||
|
ssize_t (*get_main_board_temp_value)(unsigned int temp_index, char *buf, size_t count);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int s3ip_sysfs_temp_sensor_drivers_register(struct s3ip_sysfs_temp_sensor_drivers_s *drv);
|
||||||
|
extern void s3ip_sysfs_temp_sensor_drivers_unregister(void);
|
||||||
|
#endif /*_TEMP_SENSOR_SYSFS_H_ */
|
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef _VOL_SENSOR_SYSFS_H_
|
||||||
|
#define _VOL_SENSOR_SYSFS_H_
|
||||||
|
|
||||||
|
struct s3ip_sysfs_vol_sensor_drivers_s {
|
||||||
|
int (*get_main_board_vol_number)(void);
|
||||||
|
ssize_t (*get_main_board_vol_alias)(unsigned int vol_index, char *buf, size_t count);
|
||||||
|
ssize_t (*get_main_board_vol_type)(unsigned int vol_index, char *buf, size_t count);
|
||||||
|
ssize_t (*get_main_board_vol_max)(unsigned int vol_index, char *buf, size_t count);
|
||||||
|
int (*set_main_board_vol_max)(unsigned int vol_index, const char *buf, size_t count);
|
||||||
|
ssize_t (*get_main_board_vol_min)(unsigned int vol_index, char *buf, size_t count);
|
||||||
|
int (*set_main_board_vol_min)(unsigned int vol_index, const char *buf, size_t count);
|
||||||
|
ssize_t (*get_main_board_vol_range)(unsigned int vol_index, char *buf, size_t count);
|
||||||
|
ssize_t (*get_main_board_vol_nominal_value)(unsigned int vol_index, char *buf, size_t count);
|
||||||
|
ssize_t (*get_main_board_vol_value)(unsigned int vol_index, char *buf, size_t count);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int s3ip_sysfs_vol_sensor_drivers_register(struct s3ip_sysfs_vol_sensor_drivers_s *drv);
|
||||||
|
extern void s3ip_sysfs_vol_sensor_drivers_unregister(void);
|
||||||
|
#endif /*_VOL_SENSOR_SYSFS_H_ */
|
392
platform/s3ip-sysfs/s3ip_sysfs_frame/temp_sensor_sysfs.c
Normal file
392
platform/s3ip-sysfs/s3ip_sysfs_frame/temp_sensor_sysfs.c
Normal file
@ -0,0 +1,392 @@
|
|||||||
|
/*
|
||||||
|
* temp_sensor_sysfs.c
|
||||||
|
*
|
||||||
|
* This module create temp sensor kobjects and attributes in /sys/s3ip/temp_sensor
|
||||||
|
*
|
||||||
|
* History
|
||||||
|
* [Version] [Date] [Description]
|
||||||
|
* * v1.0 2021-08-31 S3IP sysfs
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
#include "switch.h"
|
||||||
|
#include "temp_sensor_sysfs.h"
|
||||||
|
|
||||||
|
static int g_temp_sensor_loglevel = 0;
|
||||||
|
|
||||||
|
#define TEMP_SENSOR_INFO(fmt, args...) do { \
|
||||||
|
if (g_temp_sensor_loglevel & INFO) { \
|
||||||
|
printk(KERN_INFO "[TEMP_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define TEMP_SENSOR_ERR(fmt, args...) do { \
|
||||||
|
if (g_temp_sensor_loglevel & ERR) { \
|
||||||
|
printk(KERN_ERR "[TEMP_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define TEMP_SENSOR_DBG(fmt, args...) do { \
|
||||||
|
if (g_temp_sensor_loglevel & DBG) { \
|
||||||
|
printk(KERN_DEBUG "[TEMP_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
struct temp_sensor_obj_s {
|
||||||
|
struct switch_obj *obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct temp_sensor_s {
|
||||||
|
unsigned int temp_number;
|
||||||
|
struct temp_sensor_obj_s *temp;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct s3ip_sysfs_temp_sensor_drivers_s *g_temp_sensor_drv = NULL;
|
||||||
|
static struct temp_sensor_s g_temp_sensor;
|
||||||
|
static struct switch_obj *g_temp_sensor_obj = NULL;
|
||||||
|
|
||||||
|
static ssize_t temp_sensor_number_show(struct switch_obj *obj, struct switch_attribute *attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_temp_sensor.temp_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t temp_sensor_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
unsigned int temp_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_temp_sensor_drv);
|
||||||
|
check_p(g_temp_sensor_drv->get_main_board_temp_value);
|
||||||
|
|
||||||
|
temp_index = obj->index;
|
||||||
|
TEMP_SENSOR_DBG("temp index: %u\n", temp_index);
|
||||||
|
ret = g_temp_sensor_drv->get_main_board_temp_value(temp_index, buf, PAGE_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
TEMP_SENSOR_ERR("get temp%u value failed, ret: %d\n", temp_index, ret);
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t temp_sensor_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
unsigned int temp_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_temp_sensor_drv);
|
||||||
|
check_p(g_temp_sensor_drv->get_main_board_temp_alias);
|
||||||
|
|
||||||
|
temp_index = obj->index;
|
||||||
|
TEMP_SENSOR_DBG("temp index: %u\n", temp_index);
|
||||||
|
ret = g_temp_sensor_drv->get_main_board_temp_alias(temp_index, buf, PAGE_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
TEMP_SENSOR_ERR("get temp%u alias failed, ret: %d\n", temp_index, ret);
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t temp_sensor_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
unsigned int temp_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_temp_sensor_drv);
|
||||||
|
check_p(g_temp_sensor_drv->get_main_board_temp_type);
|
||||||
|
|
||||||
|
temp_index = obj->index;
|
||||||
|
TEMP_SENSOR_DBG("temp index: %u\n", temp_index);
|
||||||
|
ret = g_temp_sensor_drv->get_main_board_temp_type(temp_index, buf, PAGE_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
TEMP_SENSOR_ERR("get temp%u type failed, ret: %d\n", temp_index, ret);
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t temp_sensor_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
unsigned int temp_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_temp_sensor_drv);
|
||||||
|
check_p(g_temp_sensor_drv->get_main_board_temp_max);
|
||||||
|
|
||||||
|
temp_index = obj->index;
|
||||||
|
TEMP_SENSOR_DBG("temp index: %u\n", temp_index);
|
||||||
|
ret = g_temp_sensor_drv->get_main_board_temp_max(temp_index, buf, PAGE_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
TEMP_SENSOR_ERR("get temp%u max threshold failed, ret: %d\n", temp_index, ret);
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t temp_sensor_max_store(struct switch_obj *obj, struct switch_attribute *attr,
|
||||||
|
const char* buf, size_t count)
|
||||||
|
{
|
||||||
|
unsigned int temp_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_temp_sensor_drv);
|
||||||
|
check_p(g_temp_sensor_drv->set_main_board_temp_max);
|
||||||
|
|
||||||
|
temp_index = obj->index;
|
||||||
|
TEMP_SENSOR_DBG("temp index: %u\n", temp_index);
|
||||||
|
ret = g_temp_sensor_drv->set_main_board_temp_max(temp_index, buf, count);
|
||||||
|
if (ret < 0) {
|
||||||
|
TEMP_SENSOR_ERR("set temp%u max threshold failed, value: %s, count: %lu, ret: %d\n",
|
||||||
|
temp_index, buf, count, ret);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
TEMP_SENSOR_DBG("set temp%u max threshold success, value: %s, count: %lu, ret: %d\n",
|
||||||
|
temp_index, buf, count, ret);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t temp_sensor_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
unsigned int temp_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_temp_sensor_drv);
|
||||||
|
check_p(g_temp_sensor_drv->get_main_board_temp_min);
|
||||||
|
|
||||||
|
temp_index = obj->index;
|
||||||
|
TEMP_SENSOR_DBG("temp index: %u\n", temp_index);
|
||||||
|
ret = g_temp_sensor_drv->get_main_board_temp_min(temp_index, buf, PAGE_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
TEMP_SENSOR_ERR("get temp%u min threshold failed, ret: %d\n", temp_index, ret);
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t temp_sensor_min_store(struct switch_obj *obj, struct switch_attribute *attr,
|
||||||
|
const char* buf, size_t count)
|
||||||
|
{
|
||||||
|
unsigned int temp_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_temp_sensor_drv);
|
||||||
|
check_p(g_temp_sensor_drv->set_main_board_temp_min);
|
||||||
|
|
||||||
|
temp_index = obj->index;
|
||||||
|
TEMP_SENSOR_DBG("temp index: %u\n", temp_index);
|
||||||
|
ret = g_temp_sensor_drv->set_main_board_temp_min(temp_index, buf, count);
|
||||||
|
if (ret < 0) {
|
||||||
|
TEMP_SENSOR_ERR("set temp%u min threshold failed, value: %s, count: %lu, ret: %d\n",
|
||||||
|
temp_index, buf, count, ret);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
TEMP_SENSOR_DBG("set temp%u min threshold success, value: %s, count: %lu, ret: %d\n",
|
||||||
|
temp_index, buf, count, ret);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************temp_sensor dir and attrs*******************************************/
|
||||||
|
static struct switch_attribute num_temp_att = __ATTR(number, S_IRUGO, temp_sensor_number_show, NULL);
|
||||||
|
|
||||||
|
static struct attribute *temp_sensor_dir_attrs[] = {
|
||||||
|
&num_temp_att.attr,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct attribute_group temp_sensor_root_attr_group = {
|
||||||
|
.attrs = temp_sensor_dir_attrs,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************temp1 temp2 dir and attrs*******************************************/
|
||||||
|
static struct switch_attribute temp_value_attr = __ATTR(value, S_IRUGO, temp_sensor_value_show, NULL);
|
||||||
|
static struct switch_attribute temp_alias_attr = __ATTR(alias, S_IRUGO, temp_sensor_alias_show, NULL);
|
||||||
|
static struct switch_attribute temp_type_attr = __ATTR(type, S_IRUGO, temp_sensor_type_show, NULL);
|
||||||
|
static struct switch_attribute temp_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, temp_sensor_max_show, temp_sensor_max_store);
|
||||||
|
static struct switch_attribute temp_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, temp_sensor_min_show, temp_sensor_min_store);
|
||||||
|
|
||||||
|
static struct attribute *temp_sensor_attrs[] = {
|
||||||
|
&temp_value_attr.attr,
|
||||||
|
&temp_alias_attr.attr,
|
||||||
|
&temp_type_attr.attr,
|
||||||
|
&temp_max_attr.attr,
|
||||||
|
&temp_min_attr.attr,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct attribute_group temp_sensor_attr_group = {
|
||||||
|
.attrs = temp_sensor_attrs,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int temp_sensor_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index)
|
||||||
|
{
|
||||||
|
char name[DIR_NAME_MAX_LEN];
|
||||||
|
struct temp_sensor_obj_s *temp_sensor;
|
||||||
|
|
||||||
|
temp_sensor = &g_temp_sensor.temp[index - 1];
|
||||||
|
memset(name, 0, sizeof(name));
|
||||||
|
snprintf(name, sizeof(name), "temp%u", index);
|
||||||
|
temp_sensor->obj = switch_kobject_create(name, parent);
|
||||||
|
if (!temp_sensor->obj) {
|
||||||
|
TEMP_SENSOR_ERR("create %s object error.\n", name);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
temp_sensor->obj->index = index;
|
||||||
|
if (sysfs_create_group(&temp_sensor->obj->kobj, &temp_sensor_attr_group) != 0) {
|
||||||
|
TEMP_SENSOR_ERR("create %s attrs error.\n", name);
|
||||||
|
switch_kobject_delete(&temp_sensor->obj);
|
||||||
|
return -EBADRQC;
|
||||||
|
}
|
||||||
|
TEMP_SENSOR_DBG("create %s dir and attrs success.\n", name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void temp_sensor_sub_single_remove_kobj_and_attrs(unsigned int index)
|
||||||
|
{
|
||||||
|
struct temp_sensor_obj_s *temp_sensor;
|
||||||
|
|
||||||
|
temp_sensor = &g_temp_sensor.temp[index - 1];
|
||||||
|
if (temp_sensor->obj) {
|
||||||
|
sysfs_remove_group(&temp_sensor->obj->kobj, &temp_sensor_attr_group);
|
||||||
|
switch_kobject_delete(&temp_sensor->obj);
|
||||||
|
TEMP_SENSOR_DBG("delete temp%u dir and attrs success.\n", index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int temp_sensor_sub_create_kobj_and_attrs(struct kobject *parent, int temp_num)
|
||||||
|
{
|
||||||
|
unsigned int temp_index, i;
|
||||||
|
|
||||||
|
g_temp_sensor.temp = kzalloc(sizeof(struct temp_sensor_obj_s) * temp_num, GFP_KERNEL);
|
||||||
|
if (!g_temp_sensor.temp) {
|
||||||
|
TEMP_SENSOR_ERR("kzalloc g_temp_sensor.temp error, temp number: %d.\n", temp_num);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (temp_index = 1; temp_index <= temp_num; temp_index++) {
|
||||||
|
if (temp_sensor_sub_single_create_kobj_and_attrs(parent, temp_index) != 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
for (i = temp_index; i > 0; i--) {
|
||||||
|
temp_sensor_sub_single_remove_kobj_and_attrs(i);
|
||||||
|
}
|
||||||
|
kfree(g_temp_sensor.temp);
|
||||||
|
g_temp_sensor.temp = NULL;
|
||||||
|
return -EBADRQC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create temp[1-n] directory and attributes*/
|
||||||
|
static int temp_sensor_sub_create(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = temp_sensor_sub_create_kobj_and_attrs(&g_temp_sensor_obj->kobj,
|
||||||
|
g_temp_sensor.temp_number);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* delete temp[1-n] directory and attributes*/
|
||||||
|
static void temp_sensor_sub_remove(void)
|
||||||
|
{
|
||||||
|
unsigned int temp_index;
|
||||||
|
|
||||||
|
if (g_temp_sensor.temp) {
|
||||||
|
for (temp_index = g_temp_sensor.temp_number; temp_index > 0; temp_index--) {
|
||||||
|
temp_sensor_sub_single_remove_kobj_and_attrs(temp_index);
|
||||||
|
}
|
||||||
|
kfree(g_temp_sensor.temp);
|
||||||
|
g_temp_sensor.temp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create temp_sensor directory and number attributes */
|
||||||
|
static int temp_sensor_root_create(void)
|
||||||
|
{
|
||||||
|
g_temp_sensor_obj = switch_kobject_create("temp_sensor", NULL);
|
||||||
|
if (!g_temp_sensor_obj) {
|
||||||
|
TEMP_SENSOR_ERR("switch_kobject_create temp_sensor error!\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sysfs_create_group(&g_temp_sensor_obj->kobj, &temp_sensor_root_attr_group) != 0) {
|
||||||
|
switch_kobject_delete(&g_temp_sensor_obj);
|
||||||
|
TEMP_SENSOR_ERR("create temp_sensor dir attrs error!\n");
|
||||||
|
return -EBADRQC;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* delete temp_sensor directory and number attributes */
|
||||||
|
static void temp_sensor_root_remove(void)
|
||||||
|
{
|
||||||
|
if (g_temp_sensor_obj) {
|
||||||
|
sysfs_remove_group(&g_temp_sensor_obj->kobj, &temp_sensor_root_attr_group);
|
||||||
|
switch_kobject_delete(&g_temp_sensor_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int s3ip_sysfs_temp_sensor_drivers_register(struct s3ip_sysfs_temp_sensor_drivers_s *drv)
|
||||||
|
{
|
||||||
|
int ret, temp_num;
|
||||||
|
|
||||||
|
TEMP_SENSOR_INFO("s3ip_sysfs_temp_sensor_drivers_register...\n");
|
||||||
|
if (g_temp_sensor_drv) {
|
||||||
|
TEMP_SENSOR_ERR("g_temp_sensor_drv is not NULL, can't register\n");
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
check_p(drv);
|
||||||
|
check_p(drv->get_main_board_temp_number);
|
||||||
|
g_temp_sensor_drv = drv;
|
||||||
|
|
||||||
|
temp_num = g_temp_sensor_drv->get_main_board_temp_number();
|
||||||
|
if (temp_num <= 0) {
|
||||||
|
TEMP_SENSOR_ERR("temp sensor number: %d, don't need to create temp_sensor dirs and attrs.\n",
|
||||||
|
temp_num);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
memset(&g_temp_sensor, 0, sizeof(struct temp_sensor_s));
|
||||||
|
g_temp_sensor.temp_number = temp_num;
|
||||||
|
ret = temp_sensor_root_create();
|
||||||
|
if (ret < 0) {
|
||||||
|
TEMP_SENSOR_ERR("create temp_sensor root dir and attrs failed, ret: %d\n", ret);
|
||||||
|
g_temp_sensor_drv = NULL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = temp_sensor_sub_create();
|
||||||
|
if (ret < 0) {
|
||||||
|
TEMP_SENSOR_ERR("create temp_sensor sub dir and attrs failed, ret: %d\n", ret);
|
||||||
|
temp_sensor_root_remove();
|
||||||
|
g_temp_sensor_drv = NULL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
TEMP_SENSOR_INFO("s3ip_sysfs_temp_sensor_drivers_register success\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void s3ip_sysfs_temp_sensor_drivers_unregister(void)
|
||||||
|
{
|
||||||
|
if (g_temp_sensor_drv) {
|
||||||
|
temp_sensor_sub_remove();
|
||||||
|
temp_sensor_root_remove();
|
||||||
|
g_temp_sensor_drv = NULL;
|
||||||
|
TEMP_SENSOR_DBG("s3ip_sysfs_temp_sensor_drivers_unregister success.\n");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(s3ip_sysfs_temp_sensor_drivers_register);
|
||||||
|
EXPORT_SYMBOL(s3ip_sysfs_temp_sensor_drivers_unregister);
|
||||||
|
module_param(g_temp_sensor_loglevel, int, 0644);
|
||||||
|
MODULE_PARM_DESC(g_temp_sensor_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n");
|
434
platform/s3ip-sysfs/s3ip_sysfs_frame/vol_sensor_sysfs.c
Normal file
434
platform/s3ip-sysfs/s3ip_sysfs_frame/vol_sensor_sysfs.c
Normal file
@ -0,0 +1,434 @@
|
|||||||
|
/*
|
||||||
|
* vol_sensor_sysfs.c
|
||||||
|
*
|
||||||
|
* This module create vol sensor kobjects and attributes in /sys/s3ip/vol_sensor
|
||||||
|
*
|
||||||
|
* History
|
||||||
|
* [Version] [Date] [Description]
|
||||||
|
* * v1.0 2021-08-31 S3IP sysfs
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
#include "switch.h"
|
||||||
|
#include "vol_sensor_sysfs.h"
|
||||||
|
|
||||||
|
static int g_vol_sensor_loglevel = 0;
|
||||||
|
|
||||||
|
#define VOL_SENSOR_INFO(fmt, args...) do { \
|
||||||
|
if (g_vol_sensor_loglevel & INFO) { \
|
||||||
|
printk(KERN_INFO "[VOL_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define VOL_SENSOR_ERR(fmt, args...) do { \
|
||||||
|
if (g_vol_sensor_loglevel & ERR) { \
|
||||||
|
printk(KERN_ERR "[VOL_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define VOL_SENSOR_DBG(fmt, args...) do { \
|
||||||
|
if (g_vol_sensor_loglevel & DBG) { \
|
||||||
|
printk(KERN_DEBUG "[VOL_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
struct vol_sensor_obj_s {
|
||||||
|
struct switch_obj *obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct vol_sensor_s {
|
||||||
|
unsigned int vol_number;
|
||||||
|
struct vol_sensor_obj_s *vol;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct s3ip_sysfs_vol_sensor_drivers_s *g_vol_sensor_drv = NULL;
|
||||||
|
static struct vol_sensor_s g_vol_sensor;
|
||||||
|
static struct switch_obj *g_vol_sensor_obj = NULL;
|
||||||
|
|
||||||
|
static ssize_t vol_sensor_number_show(struct switch_obj *obj, struct switch_attribute *attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_vol_sensor.vol_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t vol_sensor_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
unsigned int vol_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_vol_sensor_drv);
|
||||||
|
check_p(g_vol_sensor_drv->get_main_board_vol_value);
|
||||||
|
|
||||||
|
vol_index = obj->index;
|
||||||
|
VOL_SENSOR_DBG("vol index: %u\n", vol_index);
|
||||||
|
ret = g_vol_sensor_drv->get_main_board_vol_value(vol_index, buf, PAGE_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
VOL_SENSOR_ERR("get vol%u value failed, ret: %d\n", vol_index, ret);
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t vol_sensor_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
unsigned int vol_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_vol_sensor_drv);
|
||||||
|
check_p(g_vol_sensor_drv->get_main_board_vol_alias);
|
||||||
|
|
||||||
|
vol_index = obj->index;
|
||||||
|
VOL_SENSOR_DBG("vol index: %u\n", vol_index);
|
||||||
|
ret = g_vol_sensor_drv->get_main_board_vol_alias(vol_index, buf, PAGE_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
VOL_SENSOR_ERR("get vol%u alias failed, ret: %d\n", vol_index, ret);
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t vol_sensor_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
unsigned int vol_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_vol_sensor_drv);
|
||||||
|
check_p(g_vol_sensor_drv->get_main_board_vol_type);
|
||||||
|
|
||||||
|
vol_index = obj->index;
|
||||||
|
VOL_SENSOR_DBG("vol index: %u\n", vol_index);
|
||||||
|
ret = g_vol_sensor_drv->get_main_board_vol_type(vol_index, buf, PAGE_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
VOL_SENSOR_ERR("get vol%u type failed, ret: %d\n", vol_index, ret);
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t vol_sensor_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
unsigned int vol_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_vol_sensor_drv);
|
||||||
|
check_p(g_vol_sensor_drv->get_main_board_vol_max);
|
||||||
|
|
||||||
|
vol_index = obj->index;
|
||||||
|
VOL_SENSOR_DBG("vol index: %u\n", vol_index);
|
||||||
|
ret = g_vol_sensor_drv->get_main_board_vol_max(vol_index, buf, PAGE_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
VOL_SENSOR_ERR("get vol%u max threshold failed, ret: %d\n", vol_index, ret);
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t vol_sensor_max_store(struct switch_obj *obj, struct switch_attribute *attr,
|
||||||
|
const char* buf, size_t count)
|
||||||
|
{
|
||||||
|
unsigned int vol_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_vol_sensor_drv);
|
||||||
|
check_p(g_vol_sensor_drv->set_main_board_vol_max);
|
||||||
|
|
||||||
|
vol_index = obj->index;
|
||||||
|
VOL_SENSOR_DBG("vol index: %u\n", vol_index);
|
||||||
|
ret = g_vol_sensor_drv->set_main_board_vol_max(vol_index, buf, count);
|
||||||
|
if (ret < 0) {
|
||||||
|
VOL_SENSOR_ERR("set vol%u max threshold failed, value: %s, count: %lu, ret: %d\n",
|
||||||
|
vol_index, buf, count, ret);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
VOL_SENSOR_DBG("set vol%u max threshold success, value: %s, count: %lu, ret: %d\n",
|
||||||
|
vol_index, buf, count, ret);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t vol_sensor_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
unsigned int vol_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_vol_sensor_drv);
|
||||||
|
check_p(g_vol_sensor_drv->get_main_board_vol_min);
|
||||||
|
|
||||||
|
vol_index = obj->index;
|
||||||
|
VOL_SENSOR_DBG("vol index: %u\n", vol_index);
|
||||||
|
ret = g_vol_sensor_drv->get_main_board_vol_min(vol_index, buf, PAGE_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
VOL_SENSOR_ERR("get vol%u min threshold failed, ret: %d\n", vol_index, ret);
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t vol_sensor_min_store(struct switch_obj *obj, struct switch_attribute *attr,
|
||||||
|
const char* buf, size_t count)
|
||||||
|
{
|
||||||
|
unsigned int vol_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_vol_sensor_drv);
|
||||||
|
check_p(g_vol_sensor_drv->set_main_board_vol_min);
|
||||||
|
|
||||||
|
vol_index = obj->index;
|
||||||
|
VOL_SENSOR_DBG("vol index: %u\n", vol_index);
|
||||||
|
ret = g_vol_sensor_drv->set_main_board_vol_min(vol_index, buf, count);
|
||||||
|
if (ret < 0) {
|
||||||
|
VOL_SENSOR_ERR("set vol%u min threshold failed, value: %s, count: %lu, ret: %d\n",
|
||||||
|
vol_index, buf, count, ret);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
VOL_SENSOR_DBG("set vol%u min threshold success, value: %s, count: %lu, ret: %d\n",
|
||||||
|
vol_index, buf, count, ret);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t vol_sensor_range_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
unsigned int vol_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_vol_sensor_drv);
|
||||||
|
check_p(g_vol_sensor_drv->get_main_board_vol_range);
|
||||||
|
|
||||||
|
vol_index = obj->index;
|
||||||
|
VOL_SENSOR_DBG("vol index: %u\n", vol_index);
|
||||||
|
ret = g_vol_sensor_drv->get_main_board_vol_range(vol_index, buf, PAGE_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
VOL_SENSOR_ERR("get vol%u range failed, ret: %d\n", vol_index, ret);
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t vol_sensor_nominal_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
unsigned int vol_index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
check_p(g_vol_sensor_drv);
|
||||||
|
check_p(g_vol_sensor_drv->get_main_board_vol_nominal_value);
|
||||||
|
|
||||||
|
vol_index = obj->index;
|
||||||
|
VOL_SENSOR_DBG("vol index: %u\n", vol_index);
|
||||||
|
ret = g_vol_sensor_drv->get_main_board_vol_nominal_value(vol_index, buf, PAGE_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
VOL_SENSOR_ERR("get vol%u nominal value failed, ret: %d\n", vol_index, ret);
|
||||||
|
return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************vol_sensor dir and attrs*******************************************/
|
||||||
|
static struct switch_attribute num_vol_att = __ATTR(number, S_IRUGO, vol_sensor_number_show, NULL);
|
||||||
|
|
||||||
|
static struct attribute *vol_sensor_dir_attrs[] = {
|
||||||
|
&num_vol_att.attr,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct attribute_group vol_sensor_root_attr_group = {
|
||||||
|
.attrs = vol_sensor_dir_attrs,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************vol1 vol2 dir and attrs*******************************************/
|
||||||
|
static struct switch_attribute vol_value_attr = __ATTR(value, S_IRUGO, vol_sensor_value_show, NULL);
|
||||||
|
static struct switch_attribute vol_alias_attr = __ATTR(alias, S_IRUGO, vol_sensor_alias_show, NULL);
|
||||||
|
static struct switch_attribute vol_type_attr = __ATTR(type, S_IRUGO, vol_sensor_type_show, NULL);
|
||||||
|
static struct switch_attribute vol_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, vol_sensor_max_show, vol_sensor_max_store);
|
||||||
|
static struct switch_attribute vol_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, vol_sensor_min_show, vol_sensor_min_store);
|
||||||
|
static struct switch_attribute vol_range_attr = __ATTR(range, S_IRUGO, vol_sensor_range_show, NULL);
|
||||||
|
static struct switch_attribute vol_nominal_value_attr = __ATTR(nominal_value, S_IRUGO, vol_sensor_nominal_value_show, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
static struct attribute *vol_sensor_attrs[] = {
|
||||||
|
&vol_value_attr.attr,
|
||||||
|
&vol_alias_attr.attr,
|
||||||
|
&vol_type_attr.attr,
|
||||||
|
&vol_max_attr.attr,
|
||||||
|
&vol_min_attr.attr,
|
||||||
|
&vol_range_attr.attr,
|
||||||
|
&vol_nominal_value_attr.attr,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct attribute_group vol_sensor_attr_group = {
|
||||||
|
.attrs = vol_sensor_attrs,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int vol_sensor_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index)
|
||||||
|
{
|
||||||
|
char name[DIR_NAME_MAX_LEN];
|
||||||
|
struct vol_sensor_obj_s *vol_sensor;
|
||||||
|
|
||||||
|
vol_sensor = &g_vol_sensor.vol[index - 1];
|
||||||
|
memset(name, 0, sizeof(name));
|
||||||
|
snprintf(name, sizeof(name), "vol%u", index);
|
||||||
|
vol_sensor->obj = switch_kobject_create(name, parent);
|
||||||
|
if (!vol_sensor->obj) {
|
||||||
|
VOL_SENSOR_ERR("create %s object error.\n", name);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
vol_sensor->obj->index = index;
|
||||||
|
if (sysfs_create_group(&vol_sensor->obj->kobj, &vol_sensor_attr_group) != 0) {
|
||||||
|
VOL_SENSOR_ERR("create %s attrs error.\n", name);
|
||||||
|
switch_kobject_delete(&vol_sensor->obj);
|
||||||
|
return -EBADRQC;
|
||||||
|
}
|
||||||
|
VOL_SENSOR_DBG("create %s dir and attrs success.\n", name);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vol_sensor_sub_single_remove_kobj_and_attrs(unsigned int index)
|
||||||
|
{
|
||||||
|
struct vol_sensor_obj_s *vol_sensor;
|
||||||
|
|
||||||
|
vol_sensor = &g_vol_sensor.vol[index - 1];
|
||||||
|
if (vol_sensor->obj) {
|
||||||
|
sysfs_remove_group(&vol_sensor->obj->kobj, &vol_sensor_attr_group);
|
||||||
|
switch_kobject_delete(&vol_sensor->obj);
|
||||||
|
VOL_SENSOR_DBG("delete vol%u dir and attrs success.\n", index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vol_sensor_sub_create_kobj_and_attrs(struct kobject *parent, int vol_num)
|
||||||
|
{
|
||||||
|
unsigned int vol_index, i;
|
||||||
|
|
||||||
|
g_vol_sensor.vol = kzalloc(sizeof(struct vol_sensor_obj_s) * vol_num, GFP_KERNEL);
|
||||||
|
if (!g_vol_sensor.vol) {
|
||||||
|
VOL_SENSOR_ERR("kzalloc g_vol_sensor.vol error, vol number: %d.\n", vol_num);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (vol_index = 1; vol_index <= vol_num; vol_index++) {
|
||||||
|
if (vol_sensor_sub_single_create_kobj_and_attrs(parent, vol_index) != 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
for (i = vol_index; i > 0; i--) {
|
||||||
|
vol_sensor_sub_single_remove_kobj_and_attrs(i);
|
||||||
|
}
|
||||||
|
kfree(g_vol_sensor.vol);
|
||||||
|
g_vol_sensor.vol = NULL;
|
||||||
|
return -EBADRQC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create vol[1-n] directory and attributes*/
|
||||||
|
static int vol_sensor_sub_create(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = vol_sensor_sub_create_kobj_and_attrs(&g_vol_sensor_obj->kobj, g_vol_sensor.vol_number);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* delete vol[1-n] directory and attributes*/
|
||||||
|
static void vol_sensor_sub_remove(void)
|
||||||
|
{
|
||||||
|
unsigned int vol_index;
|
||||||
|
|
||||||
|
if (g_vol_sensor.vol) {
|
||||||
|
for (vol_index = g_vol_sensor.vol_number; vol_index > 0; vol_index--) {
|
||||||
|
vol_sensor_sub_single_remove_kobj_and_attrs(vol_index);
|
||||||
|
}
|
||||||
|
kfree(g_vol_sensor.vol);
|
||||||
|
g_vol_sensor.vol = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create vol_sensor directory and number attributes */
|
||||||
|
static int vol_sensor_root_create(void)
|
||||||
|
{
|
||||||
|
g_vol_sensor_obj = switch_kobject_create("vol_sensor", NULL);
|
||||||
|
if (!g_vol_sensor_obj) {
|
||||||
|
VOL_SENSOR_ERR("switch_kobject_create vol_sensor error!\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sysfs_create_group(&g_vol_sensor_obj->kobj, &vol_sensor_root_attr_group) != 0) {
|
||||||
|
switch_kobject_delete(&g_vol_sensor_obj);
|
||||||
|
VOL_SENSOR_ERR("create vol_sensor dir attrs error!\n");
|
||||||
|
return -EBADRQC;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* delete vol_sensor directory and number attributes */
|
||||||
|
static void vol_sensor_root_remove(void)
|
||||||
|
{
|
||||||
|
if (g_vol_sensor_obj) {
|
||||||
|
sysfs_remove_group(&g_vol_sensor_obj->kobj, &vol_sensor_root_attr_group);
|
||||||
|
switch_kobject_delete(&g_vol_sensor_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int s3ip_sysfs_vol_sensor_drivers_register(struct s3ip_sysfs_vol_sensor_drivers_s *drv)
|
||||||
|
{
|
||||||
|
int ret, vol_num;
|
||||||
|
|
||||||
|
VOL_SENSOR_INFO("s3ip_sysfs_vol_sensor_drivers_register...\n");
|
||||||
|
if (g_vol_sensor_drv) {
|
||||||
|
VOL_SENSOR_ERR("g_vol_sensor_drv is not NULL, can't register\n");
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
check_p(drv);
|
||||||
|
check_p(drv->get_main_board_vol_number);
|
||||||
|
g_vol_sensor_drv = drv;
|
||||||
|
|
||||||
|
vol_num = g_vol_sensor_drv->get_main_board_vol_number();
|
||||||
|
if (vol_num <= 0) {
|
||||||
|
VOL_SENSOR_ERR("vol sensor number: %d, don't need to create vol_sensor dirs and attrs.\n",
|
||||||
|
vol_num);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
memset(&g_vol_sensor, 0, sizeof(struct vol_sensor_s));
|
||||||
|
g_vol_sensor.vol_number = vol_num;
|
||||||
|
ret = vol_sensor_root_create();
|
||||||
|
if (ret < 0) {
|
||||||
|
VOL_SENSOR_ERR("create vol_sensor root dir and attrs failed, ret: %d\n", ret);
|
||||||
|
g_vol_sensor_drv = NULL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = vol_sensor_sub_create();
|
||||||
|
if (ret < 0) {
|
||||||
|
VOL_SENSOR_ERR("create vol_sensor sub dir and attrs failed, ret: %d\n", ret);
|
||||||
|
vol_sensor_root_remove();
|
||||||
|
g_vol_sensor_drv = NULL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
VOL_SENSOR_INFO("s3ip_sysfs_vol_sensor_drivers_register success\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void s3ip_sysfs_vol_sensor_drivers_unregister(void)
|
||||||
|
{
|
||||||
|
if (g_vol_sensor_drv) {
|
||||||
|
vol_sensor_sub_remove();
|
||||||
|
vol_sensor_root_remove();
|
||||||
|
g_vol_sensor_drv = NULL;
|
||||||
|
VOL_SENSOR_DBG("s3ip_sysfs_vol_sensor_drivers_unregister success.\n");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(s3ip_sysfs_vol_sensor_drivers_register);
|
||||||
|
EXPORT_SYMBOL(s3ip_sysfs_vol_sensor_drivers_unregister);
|
||||||
|
module_param(g_vol_sensor_loglevel, int, 0644);
|
||||||
|
MODULE_PARM_DESC(g_vol_sensor_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n");
|
Loading…
Reference in New Issue
Block a user