diff options
author | Xo Wang <xow@google.com> | 2016-09-22 11:26:14 -0700 |
---|---|---|
committer | Patrick Williams <patrick@stwcx.xyz> | 2016-10-04 03:01:53 +0000 |
commit | 20a194169c527fbded95749acd29ef44dfbe70c7 (patch) | |
tree | 9a86048487d2003616757dd0c21f9e9a7e1b1d04 /op-pwrctl | |
parent | 4088ec386cba731b02981984640bad2c1576cd27 (diff) | |
download | talos-skeleton-20a194169c527fbded95749acd29ef44dfbe70c7.tar.gz talos-skeleton-20a194169c527fbded95749acd29ef44dfbe70c7.zip |
pwrctl: Use PowerGpio configuration for power control
Use power GPIO configuration read from Python system configuration to
control power and reset lines. This removes the need for
machine-specific patches.
Signed-off-by: Xo Wang <xow@google.com>
Change-Id: I83d55a7069558ec810bc2e0dbbff1c5495957e6d
Diffstat (limited to 'op-pwrctl')
-rw-r--r-- | op-pwrctl/power_control_obj.c | 174 |
1 files changed, 111 insertions, 63 deletions
diff --git a/op-pwrctl/power_control_obj.c b/op-pwrctl/power_control_obj.c index dfc7fa9..cd13c68 100644 --- a/op-pwrctl/power_control_obj.c +++ b/op-pwrctl/power_control_obj.c @@ -10,18 +10,14 @@ #include <openbmc_intf.h> #include <openbmc.h> #include <gpio.h> +#include <power_gpio.h> /* ------------------------------------------------------------------------- */ static const gchar* dbus_object_path = "/org/openbmc/control"; static const gchar* instance_name = "power0"; static const gchar* dbus_name = "org.openbmc.control.Power"; -//This object will use these GPIOs -GPIO power_pin = (GPIO){ "POWER_PIN" }; -GPIO pgood = (GPIO){ "PGOOD" }; -GPIO usb_reset = (GPIO){ "USB_RESET" }; -GPIO pcie_reset = (GPIO){ "PCIE_RESET" }; - +static PowerGpio g_power_gpio; static GDBusObjectManagerServer *manager = NULL; @@ -38,7 +34,7 @@ poll_pgood(gpointer user_data) guint poll_int = control_get_poll_interval(control); if(poll_int == 0) { - printf("ERROR PowerControl: Poll interval cannot be 0\n"); + g_print("ERROR PowerControl: Poll interval cannot be 0\n"); return FALSE; } //handle timeout @@ -46,56 +42,67 @@ poll_pgood(gpointer user_data) if(difftime(current_time,pgood_timeout_start) > control_power_get_pgood_timeout(control_power) && pgood_timeout_start != 0) { - printf("ERROR PowerControl: Pgood poll timeout\n"); + g_print("ERROR PowerControl: Pgood poll timeout\n"); // set timeout to 0 so timeout doesn't happen again control_power_set_pgood_timeout(control_power,0); pgood_timeout_start = 0; return TRUE; } - uint8_t gpio; + uint8_t pgood_state; - int rc = gpio_open(&pgood); - rc = gpio_read(&pgood,&gpio); - gpio_close(&pgood); + int rc = gpio_open(&g_power_gpio.power_good_in); + if(rc != GPIO_OK) { + g_print("ERROR PowerControl: GPIO open error (gpio=%s,rc=%d)\n", + g_power_gpio.power_good_in.name, rc); + return FALSE; + } + rc = gpio_read(&g_power_gpio.power_good_in, &pgood_state); + gpio_close(&g_power_gpio.power_good_in); if(rc == GPIO_OK) { //if changed, set property and emit signal - if(gpio != control_power_get_pgood(control_power)) + if(pgood_state != control_power_get_pgood(control_power)) { - control_power_set_pgood(control_power,gpio); - if(gpio==0) + int i; + uint8_t reset_state; + control_power_set_pgood(control_power, pgood_state); + if(pgood_state == 0) { control_power_emit_power_lost(control_power); control_emit_goto_system_state(control,"HOST_POWERED_OFF"); - rc = gpio_open(&pcie_reset); - rc = gpio_write(&pcie_reset,0); - gpio_close(&pcie_reset); - - rc = gpio_open(&usb_reset); - rc = gpio_write(&usb_reset,0); - gpio_close(&usb_reset); - } else { control_power_emit_power_good(control_power); control_emit_goto_system_state(control,"HOST_POWERED_ON"); - rc = gpio_open(&pcie_reset); - rc = gpio_write(&pcie_reset,1); - gpio_close(&pcie_reset); + } - rc = gpio_open(&usb_reset); - rc = gpio_write(&usb_reset,1); - gpio_close(&usb_reset); + for(i = 0; i < g_power_gpio.num_reset_outs; i++) + { + GPIO *reset_out = &g_power_gpio.reset_outs[i]; + rc = gpio_open(reset_out); + if(rc != GPIO_OK) + { + g_print("ERROR PowerControl: GPIO open error (gpio=%s,rc=%d)\n", + reset_out->name, rc); + continue; + } + + reset_state = pgood_state ^ g_power_gpio.reset_pols[i]; + g_print("PowerControl: setting reset %s to %d\n", reset_out->name, + (int)reset_state); + gpio_write(reset_out, reset_state); + gpio_close(reset_out); } } } else { - printf("ERROR PowerControl: GPIO read error (gpio=%s,rc=%d)\n",pgood.name,rc); + g_print("ERROR PowerControl: GPIO read error (gpio=%s,rc=%d)\n", + g_power_gpio.power_good_in.name, rc); //return false so poll won't get called anymore return FALSE; } //pgood is not at desired state yet - if(gpio != control_power_get_state(control_power) && + if(pgood_state != control_power_get_state(control_power) && control_power_get_pgood_timeout(control_power) > 0) { if(pgood_timeout_start == 0 ) { @@ -133,21 +140,36 @@ on_set_power_state(ControlPower *pwr, { int error = 0; do { + int i; + uint8_t power_up_out; if(state == 1) { control_emit_goto_system_state(control,"HOST_POWERING_ON"); } else { control_emit_goto_system_state(control,"HOST_POWERING_OFF"); } - error = gpio_open(&power_pin); - if(error != GPIO_OK) { break; } - error = gpio_write(&power_pin,!state); + for (i = 0; i < g_power_gpio.num_power_up_outs; i++) { + GPIO *power_pin = &g_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_power_gpio.power_up_outs[i].name, error); + continue; + } + power_up_out = state ^ g_power_gpio.power_up_pols[i]; + g_print("PowerControl: setting power up %s to %d\n", + g_power_gpio.power_up_outs[i].name, (int)power_up_out); + error = gpio_write(power_pin, power_up_out); + if(error != GPIO_OK) { + continue; + } + gpio_close(power_pin); + } if(error != GPIO_OK) { break; } - gpio_close(&power_pin); control_power_set_state(pwr,state); } while(0); if(error != GPIO_OK) { - printf("ERROR PowerControl: GPIO set power state (rc=%d)\n",error); + g_print("ERROR PowerControl: GPIO set power state (rc=%d)\n",error); } } return TRUE; @@ -175,6 +197,50 @@ on_get_power_state(ControlPower *pwr, return TRUE; } +static int +set_up_gpio(GDBusConnection *connection, + PowerGpio *power_gpio, + ControlPower* control_power) +{ + int error = GPIO_OK; + int rc; + int i; + uint8_t pgood_state; + + // get gpio device paths + rc = gpio_init(connection, &power_gpio->power_good_in); + if(rc != GPIO_OK) { + error = rc; + } + for(int i = 0; i < power_gpio->num_power_up_outs; i++) { + rc = gpio_init(connection, &power_gpio->power_up_outs[i]); + if(rc != GPIO_OK) { + error = rc; + } + } + for(int i = 0; i < power_gpio->num_reset_outs; i++) { + rc = gpio_init(connection, &power_gpio->reset_outs[i]); + if(rc != GPIO_OK) { + error = rc; + } + } + + rc = gpio_open(&power_gpio->power_good_in); + if(rc != GPIO_OK) { + return rc; + } + rc = gpio_read(&power_gpio->power_good_in, &pgood_state); + if(rc != GPIO_OK) { + return rc; + } + gpio_close(&power_gpio->power_good_in); + control_power_set_pgood(control_power, pgood_state); + control_power_set_state(control_power, pgood_state); + g_print("Pgood state: %d\n", pgood_state); + + return error; +} + static void on_bus_acquired(GDBusConnection *connection, const gchar *name, @@ -223,39 +289,20 @@ on_bus_acquired(GDBusConnection *connection, g_dbus_object_manager_server_export(manager, G_DBUS_OBJECT_SKELETON(object)); g_object_unref(object); - // get gpio device paths - int rc = GPIO_OK; - do { - rc = gpio_init(connection,&power_pin); - if(rc != GPIO_OK) { break; } - rc = gpio_init(connection,&pgood); - if(rc != GPIO_OK) { break; } - rc = gpio_init(connection,&pcie_reset); - if(rc != GPIO_OK) { break; } - rc = gpio_init(connection,&usb_reset); - if(rc != GPIO_OK) { break; } - - uint8_t gpio; - rc = gpio_open(&pgood); - if(rc != GPIO_OK) { break; } - rc = gpio_read(&pgood,&gpio); - if(rc != GPIO_OK) { break; } - gpio_close(&pgood); - control_power_set_pgood(control_power,gpio); - control_power_set_state(control_power,gpio); - printf("Pgood state: %d\n",gpio); - - } while(0); - if(rc != GPIO_OK) - { - printf("ERROR PowerControl: GPIO setup (rc=%d)\n",rc); + if(read_power_gpio(connection, &g_power_gpio) != TRUE) { + g_print("ERROR PowerControl: could not read power GPIO configuration\n"); + } + + int rc = set_up_gpio(connection, &g_power_gpio, control_power); + if(rc != GPIO_OK) { + g_print("ERROR PowerControl: GPIO setup (rc=%d)\n",rc); } //start poll pgood_timeout_start = 0; int poll_interval = atoi(cmd->argv[1]); int pgood_timeout = atoi(cmd->argv[2]); if(poll_interval < 1000 || pgood_timeout <5) { - printf("ERROR PowerControl: poll_interval < 1000 or pgood_timeout < 5\n"); + g_print("ERROR PowerControl: poll_interval < 1000 or pgood_timeout < 5\n"); } else { control_set_poll_interval(control,poll_interval); control_power_set_pgood_timeout(control_power,pgood_timeout); @@ -275,6 +322,7 @@ on_name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data) { + free_power_gpio(&g_power_gpio); } /*----------------------------------------------------------------*/ |