aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnshuman Khandual <khandual@linux.vnet.ibm.com>2015-03-08 16:16:03 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-03-20 02:35:04 +1100
commit47fde67de057498637875963d99d7eee63cfb84f (patch)
tree44f16e012fd17dcc34c3db4b5ae5f384ebd0c25d
parentc2bdc55a1226ccdff9e3528ac3c0be23e921d88c (diff)
downloadskiboot-47fde67de057498637875963d99d7eee63cfb84f.zip
skiboot-47fde67de057498637875963d99d7eee63cfb84f.tar.gz
skiboot-47fde67de057498637875963d99d7eee63cfb84f.tar.bz2
FSP/LEDS: Serialize the entire LED state change code and it's callback
This patch increase the scope of the lock to cover all data structure manipulation and SPCN command queuing to change the LED state. It also locks the corresponding sections in the function callback. Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r--hw/fsp/fsp-leds.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/hw/fsp/fsp-leds.c b/hw/fsp/fsp-leds.c
index 506e031..df2f945 100644
--- a/hw/fsp/fsp-leds.c
+++ b/hw/fsp/fsp-leds.c
@@ -252,6 +252,8 @@ static void fsp_spcn_set_led_completion(struct fsp_msg *msg)
u8 status = resp->word1 & 0xff00;
struct led_set_cmd *spcn_cmd = (struct led_set_cmd *)msg->user_data;
+ lock(&led_lock);
+
/*
* LED state update request came as part of FSP async message
* FSP_CMD_SET_LED_STATE, hence need to send response message.
@@ -284,6 +286,8 @@ static void fsp_spcn_set_led_completion(struct fsp_msg *msg)
}
}
+ unlock(&led_lock);
+
/* free msg and spcn command */
free(spcn_cmd);
fsp_freemsg(msg);
@@ -319,6 +323,8 @@ static int fsp_msg_set_led_state(struct led_set_cmd *spcn_cmd)
sled.lc_len = strlen(spcn_cmd->loc_code);
strncpy(sled.lc_code, spcn_cmd->loc_code, sled.lc_len);
+ lock(&led_lock);
+
/* Location code length + Location code + LED control */
data_len = LOC_CODE_LEN + sled.lc_len + LED_CONTROL_LEN;
cmd_hdr = SPCN_MOD_SET_LED_CTL_LOC_CODE << 24 | SPCN_CMD_SET << 16 |
@@ -346,6 +352,8 @@ static int fsp_msg_set_led_state(struct led_set_cmd *spcn_cmd)
"|FSP_STATUS_INVALID_LC\n");
}
}
+
+ unlock(&led_lock);
free(spcn_cmd);
return rc;
}
@@ -399,6 +407,7 @@ static int fsp_msg_set_led_state(struct led_set_cmd *spcn_cmd)
msg = fsp_mkmsg(FSP_CMD_SPCN_PASSTHRU, 4,
SPCN_ADDR_MODE_CEC_NODE, cmd_hdr, 0, PSI_DMA_LED_BUF);
if (!msg) {
+ unlock(&led_lock);
free(spcn_cmd);
return rc;
}
@@ -407,10 +416,8 @@ static int fsp_msg_set_led_state(struct led_set_cmd *spcn_cmd)
* Update the local lists based on the attempted SPCN command to
* set/reset an individual led (CEC or ENCL).
*/
- lock(&led_lock);
update_led_list(spcn_cmd->loc_code, sled.state);
msg->user_data = spcn_cmd;
- unlock(&led_lock);
rc = fsp_queue_msg(msg, fsp_spcn_set_led_completion);
if (rc != OPAL_SUCCESS) {
@@ -418,6 +425,7 @@ static int fsp_msg_set_led_state(struct led_set_cmd *spcn_cmd)
free(spcn_cmd);
}
+ unlock(&led_lock);
return rc;
}