GPIO abstraction for power and host control

In libopenbmc_intf/power_gpio.c there are GPIO abstractions for power
related GPIOs.
Host control related GPIOs need to do the same abstraction.

The changes include:
1. Add host control related GPIOs in gpio_configs and update
system_manager.py
2. Update control_host_obj.c to use the abstracted GPIOs
3. Update GPIO_CONFIGS for all machines and add host control related
GPIOs

power_gpio will be renamed to gpio_configs in next commit;

Resolves openbmc/openbmc#814

Change-Id: I7832065d495d7d64c5df2f5b177005b97e68900a
Signed-off-by: Lei YU <mine260309@gmail.com>
diff --git a/op-hostctl/control_host_obj.c b/op-hostctl/control_host_obj.c
index 6202044..c0b4e12 100644
--- a/op-hostctl/control_host_obj.c
+++ b/op-hostctl/control_host_obj.c
@@ -8,20 +8,24 @@
 #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 = "host0";
 static const gchar* dbus_name = "org.openbmc.control.Host";
 
+static GpioConfigs g_gpio_configs;
+
 static GDBusObjectManagerServer *manager = NULL;
 
-GPIO fsi_data     = (GPIO){ "FSI_DATA" };
-GPIO fsi_clk      = (GPIO){ "FSI_CLK" };
-GPIO fsi_enable   = (GPIO){ "FSI_ENABLE" };
-GPIO cronus_sel   = (GPIO){ "CRONUS_SEL" };
-GPIO Throttle     = (GPIO){ "BMC_THROTTLE" };
-GPIO idbtn     	  = (GPIO){ "IDBTN" };
+static GPIO* fsi_data;
+static GPIO* fsi_clk;
+static GPIO* fsi_enable;
+static GPIO* cronus_sel;
+static size_t num_optionals;
+static GPIO* optionals;
+static gboolean* optional_pols;
 
 /* Bit bang patterns */
 
@@ -37,7 +41,7 @@
 static const char* attnA = "000011111111111101111110001001101111111111111111111111111111110001111111";
 //putcfam pu 0x100D 40000000
 static const char* attnB = "000011111111111011111100101001011111111111111111111111111111110001111111";
-//putcfam pu  0x100B FFFFFFFF
+//putcfam pu 0x100B FFFFFFFF
 static const char* attnC = "000011111111111011111101001000000000000000000000000000000000001011111111";
 
 
@@ -57,9 +61,9 @@
 	int rc=GPIO_OK;
 	int i;
 	for(i=0;i<strlen(pattern);i++) {
-		rc = gpio_writec(&fsi_data,pattern[i]);
+		rc = gpio_writec(fsi_data,pattern[i]);
 		if(rc!=GPIO_OK) { break; }
-		rc = gpio_clock_cycle(&fsi_clk,1);
+		rc = gpio_clock_cycle(fsi_clk,1);
 		if(rc!=GPIO_OK) { break; }
 	}
 	return rc;
@@ -69,9 +73,9 @@
 fsi_standby()
 {
 	int rc=GPIO_OK;
-	rc = gpio_write(&fsi_data,1);
+	rc = gpio_write(fsi_data,1);
 	if(rc!=GPIO_OK) { return rc; }
-	rc = gpio_clock_cycle(&fsi_clk,5000);
+	rc = gpio_clock_cycle(fsi_clk,5000);
 	if(rc!=GPIO_OK) { return rc; }
 	return rc;
 }
@@ -89,13 +93,16 @@
 	GDBusConnection *connection =
 		g_dbus_object_manager_server_get_connection(manager);
 
