summaryrefslogtreecommitdiffstats
path: root/op-pwrctl
diff options
context:
space:
mode:
authorXo Wang <xow@google.com>2016-09-22 11:26:14 -0700
committerPatrick Williams <patrick@stwcx.xyz>2016-10-04 03:01:53 +0000
commit20a194169c527fbded95749acd29ef44dfbe70c7 (patch)
tree9a86048487d2003616757dd0c21f9e9a7e1b1d04 /op-pwrctl
parent4088ec386cba731b02981984640bad2c1576cd27 (diff)
downloadtalos-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.c174
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);
}
/*----------------------------------------------------------------*/
OpenPOWER on IntegriCloud