[pddf]: Adding PDDF common framework enhancements. (#12863)

- Consolidating multiple read functions in a PSU driver on the basis of byte, word or block read,
- Enhancing PDDF parsing script support for CPU and PCH temperature reading,
- Adding missing methods in PDDF common APIs

Why I did it
- PSU driver changes are to optimize the code and increase the code coverage
- PDDF parser script enhancements to accommodate the CPU and PCH temp reading using hwmon device path
- Some of the new APIs were missing from the PDDF common platform classes

How I did it
Added code changes and verified them on AS7816 adn AS7726 platforms.
This commit is contained in:
FuzailBrcm 2022-12-18 04:06:52 +05:30 committed by GitHub
parent 372a7c85c5
commit abc8ed8a79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 313 additions and 435 deletions

View File

@ -24,18 +24,8 @@ extern void get_psu_duplicate_sysfs(int idx, char *str);
extern ssize_t psu_show_default(struct device *dev, struct device_attribute *da, char *buf);
extern ssize_t psu_store_default(struct device *dev, struct device_attribute *da, const char *buf, size_t count);
extern int sonic_i2c_get_psu_present_default(void *client, PSU_DATA_ATTR *adata, void *data);
extern int sonic_i2c_get_psu_power_good_default(void *client, PSU_DATA_ATTR *adata, void *data);
extern int sonic_i2c_get_psu_model_name_default(void *client, PSU_DATA_ATTR *adata, void *data);
extern int sonic_i2c_get_psu_mfr_id_default(void *client, PSU_DATA_ATTR *adata, void *data);
extern int sonic_i2c_get_psu_serial_num_default(void *client, PSU_DATA_ATTR *adata, void *data);
extern int sonic_i2c_get_psu_fan_dir_default(void *client, PSU_DATA_ATTR *adata, void *data);
extern int sonic_i2c_get_psu_v_out_default(void *client, PSU_DATA_ATTR *adata, void *data);
extern int sonic_i2c_get_psu_i_out_default(void *client, PSU_DATA_ATTR *adata, void *data);
extern int sonic_i2c_get_psu_p_out_default(void *client, PSU_DATA_ATTR *adata, void *data);
extern int sonic_i2c_get_psu_fan1_speed_rpm_default(void *client, PSU_DATA_ATTR *adata, void *data);
extern int sonic_i2c_get_psu_temp1_input_default(void *client, PSU_DATA_ATTR *adata, void *data);
extern int sonic_i2c_get_psu_v_in_default(void *client, PSU_DATA_ATTR *adata, void *data);
extern int sonic_i2c_get_psu_i_in_default(void *client, PSU_DATA_ATTR *adata, void *data);
extern int sonic_i2c_get_psu_byte_default(void *client, PSU_DATA_ATTR *adata, void *data);
extern int sonic_i2c_get_psu_block_default(void *client, PSU_DATA_ATTR *adata, void *data);
extern int sonic_i2c_get_psu_word_default(void *client, PSU_DATA_ATTR *adata, void *data);
#endif

View File

@ -27,12 +27,17 @@ enum psu_sysfs_attributes {
PSU_SERIAL_NUM,
PSU_FAN_DIR,
PSU_V_OUT,
PSU_V_OUT_MIN,
PSU_V_OUT_MAX,
PSU_I_OUT,
PSU_P_OUT, /* This is in micro watts to comply with lm-sensors */
PSU_P_OUT_MAX,
PSU_FAN1_SPEED,
PSU_TEMP1_INPUT,
PSU_TEMP1_HIGH_THRESHOLD,
PSU_V_IN,
PSU_I_IN,
PSU_P_IN,
PSU_ATTR_MAX
};

View File

@ -201,9 +201,12 @@ ssize_t psu_show_default(struct device *dev, struct device_attribute *da, char *
return sprintf(buf, "%s\n", sysfs_attr_info->val.strval);
break;
case PSU_V_OUT:
case PSU_V_OUT_MIN:
case PSU_V_OUT_MAX:
case PSU_I_OUT:
case PSU_V_IN:
case PSU_I_IN:
case PSU_P_OUT_MAX:
multiplier = 1000;
value = sysfs_attr_info->val.shortval;
exponent = two_complement_to_int(value >> 11, 5, 0x1f);
@ -214,6 +217,7 @@ ssize_t psu_show_default(struct device *dev, struct device_attribute *da, char *
return sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent));
break;
case PSU_P_IN:
case PSU_P_OUT:
multiplier = 1000000;
value = sysfs_attr_info->val.shortval;
@ -236,6 +240,7 @@ ssize_t psu_show_default(struct device *dev, struct device_attribute *da, char *
break;
case PSU_TEMP1_INPUT:
case PSU_TEMP1_HIGH_THRESHOLD:
multiplier = 1000;
value = sysfs_attr_info->val.shortval;
exponent = two_complement_to_int(value >> 11, 5, 0x1f);
@ -293,7 +298,7 @@ exit:
return count;
}
int sonic_i2c_get_psu_present_default(void *client, PSU_DATA_ATTR *adata, void *data)
int sonic_i2c_get_psu_byte_default(void *client, PSU_DATA_ATTR *adata, void *data)
{
int status = 0;
int val = 0;
@ -306,41 +311,23 @@ int sonic_i2c_get_psu_present_default(void *client, PSU_DATA_ATTR *adata, void *
if (val < 0)
return val;
padata->val.intval = ((val & adata->mask) == adata->cmpval);
psu_dbg(KERN_ERR "%s: status_value = 0x%x\n", __FUNCTION__, padata->val.intval);
psu_dbg(KERN_ERR "%s: byte_value = 0x%x\n", __FUNCTION__, padata->val.intval);
}
return status;
}
int sonic_i2c_get_psu_power_good_default(void *client, PSU_DATA_ATTR *adata, void *data)
{
int status = 0;
int val = 0;
struct psu_attr_info *padata = (struct psu_attr_info *)data;
if (strncmp(adata->devtype, "cpld", strlen("cpld")) == 0)
{
val = board_i2c_cpld_read(adata->devaddr , adata->offset);
if (val < 0)
return val;
padata->val.intval = ((val & adata->mask) == adata->cmpval);
psu_dbg(KERN_ERR "%s: status_value = 0x%x\n", __FUNCTION__, padata->val.intval);
}
return status;
}
int sonic_i2c_get_psu_model_name_default(void *client, PSU_DATA_ATTR *adata, void *data)
int sonic_i2c_get_psu_block_default(void *client, PSU_DATA_ATTR *adata, void *data)
{
int status = 0, retry = 10;
struct psu_attr_info *padata = (struct psu_attr_info *)data;
char model[32]=""; //temporary placeholder for model name
char buf[32]=""; //temporary placeholder for block data
uint8_t offset = (uint8_t)adata->offset;
int data_len = adata->len;
while (retry)
{
status = i2c_smbus_read_i2c_block_data((struct i2c_client *)client, offset, data_len-1, model);
status = i2c_smbus_read_i2c_block_data((struct i2c_client *)client, offset, data_len-1, buf);
if (unlikely(status<0))
{
msleep(60);
@ -352,144 +339,24 @@ int sonic_i2c_get_psu_model_name_default(void *client, PSU_DATA_ATTR *adata, voi
if (status < 0)
{
model[0] = '\0';
dev_dbg(&((struct i2c_client *)client)->dev, "unable to read model name from (0x%x)\n", ((struct i2c_client *)client)->addr);
buf[0] = '\0';
dev_dbg(&((struct i2c_client *)client)->dev, "unable to read block of data from (0x%x)\n", ((struct i2c_client *)client)->addr);
}
else
{
model[data_len-1] = '\0';
buf[data_len-1] = '\0';
}
if (strncmp(adata->devtype, "pmbus", strlen("pmbus")) == 0)
strncpy(padata->val.strval, model+1, data_len-1);
strncpy(padata->val.strval, buf+1, data_len-1);
else
strncpy(padata->val.strval, model, data_len);
strncpy(padata->val.strval, buf, data_len);
psu_dbg(KERN_ERR "%s: status = %d, model_name : %s\n", __FUNCTION__, status, padata->val.strval);
psu_dbg(KERN_ERR "%s: status = %d, buf block: %s\n", __FUNCTION__, status, padata->val.strval);
return 0;
}
int sonic_i2c_get_psu_mfr_id_default(void *client, PSU_DATA_ATTR *adata, void *data)
{
int status = 0, retry = 10;
struct psu_attr_info *padata = (struct psu_attr_info *)data;
char mfr_id[16] = ""; // temporary place holder for mfr_id
uint8_t offset = (uint8_t)adata->offset;
int data_len = adata->len;
while (retry)
{
status = i2c_smbus_read_i2c_block_data((struct i2c_client *)client, offset, data_len-1, mfr_id);
if (unlikely(status<0))
{
msleep(60);
retry--;
continue;
}
break;
}
if (status < 0)
{
mfr_id[0] = '\0';
dev_dbg(&((struct i2c_client *)client)->dev, "unable to read mfr_id from (0x%x)\n", ((struct i2c_client *)client)->addr);
}
else
{
mfr_id[data_len-1] = '\0';
}
if (strncmp(adata->devtype, "pmbus", strlen("pmbus")) == 0)
strncpy(padata->val.strval, mfr_id+1, data_len-1);
else
strncpy(padata->val.strval, mfr_id, data_len);
psu_dbg(KERN_ERR "%s: status = %d, mfr_id : %s\n", __FUNCTION__, status, padata->val.strval);
return 0;
}
int sonic_i2c_get_psu_serial_num_default(void *client, PSU_DATA_ATTR *adata, void *data)
{
int status = 0, retry = 10;
struct psu_attr_info *padata = (struct psu_attr_info *)data;
char serial[32] = ""; // temporary string to store the serial num
uint8_t offset = (uint8_t)adata->offset;
int data_len = adata->len;
while (retry)
{
status = i2c_smbus_read_i2c_block_data((struct i2c_client *)client, offset, data_len-1, serial);
if (unlikely(status<0))
{
msleep(60);
retry--;
continue;
}
break;
}
if (status < 0)
{
serial[0] = '\0';
dev_dbg(&((struct i2c_client *)client)->dev, "unable to read serial num from (0x%x)\n", ((struct i2c_client *)client)->addr);
}
else
{
serial[data_len-1] = '\0';
}
if (strncmp(adata->devtype, "pmbus", strlen("pmbus")) == 0)
strncpy(padata->val.strval, serial+1, data_len-1);
else
strncpy(padata->val.strval, serial, data_len);
psu_dbg(KERN_ERR "%s: status = %d, serial_num : %s\n", __FUNCTION__, status, padata->val.strval);
return 0;
}
int sonic_i2c_get_psu_fan_dir_default(void *client, PSU_DATA_ATTR *adata, void *data)
{
int status = 0, retry = 10;
struct psu_attr_info *padata = (struct psu_attr_info *)data;
char fan_dir[5] = "";
uint8_t offset = (uint8_t)adata->offset;
int data_len = adata->len;
while (retry)
{
status = i2c_smbus_read_i2c_block_data((struct i2c_client *)client, offset, data_len-1, fan_dir);
if (unlikely(status<0))
{
msleep(60);
retry--;
continue;
}
break;
}
if (status < 0)
{
fan_dir[0] = '\0';
dev_dbg(&((struct i2c_client *)client)->dev, "unable to read fan_dir from (0x%x)\n", ((struct i2c_client *)client)->addr);
}
else
{
fan_dir[data_len-1] = '\0';
}
if (strncmp(adata->devtype, "pmbus", strlen("pmbus")) == 0)
strncpy(padata->val.strval, fan_dir+1, data_len-1);
else
strncpy(padata->val.strval, fan_dir, data_len);
psu_dbg(KERN_ERR "%s: status = %d, fan_dir : %s\n", __FUNCTION__, status, padata->val.strval);
return 0;
}
int sonic_i2c_get_psu_v_out_default(void *client, PSU_DATA_ATTR *adata, void *data)
int sonic_i2c_get_psu_word_default(void *client, PSU_DATA_ATTR *adata, void *data)
{
int status = 0, retry = 10;
@ -509,199 +376,13 @@ int sonic_i2c_get_psu_v_out_default(void *client, PSU_DATA_ATTR *adata, void *da
if (status < 0)
{
padata->val.shortval = 0;
dev_dbg(&((struct i2c_client *)client)->dev, "unable to read v_out from (0x%x)\n", ((struct i2c_client *)client)->addr);
dev_dbg(&((struct i2c_client *)client)->dev, "unable to read a word from (0x%x)\n", ((struct i2c_client *)client)->addr);
}
else
{
padata->val.shortval = status;
}
psu_dbg(KERN_ERR "%s: v_out : %d\n", __FUNCTION__, padata->val.shortval);
return 0;
}
int sonic_i2c_get_psu_i_out_default(void *client, PSU_DATA_ATTR *adata, void *data)
{
int status = 0, retry = 10;
struct psu_attr_info *padata = (struct psu_attr_info *)data;
uint8_t offset = (uint8_t)adata->offset;
while (retry) {
status = i2c_smbus_read_word_data((struct i2c_client *)client, offset);
if (unlikely(status < 0)) {
msleep(60);
retry--;
continue;
}
break;
}
if (status < 0)
{
padata->val.shortval = 0;
dev_dbg(&((struct i2c_client *)client)->dev, "unable to read i_out from (0x%x)\n", ((struct i2c_client *)client)->addr);
}
else
{
padata->val.shortval = status;
}
psu_dbg(KERN_ERR "%s: i_out : %d\n", __FUNCTION__, padata->val.shortval);
return 0;
}
int sonic_i2c_get_psu_p_out_default(void *client, PSU_DATA_ATTR *adata, void *data)
{
int status = 0, retry = 10;
struct psu_attr_info *padata = (struct psu_attr_info *)data;
uint8_t offset = (uint8_t)adata->offset;
while (retry) {
status = i2c_smbus_read_word_data((struct i2c_client *)client, offset);
if (unlikely(status < 0)) {
msleep(60);
retry--;
continue;
}
break;
}
if (status < 0)
{
padata->val.shortval = 0;
dev_dbg(&((struct i2c_client *)client)->dev, "unable to read p_out from (0x%x)\n", ((struct i2c_client *)client)->addr);
}
else
{
padata->val.shortval = status;
}
psu_dbg(KERN_ERR "%s: p_out : %d\n", __FUNCTION__, padata->val.shortval);
return 0;
}
int sonic_i2c_get_psu_v_in_default(void *client, PSU_DATA_ATTR *adata, void *data)
{
int status = 0, retry = 10;
struct psu_attr_info *padata = (struct psu_attr_info *)data;
uint8_t offset = (uint8_t)adata->offset;
while (retry) {
status = i2c_smbus_read_word_data((struct i2c_client *)client, offset);
if (unlikely(status < 0)) {
msleep(60);
retry--;
continue;
}
break;
}
if (status < 0)
{
padata->val.shortval = 0;
dev_dbg(&((struct i2c_client *)client)->dev, "unable to read v_in from (0x%x)\n", ((struct i2c_client *)client)->addr);
}
else
{
padata->val.shortval = status;
}
psu_dbg(KERN_ERR "%s: v_in : %d\n", __FUNCTION__, padata->val.shortval);
return 0;
}
int sonic_i2c_get_psu_i_in_default(void *client, PSU_DATA_ATTR *adata, void *data)
{
int status = 0, retry = 10;
struct psu_attr_info *padata = (struct psu_attr_info *)data;
uint8_t offset = (uint8_t)adata->offset;
while (retry) {
status = i2c_smbus_read_word_data((struct i2c_client *)client, offset);
if (unlikely(status < 0)) {
msleep(60);
retry--;
continue;
}
break;
}
if (status < 0)
{
padata->val.shortval = 0;
dev_dbg(&((struct i2c_client *)client)->dev, "unable to read i_in from (0x%x)\n", ((struct i2c_client *)client)->addr);
}
else
{
padata->val.shortval = status;
}
psu_dbg(KERN_ERR "%s: i_in : %d\n", __FUNCTION__, padata->val.shortval);
return 0;
}
int sonic_i2c_get_psu_fan1_speed_rpm_default(void *client, PSU_DATA_ATTR *adata, void *data)
{
int status = 0, retry = 10;
struct psu_attr_info *padata = (struct psu_attr_info *)data;
uint8_t offset = (uint8_t)adata->offset;
while (retry) {
status = i2c_smbus_read_word_data((struct i2c_client *)client, offset);
if (unlikely(status < 0)) {
msleep(60);
retry--;
continue;
}
break;
}
if (status < 0)
{
padata->val.shortval = 0;
dev_dbg(&((struct i2c_client *)client)->dev, "unable to read fan1_speed_rpm from (0x%x)\n", ((struct i2c_client *)client)->addr);
}
else
{
padata->val.shortval = status;
}
psu_dbg(KERN_ERR "%s: fan1_speed_rpm : %d\n", __FUNCTION__, padata->val.shortval);
return 0;
}
int sonic_i2c_get_psu_temp1_input_default(void *client, PSU_DATA_ATTR *adata, void *data)
{
int status = 0, retry = 10;
struct psu_attr_info *padata = (struct psu_attr_info *)data;
uint8_t offset = (uint8_t)adata->offset;
while (retry) {
status = i2c_smbus_read_word_data((struct i2c_client *)client, offset);
if (unlikely(status < 0)) {
msleep(60);
retry--;
continue;
}
break;
}
if (status < 0)
{
padata->val.shortval = 0;
dev_dbg(&((struct i2c_client *)client)->dev, "unable to read temp1_input from (0x%x)\n", ((struct i2c_client *)client)->addr);
}
else
{
padata->val.shortval = status;
}
psu_dbg(KERN_ERR "%s: temp1_input : %d\n", __FUNCTION__, padata->val.shortval);
psu_dbg(KERN_ERR "%s: word value : %d\n", __FUNCTION__, padata->val.shortval);
return 0;
}

View File

@ -53,45 +53,59 @@ struct pddf_ops_t pddf_psu_ops = {
EXPORT_SYMBOL(pddf_psu_ops);
PSU_SYSFS_ATTR_DATA access_psu_present = {PSU_PRESENT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_present_default, NULL, NULL, NULL, NULL, NULL};
PSU_SYSFS_ATTR_DATA access_psu_present = {PSU_PRESENT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_byte_default, NULL, NULL, NULL, NULL, NULL};
EXPORT_SYMBOL(access_psu_present);
PSU_SYSFS_ATTR_DATA access_psu_model_name = {PSU_MODEL_NAME, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_model_name_default, NULL, NULL, NULL, NULL, NULL};
PSU_SYSFS_ATTR_DATA access_psu_model_name = {PSU_MODEL_NAME, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_block_default, NULL, NULL, NULL, NULL, NULL};
EXPORT_SYMBOL(access_psu_model_name);
PSU_SYSFS_ATTR_DATA access_psu_power_good = {PSU_POWER_GOOD, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_power_good_default, NULL, NULL, NULL, NULL, NULL};
PSU_SYSFS_ATTR_DATA access_psu_power_good = {PSU_POWER_GOOD, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_byte_default, NULL, NULL, NULL, NULL, NULL};
EXPORT_SYMBOL(access_psu_power_good);
PSU_SYSFS_ATTR_DATA access_psu_mfr_id = {PSU_MFR_ID, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_mfr_id_default, NULL, NULL, NULL, NULL, NULL};
PSU_SYSFS_ATTR_DATA access_psu_mfr_id = {PSU_MFR_ID, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_block_default, NULL, NULL, NULL, NULL, NULL};
EXPORT_SYMBOL(access_psu_mfr_id);
PSU_SYSFS_ATTR_DATA access_psu_serial_num = {PSU_SERIAL_NUM, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_serial_num_default, NULL, NULL, NULL, NULL, NULL};
PSU_SYSFS_ATTR_DATA access_psu_serial_num = {PSU_SERIAL_NUM, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_block_default, NULL, NULL, NULL, NULL, NULL};
EXPORT_SYMBOL(access_psu_serial_num);
PSU_SYSFS_ATTR_DATA access_psu_fan_dir = {PSU_FAN_DIR, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_fan_dir_default, NULL, NULL, NULL, NULL, NULL};
PSU_SYSFS_ATTR_DATA access_psu_fan_dir = {PSU_FAN_DIR, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_block_default, NULL, NULL, NULL, NULL, NULL};
EXPORT_SYMBOL(access_psu_fan_dir);
PSU_SYSFS_ATTR_DATA access_psu_v_out = {PSU_V_OUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_v_out_default, NULL, NULL, NULL, NULL, NULL};
PSU_SYSFS_ATTR_DATA access_psu_v_out = {PSU_V_OUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL};
EXPORT_SYMBOL(access_psu_v_out);
PSU_SYSFS_ATTR_DATA access_psu_i_out = {PSU_I_OUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_i_out_default, NULL, NULL, NULL, NULL, NULL};
PSU_SYSFS_ATTR_DATA access_psu_v_out_min = {PSU_V_OUT_MIN, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL};
EXPORT_SYMBOL(access_psu_v_out_min);
PSU_SYSFS_ATTR_DATA access_psu_v_out_max = {PSU_V_OUT_MAX, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL};
EXPORT_SYMBOL(access_psu_v_out_max);
PSU_SYSFS_ATTR_DATA access_psu_i_out = {PSU_I_OUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL};
EXPORT_SYMBOL(access_psu_i_out);
PSU_SYSFS_ATTR_DATA access_psu_p_out = {PSU_P_OUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_p_out_default, NULL, NULL, NULL, NULL, NULL};
PSU_SYSFS_ATTR_DATA access_psu_p_out = {PSU_P_OUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL};
EXPORT_SYMBOL(access_psu_p_out);
PSU_SYSFS_ATTR_DATA access_psu_fan1_speed_rpm = {PSU_FAN1_SPEED, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_fan1_speed_rpm_default, NULL, NULL, NULL, NULL, NULL};
PSU_SYSFS_ATTR_DATA access_psu_p_out_max = {PSU_P_OUT_MAX, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL};
EXPORT_SYMBOL(access_psu_p_out_max);
PSU_SYSFS_ATTR_DATA access_psu_fan1_speed_rpm = {PSU_FAN1_SPEED, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL};
EXPORT_SYMBOL(access_psu_fan1_speed_rpm);
PSU_SYSFS_ATTR_DATA access_psu_temp1_input = {PSU_TEMP1_INPUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_temp1_input_default, NULL, NULL, NULL, NULL, NULL};
PSU_SYSFS_ATTR_DATA access_psu_temp1_input = {PSU_TEMP1_INPUT, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL};
EXPORT_SYMBOL(access_psu_temp1_input);
PSU_SYSFS_ATTR_DATA access_psu_v_in = {PSU_V_IN, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_v_in_default, NULL, NULL, NULL, NULL, NULL};
PSU_SYSFS_ATTR_DATA access_psu_temp1_high_threshold = {PSU_TEMP1_HIGH_THRESHOLD, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL};
EXPORT_SYMBOL(access_psu_temp1_high_threshold);
PSU_SYSFS_ATTR_DATA access_psu_v_in = {PSU_V_IN, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL};
EXPORT_SYMBOL(access_psu_v_in);
PSU_SYSFS_ATTR_DATA access_psu_i_in = {PSU_I_IN, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_i_in_default, NULL, NULL, NULL, NULL, NULL};
PSU_SYSFS_ATTR_DATA access_psu_i_in = {PSU_I_IN, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL};
EXPORT_SYMBOL(access_psu_i_in);
PSU_SYSFS_ATTR_DATA access_psu_p_in = {PSU_P_IN, S_IRUGO, psu_show_default, NULL, sonic_i2c_get_psu_word_default, NULL, NULL, NULL, NULL, NULL};
EXPORT_SYMBOL(access_psu_p_in);
PSU_SYSFS_ATTR_DATA_ENTRY psu_sysfs_attr_data_tbl[]=
{
@ -102,12 +116,17 @@ PSU_SYSFS_ATTR_DATA_ENTRY psu_sysfs_attr_data_tbl[]=
{ "psu_serial_num" , &access_psu_serial_num},
{ "psu_fan_dir" , &access_psu_fan_dir},
{ "psu_v_out" , &access_psu_v_out},
{ "psu_v_out_min" , &access_psu_v_out_min},
{ "psu_v_out_max" , &access_psu_v_out_max},
{ "psu_i_out" , &access_psu_i_out},
{ "psu_p_out" , &access_psu_p_out},
{ "psu_p_out_max" , &access_psu_p_out_max},
{ "psu_fan1_speed_rpm" , &access_psu_fan1_speed_rpm},
{ "psu_temp1_input" , &access_psu_temp1_input},
{ "psu_temp1_high_threshold" , &access_psu_temp1_high_threshold},
{ "psu_v_in" , &access_psu_v_in},
{ "psu_i_in" , &access_psu_i_in}
{ "psu_i_in" , &access_psu_i_in},
{ "psu_p_in" , &access_psu_p_in}
};
void *get_psu_access_data(char *name)

View File

@ -844,8 +844,8 @@ class PddfParse():
for entry in obj[key]:
print("\t"+entry)
def add_list_sysfs_obj(self, obj, KEY, list):
for sysfs in list:
def add_list_sysfs_obj(self, obj, KEY, extra_list):
for sysfs in extra_list:
if not sysfs in obj[KEY]:
obj[KEY].append(sysfs)
@ -854,8 +854,9 @@ class PddfParse():
if not sysfs_path in obj[obj_key]:
obj[obj_key].append(sysfs_path)
def sysfs_device(self, attr, path, obj, obj_key):
def sysfs_device(self, attr, path, obj, obj_key, exceptions=[]):
for key in attr.keys():
if key not in exceptions:
sysfs_path = "/sys/kernel/%s/%s" % (path, key)
if not sysfs_path in obj[obj_key]:
obj[obj_key].append(sysfs_path)
@ -868,14 +869,14 @@ class PddfParse():
if not KEY in self.sysfs_obj:
self.sysfs_obj[KEY] = []
self.sysfs_device(dev['i2c']['topo_info'], "pddf/devices/mux", self.sysfs_obj, KEY)
self.sysfs_device(dev['i2c']['dev_attr'], "pddf/devices/mux", self.sysfs_obj, KEY)
self.sysfs_device(dev['i2c']['dev_attr'], "pddf/devices/mux", self.sysfs_obj, KEY, ['idle_state'])
sysfs_path = "/sys/kernel/pddf/devices/mux/dev_ops"
if not sysfs_path in self.sysfs_obj[KEY]:
self.sysfs_obj[KEY].append(sysfs_path)
list = ['/sys/kernel/pddf/devices/mux/i2c_type',
extra_list = ['/sys/kernel/pddf/devices/mux/i2c_type',
'/sys/kernel/pddf/devices/mux/i2c_name',
'/sys/kernel/pddf/devices/mux/error']
self.add_list_sysfs_obj(self.sysfs_obj, KEY, list)
self.add_list_sysfs_obj(self.sysfs_obj, KEY, extra_list)
def show_gpio_device(self, dev, ops):
KEY = 'gpio'
@ -886,10 +887,10 @@ class PddfParse():
sysfs_path = "/sys/kernel/pddf/devices/gpio/dev_ops"
if not sysfs_path in self.sysfs_obj[KEY]:
self.sysfs_obj[KEY].append(sysfs_path)
list = ['/sys/kernel/pddf/devices/gpio/i2c_type',
extra_list = ['/sys/kernel/pddf/devices/gpio/i2c_type',
'/sys/kernel/pddf/devices/gpio/i2c_name',
'/sys/kernel/pddf/devices/gpio/error']
self.add_list_sysfs_obj(self.sysfs_obj, KEY, list)
self.add_list_sysfs_obj(self.sysfs_obj, KEY, extra_list)
def show_psu_i2c_device(self, dev, ops):
KEY = 'psu'
@ -906,12 +907,11 @@ class PddfParse():
sysfs_path = "/sys/kernel/pddf/devices/psu/i2c/dev_ops"
if not sysfs_path in self.sysfs_obj[KEY]:
self.sysfs_obj[KEY].append(sysfs_path)
list = ['/sys/kernel/pddf/devices/psu/i2c/i2c_type',
extra_list = ['/sys/kernel/pddf/devices/psu/i2c/i2c_type',
'/sys/kernel/pddf/devices/fan/i2c/i2c_name',
'/sys/kernel/pddf/devices/psu/i2c/error',
'/sys/kernel/pddf/devices/psu/i2c/attr_ops']
self.add_list_sysfs_obj(self.sysfs_obj, KEY, list)
self.add_list_sysfs_obj(self.sysfs_obj, KEY, extra_list)
def show_psu_device(self, dev, ops):
self.show_psu_i2c_device(dev, ops)
@ -921,8 +921,8 @@ class PddfParse():
KEY = 'client'
if not KEY in self.sysfs_obj:
self.sysfs_obj[KEY] = []
list = ['/sys/kernel/pddf/devices/showall']
self.add_list_sysfs_obj(self.sysfs_obj, KEY, list)
extra_list = ['/sys/kernel/pddf/devices/showall']
self.add_list_sysfs_obj(self.sysfs_obj, KEY, extra_list)
def show_fan_device(self, dev, ops):
KEY = 'fan'
@ -931,16 +931,16 @@ class PddfParse():
if not KEY in self.sysfs_obj:
self.sysfs_obj[KEY] = []
self.sysfs_device(dev['i2c']['topo_info'], path, self.sysfs_obj, KEY)
self.sysfs_device(dev['i2c']['topo_info'], path, self.sysfs_obj, KEY, ['client_type'])
self.sysfs_device(dev['i2c']['dev_attr'], path, self.sysfs_obj, KEY)
for attr in dev['i2c']['attr_list']:
self.sysfs_device(attr, path, self.sysfs_obj, KEY)
list = ['/sys/kernel/pddf/devices/fan/i2c/i2c_type',
extra_list = ['/sys/kernel/pddf/devices/fan/i2c/i2c_type',
'/sys/kernel/pddf/devices/fan/i2c/i2c_name',
'/sys/kernel/pddf/devices/fan/i2c/error',
'/sys/kernel/pddf/devices/fan/i2c/attr_ops',
'/sys/kernel/pddf/devices/fan/i2c/dev_ops']
self.add_list_sysfs_obj(self.sysfs_obj, KEY, list)
self.add_list_sysfs_obj(self.sysfs_obj, KEY, extra_list)
def show_temp_sensor_device(self, dev, ops):
return
@ -960,18 +960,18 @@ class PddfParse():
if dev['i2c']['topo_info']['dev_type'] in self.data['PLATFORM']['pddf_dev_types']['PORT_MODULE']:
if not KEY in self.sysfs_obj:
self.sysfs_obj[KEY] = []
self.sysfs_device(dev['i2c']['topo_info'], "pddf/devices/xcvr/i2c", self.sysfs_obj, KEY)
self.sysfs_device(dev['i2c']['topo_info'], "pddf/devices/xcvr/i2c", self.sysfs_obj, KEY, ['client_type'])
for attr in dev['i2c']['attr_list']:
self.sysfs_device(attr, "pddf/devices/xcvr/i2c", self.sysfs_obj, KEY)
sysfs_path = "/sys/kernel/pddf/devices/xcvr/i2c/dev_ops"
if not sysfs_path in self.sysfs_obj[KEY]:
self.sysfs_obj[KEY].append(sysfs_path)
list = ['/sys/kernel/pddf/devices/xcvr/i2c/i2c_type',
extra_list = ['/sys/kernel/pddf/devices/xcvr/i2c/i2c_type',
'/sys/kernel/pddf/devices/xcvr/i2c/i2c_name',
'/sys/kernel/pddf/devices/xcvr/i2c/error',
'/sys/kernel/pddf/devices/xcvr/i2c/attr_ops']
self.add_list_sysfs_obj(self.sysfs_obj, KEY, list)
self.add_list_sysfs_obj(self.sysfs_obj, KEY, extra_list)
def show_xcvr_device(self, dev, ops):
self.show_xcvr_i2c_device(dev, ops)
@ -986,10 +986,10 @@ class PddfParse():
sysfs_path = "/sys/kernel/pddf/devices/cpld/dev_ops"
if not sysfs_path in self.sysfs_obj[KEY]:
self.sysfs_obj[KEY].append(sysfs_path)
list = ['/sys/kernel/pddf/devices/cpld/i2c_type',
extra_list = ['/sys/kernel/pddf/devices/cpld/i2c_type',
'/sys/kernel/pddf/devices/cpld/i2c_name',
'/sys/kernel/pddf/devices/cpld/error']
self.add_list_sysfs_obj(self.sysfs_obj, KEY, list)
self.add_list_sysfs_obj(self.sysfs_obj, KEY, extra_list)
def show_led_platform_device(self, key, ops):
if ops['attr'] == 'all' or ops['attr'] == 'PLATFORM':
@ -1059,7 +1059,7 @@ class PddfParse():
print(ret_val)
def validate_mux_device(self, dev, ops):
devtype_list = ['pca9548', 'pca954x']
devtype_list = ['pca9548', 'pca9545', 'pca9546', 'pca954x']
dev_channels = ["0", "1", "2", "3", "4", "5", "6", "7"]
ret_val = "mux failed"

View File

@ -26,6 +26,7 @@ class PddfFan(FanBase):
def __init__(self, tray_idx, fan_idx=0, pddf_data=None, pddf_plugin_data=None, is_psu_fan=False, psu_index=0):
# idx is 0-based
FanBase.__init__(self)
if not pddf_data or not pddf_plugin_data:
raise ValueError('PDDF JSON data error')
@ -99,7 +100,7 @@ class PddfFan(FanBase):
device = "PSU{}".format(self.fans_psu_index)
output = self.pddf_obj.get_attr_name_output(device, "psu_fan_dir")
if not output:
return False
return None
mode = output['mode']
val = output['status']
@ -117,7 +118,7 @@ class PddfFan(FanBase):
attr = "fan" + str(idx) + "_direction"
output = self.pddf_obj.get_attr_name_output("FAN-CTRL", attr)
if not output:
return False
return None
mode = output['mode']
val = output['status']
@ -168,7 +169,7 @@ class PddfFan(FanBase):
if output['status'].isalpha():
return 0
else:
fpwm = int(output['status'])
fpwm = int(float(output['status']))
pwm_to_dc = eval(self.plugin_data['FAN']['pwm_to_duty_cycle'])
speed_percentage = int(round(pwm_to_dc(fpwm)))
@ -190,10 +191,11 @@ class PddfFan(FanBase):
return 0
output['status'] = output['status'].rstrip()
if output['status'].isalpha():
return 0
else:
if output['status'].replace('.', '', 1).isdigit():
speed = int(float(output['status']))
else:
return 0
rpm_speed = speed
return rpm_speed
@ -237,7 +239,7 @@ class PddfFan(FanBase):
if output['status'].isalpha():
return 0
else:
fpwm = int(output['status'])
fpwm = int(float(output['status']))
pwm_to_dc = eval(self.plugin_data['FAN']['pwm_to_duty_cycle'])
speed_percentage = int(round(pwm_to_dc(fpwm)))
@ -328,5 +330,27 @@ class PddfFan(FanBase):
color = self.pddf_obj.get_led_color()
return (color)
def get_position_in_parent(self):
"""
Retrieves 1-based relative physical position in parent device.
Returns:
integer: The 1-based relative physical position in parent
device or -1 if cannot determine the position
"""
# self.fan_index represents the fan index in a Fantray as well as in the PSU
return self.fan_index
def is_replaceable(self):
"""
Indicate whether Fan (inside a Fantray) is replaceable
Returns:
bool: True if it is replaceable.
"""
# Usually a psu-fan is not replaceable
if self.is_psu_fan:
return False
else:
return True
def dump_sysfs(self):
return self.pddf_obj.cli_dump_dsysfs('fan')

View File

@ -11,9 +11,17 @@
# - psu_serial_num
# - psu_fan_dir
# - psu_v_out
# - psu_v_out_min
# - psu_v_out_max
# - psu_i_out
# - psu_p_out
# - psu_p_out_max
# - psu_fan1_speed_rpm
# - psu_temp1_input
# - psu_temp1_high_threshold
# - psu_v_in
# - psu_i_in
# - psu_p_in
#############################################################################
@ -129,6 +137,10 @@ class PddfPsu(PsuBase):
serial = output['status']
# strip_non_ascii
stripped = (c for c in serial if 0 < ord(c) < 127)
serial = ''.join(stripped)
return serial.rstrip('\n')
def get_status(self):
@ -168,6 +180,10 @@ class PddfPsu(PsuBase):
mfr = output['status']
# strip_non_ascii
stripped = (c for c in mfr if 0 < ord(c) < 127)
mfr = ''.join(stripped)
return mfr.rstrip('\n')
def get_voltage(self):
@ -319,5 +335,99 @@ class PddfPsu(PsuBase):
# current in mA
return float(i_in)/1000
def get_input_power(self):
"""
Retrieves current energy supplied to the PSU
Returns:
A float number, the power in watts, e.g. 302.6
"""
device = "PSU{}".format(self.psu_index)
output = self.pddf_obj.get_attr_name_output(device, "psu_p_in")
if not output:
return 0.0
p_in = output['status']
# power is returned in micro watts
return float(p_in)/1000000
def get_temperature_high_threshold(self):
"""
Retrieves the high threshold temperature of PSU
Returns:
A float number, the high threshold temperature of PSU in Celsius
up to nearest thousandth of one degree Celsius, e.g. 30.125
"""
device = "PSU{}".format(self.psu_index)
output = self.pddf_obj.get_attr_name_output(device, "psu_temp1_high_threshold")
if not output:
return 0.0
temp_high_thresh = output['status']
return float(temp_high_thresh)/1000
def get_voltage_high_threshold(self):
"""
Retrieves the high threshold PSU voltage output
Returns:
A float number, the high threshold output voltage in volts,
e.g. 12.1
"""
device = "PSU{}".format(self.psu_index)
output = self.pddf_obj.get_attr_name_output(device, "psu_v_out_max")
if not output:
return 0.0
v_out_max = output['status']
return float(v_out_max)/1000
def get_voltage_low_threshold(self):
"""
Retrieves the low threshold PSU voltage output
Returns:
A float number, the low threshold output voltage in volts,
e.g. 12.1
"""
device = "PSU{}".format(self.psu_index)
output = self.pddf_obj.get_attr_name_output(device, "psu_v_out_min")
if not output:
return 0.0
v_out_min = output['status']
return float(v_out_min)/1000
def get_maximum_supplied_power(self):
"""
Retrieves the maximum supplied power by PSU
Returns:
A float number, the maximum power output in Watts.
e.g. 1200.1
"""
device = "PSU{}".format(self.psu_index)
output = self.pddf_obj.get_attr_name_output(device, "psu_p_out_max")
if not output:
return 0.0
p_out_max = output['status']
# max power is in milliwatts
return float(p_out_max)/1000
def get_position_in_parent(self):
"""
Retrieves 1-based relative physical position in parent device.
Returns:
integer: The 1-based relative physical position in parent
device or -1 if cannot determine the position
"""
return self.psu_index
def is_replaceable(self):
"""
Indicate whether PSU is replaceable.
Returns:
bool: True if it is replaceable.
"""
return True
def dump_sysfs(self):
return self.pddf_obj.cli_dump_dsysfs('psu')

View File

@ -40,6 +40,7 @@ class PddfSfp(SfpOptoeBase):
print("Invalid port index %d" % index)
return
# 1-based port index
self.port_index = index+1
self.device = 'PORT{}'.format(self.port_index)
self.sfp_type = self.pddf_obj.get_device_type(self.device)
@ -348,5 +349,22 @@ class PddfSfp(SfpOptoeBase):
return status
def get_position_in_parent(self):
"""
Retrieves 1-based relative physical position in parent device.
Returns:
integer: The 1-based relative physical position in parent
device or -1 if cannot determine the position
"""
return self.port_index
def is_replaceable(self):
"""
Indicate whether the SFP is replaceable.
Returns:
bool: True if it is replaceable.
"""
return True
def dump_sysfs(self):
return self.pddf_obj.cli_dump_dsysfs('xcvr')

View File

@ -13,7 +13,7 @@
try:
from sonic_platform_base.thermal_base import ThermalBase
import os
from subprocess import getstatusoutput
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
@ -141,9 +141,11 @@ class PddfThermal(ThermalBase):
return None
cmd = "echo '%d' > %s" % (temperature * 1000, node)
os.system(cmd)
ret, _ = getstatusoutput(cmd)
if ret == 0:
return (True)
else:
return (False)
else:
raise NotImplementedError
@ -154,9 +156,11 @@ class PddfThermal(ThermalBase):
print("ERROR %s does not exist" % node)
return None
cmd = "echo '%d' > %s" % (temperature * 1000, node)
os.system(cmd)
ret, _ = getstatusoutput(cmd)
if ret == 0:
return (True)
else:
return (False)
else:
raise NotImplementedError
@ -210,19 +214,40 @@ class PddfThermal(ThermalBase):
else:
raise NotImplementedError
def get_position_in_parent(self):
"""
Retrieves 1-based relative physical position in parent device.
Returns:
integer: The 1-based relative physical position in parent
device or -1 if cannot determine the position
"""
return self.thermal_index
def is_replaceable(self):
"""
Indicate whether Thermal is replaceable.
Returns:
bool: True if it is replaceable.
"""
# Usually thermal sensor is not replaceable
return False
# Helper Functions
def get_temp_label(self):
label = None
if 'bmc' in self.pddf_obj.data[self.thermal_obj_name].keys():
return None
return label
else:
if self.thermal_obj_name in self.pddf_obj.data.keys():
dev = self.pddf_obj.data[self.thermal_obj_name]
if 'topo_info' in dev['i2c']:
topo_info = dev['i2c']['topo_info']
label = "%s-i2c-%d-%x" % (topo_info['dev_type'], int(topo_info['parent_bus'], 0),
int(topo_info['dev_addr'], 0))
elif 'path_info' in dev['i2c']:
label = self.get_name()
return (label)
else:
return None
def dump_sysfs(self):
return self.pddf_obj.cli_dump_dsysfs('temp-sensors')

View File

@ -406,15 +406,21 @@ class PddfApi():
for attr in attr_list:
if attr_name == attr['attr_name'] or attr_name == 'all':
path = self.show_device_sysfs(dev, ops)+"/%d-00%x/" % (int(dev['i2c']['topo_info']['parent_bus'], 0),
int(dev['i2c']['topo_info']['dev_addr'], 0))
if 'drv_attr_name' in attr.keys():
real_name = attr['drv_attr_name']
else:
real_name = attr['attr_name']
if 'topo_info' in dev['i2c']:
path = self.show_device_sysfs(dev, ops)+"/%d-00%x/" % (int(dev['i2c']['topo_info']['parent_bus'], 0),
int(dev['i2c']['topo_info']['dev_addr'], 0))
if (os.path.exists(path)):
full_path = glob.glob(path + 'hwmon/hwmon*/' + real_name)[0]
elif 'path_info' in dev['i2c']:
path = dev['i2c']['path_info']['sysfs_base_path']
if (os.path.exists(path)):
full_path = "/".join([path, real_name])
dsysfs_path = full_path
if dsysfs_path not in self.data_sysfs_obj[KEY]:
self.data_sysfs_obj[KEY].append(dsysfs_path)