[PATCH] mtd: spi-nor: intel-spi: Split intel-spi reading from writing

From: Daniel Gutson
Date: Wed Oct 28 2020 - 17:44:57 EST


This patch separates the writing part of the intel-spi drivers
so the 'dangerous' part can be set/unset independently.
This way, the kernel can be configured to include the reading
parts of the driver which can be used without
the dangerous write operations that can turn the system
unbootable.

Signed-off-by: Daniel Gutson <daniel.gutson@xxxxxxxxxxxxx>
---
drivers/mtd/spi-nor/controllers/Kconfig | 39 ++++++++++++---------
drivers/mtd/spi-nor/controllers/intel-spi.c | 12 +++++--
2 files changed, 33 insertions(+), 18 deletions(-)

diff --git a/drivers/mtd/spi-nor/controllers/Kconfig b/drivers/mtd/spi-nor/controllers/Kconfig
index 5c0e0ec2e6d1..491c755fea49 100644
--- a/drivers/mtd/spi-nor/controllers/Kconfig
+++ b/drivers/mtd/spi-nor/controllers/Kconfig
@@ -31,34 +31,41 @@ config SPI_INTEL_SPI
tristate

config SPI_INTEL_SPI_PCI
- tristate "Intel PCH/PCU SPI flash PCI driver (DANGEROUS)"
+ tristate "Intel PCH/PCU SPI flash PCI driver"
depends on X86 && PCI
select SPI_INTEL_SPI
help
- This enables PCI support for the Intel PCH/PCU SPI controller in
- master mode. This controller is present in modern Intel hardware
- and is used to hold BIOS and other persistent settings. Using
- this driver it is possible to upgrade BIOS directly from Linux.
-
- Say N here unless you know what you are doing. Overwriting the
- SPI flash may render the system unbootable.
+ This enables read only PCI support for the Intel PCH/PCU SPI
+ controller in master mode. This controller is present in modern
+ Intel hardware and is used to hold BIOS and other persistent settings.
+ Using this driver it is possible to read the SPI chip directly
+ from Linux.

To compile this driver as a module, choose M here: the module
will be called intel-spi-pci.

config SPI_INTEL_SPI_PLATFORM
- tristate "Intel PCH/PCU SPI flash platform driver (DANGEROUS)"
+ tristate "Intel PCH/PCU SPI flash platform driver"
depends on X86
select SPI_INTEL_SPI
help
- This enables platform support for the Intel PCH/PCU SPI
+ This enables read only platform support for the Intel PCH/PCU SPI
controller in master mode. This controller is present in modern
- Intel hardware and is used to hold BIOS and other persistent
- settings. Using this driver it is possible to upgrade BIOS
- directly from Linux.
+ Intel hardware and is used to hold BIOS and other persistent settings.
+ Using this driver it is possible to read the SPI chip directly
+ from Linux.
+
+ To compile this driver as a module, choose M here: the module
+ will be called intel-spi-pci.
+
+config SPI_INTEL_SPI_WRITE
+ bool "Intel PCH/PCU SPI flash drivers write operations (DANGEROUS)"
+ depends on SPI_INTEL_SPI_PCI || SPI_INTEL_SPI_PLATFORM
+ help
+ This enables full read/write support for the Intel PCH/PCU SPI
+ controller.
+ Using this option it may be possible to upgrade BIOS directly
+ from Linux.

Say N here unless you know what you are doing. Overwriting the
SPI flash may render the system unbootable.
-
- To compile this driver as a module, choose M here: the module
- will be called intel-spi-platform.
diff --git a/drivers/mtd/spi-nor/controllers/intel-spi.c b/drivers/mtd/spi-nor/controllers/intel-spi.c
index b54a56a68100..8d8053395c3d 100644
--- a/drivers/mtd/spi-nor/controllers/intel-spi.c
+++ b/drivers/mtd/spi-nor/controllers/intel-spi.c
@@ -266,6 +266,7 @@ static int intel_spi_read_block(struct intel_spi *ispi, void *buf, size_t size)
return 0;
}

+#ifdef CONFIG_SPI_INTEL_SPI_WRITE
/* Writes max INTEL_SPI_FIFO_SZ bytes to the device fifo */
static int intel_spi_write_block(struct intel_spi *ispi, const void *buf,
size_t size)
@@ -286,6 +287,7 @@ static int intel_spi_write_block(struct intel_spi *ispi, const void *buf,

return 0;
}
+#endif /* CONFIG_SPI_INTEL_SPI_WRITE */

static int intel_spi_wait_hw_busy(struct intel_spi *ispi)
{
@@ -576,6 +578,7 @@ static int intel_spi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
return intel_spi_read_block(ispi, buf, len);
}

+#ifdef CONFIG_SPI_INTEL_SPI_WRITE
static int intel_spi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf,
size_t len)
{
@@ -633,6 +636,7 @@ static int intel_spi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf,
OPTYPE_WRITE_NO_ADDR);
return intel_spi_hw_cycle(ispi, opcode, len);
}
+#endif /* CONFIG_SPI_INTEL_SPI_WRITE */

static ssize_t intel_spi_read(struct spi_nor *nor, loff_t from, size_t len,
u_char *read_buf)
@@ -705,6 +709,7 @@ static ssize_t intel_spi_read(struct spi_nor *nor, loff_t from, size_t len,
return retlen;
}

+#ifdef CONFIG_SPI_INTEL_SPI_WRITE
static ssize_t intel_spi_write(struct spi_nor *nor, loff_t to, size_t len,
const u_char *write_buf)
{
@@ -829,6 +834,7 @@ static int intel_spi_erase(struct spi_nor *nor, loff_t offs)

return 0;
}
+#endif /* CONFIG_SPI_INTEL_SPI_WRITE */

static bool intel_spi_is_protected(const struct intel_spi *ispi,
unsigned int base, unsigned int limit)
@@ -897,10 +903,12 @@ static void intel_spi_fill_partition(struct intel_spi *ispi,

static const struct spi_nor_controller_ops intel_spi_controller_ops = {
.read_reg = intel_spi_read_reg,
- .write_reg = intel_spi_write_reg,
.read = intel_spi_read,
+#ifdef CONFIG_SPI_INTEL_SPI_WRITE
+ .write_reg = intel_spi_write_reg,
.write = intel_spi_write,
- .erase = intel_spi_erase,
+ .erase = intel_spi_erase
+#endif
};

struct intel_spi *intel_spi_probe(struct device *dev,
--
2.25.1