in meta-facebook/meta-fby2/recipes-fby2/gpiointrd/files/gpiointrd.c [547:746]
static void gpio_event_handle(gpiopoll_pin_t *gp, gpio_value_t last, gpio_value_t curr)
{
char cmd[128] = {0};
uint8_t slot_id;
uint8_t slot_12v = 1;
int value;
char vpath[80] = {0};
char locstr[MAX_VALUE_LEN];
static bool prsnt_assert[MAX_NODES + 1]={0};
static pthread_t hsvc_action_tid[MAX_NODES + 1];
static pthread_t latch_open_tid[MAX_NODES + 1];
hot_service_info hsvc_info[MAX_NODES + 1];
uint8_t action;
struct timespec ts;
pthread_t hsc_alert_tid;
const struct gpiopoll_config *cfg = gpio_poll_get_config(gp);
if (strncmp(cfg->shadow, "FAN_LATCH_DETECT", sizeof(cfg->shadow)) == 0) { // GPIO_FAN_LATCH_DETECT
if (curr == 1) { // low to high
syslog(LOG_CRIT, "ASSERT: SLED is not seated");
action = OPEN;
} else { // high to low
syslog(LOG_CRIT, "DEASSERT: SLED is seated");
action = CLOSE;
}
fan_latch_action(action);
}
else if ((strncmp(cfg->shadow, "SLOT1_EJECTOR_LATCH_DETECT_N", sizeof(cfg->shadow)) == 0) || (strncmp(cfg->shadow, "SLOT2_EJECTOR_LATCH_DETECT_N", sizeof(cfg->shadow)) == 0) ||
(strncmp(cfg->shadow, "SLOT3_EJECTOR_LATCH_DETECT_N", sizeof(cfg->shadow)) == 0) || (strncmp(cfg->shadow, "SLOT4_EJECTOR_LATCH_DETECT_N", sizeof(cfg->shadow)) == 0)
) // GnPIO_SLOT1/2/3/4_EJECTOR_LATCH_DETECT_N
{
if (strncmp(cfg->shadow, "SLOT1_EJECTOR_LATCH_DETECT_N", sizeof(cfg->shadow)) == 0) {
slot_id = 1;
} else if (strncmp(cfg->shadow, "SLOT2_EJECTOR_LATCH_DETECT_N", sizeof(cfg->shadow)) == 0) {
slot_id = 2;
} else if (strncmp(cfg->shadow, "SLOT3_EJECTOR_LATCH_DETECT_N", sizeof(cfg->shadow)) == 0) {
slot_id = 3;
} else {
slot_id = 4;
}
if (curr == 1) { // low to high
clock_gettime(CLOCK_MONOTONIC, &ts);
if (last_ejector_ts[slot_id].tv_sec && ((ts.tv_sec - last_ejector_ts[slot_id].tv_sec) < 5)) {
return;
}
last_ejector_ts[slot_id].tv_sec = ts.tv_sec;
fby2_common_get_gpio_val("FAN_LATCH_DETECT", &value);
// 12V action would be triggered when SLED is pulled out
// if SLED is seated, log the event that slot latch is open
if (!value) {
syslog(LOG_CRIT,"FRU: %u, SLOT%u_EJECTOR_LATCH is not closed while in VCubby", slot_id, slot_id);
} else {
syslog(LOG_CRIT,"FRU: %u, SLOT%u_EJECTOR_LATCH is not closed", slot_id, slot_id);
pthread_mutex_lock(&latch_open_mutex[slot_id]);
if ( IsLatchOpenStart[slot_id] )
{
#ifdef DEBUG
syslog(LOG_WARNING, "[%s] Close the previous thread for slot%x\n", __func__, slot_id);
#endif
pthread_cancel(latch_open_tid[slot_id]);
}
//Create thread for latch open detect
value = slot_id;
if (pthread_create(&latch_open_tid[slot_id], NULL, latch_open_handler, (void *)value) < 0) {
syslog(LOG_WARNING, "[%s] Create latch_open_handler thread failed for slot%u", __func__, slot_id);
pthread_mutex_unlock(&latch_open_mutex[slot_id]);
return;
}
IsLatchOpenStart[slot_id] = true;
pthread_mutex_unlock(&latch_open_mutex[slot_id]);
} // end of SLED seated check
} //End of low to high
} //End of GPIO_SLOT1/2/3/4_EJECTOR_LATCH_DETECT_N
else if ((strncmp(cfg->shadow, "SLOT1_PRSNT_B_N", sizeof(cfg->shadow)) == 0) || (strncmp(cfg->shadow, "SLOT2_PRSNT_B_N", sizeof(cfg->shadow)) == 0) ||
(strncmp(cfg->shadow, "SLOT3_PRSNT_B_N", sizeof(cfg->shadow)) == 0) || (strncmp(cfg->shadow, "SLOT4_PRSNT_B_N", sizeof(cfg->shadow)) == 0) ||
(strncmp(cfg->shadow, "SLOT1_PRSNT_N" , sizeof(cfg->shadow)) == 0) || (strncmp(cfg->shadow, "SLOT2_PRSNT_N" , sizeof(cfg->shadow)) == 0) ||
(strncmp(cfg->shadow, "SLOT3_PRSNT_N" , sizeof(cfg->shadow)) == 0) || (strncmp(cfg->shadow, "SLOT4_PRSNT_N" , sizeof(cfg->shadow)) == 0)
) // GPIO_SLOT1/2/3/4_PRSNT_B_N, GPIO_SLOT1/2/3/4_PRSNT_N
{
if ((strncmp(cfg->shadow, "SLOT1_PRSNT_B_N", sizeof(cfg->shadow)) == 0) || (strncmp(cfg->shadow, "SLOT1_PRSNT_N", sizeof(cfg->shadow)) == 0)) {
slot_id = 1;
} else if ((strncmp(cfg->shadow, "SLOT2_PRSNT_B_N", sizeof(cfg->shadow)) == 0) || (strncmp(cfg->shadow, "SLOT2_PRSNT_N", sizeof(cfg->shadow)) == 0)) {
slot_id = 2;
} else if ((strncmp(cfg->shadow, "SLOT3_PRSNT_B_N", sizeof(cfg->shadow)) == 0) || (strncmp(cfg->shadow, "SLOT3_PRSNT_N", sizeof(cfg->shadow)) == 0)) {
slot_id = 3;
} else {
slot_id = 4;
}
// Use flag to ignore the interrupt of pair present pin
if (prsnt_assert[slot_id])
{
prsnt_assert[slot_id] = false;
return;
}
// HOT SERVER event would be detected
prsnt_assert[slot_id] = true;
if (curr == 1) { // SLOT Removal
hsvc_info[slot_id].slot_id = slot_id;
hsvc_info[slot_id].action = REMOVAl;
pthread_mutex_lock(&hsvc_mutex[slot_id]);
if ( IsHotServiceStart[slot_id] )
{
#ifdef DEBUG
syslog(LOG_WARNING, "[%s] Close the previous thread for slot%x\n", __func__, slot_id);
#endif
pthread_cancel(hsvc_action_tid[slot_id]);
}
if (IsLatchOpenStart[slot_id]) {
pthread_cancel(latch_open_tid[slot_id]);
pthread_mutex_lock(&latch_open_mutex[slot_id]);
IsLatchOpenStart[slot_id] = false;
pthread_mutex_unlock(&latch_open_mutex[slot_id]);
}
//Create thread for hsvc event detect
if (pthread_create(&hsvc_action_tid[slot_id], NULL, hsvc_event_handler, &hsvc_info[slot_id]) < 0) {
syslog(LOG_WARNING, "[%s] Create hsvc_event_handler thread failed for slot%x\n",__func__, slot_id);
pthread_mutex_unlock(&hsvc_mutex[slot_id]);
return;
}
IsHotServiceStart[slot_id] = true;
pthread_mutex_unlock(&hsvc_mutex[slot_id]);
}
else { // SLOT INSERTION
hsvc_info[slot_id].slot_id = slot_id;
hsvc_info[slot_id].action = INSERTION;
pthread_mutex_lock(&hsvc_mutex[slot_id]);
if ( IsHotServiceStart[slot_id] )
{
#ifdef DEBUG
syslog(LOG_WARNING, "[%s] Close the previous thread for slot%x\n", __func__, slot_id);
#endif
pthread_cancel(hsvc_action_tid[slot_id]);
}
//Create thread for hsvc event detect
if (pthread_create(&hsvc_action_tid[slot_id], NULL, hsvc_event_handler, &hsvc_info[slot_id]) < 0) {
syslog(LOG_WARNING, "[%s] Create hsvc_event_handler thread failed for slot%x\n",__func__, slot_id);
pthread_mutex_unlock(&hsvc_mutex[slot_id]);
return;
}
IsHotServiceStart[slot_id] = true;
pthread_mutex_unlock(&hsvc_mutex[slot_id]);
}
} // End of GPIO_SLOT1/2/3/4_PRSNT_B_N, GPIO_SLOT1/2/3/4_PRSNT_N
else if (strncmp(cfg->shadow, "UART_SEL", sizeof(cfg->shadow)) == 0) {
if (pal_get_hand_sw(&slot_id)) {
slot_id = HAND_SW_BMC;
}
slot_id = (slot_id >= HAND_SW_BMC) ? HAND_SW_SERVER1 : (slot_id + 1);
sprintf(locstr, "%u", slot_id);
kv_set("spb_hand_sw", locstr, 0, 0);
syslog(LOG_INFO, "change hand_sw location to FRU %s by button", locstr);
}
else if ((strncmp(cfg->shadow, "SLOT1_POWER_EN", sizeof(cfg->shadow)) == 0) || (strncmp(cfg->shadow, "SLOT2_POWER_EN", sizeof(cfg->shadow)) == 0) ||
(strncmp(cfg->shadow, "SLOT3_POWER_EN", sizeof(cfg->shadow)) == 0) || (strncmp(cfg->shadow, "SLOT4_POWER_EN", sizeof(cfg->shadow)) == 0)
) // SLOT1/2/3/4_POWER_EN
{
if (strncmp(cfg->shadow, "SLOT1_POWER_EN", sizeof(cfg->shadow)) == 0) {
slot_id = 1;
} else if (strncmp(cfg->shadow, "SLOT2_POWER_EN", sizeof(cfg->shadow)) == 0) {
slot_id = 2;
} else if (strncmp(cfg->shadow, "SLOT3_POWER_EN", sizeof(cfg->shadow)) == 0) {
slot_id = 3;
} else {
slot_id = 4;
}
if (curr == 1) { // low to high
syslog(LOG_WARNING, "[%s] slot%d power enable pin on", __func__,slot_id);
#if defined(CONFIG_FBY2_GPV2)
if (fby2_get_slot_type(slot_id) == SLOT_TYPE_GPV2) {
if (pal_is_server_12v_on(slot_id, &slot_12v))
syslog(LOG_WARNING, "%s : pal_is_server_12v_on failed for slot: %u", __func__, slot_id);
if (slot_12v)
fru_cahe_init(slot_id);
}
#endif
} else { // high to low
syslog(LOG_WARNING, "[%s] slot%d power enable pin off", __func__,slot_id);
fby2_common_set_ierr(slot_id,false);
}
}
else if (strncmp(cfg->shadow, "SMB_HOTSWAP_ALERT_N", sizeof(cfg->shadow)) == 0) {
if (curr == 0) {
if (pthread_create(&hsc_alert_tid, NULL, hsc_alert_handler, NULL)) {
syslog(LOG_WARNING, "[%s] Create hsc_alert_handler thread failed", __func__);
}
}
}
}