gpio: Avoid glitching 'out'-direction GPIOs

Change-Id: I42dafd3235d13ec57f7b15e043bc3fe82fdb4665
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
diff --git a/libopenbmc_intf/gpio.c b/libopenbmc_intf/gpio.c
index e48eff4..0dfb260 100644
--- a/libopenbmc_intf/gpio.c
+++ b/libopenbmc_intf/gpio.c
@@ -149,18 +149,36 @@
 			}
 		}
 		const char* file = "edge";
-		if (strcmp(gpio->direction,"in")==0 || strcmp(gpio->direction,"out")==0)
+		const char* direction = gpio->direction;
+		if (strcmp(direction, "in") == 0)
 		{
 			file = "direction";
 		}
+		else if (strcmp(direction, "out") == 0)
+		{
+			file = "direction";
+
+			// Read current value, so we can set 'high' or 'low'.
+			// Setting direction directly to 'out' is the same as
+			// setting to 'low' which can change the value in the
+			// GPIO.
+			uint8_t value = 0;
+			rc = gpio_open(gpio);
+			if (rc) break;
+			rc = gpio_read(gpio, &value);
+			if (rc) break;
+			gpio_close(gpio);
+
+			direction = (value ? "high" : "low");
+		}
 		sprintf(dev,"%s/gpio%d/%s",gpio->dev,gpio->num,file);
 		fd = open(dev,O_WRONLY);
 		if (fd == GPIO_ERROR) {
 			rc = GPIO_WRITE_ERROR;
 			break;
 		}
-		rc = write(fd,gpio->direction,strlen(gpio->direction));
-		if (rc != strlen(gpio->direction)) {
+		rc = write(fd,direction,strlen(direction));
+		if (rc != strlen(direction)) {
 			rc = GPIO_WRITE_ERROR;
 			break;
 		}