[PATCH 19/23] mtd: st_spi_fsm: Add a check to if the chip can handle an SoC reset
Lee Jones
lee.jones at linaro.org
Fri Nov 22 11:22:56 EST 2013
Based on information we can obtain though platform specific data and/or
chip capabilities we are able to determine whether or not we can handle
a SoC reset or not. To find out why this is important please read the
comment provided in the patch.
Signed-off-by: Lee Jones <lee.jones at linaro.org>
---
drivers/mtd/devices/st_spi_fsm.c | 38 ++++++++++++++++++++++++++++++++++++++
drivers/mtd/devices/st_spi_fsm.h | 2 ++
2 files changed, 40 insertions(+)
diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 85abf9a..9a66c99 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -128,6 +128,40 @@ static void stfsm_wait_seq(struct stfsm *fsm)
dev_err(fsm->dev, "timeout on sequence completion\n");
}
+/*
+ * SoC reset on 'boot-from-spi' systems
+ *
+ * Certain modes of operation cause the Flash device to enter a particular state
+ * for a period of time (e.g. 'Erase Sector', 'Quad Enable', and 'Enter 32-bit
+ * Addr' commands). On boot-from-spi systems, it is important to consider what
+ * happens if a warm reset occurs during this period. The SPIBoot controller
+ * assumes that Flash device is in its default reset state, 24-bit address mode,
+ * and ready to accept commands. This can be achieved using some form of
+ * on-board logic/controller to force a device POR in response to a SoC-level
+ * reset or by making use of the device reset signal if available (limited
+ * number of devices only).
+ *
+ * Failure to take such precautions can cause problems following a warm reset.
+ * For some operations (e.g. ERASE), there is little that can be done. For
+ * other modes of operation (e.g. 32-bit addressing), options are often
+ * available that can help minimise the window in which a reset could cause a
+ * problem.
+ *
+ */
+static bool stfsm_can_handle_soc_reset(struct stfsm *fsm)
+{
+ /* Reset signal is available on the board and supported by the device */
+ if (fsm->reset_signal && fsm->info->flags & FLASH_FLAG_RESET)
+ return true;
+
+ /* Board-level logic forces a power-on-reset */
+ if (fsm->reset_por)
+ return true;
+
+ /* Reset is not properly handled and may result in failure to reboot */
+ return false;
+}
+
/* Configure 'addr_cfg' according to addressing mode */
static void stfsm_prepare_erasesec_seq(struct stfsm *fsm,
struct stfsm_seq *seq)
@@ -442,6 +476,10 @@ static void stfsm_fetch_platform_configs(struct platform_device *pdev)
goto boot_device_fail;
}
+ fsm->reset_signal = of_property_read_bool(np, "st,reset-signal");
+
+ fsm->reset_por = of_property_read_bool(np, "st,reset-por");
+
/* Where in the syscon the boot device information lives */
ret = of_property_read_u32(np, "boot-device-reg", &boot_device_reg);
if (ret)
diff --git a/drivers/mtd/devices/st_spi_fsm.h b/drivers/mtd/devices/st_spi_fsm.h
index 2e12bff..8eb9e20 100644
--- a/drivers/mtd/devices/st_spi_fsm.h
+++ b/drivers/mtd/devices/st_spi_fsm.h
@@ -239,6 +239,8 @@ struct stfsm {
uint32_t fifo_dir_delay;
bool booted_from_spi;
+ bool reset_signal;
+ bool reset_por;
};
struct stfsm_seq {
--
1.8.1.2
More information about the linux-arm-kernel
mailing list