summaryrefslogtreecommitdiffstats
path: root/op-pwrctl
diff options
context:
space:
mode:
authorXo Wang <xow@google.com>2017-03-03 14:25:01 -0800
committerXo Wang <xow@google.com>2017-03-07 11:40:04 -0800
commitaa6c76fc5cfa8e50dfd86146fee508b7d950ff63 (patch)
tree3c648a56a6399a2c05771d29b3f6f84a1c20b3e6 /op-pwrctl
parentd4bca7bd9c5ace712f033c625031072a0b37f3a2 (diff)
downloadtalos-skeleton-aa6c76fc5cfa8e50dfd86146fee508b7d950ff63.tar.gz
talos-skeleton-aa6c76fc5cfa8e50dfd86146fee508b7d950ff63.zip
op-pwrctl: Make latch transparent briefly, only after state changes
The Zaius motherboard has latches between BMC control pins to power up the host and the input pins to the power sequencer. This allows BMC resets to not interrupt power to the host. Currently, the latches are made transparent prior to sampling the power state of the system, which causes BMC boot to kill host power. In addition the latches remain transparent, so the system can be brought down by the BMC shutting down. Enable the latches only after power control pins change state. Enable the latches only momentarily. After this change, Zaius BMC can reboot without taking down its host. Signed-off-by: Xo Wang <xow@google.com> Change-Id: If150cbcf3fabda359d1ce94602c40cb96741e869
Diffstat (limited to 'op-pwrctl')
-rw-r--r--op-pwrctl/power_control_obj.c61
1 files changed, 36 insertions, 25 deletions
diff --git a/op-pwrctl/power_control_obj.c b/op-pwrctl/power_control_obj.c
index bd0287a..60c9009 100644
--- a/op-pwrctl/power_control_obj.c
+++ b/op-pwrctl/power_control_obj.c
@@ -220,6 +220,7 @@ on_set_power_state(ControlPower *pwr,
gpointer user_data)
{
Control* control = object_get_control((Object*)user_data);
+ PowerGpio *power_gpio = &g_gpio_configs.power_gpio;
if(state > 1)
{
g_dbus_method_invocation_return_dbus_error(invocation,
@@ -244,17 +245,17 @@ on_set_power_state(ControlPower *pwr,
} else {
control_emit_goto_system_state(control,"HOST_POWERING_OFF");
}
- for (i = 0; i < g_gpio_configs.power_gpio.num_power_up_outs; i++) {
- GPIO *power_pin = &g_gpio_configs.power_gpio.power_up_outs[i];
+ for (i = 0; i < power_gpio->num_power_up_outs; i++) {
+ GPIO *power_pin = &power_gpio->power_up_outs[i];
error = gpio_open(power_pin);
if(error != GPIO_OK) {
g_print("ERROR PowerControl: GPIO open error (gpio=%s,rc=%d)\n",
- g_gpio_configs.power_gpio.power_up_outs[i].name, error);
+ power_gpio->power_up_outs[i].name, error);
continue;
}
- power_up_out = state ^ !g_gpio_configs.power_gpio.power_up_pols[i];
+ power_up_out = state ^ !power_gpio->power_up_pols[i];
g_print("PowerControl: setting power up %s to %d\n",
- g_gpio_configs.power_gpio.power_up_outs[i].name, (int)power_up_out);
+ power_gpio->power_up_outs[i].name, (int)power_up_out);
error = gpio_write(power_pin, power_up_out);
if(error != GPIO_OK) {
continue;
@@ -268,7 +269,37 @@ on_set_power_state(ControlPower *pwr,
{
g_print("ERROR PowerControl: GPIO set power state (rc=%d)\n",error);
}
+
+ /* If there's a latch, it should be enabled following changes to the
+ * power pins' states. This commits the changes to the latch states. */
+ if (power_gpio->latch_out.name != NULL) {
+ int rc;
+ uint8_t latch_value = 0;
+ rc = gpio_open(&power_gpio->latch_out);
+ if (rc != GPIO_OK) {
+ /* Failures are non-fatal. */
+ g_print("PowerControl ERROR failed to open latch %s rc=%d\n",
+ power_gpio->latch_out.name, rc);
+ return TRUE;
+ }
+ /* Make the latch transparent for as brief of a time as possible. */
+ rc = gpio_write(&power_gpio->latch_out, 1);
+ if (rc != GPIO_OK) {
+ g_print("PowerControl ERROR failed to assert latch %s rc=%d\n",
+ power_gpio->latch_out.name, rc);
+ } else {
+ g_print("PowerControl asserted latch %s\n",
+ power_gpio->latch_out.name);
+ }
+ rc = gpio_write(&power_gpio->latch_out, 0);
+ if (rc != GPIO_OK) {
+ g_print("PowerControl ERROR failed to clear latch %s rc=%d\n",
+ power_gpio->latch_out.name, rc);
+ }
+ gpio_close(&power_gpio->latch_out);
+ }
}
+
return TRUE;
}
@@ -334,26 +365,6 @@ set_up_gpio(GDBusConnection *connection,
}
}
- /* If there's a latch, it only needs to be set once. */
- if(power_gpio->latch_out.name != NULL) {
- do {
- rc = gpio_open(&power_gpio->latch_out);
- if(rc != GPIO_OK) {
- /* Failures are non-fatal. */
- break;
- }
- rc = gpio_write(&power_gpio->latch_out, 1);
- gpio_close(&power_gpio->latch_out);
- } while(0);
- if (rc != GPIO_OK) {
- error = rc;
- g_print("PowerControl ERROR failed to assert latch %s rc=%d\n",
- power_gpio->latch_out.name, rc);
- } else {
- g_print("PowerControl asserted latch %s\n", power_gpio->latch_out.name);
- }
- }
-
rc = gpio_open(&power_gpio->power_good_in);
if(rc != GPIO_OK) {
return rc;
OpenPOWER on IntegriCloud