-	if(control_host_get_debug_mode(host)==1)
-	{
+	if (!(fsi_data && fsi_clk && fsi_enable && cronus_sel)) {
+		g_print("ERROR invalid GPIO configuration, will not boot\n");
+		return FALSE;
+	}
+	if(control_host_get_debug_mode(host)==1) {
 		g_print("Enabling debug mode; not booting host\n");
-		rc |= gpio_open(&fsi_enable);
-		rc |= gpio_open(&cronus_sel);
-		rc |= gpio_write(&fsi_enable,1);
-		rc |= gpio_write(&cronus_sel,0);
+		rc |= gpio_open(fsi_enable);
+		rc |= gpio_open(cronus_sel);
+		rc |= gpio_write(fsi_enable,1);
+		rc |= gpio_write(cronus_sel,0);
 		if(rc!=GPIO_OK) {
 			g_print("ERROR enabling debug mode: %d\n",rc);
 		}
@@ -105,30 +112,32 @@
 	Control* control = object_get_control((Object*)user_data);
 	control_host_complete_boot(host,invocation);
 	do {
-		rc = gpio_open(&fsi_clk);
-		rc |= gpio_open(&fsi_data);
-		rc |= gpio_open(&fsi_enable);
-		rc |= gpio_open(&cronus_sel);
-		rc |= gpio_open(&Throttle);
-		rc |= gpio_open(&idbtn);
+		rc = gpio_open(fsi_clk);
+		rc |= gpio_open(fsi_data);
+		rc |= gpio_open(fsi_enable);
+		rc |= gpio_open(cronus_sel);
+		for (size_t i = 0; i < num_optionals; ++i) {
+			rc |= gpio_open(&optionals[i]);
+		}
 		if(rc!=GPIO_OK) { break; }
 
 		//setup dc pins
-		rc = gpio_write(&cronus_sel,1);
-		rc |= gpio_write(&fsi_enable,1);
-		rc |= gpio_write(&fsi_clk,1);
-		rc |= gpio_write(&Throttle,1);
-		rc |= gpio_write(&idbtn,0);
+		rc = gpio_write(cronus_sel,1);
+		rc |= gpio_write(fsi_enable,1);
+		rc |= gpio_write(fsi_clk,1);
+		for (size_t i = 0; i < num_optionals; ++i) {
+			rc |= gpio_write(&optionals[i], optional_pols[i]);
+		}
 		if(rc!=GPIO_OK) { break; }
 
 		//data standy state
 		rc = fsi_standby();
 
 		//clear out pipes
-		rc |= gpio_write(&fsi_data,0);
-		rc |= gpio_clock_cycle(&fsi_clk,256);
-		rc |= gpio_write(&fsi_data,1);
-		rc |= gpio_clock_cycle(&fsi_clk,50);
+		rc |= gpio_write(fsi_data,0);
+		rc |= gpio_clock_cycle(fsi_clk,256);
+		rc |= gpio_write(fsi_data,1);
+		rc |= gpio_clock_cycle(fsi_clk,50);
 		if(rc!=GPIO_OK) { break; }
 
 		rc = fsi_bitbang(attnA);
@@ -157,13 +166,13 @@
 
 		rc = fsi_bitbang(go);
 
-		rc |= gpio_write(&fsi_data,1); /* Data standby state */
-		rc |= gpio_clock_cycle(&fsi_clk,2);
+		rc |= gpio_write(fsi_data,1); /* Data standby state */
+		rc |= gpio_clock_cycle(fsi_clk,2);
 
-		rc |= gpio_write(&fsi_clk,0); /* hold clk low for clock mux */
-		rc |= gpio_write(&fsi_enable,0);
-		rc |= gpio_clock_cycle(&fsi_clk,16);
-		rc |= gpio_write(&fsi_clk,0); /* Data standby state */
+		rc |= gpio_write(fsi_clk,0); /* hold clk low for clock mux */
+		rc |= gpio_write(fsi_enable,0);
+		rc |= gpio_clock_cycle(fsi_clk,16);
+		rc |= gpio_write(fsi_clk,0); /* Data standby state */
 
 	} while(0);
 	if(rc != GPIO_OK)
@@ -172,12 +181,13 @@
 	} else {
 		control_emit_goto_system_state(control,"HOST_BOOTING");
 	}
-	gpio_close(&fsi_clk);
-	gpio_close(&fsi_data);
-	gpio_close(&fsi_enable);
-	gpio_close(&cronus_sel);
-	gpio_close(&Throttle);
-	gpio_close(&idbtn);
+	gpio_close(fsi_clk);
+	gpio_close(fsi_data);
+	gpio_close(fsi_enable);
+	gpio_close(cronus_sel);
+	for (size_t i = 0; i < num_optionals; ++i) {
+		gpio_close(&optionals[i]);
+	}
 
 	// Start watchdog with 30s timeout per the OpenPower Host IPMI Spec.
 	// Once the host starts booting, it'll reset and refresh the timer.
@@ -273,12 +283,26 @@
 	g_dbus_object_manager_server_export(manager, G_DBUS_OBJECT_SKELETON(object));
 	g_object_unref(object);
 
-	gpio_init(connection,&fsi_data);
-	gpio_init(connection,&fsi_clk);
-	gpio_init(connection,&fsi_enable);
-	gpio_init(connection,&cronus_sel);
-	gpio_init(connection,&Throttle);
-	gpio_init(connection,&idbtn);
+	if(read_gpios(connection, &g_gpio_configs) != TRUE) {
+		g_print("ERROR Hostctl: could not read GPIO configuration\n");
+		return;
+	}
+
+	fsi_data = &g_gpio_configs.hostctl_gpio.fsi_data;
+	fsi_clk = &g_gpio_configs.hostctl_gpio.fsi_clk;
+	fsi_enable = &g_gpio_configs.hostctl_gpio.fsi_enable;
+	cronus_sel = &g_gpio_configs.hostctl_gpio.cronus_sel;
+	num_optionals = g_gpio_configs.hostctl_gpio.num_optionals;
+	optionals = g_gpio_configs.hostctl_gpio.optionals;
+	optional_pols = g_gpio_configs.hostctl_gpio.optional_pols;
+
+	gpio_init(connection, fsi_data);
+	gpio_init(connection, fsi_clk);
+	gpio_init(connection, fsi_enable);
+	gpio_init(connection, cronus_sel);
+	for (int i = 0; i < num_optionals; ++i) {
+		gpio_init(connection, &optionals[i]);
+	}
 }
 
 static void
@@ -286,7 +310,7 @@
 		const gchar *name,
 		gpointer user_data)
 {
-	//  g_print ("Acquired the name %s\n", name);
+	// g_print ("Acquired the name %s\n", name);
 }
 
 static void
@@ -294,7 +318,8 @@
 		const gchar *name,
 		gpointer user_data)
 {
-	//  g_print ("Lost the name %s\n", name);
+	// g_print ("Lost the name %s\n", name);
+	free_gpios(&g_gpio_configs);
 }
 
 gint