mirror of
https://github.com/Telecominfraproject/OpenNetworkLinux.git
synced 2025-12-25 17:27:01 +00:00
Merge pull request #468 from brandonchuang/as5916_54xks
[as5916-54xks] Add cpld watchdog / enhance mutex protection of peripheral drivers
This commit is contained in:
@@ -270,8 +270,6 @@ static struct as5916_54xks_fan_data *as5916_54xks_fan_update_device(void)
|
||||
return data;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data->valid = 0;
|
||||
status = ipmi_send_message(&data->ipmi, IPMI_FAN_READ_CMD, NULL, 0,
|
||||
data->ipmi_resp, sizeof(data->ipmi_resp));
|
||||
@@ -288,7 +286,6 @@ static struct as5916_54xks_fan_data *as5916_54xks_fan_update_device(void)
|
||||
data->valid = 1;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -296,14 +293,17 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *da, char *b
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
unsigned char fid = attr->index / NUM_OF_PER_FAN_ATTR;
|
||||
struct as5916_54xks_fan_data *data = NULL;
|
||||
int value = 0;
|
||||
int index = 0;
|
||||
int present = 0;
|
||||
int error = 0;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data = as5916_54xks_fan_update_device();
|
||||
if (!data->valid) {
|
||||
return -EIO;
|
||||
error = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
index = fid * FAN_DATA_COUNT; /* base index */
|
||||
@@ -336,10 +336,16 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *da, char *b
|
||||
(int)data->ipmi_resp[index + FAN_SPEED1] << 8;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
error = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
return sprintf(buf, "%d\n", present ? value : 0);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
static ssize_t set_fan(struct device *dev, struct device_attribute *da,
|
||||
@@ -357,6 +363,8 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *da,
|
||||
|
||||
pwm = (pwm * 100) / 625 - 1; /* Convert pwm to register value */
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
/* Send IPMI write command */
|
||||
data->ipmi_tx_data[0] = 1; /* All FANs share the same PWM register, ALWAYS set 1 for each fan */
|
||||
data->ipmi_tx_data[1] = 0x02;
|
||||
@@ -364,17 +372,21 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *da,
|
||||
status = ipmi_send_message(&data->ipmi, IPMI_FAN_WRITE_CMD,
|
||||
data->ipmi_tx_data, sizeof(data->ipmi_tx_data), NULL, 0);
|
||||
if (unlikely(status != 0)) {
|
||||
return status;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (unlikely(data->ipmi.rx_result != 0)) {
|
||||
return -EIO;
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Update pwm to ipmi_resp buffer to prevent from the impact of lazy update */
|
||||
data->ipmi_resp[fid * FAN_DATA_COUNT + FAN_PWM] = pwm;
|
||||
status = count;
|
||||
|
||||
return count;
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int as5916_54xks_fan_probe(struct platform_device *pdev)
|
||||
|
||||
@@ -254,8 +254,6 @@ static struct as5916_54xks_led_data *as5916_54xks_led_update_device(void)
|
||||
return data;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data->valid = 0;
|
||||
status = ipmi_send_message(&data->ipmi, IPMI_LED_READ_CMD, NULL, 0,
|
||||
data->ipmi_resp, sizeof(data->ipmi_resp));
|
||||
@@ -272,19 +270,21 @@ static struct as5916_54xks_led_data *as5916_54xks_led_update_device(void)
|
||||
data->valid = 1;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return data;
|
||||
}
|
||||
|
||||
static ssize_t show_led(struct device *dev, struct device_attribute *da, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct as5916_54xks_led_data *data = NULL;
|
||||
int value = 0;
|
||||
int error = 0;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data = as5916_54xks_led_update_device();
|
||||
if (!data->valid) {
|
||||
return -EIO;
|
||||
error = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch (attr->index) {
|
||||
@@ -309,10 +309,16 @@ static ssize_t show_led(struct device *dev, struct device_attribute *da, char *b
|
||||
value = LED_MODE_AUTO;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
error = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
return sprintf(buf, "%d\n", value);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
static ssize_t set_led(struct device *dev, struct device_attribute *da,
|
||||
@@ -321,16 +327,18 @@ static ssize_t set_led(struct device *dev, struct device_attribute *da,
|
||||
long mode;
|
||||
int status;
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct as5916_54xks_led_data *data = NULL;
|
||||
|
||||
status = kstrtol(buf, 10, &mode);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data = as5916_54xks_led_update_device();
|
||||
if (!data->valid) {
|
||||
return -EIO;
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch (attr->index) {
|
||||
@@ -355,21 +363,27 @@ static ssize_t set_led(struct device *dev, struct device_attribute *da,
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -EINVAL;
|
||||
status = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Send IPMI write command */
|
||||
status = ipmi_send_message(&data->ipmi, IPMI_LED_WRITE_CMD,
|
||||
data->ipmi_resp, sizeof(data->ipmi_resp), NULL, 0);
|
||||
if (unlikely(status != 0)) {
|
||||
return status;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (unlikely(data->ipmi.rx_result != 0)) {
|
||||
return -EIO;
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
return count;
|
||||
status = count;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int as5916_54xks_led_probe(struct platform_device *pdev)
|
||||
|
||||
@@ -302,8 +302,6 @@ static struct as5916_54xks_psu_data *as5916_54xks_psu_update_device(struct devic
|
||||
return data;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data->valid[pid] = 0;
|
||||
|
||||
/* Get status from ipmi */
|
||||
@@ -349,7 +347,6 @@ static struct as5916_54xks_psu_data *as5916_54xks_psu_update_device(struct devic
|
||||
data->valid[pid] = 1;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -364,12 +361,15 @@ static ssize_t show_psu(struct device *dev, struct device_attribute *da, char *b
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
unsigned char pid = attr->index / NUM_OF_PER_PSU_ATTR;
|
||||
struct as5916_54xks_psu_data *data = NULL;
|
||||
int value = 0;
|
||||
int error = 0;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data = as5916_54xks_psu_update_device(da);
|
||||
if (!data->valid[pid]) {
|
||||
return -EIO;
|
||||
error = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch (attr->index) {
|
||||
@@ -385,50 +385,59 @@ static ssize_t show_psu(struct device *dev, struct device_attribute *da, char *b
|
||||
case PSU1_VOUT:
|
||||
case PSU2_VOUT:
|
||||
VALIDATE_PRESENT_RETURN(pid);
|
||||
value = ((int)data->ipmi_resp[pid].status[PSU_VOUT0] |
|
||||
(int)data->ipmi_resp[pid].status[PSU_VOUT1] << 8) * 1000;
|
||||
value = ((u32)data->ipmi_resp[pid].status[PSU_VOUT0] |
|
||||
(u32)data->ipmi_resp[pid].status[PSU_VOUT1] << 8) * 1000;
|
||||
break;
|
||||
case PSU1_IOUT:
|
||||
case PSU2_IOUT:
|
||||
VALIDATE_PRESENT_RETURN(pid);
|
||||
value = ((int)data->ipmi_resp[pid].status[PSU_IOUT0] |
|
||||
(int)data->ipmi_resp[pid].status[PSU_IOUT1] << 8) * 1000;
|
||||
value = ((u32)data->ipmi_resp[pid].status[PSU_IOUT0] |
|
||||
(u32)data->ipmi_resp[pid].status[PSU_IOUT1] << 8) * 1000;
|
||||
break;
|
||||
case PSU1_POUT:
|
||||
case PSU2_POUT:
|
||||
VALIDATE_PRESENT_RETURN(pid);
|
||||
value = ((int)data->ipmi_resp[pid].status[PSU_POUT0] |
|
||||
(int)data->ipmi_resp[pid].status[PSU_POUT1] << 8) * 1000;
|
||||
value = ((u32)data->ipmi_resp[pid].status[PSU_POUT0] |
|
||||
(u32)data->ipmi_resp[pid].status[PSU_POUT1] << 8) * 1000;
|
||||
break;
|
||||
case PSU1_TEMP_INPUT:
|
||||
case PSU2_TEMP_INPUT:
|
||||
VALIDATE_PRESENT_RETURN(pid);
|
||||
value = ((int)data->ipmi_resp[pid].status[PSU_TEMP0] |
|
||||
(int)data->ipmi_resp[pid].status[PSU_TEMP1] << 8) * 1000;
|
||||
value = ((u32)data->ipmi_resp[pid].status[PSU_TEMP0] |
|
||||
(u32)data->ipmi_resp[pid].status[PSU_TEMP1] << 8) * 1000;
|
||||
break;
|
||||
case PSU1_FAN_INPUT:
|
||||
case PSU2_FAN_INPUT:
|
||||
VALIDATE_PRESENT_RETURN(pid);
|
||||
value = ((int)data->ipmi_resp[pid].status[PSU_FAN0] |
|
||||
(int)data->ipmi_resp[pid].status[PSU_FAN1] << 8);
|
||||
value = ((u32)data->ipmi_resp[pid].status[PSU_FAN0] |
|
||||
(u32)data->ipmi_resp[pid].status[PSU_FAN1] << 8);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
error = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
return sprintf(buf, "%d\n", value);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
static ssize_t show_string(struct device *dev, struct device_attribute *da, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
unsigned char pid = attr->index / NUM_OF_PER_PSU_ATTR;
|
||||
struct as5916_54xks_psu_data *data;
|
||||
char *str = NULL;
|
||||
int error = 0;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data = as5916_54xks_psu_update_device(da);
|
||||
if (!data->valid[pid]) {
|
||||
return -EIO;
|
||||
error = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch (attr->index) {
|
||||
@@ -443,10 +452,16 @@ static ssize_t show_string(struct device *dev, struct device_attribute *da, char
|
||||
str = data->ipmi_resp[pid].serial;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
error = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
return sprintf(buf, "%s\n", str);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int as5916_54xks_psu_probe(struct platform_device *pdev)
|
||||
|
||||
@@ -493,8 +493,6 @@ static struct as5916_54xks_sfp_data *as5916_54xks_sfp_update_present(void)
|
||||
return data;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data->ipmi_resp.sfp_valid[SFP_PRESENT] = 0;
|
||||
|
||||
/* Get status from ipmi */
|
||||
@@ -516,7 +514,6 @@ static struct as5916_54xks_sfp_data *as5916_54xks_sfp_update_present(void)
|
||||
data->ipmi_resp.sfp_valid[SFP_PRESENT] = 1;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -529,8 +526,6 @@ static struct as5916_54xks_sfp_data *as5916_54xks_sfp_update_txdisable(void)
|
||||
return data;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data->ipmi_resp.sfp_valid[SFP_TXDISABLE] = 0;
|
||||
|
||||
/* Get status from ipmi */
|
||||
@@ -552,7 +547,6 @@ static struct as5916_54xks_sfp_data *as5916_54xks_sfp_update_txdisable(void)
|
||||
data->ipmi_resp.sfp_valid[SFP_TXDISABLE] = 1;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -565,8 +559,6 @@ static struct as5916_54xks_sfp_data *as5916_54xks_sfp_update_txfault(void)
|
||||
return data;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data->ipmi_resp.sfp_valid[SFP_TXFAULT] = 0;
|
||||
|
||||
/* Get status from ipmi */
|
||||
@@ -588,7 +580,6 @@ static struct as5916_54xks_sfp_data *as5916_54xks_sfp_update_txfault(void)
|
||||
data->ipmi_resp.sfp_valid[SFP_TXFAULT] = 1;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -601,8 +592,6 @@ static struct as5916_54xks_sfp_data *as5916_54xks_sfp_update_rxlos(void)
|
||||
return data;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data->ipmi_resp.sfp_valid[SFP_RXLOS] = 0;
|
||||
|
||||
/* Get status from ipmi */
|
||||
@@ -624,7 +613,6 @@ static struct as5916_54xks_sfp_data *as5916_54xks_sfp_update_rxlos(void)
|
||||
data->ipmi_resp.sfp_valid[SFP_RXLOS] = 1;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -637,8 +625,6 @@ static struct as5916_54xks_sfp_data *as5916_54xks_qsfp_update_present(void)
|
||||
return data;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data->ipmi_resp.qsfp_valid[QSFP_PRESENT] = 0;
|
||||
|
||||
/* Get status from ipmi */
|
||||
@@ -660,7 +646,6 @@ static struct as5916_54xks_sfp_data *as5916_54xks_qsfp_update_present(void)
|
||||
data->ipmi_resp.qsfp_valid[QSFP_PRESENT] = 1;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -673,8 +658,6 @@ static struct as5916_54xks_sfp_data *as5916_54xks_qsfp_update_txdisable(void)
|
||||
return data;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data->ipmi_resp.qsfp_valid[QSFP_TXDISABLE] = 0;
|
||||
|
||||
/* Get status from ipmi */
|
||||
@@ -696,7 +679,6 @@ static struct as5916_54xks_sfp_data *as5916_54xks_qsfp_update_txdisable(void)
|
||||
data->ipmi_resp.qsfp_valid[QSFP_TXDISABLE] = 1;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -709,8 +691,6 @@ static struct as5916_54xks_sfp_data *as5916_54xks_qsfp_update_reset(void)
|
||||
return data;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data->ipmi_resp.qsfp_valid[QSFP_RESET] = 0;
|
||||
|
||||
/* Get status from ipmi */
|
||||
@@ -732,7 +712,6 @@ static struct as5916_54xks_sfp_data *as5916_54xks_qsfp_update_reset(void)
|
||||
data->ipmi_resp.qsfp_valid[QSFP_RESET] = 1;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -745,8 +724,6 @@ static struct as5916_54xks_sfp_data *as5916_54xks_qsfp_update_lpmode(void)
|
||||
return data;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data->ipmi_resp.qsfp_valid[QSFP_LPMODE] = 0;
|
||||
|
||||
/* Get status from ipmi */
|
||||
@@ -768,27 +745,29 @@ static struct as5916_54xks_sfp_data *as5916_54xks_qsfp_update_lpmode(void)
|
||||
data->ipmi_resp.qsfp_valid[QSFP_LPMODE] = 1;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return data;
|
||||
}
|
||||
|
||||
static ssize_t show_all(struct device *dev, struct device_attribute *da, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct as5916_54xks_sfp_data *data = NULL;
|
||||
u64 values = 0;
|
||||
int i;
|
||||
|
||||
switch (attr->index) {
|
||||
case PRESENT_ALL:
|
||||
{
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data = as5916_54xks_sfp_update_present();
|
||||
if (!data->ipmi_resp.sfp_valid[SFP_PRESENT]) {
|
||||
mutex_unlock(&data->update_lock);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
data = as5916_54xks_qsfp_update_present();
|
||||
if (!data->ipmi_resp.qsfp_valid[QSFP_PRESENT]) {
|
||||
mutex_unlock(&data->update_lock);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -803,6 +782,8 @@ static ssize_t show_all(struct device *dev, struct device_attribute *da, char *b
|
||||
values <<= 1;
|
||||
values |= (data->ipmi_resp.sfp_resp[SFP_PRESENT][i] & 0x1);
|
||||
}
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
/* Return values 1 -> 54 in order */
|
||||
return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x %.2x\n",
|
||||
@@ -816,8 +797,11 @@ static ssize_t show_all(struct device *dev, struct device_attribute *da, char *b
|
||||
}
|
||||
case RXLOS_ALL:
|
||||
{
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data = as5916_54xks_sfp_update_rxlos();
|
||||
if (!data->ipmi_resp.sfp_valid[SFP_RXLOS]) {
|
||||
mutex_unlock(&data->update_lock);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -827,6 +811,8 @@ static ssize_t show_all(struct device *dev, struct device_attribute *da, char *b
|
||||
values |= !(data->ipmi_resp.sfp_resp[SFP_RXLOS][i] & 0x1);
|
||||
}
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
/* Return values 1 -> 48 in order */
|
||||
return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n",
|
||||
(unsigned int)(0xFF & values),
|
||||
@@ -847,8 +833,10 @@ static ssize_t show_sfp(struct device *dev, struct device_attribute *da, char *b
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
unsigned char pid = attr->index / NUM_OF_PER_SFP_ATTR; /* port id, 0 based */
|
||||
struct as5916_54xks_sfp_data *data = NULL;
|
||||
int value = 0;
|
||||
int error = 0;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
switch (attr->index) {
|
||||
case SFP1_PRESENT:
|
||||
@@ -902,7 +890,8 @@ static ssize_t show_sfp(struct device *dev, struct device_attribute *da, char *b
|
||||
{
|
||||
data = as5916_54xks_sfp_update_present();
|
||||
if (!data->ipmi_resp.sfp_valid[SFP_PRESENT]) {
|
||||
return -EIO;
|
||||
error = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
value = data->ipmi_resp.sfp_resp[SFP_PRESENT][pid];
|
||||
@@ -959,7 +948,8 @@ static ssize_t show_sfp(struct device *dev, struct device_attribute *da, char *b
|
||||
{
|
||||
data = as5916_54xks_sfp_update_txdisable();
|
||||
if (!data->ipmi_resp.sfp_valid[SFP_TXDISABLE]) {
|
||||
return -EIO;
|
||||
error = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
value = !data->ipmi_resp.sfp_resp[SFP_TXDISABLE][pid];
|
||||
@@ -1016,7 +1006,8 @@ static ssize_t show_sfp(struct device *dev, struct device_attribute *da, char *b
|
||||
{
|
||||
data = as5916_54xks_sfp_update_txfault();
|
||||
if (!data->ipmi_resp.sfp_valid[SFP_TXFAULT]) {
|
||||
return -EIO;
|
||||
error = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
value = data->ipmi_resp.sfp_resp[SFP_TXFAULT][pid];
|
||||
@@ -1073,17 +1064,24 @@ static ssize_t show_sfp(struct device *dev, struct device_attribute *da, char *b
|
||||
{
|
||||
data = as5916_54xks_sfp_update_rxlos();
|
||||
if (!data->ipmi_resp.sfp_valid[SFP_RXLOS]) {
|
||||
return -EIO;
|
||||
error = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
value = !data->ipmi_resp.sfp_resp[SFP_RXLOS][pid];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -EINVAL;
|
||||
error = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
return sprintf(buf, "%d\n", value);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
static ssize_t set_sfp(struct device *dev, struct device_attribute *da,
|
||||
@@ -1101,6 +1099,8 @@ static ssize_t set_sfp(struct device *dev, struct device_attribute *da,
|
||||
|
||||
disable = !disable; /* the IPMI cmd is 0 for tx-disable and 1 for tx-enable */
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
/* Send IPMI write command */
|
||||
data->ipmi_tx_data[0] = pid + 1; /* Port ID base id for ipmi start from 1 */
|
||||
data->ipmi_tx_data[1] = 0x01;
|
||||
@@ -1108,25 +1108,31 @@ static ssize_t set_sfp(struct device *dev, struct device_attribute *da,
|
||||
status = ipmi_send_message(&data->ipmi, IPMI_SFP_WRITE_CMD,
|
||||
data->ipmi_tx_data, sizeof(data->ipmi_tx_data), NULL, 0);
|
||||
if (unlikely(status != 0)) {
|
||||
return status;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (unlikely(data->ipmi.rx_result != 0)) {
|
||||
return -EIO;
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Update to ipmi_resp buffer to prevent from the impact of lazy update */
|
||||
data->ipmi_resp.sfp_resp[SFP_TXDISABLE][pid] = disable;
|
||||
status = count;
|
||||
|
||||
return count;
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
static ssize_t show_qsfp(struct device *dev, struct device_attribute *da, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
unsigned char pid = attr->index / NUM_OF_PER_QSFP_ATTR; /* port id, 0 based */
|
||||
struct as5916_54xks_sfp_data *data = NULL;
|
||||
int value = 0;
|
||||
int error = 0;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
switch (attr->index) {
|
||||
case QSFP49_PRESENT:
|
||||
@@ -1138,7 +1144,8 @@ static ssize_t show_qsfp(struct device *dev, struct device_attribute *da, char *
|
||||
{
|
||||
data = as5916_54xks_qsfp_update_present();
|
||||
if (!data->ipmi_resp.qsfp_valid[QSFP_PRESENT]) {
|
||||
return -EIO;
|
||||
error = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
value = data->ipmi_resp.qsfp_resp[QSFP_PRESENT][pid];
|
||||
@@ -1153,7 +1160,8 @@ static ssize_t show_qsfp(struct device *dev, struct device_attribute *da, char *
|
||||
{
|
||||
data = as5916_54xks_qsfp_update_txdisable();
|
||||
if (!data->ipmi_resp.qsfp_valid[QSFP_TXDISABLE]) {
|
||||
return -EIO;
|
||||
error = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
value = !!data->ipmi_resp.qsfp_resp[QSFP_TXDISABLE][pid];
|
||||
@@ -1168,7 +1176,8 @@ static ssize_t show_qsfp(struct device *dev, struct device_attribute *da, char *
|
||||
{
|
||||
data = as5916_54xks_qsfp_update_reset();
|
||||
if (!data->ipmi_resp.qsfp_valid[QSFP_RESET]) {
|
||||
return -EIO;
|
||||
error = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
value = !data->ipmi_resp.qsfp_resp[QSFP_RESET][pid];
|
||||
@@ -1183,17 +1192,24 @@ static ssize_t show_qsfp(struct device *dev, struct device_attribute *da, char *
|
||||
{
|
||||
data = as5916_54xks_qsfp_update_lpmode();
|
||||
if (!data->ipmi_resp.qsfp_valid[QSFP_LPMODE]) {
|
||||
return -EIO;
|
||||
error = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
value = data->ipmi_resp.qsfp_resp[QSFP_LPMODE][pid];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -EINVAL;
|
||||
error = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
return sprintf(buf, "%d\n", value);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
static ssize_t set_qsfp_txdisable(struct device *dev, struct device_attribute *da,
|
||||
@@ -1203,20 +1219,23 @@ static ssize_t set_qsfp_txdisable(struct device *dev, struct device_attribute *d
|
||||
int status;
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
unsigned char pid = attr->index / NUM_OF_PER_QSFP_ATTR; /* port id, 0 based */
|
||||
struct as5916_54xks_sfp_data *data = NULL;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data = as5916_54xks_qsfp_update_present();
|
||||
if (!data->ipmi_resp.qsfp_valid[QSFP_PRESENT]) {
|
||||
return -EIO;
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!data->ipmi_resp.qsfp_resp[QSFP_PRESENT][pid]) {
|
||||
return -ENXIO;
|
||||
status = -ENXIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = kstrtol(buf, 10, &disable);
|
||||
if (status) {
|
||||
return status;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Send IPMI write command */
|
||||
@@ -1226,17 +1245,21 @@ static ssize_t set_qsfp_txdisable(struct device *dev, struct device_attribute *d
|
||||
status = ipmi_send_message(&data->ipmi, IPMI_QSFP_WRITE_CMD,
|
||||
data->ipmi_tx_data, sizeof(data->ipmi_tx_data), NULL, 0);
|
||||
if (unlikely(status != 0)) {
|
||||
return status;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (unlikely(data->ipmi.rx_result != 0)) {
|
||||
return -EIO;
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Update to ipmi_resp buffer to prevent from the impact of lazy update */
|
||||
data->ipmi_resp.qsfp_resp[QSFP_TXDISABLE][pid] = disable;
|
||||
status = count;
|
||||
|
||||
return count;
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
static ssize_t set_qsfp_reset(struct device *dev, struct device_attribute *da,
|
||||
@@ -1254,6 +1277,8 @@ static ssize_t set_qsfp_reset(struct device *dev, struct device_attribute *da,
|
||||
|
||||
reset = !reset; /* the IPMI cmd is 0 for reset and 1 for out of reset */
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
/* Send IPMI write command */
|
||||
data->ipmi_tx_data[0] = pid + 1; /* Port ID base id for ipmi start from 1 */
|
||||
data->ipmi_tx_data[1] = 0x11;
|
||||
@@ -1261,17 +1286,21 @@ static ssize_t set_qsfp_reset(struct device *dev, struct device_attribute *da,
|
||||
status = ipmi_send_message(&data->ipmi, IPMI_QSFP_WRITE_CMD,
|
||||
data->ipmi_tx_data, sizeof(data->ipmi_tx_data), NULL, 0);
|
||||
if (unlikely(status != 0)) {
|
||||
return status;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (unlikely(data->ipmi.rx_result != 0)) {
|
||||
return -EIO;
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Update to ipmi_resp buffer to prevent from the impact of lazy update */
|
||||
data->ipmi_resp.qsfp_resp[QSFP_RESET][pid] = reset;
|
||||
|
||||
return count;
|
||||
status = count;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
static ssize_t set_qsfp_lpmode(struct device *dev, struct device_attribute *da,
|
||||
@@ -1287,6 +1316,8 @@ static ssize_t set_qsfp_lpmode(struct device *dev, struct device_attribute *da,
|
||||
return status;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
/* Send IPMI write command */
|
||||
data->ipmi_tx_data[0] = pid + 1; /* Port ID base id for ipmi start from 1 */
|
||||
data->ipmi_tx_data[1] = 0x12;
|
||||
@@ -1294,17 +1325,21 @@ static ssize_t set_qsfp_lpmode(struct device *dev, struct device_attribute *da,
|
||||
status = ipmi_send_message(&data->ipmi, IPMI_QSFP_WRITE_CMD,
|
||||
data->ipmi_tx_data, sizeof(data->ipmi_tx_data), NULL, 0);
|
||||
if (unlikely(status != 0)) {
|
||||
return status;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (unlikely(data->ipmi.rx_result != 0)) {
|
||||
return -EIO;
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Update to ipmi_resp buffer to prevent from the impact of lazy update */
|
||||
data->ipmi_resp.qsfp_resp[QSFP_LPMODE][pid] = lpmode;
|
||||
|
||||
return count;
|
||||
status = count;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*************************************************************************************
|
||||
|
||||
@@ -52,6 +52,9 @@
|
||||
#define CPU_CPLD_ADDR 0x65
|
||||
#define FAN_CPLD_ADDR 0x66
|
||||
|
||||
#define IPMI_CPLD_READ_CMD 0x22
|
||||
#define IPMI_CPLD_WRITE_CMD 0x23
|
||||
|
||||
static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data);
|
||||
static int as5916_54xks_sys_probe(struct platform_device *pdev);
|
||||
static int as5916_54xks_sys_remove(struct platform_device *pdev);
|
||||
@@ -62,6 +65,9 @@ static ssize_t show_interrupt_status_6(struct device *dev, struct device_attribu
|
||||
static ssize_t set_interrupt_status_6_mask(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count);
|
||||
static ssize_t show_cpld_version(struct device *dev, struct device_attribute *da, char *buf);
|
||||
static ssize_t show_watchdog(struct device *dev, struct device_attribute *da, char *buf);
|
||||
static ssize_t set_watchdog(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count);
|
||||
|
||||
struct ipmi_data {
|
||||
struct completion read_complete;
|
||||
@@ -132,6 +138,11 @@ enum as5916_54xks_sys_sysfs_attrs {
|
||||
MB_CPLD2_VER, /* mainboard cpld2 version */
|
||||
CPU_CPLD_VER, /* CPU board CPLD version */
|
||||
FAN_CPLD_VER, /* FAN CPLD version */
|
||||
CPU_CPLD_WDS1,/* CPU board CPLD Offset 0x02 Watch Dog Status_1 */
|
||||
CPU_CPLD_WDS2,/* CPU board CPLD Offset 0x03 Watch Dog Status_2 */
|
||||
CPU_CPLD_SR, /* CPU board CPLD Offset 0x04 System Reset */
|
||||
CPU_CPLD_LRS, /* CPU board CPLD Offset 0x24 Last Reset Reason Register */
|
||||
MB_CPLD_SR1, /* main board CPLD Offset 0x08 System Reset-1 */
|
||||
};
|
||||
|
||||
static SENSOR_DEVICE_ATTR(tcam_rst_c, S_IWUSR | S_IRUGO, show_sys_reset_6, set_sys_reset_6, TCAM_CRST_L);
|
||||
@@ -145,6 +156,12 @@ static SENSOR_DEVICE_ATTR(mb_cpld1_ver, S_IRUGO, show_cpld_version, NULL, MB_CPL
|
||||
static SENSOR_DEVICE_ATTR(mb_cpld2_ver, S_IRUGO, show_cpld_version, NULL, MB_CPLD2_VER);
|
||||
static SENSOR_DEVICE_ATTR(cpu_cpld_ver, S_IRUGO, show_cpld_version, NULL, CPU_CPLD_VER);
|
||||
static SENSOR_DEVICE_ATTR(fan_cpld_ver, S_IRUGO, show_cpld_version, NULL, FAN_CPLD_VER);
|
||||
static SENSOR_DEVICE_ATTR(cpu_cpld_wds1, S_IWUSR | S_IRUGO, show_watchdog, set_watchdog, CPU_CPLD_WDS1);
|
||||
static SENSOR_DEVICE_ATTR(cpu_cpld_wds2, S_IWUSR | S_IRUGO, show_watchdog, set_watchdog, CPU_CPLD_WDS2);
|
||||
static SENSOR_DEVICE_ATTR(cpu_cpld_system_reset, S_IWUSR | S_IRUGO, show_watchdog, set_watchdog, CPU_CPLD_SR);
|
||||
static SENSOR_DEVICE_ATTR(cpu_cpld_last_reset_reson, S_IRUGO, show_watchdog, NULL, CPU_CPLD_LRS);
|
||||
static SENSOR_DEVICE_ATTR(mb_cpld1_system_reset1, S_IWUSR | S_IRUGO, show_watchdog, set_watchdog, MB_CPLD_SR1);
|
||||
|
||||
|
||||
static struct attribute *as5916_54xks_sys_attributes[] = {
|
||||
&sensor_dev_attr_tcam_rst_c.dev_attr.attr,
|
||||
@@ -158,6 +175,11 @@ static struct attribute *as5916_54xks_sys_attributes[] = {
|
||||
&sensor_dev_attr_mb_cpld2_ver.dev_attr.attr,
|
||||
&sensor_dev_attr_cpu_cpld_ver.dev_attr.attr,
|
||||
&sensor_dev_attr_fan_cpld_ver.dev_attr.attr,
|
||||
&sensor_dev_attr_cpu_cpld_wds1.dev_attr.attr,
|
||||
&sensor_dev_attr_cpu_cpld_wds2.dev_attr.attr,
|
||||
&sensor_dev_attr_cpu_cpld_system_reset.dev_attr.attr,
|
||||
&sensor_dev_attr_cpu_cpld_last_reset_reson.dev_attr.attr,
|
||||
&sensor_dev_attr_mb_cpld1_system_reset1.dev_attr.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -367,8 +389,6 @@ static struct as5916_54xks_sys_data *as5916_54xks_sys_update_tcam(unsigned char
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data->valid = 0;
|
||||
data->ipmi_tx_data[0] = subcmd;
|
||||
status = ipmi_send_message(&data->ipmi, IPMI_TCAM_READ_CMD, data->ipmi_tx_data, 1,
|
||||
@@ -386,7 +406,6 @@ static struct as5916_54xks_sys_data *as5916_54xks_sys_update_tcam(unsigned char
|
||||
data->valid = 1;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -396,16 +415,18 @@ static ssize_t set_sys_reset_6(struct device *dev, struct device_attribute *da,
|
||||
long reset; /* reset value to be set */
|
||||
int status;
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct as5916_54xks_sys_data *data = NULL;
|
||||
|
||||
status = kstrtol(buf, 10, &reset);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data = as5916_54xks_sys_update_tcam(IPMI_TCAM_RESET_SUBCMD);
|
||||
if (!data->valid) {
|
||||
return -EIO;
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch (attr->index) {
|
||||
@@ -427,7 +448,8 @@ static ssize_t set_sys_reset_6(struct device *dev, struct device_attribute *da,
|
||||
data->ipmi_tx_data[1] = reset;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
status = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Send IPMI write command */
|
||||
@@ -435,25 +457,33 @@ static ssize_t set_sys_reset_6(struct device *dev, struct device_attribute *da,
|
||||
status = ipmi_send_message(&data->ipmi, IPMI_TCAM_WRITE_CMD,
|
||||
data->ipmi_tx_data, 2, NULL, 0);
|
||||
if (unlikely(status != 0)) {
|
||||
return status;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (unlikely(data->ipmi.rx_result != 0)) {
|
||||
return -EIO;
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
return count;
|
||||
status = count;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
static ssize_t show_sys_reset_6(struct device *dev, struct device_attribute *da, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct as5916_54xks_sys_data *data = NULL;
|
||||
int value = 0;
|
||||
int error = 0;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data = as5916_54xks_sys_update_tcam(IPMI_TCAM_RESET_SUBCMD);
|
||||
if (!data->valid) {
|
||||
return -EIO;
|
||||
error = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch (attr->index) {
|
||||
@@ -474,18 +504,24 @@ static ssize_t show_sys_reset_6(struct device *dev, struct device_attribute *da,
|
||||
value = data->ipmi_resp_tcam & 0xff;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
error = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
return sprintf(buf, "%d\n", value);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
static ssize_t show_interrupt_status_6(struct device *dev, struct device_attribute *da, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct as5916_54xks_sys_data *data = NULL;
|
||||
unsigned char subcmd = 0;
|
||||
int value = 0;
|
||||
int error = 0;
|
||||
|
||||
switch (attr->index) {
|
||||
case TCAM_CPLD1_GIO_L:
|
||||
@@ -498,13 +534,21 @@ static ssize_t show_interrupt_status_6(struct device *dev, struct device_attribu
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data = as5916_54xks_sys_update_tcam(subcmd);
|
||||
if (!data->valid) {
|
||||
return -EIO;
|
||||
error = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
value = data->ipmi_resp_tcam & 0x3;
|
||||
mutex_unlock(&data->update_lock);
|
||||
return sprintf(buf, "%d\n", value);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
static ssize_t set_interrupt_status_6_mask(struct device *dev, struct device_attribute *da,
|
||||
@@ -512,16 +556,18 @@ static ssize_t set_interrupt_status_6_mask(struct device *dev, struct device_att
|
||||
{
|
||||
long mask = 0; /* mask value to be set */
|
||||
int status;
|
||||
struct as5916_54xks_sys_data *data = NULL;
|
||||
|
||||
status = kstrtol(buf, 10, &mask);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data = as5916_54xks_sys_update_tcam(IPMI_TCAM_INT_MASK_SUBCMD);
|
||||
if (!data->valid) {
|
||||
return -EIO;
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Send IPMI write command */
|
||||
@@ -530,22 +576,25 @@ static ssize_t set_interrupt_status_6_mask(struct device *dev, struct device_att
|
||||
status = ipmi_send_message(&data->ipmi, IPMI_TCAM_WRITE_CMD,
|
||||
data->ipmi_tx_data, 2, NULL, 0);
|
||||
if (unlikely(status != 0)) {
|
||||
return status;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (unlikely(data->ipmi.rx_result != 0)) {
|
||||
return -EIO;
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
return count;
|
||||
status = count;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
static struct as5916_54xks_sys_data *as5916_54xks_sys_update_cpld_ver(unsigned char cpld_addr)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data->valid = 0;
|
||||
data->ipmi_tx_data[0] = cpld_addr;
|
||||
status = ipmi_send_message(&data->ipmi, IPMI_GET_CPLD_VER_CMD, data->ipmi_tx_data, 1,
|
||||
@@ -563,15 +612,14 @@ static struct as5916_54xks_sys_data *as5916_54xks_sys_update_cpld_ver(unsigned c
|
||||
data->valid = 1;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return data;
|
||||
}
|
||||
|
||||
static ssize_t show_cpld_version(struct device *dev, struct device_attribute *da, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct as5916_54xks_sys_data *data = NULL;
|
||||
unsigned char cpld_addr = 0;
|
||||
unsigned char cpld_addr = 0, value = 0;
|
||||
int error = 0;
|
||||
|
||||
switch (attr->index) {
|
||||
case MB_CPLD1_VER:
|
||||
@@ -590,12 +638,165 @@ static ssize_t show_cpld_version(struct device *dev, struct device_attribute *da
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data = as5916_54xks_sys_update_cpld_ver(cpld_addr);
|
||||
if (!data->valid) {
|
||||
return -EIO;
|
||||
error = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
return sprintf(buf, "%d\n", data->ipmi_resp_cpld);
|
||||
value = data->ipmi_resp_cpld;
|
||||
mutex_unlock(&data->update_lock);
|
||||
return sprintf(buf, "%d\n", value);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
static struct as5916_54xks_sys_data *as5916_54xks_sys_update_watchdog(unsigned char cpld_addr,
|
||||
unsigned char reg)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
data->valid = 0;
|
||||
data->ipmi_tx_data[0] = cpld_addr;
|
||||
data->ipmi_tx_data[1] = reg;
|
||||
status = ipmi_send_message(&data->ipmi, IPMI_CPLD_READ_CMD, data->ipmi_tx_data, 2,
|
||||
&data->ipmi_resp_cpld, sizeof(data->ipmi_resp_cpld));
|
||||
if (unlikely(status != 0)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (unlikely(data->ipmi.rx_result != 0)) {
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
data->last_updated = jiffies;
|
||||
data->valid = 1;
|
||||
|
||||
exit:
|
||||
return data;
|
||||
}
|
||||
|
||||
/* Get CPLD<4C><44>s Offset Value
|
||||
* ipmitool raw 0x34 0x22 <I2CAddress of CPLD > <Offset>
|
||||
* # ipmitool raw 0x34 0x22 0x65 0x02
|
||||
* # ipmitool raw 0x34 0x22 0x65 0x03
|
||||
* # ipmitool raw 0x34 0x22 0x65 0x04
|
||||
* # ipmitool raw 0x34 0x22 0x65 0x24
|
||||
* # ipmitool raw 0x34 0x22 0x60 0x08
|
||||
*/
|
||||
static ssize_t show_watchdog(struct device *dev, struct device_attribute *da, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
unsigned char cpld_addr = 0, reg = 0, value = 0;
|
||||
int error = 0;
|
||||
|
||||
switch (attr->index) {
|
||||
case CPU_CPLD_WDS1:
|
||||
cpld_addr = CPU_CPLD_ADDR;
|
||||
reg = 0x2;
|
||||
break;
|
||||
case CPU_CPLD_WDS2:
|
||||
cpld_addr = CPU_CPLD_ADDR;
|
||||
reg = 0x3;
|
||||
break;
|
||||
case CPU_CPLD_SR:
|
||||
cpld_addr = CPU_CPLD_ADDR;
|
||||
reg = 0x4;
|
||||
break;
|
||||
case CPU_CPLD_LRS:
|
||||
cpld_addr = CPU_CPLD_ADDR;
|
||||
reg = 0x24;
|
||||
break;
|
||||
case MB_CPLD_SR1:
|
||||
cpld_addr = MAINBOARD_CPLD1_ADDR;
|
||||
reg = 0x8;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data = as5916_54xks_sys_update_watchdog(cpld_addr, reg);
|
||||
if (!data->valid) {
|
||||
error = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
value = data->ipmi_resp_cpld;
|
||||
mutex_unlock(&data->update_lock);
|
||||
return sprintf(buf, "%d\n", value);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Set CPLDValue
|
||||
* # ipmitool raw 0x34 0x23 <I2CAddress of CPLD > <Offset> <Value>
|
||||
* # ipmitool raw 0x34 0x23 0x65 0x03 0x08
|
||||
*/
|
||||
static ssize_t set_watchdog(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
long value = 0; /* cpld value to be set */
|
||||
int status;
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
unsigned char cpld_addr = 0, reg = 0;
|
||||
|
||||
status = kstrtol(buf, 10, &value);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
|
||||
switch (attr->index) {
|
||||
case CPU_CPLD_WDS1:
|
||||
cpld_addr = CPU_CPLD_ADDR;
|
||||
reg = 0x2;
|
||||
break;
|
||||
case CPU_CPLD_WDS2:
|
||||
cpld_addr = CPU_CPLD_ADDR;
|
||||
reg = 0x3;
|
||||
break;
|
||||
case CPU_CPLD_SR:
|
||||
cpld_addr = CPU_CPLD_ADDR;
|
||||
reg = 0x4;
|
||||
break;
|
||||
case MB_CPLD_SR1:
|
||||
cpld_addr = MAINBOARD_CPLD1_ADDR;
|
||||
reg = 0x8;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
/* Send IPMI write command */
|
||||
data->ipmi_tx_data[0] = cpld_addr;
|
||||
data->ipmi_tx_data[1] = reg;
|
||||
data->ipmi_tx_data[2] = value;
|
||||
status = ipmi_send_message(&data->ipmi, IPMI_CPLD_WRITE_CMD,
|
||||
data->ipmi_tx_data, 3, NULL, 0);
|
||||
if (unlikely(status != 0)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (unlikely(data->ipmi.rx_result != 0)) {
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = count;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int as5916_54xks_sys_probe(struct platform_device *pdev)
|
||||
|
||||
@@ -244,8 +244,6 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *da, char *
|
||||
data->valid = 1;
|
||||
}
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
/* Get temp fault status */
|
||||
index = attr->index * TEMP_DATA_COUNT + TEMP_FAULT;
|
||||
if (unlikely(data->ipmi_resp[index] == 0)) {
|
||||
@@ -257,6 +255,7 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *da, char *
|
||||
index = attr->index * TEMP_DATA_COUNT + TEMP_INPUT;
|
||||
status = data->ipmi_resp[index] * 1000;
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
return sprintf(buf, "%d\n", status);
|
||||
|
||||
exit:
|
||||
|
||||
Reference in New Issue
Block a user