UPSTREAM: linux_spi.c: set SPI mode, bit order and bits per word on init

Previously we relied on a correctly set up state.

Also, we start to rely on the shutdown function for cleanup after
registering it, i.e. we no longer explicitly call close(fd) after
register_shutdown().

Corresponding to flashrom svn r1512.

Original-Signed-off-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
Original-Tested-by: Denis 'GNUtoo' Carikli <GNUtoo@no-log.org>
Original-Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
(cherry picked from commit 2c3e9d5f57b8f2c33bda30dcac043c1b31089183)

BUG=b:153598437
BRANCH=none
TEST=builds

Tested-by: Nikolai Artemiev <nartemiev@chromium.org>
Signed-off-by: Nikolai Artemiev <nartemiev@chromium.org>
Change-Id: Id31bc9e44a7cfe5daad49d390ef5a6b9aac81414
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/flashrom/+/2209942
Commit-Queue: Edward O'Callaghan <quasisec@chromium.org>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>
diff --git a/linux_spi.c b/linux_spi.c
index d387b60..d3af2d0 100644
--- a/linux_spi.c
+++ b/linux_spi.c
@@ -166,6 +166,10 @@
 {
 	char *p, *endp, *dev;
 	uint32_t speed = 0;
+	/* FIXME: make the following configurable by CLI options. */
+	/* SPI mode 0 (beware this also includes: MSB first, CS active low and others */
+	const uint8_t mode = SPI_MODE_0;
+	const uint8_t bits = 8;
 
 	/*
 	 * FIXME: There might be other programmers with flash memory (such as
@@ -203,19 +207,31 @@
 		}
 	}
 
+	if (register_shutdown(linux_spi_shutdown, NULL))
+		return 1;
+	/* We rely on the shutdown function for cleanup from here on. */
+
 	if (speed > 0) {
 		if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) == -1) {
-			msg_perr("%s: failed to set speed %dHz: %s\n",
+			msg_perr("%s: failed to set speed to %d Hz: %s\n",
 				 __func__, speed, strerror(errno));
-			close(fd);
 			return 1;
 		}
 
 		msg_pdbg("Using %d kHz clock\n", speed);
 	}
 
-	if (register_shutdown(linux_spi_shutdown, NULL))
+	if (ioctl(fd, SPI_IOC_WR_MODE, &mode) == -1) {
+		msg_perr("%s: failed to set SPI mode to 0x%02x: %s\n",
+			 __func__, mode, strerror(errno));
 		return 1;
+	}
+
+	if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits) == -1) {
+		msg_perr("%s: failed to set the number of bits per SPI word to %u: %s\n",
+			 __func__, bits == 0 ? 8 : bits, strerror(errno));
+		return 1;
+	}
 
 	register_spi_master(&spi_master_linux);