diff options
author | Xo Wang <xow@google.com> | 2016-09-22 11:17:01 -0700 |
---|---|---|
committer | Patrick Williams <patrick@stwcx.xyz> | 2016-10-04 03:01:53 +0000 |
commit | 3f87de8bb45887f223a7539afb8249fdb22837fd (patch) | |
tree | 4e35b39684579b6e6fd890d1f25b9ede9e1290ae /libopenbmc_intf | |
parent | eb27fa9fc540405991c2f1dee2a0eac1c8ebdd0d (diff) | |
download | talos-skeleton-3f87de8bb45887f223a7539afb8249fdb22837fd.tar.gz talos-skeleton-3f87de8bb45887f223a7539afb8249fdb22837fd.zip |
system_manager, libobmc-intf: Add power GPIO configuration interface
This adds a dbus call (in org.openbmc.managers.System) and C binding (in
libopenbmc-intf) to read a POWER_CONFIG from the Python system
configuration that abstracts GPIO functionality (power good, reset, etc)
from their net names in GPIO_CONFIG.
This should eventually replace machine-specific patches to op-pwrctl
that define their own power and reset lines.
Change-Id: I56eaaf60ef852b68124e4a765942243ad17d06ac
Signed-off-by: Xo Wang <xow@google.com>
Diffstat (limited to 'libopenbmc_intf')
-rw-r--r-- | libopenbmc_intf/Makefile | 4 | ||||
-rw-r--r-- | libopenbmc_intf/power_gpio.c | 123 | ||||
-rw-r--r-- | libopenbmc_intf/power_gpio.h | 45 |
3 files changed, 170 insertions, 2 deletions
diff --git a/libopenbmc_intf/Makefile b/libopenbmc_intf/Makefile index cd86906..fe17dc9 100644 --- a/libopenbmc_intf/Makefile +++ b/libopenbmc_intf/Makefile @@ -5,7 +5,7 @@ PACKAGE_DEPS=gio-unix-2.0 glib-2.0 SONAME=libopenbmc_intf.so VERSION=1 LIBOBMC=$(SONAME).$(VERSION) -INCLUDES=openbmc_intf.h openbmc.h gpio.h +INCLUDES=openbmc_intf.h openbmc.h gpio.h power_gpio.h LDLIBS+=$(shell pkg-config --libs $(PACKAGE_DEPS)) ALL_CFLAGS+=$(shell pkg-config --cflags $(PACKAGE_DEPS)) -fPIC -Werror $(CFLAGS) @@ -18,7 +18,7 @@ all: $(SONAME) $(SONAME): $(LIBOBMC) ln -sf $^ $@ -$(LIBOBMC): lib%.so.$(VERSION): %.o gpio.o +$(LIBOBMC): lib%.so.$(VERSION): %.o gpio.o power_gpio.o $(CC) -shared $(CFLAGS) $(LDFLAGS) -Wl,-soname,$(SONAME) \ -o $@ $^ $(LDLIBS) diff --git a/libopenbmc_intf/power_gpio.c b/libopenbmc_intf/power_gpio.c new file mode 100644 index 0000000..3f4b5a8 --- /dev/null +++ b/libopenbmc_intf/power_gpio.c @@ -0,0 +1,123 @@ +/** + * Copyright © 2016 Google Inc. + * Copyright © 2016 IBM Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "power_gpio.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <glib.h> + +gboolean read_power_gpio(GDBusConnection *connection, PowerGpio *power_gpio) +{ + GDBusProxy *proxy; + GError *error; + GVariant *value; + gchar *power_good_in_name; + GVariantIter *power_up_outs_iter; + GVariantIter *reset_outs_iter; + gchar *power_up_out_name; + gchar *reset_out_name; + gboolean power_up_polarity; + gboolean reset_out_polarity; + int i; + + proxy = g_dbus_proxy_new_sync(connection, + G_DBUS_PROXY_FLAGS_NONE, + NULL, /* GDBusInterfaceInfo */ + "org.openbmc.managers.System", /* name */ + "/org/openbmc/managers/System", /* object path */ + "org.openbmc.managers.System", /* interface */ + NULL, /* GCancellable */ + &error); + if(error != NULL) { + fprintf(stderr, "Unable to create proxy: %s\n", error->message); + g_error_free(error); + return FALSE; + } + + value = g_dbus_proxy_call_sync(proxy, + "getPowerConfiguration", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if(error != NULL) { + fprintf(stderr, "Power GPIO: call to getPowerConfiguration failed: %s\n", + error->message); + g_error_free(error); + return FALSE; + } + + g_assert(value != NULL); + memset(power_gpio, 0, sizeof(*power_gpio)); + g_variant_get(value, "(&sa(sb)a(sb))", &power_good_in_name, + &power_up_outs_iter, &reset_outs_iter); + + g_print("Power GPIO power good input %s\n", power_good_in_name); + power_gpio->power_good_in.name = g_strdup(power_good_in_name); + power_gpio->num_power_up_outs = g_variant_iter_n_children( + power_up_outs_iter); + g_print("Power GPIO %d power_up outputs\n", + power_gpio->num_power_up_outs); + power_gpio->power_up_outs = g_malloc0_n(power_gpio->num_power_up_outs, + sizeof(GPIO)); + power_gpio->power_up_pols = g_malloc0_n(power_gpio->num_power_up_outs, + sizeof(gboolean)); + for(i = 0; g_variant_iter_next(power_up_outs_iter, "(&sb)", + &power_up_out_name, &power_up_polarity); + i++) { + g_print("Power GPIO power_up[%d] = %s active %s\n", i, + power_up_out_name, power_up_polarity ? "HIGH" : "LOW"); + power_gpio->power_up_outs[i].name = g_strdup(power_up_out_name); + power_gpio->power_up_pols[i] = power_up_polarity; + } + power_gpio->num_reset_outs = g_variant_iter_n_children(reset_outs_iter); + g_print("Power GPIO %d reset outputs\n", power_gpio->num_reset_outs); + power_gpio->reset_outs = g_malloc0_n(power_gpio->num_reset_outs, sizeof(GPIO)); + power_gpio->reset_pols = g_malloc0_n(power_gpio->num_reset_outs, + sizeof(gboolean)); + for(i = 0; g_variant_iter_next(reset_outs_iter, "(&sb)", &reset_out_name, + &reset_out_polarity); i++) { + g_print("Power GPIO reset[%d] = %s active %s\n", i, reset_out_name, + reset_out_polarity ? "HIGH" : "LOW"); + power_gpio->reset_outs[i].name = g_strdup(reset_out_name); + power_gpio->reset_pols[i] = reset_out_polarity; + } + + g_variant_iter_free(power_up_outs_iter); + g_variant_iter_free(reset_outs_iter); + g_variant_unref(value); + + return TRUE; +} + +void free_power_gpio(PowerGpio *power_gpio) { + int i; + g_free(power_gpio->power_good_in.name); + for(i = 0; i < power_gpio->num_power_up_outs; i++) { + g_free(power_gpio->power_up_outs[i].name); + } + g_free(power_gpio->power_up_outs); + g_free(power_gpio->power_up_pols); + for(i = 0; i < power_gpio->num_reset_outs; i++) { + g_free(power_gpio->reset_outs[i].name); + } + g_free(power_gpio->reset_outs); + g_free(power_gpio->reset_pols); +} diff --git a/libopenbmc_intf/power_gpio.h b/libopenbmc_intf/power_gpio.h new file mode 100644 index 0000000..f36a722 --- /dev/null +++ b/libopenbmc_intf/power_gpio.h @@ -0,0 +1,45 @@ +/** + * Copyright © 2016 Google Inc. + * Copyright © 2016 IBM Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __POWER_GPIO_H__ +#define __POWER_GPIO_H__ + +#include <stddef.h> +#include <glib.h> +#include "gpio.h" + +typedef struct PowerGpio { + /* Active high pin that is asserted following successful host power up. */ + GPIO power_good_in; + /* Selectable polarity pins enabling host power rails. */ + size_t num_power_up_outs; + GPIO *power_up_outs; + /* TRUE for active high */ + gboolean *power_up_pols; + /* Selectable polarity pins holding system complexes in reset. */ + size_t num_reset_outs; + GPIO *reset_outs; + /* TRUE for active high */ + gboolean *reset_pols; +} PowerGpio; + +/* Read system configuration for power GPIOs. */ +gboolean read_power_gpio(GDBusConnection *connection, PowerGpio *power_gpio); +/* Frees internal buffers. Does not free parameter. Does not close GPIOs. */ +void free_power_gpio(PowerGpio *power_gpio); + +#endif |