diff options
author | Lee Jones <lee.jones@linaro.org> | 2014-03-20 05:20:50 -0400 |
---|---|---|
committer | Brian Norris <computersforpeace@gmail.com> | 2014-03-20 07:17:17 -0400 |
commit | 0ea7d70693431842b6b5c1808f59aa49e3fca6b1 (patch) | |
tree | d75343e22265399f2c6a9750218a943bfdba3f64 /drivers/mtd/devices/st_spi_fsm.c | |
parent | 88cccb89117dfe258c5d8abb55db47e0a2a7daec (diff) |
mtd: st_spi_fsm: Add a check to if the chip can handle an SoC reset
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.
Acked-by Angus Clark <angus.clark@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Diffstat (limited to 'drivers/mtd/devices/st_spi_fsm.c')
-rw-r--r-- | drivers/mtd/devices/st_spi_fsm.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c index 3e13d579aef8..7cc4425e7f1f 100644 --- a/drivers/mtd/devices/st_spi_fsm.c +++ b/drivers/mtd/devices/st_spi_fsm.c | |||
@@ -210,6 +210,8 @@ struct stfsm { | |||
210 | 210 | ||
211 | uint32_t fifo_dir_delay; | 211 | uint32_t fifo_dir_delay; |
212 | bool booted_from_spi; | 212 | bool booted_from_spi; |
213 | bool reset_signal; | ||
214 | bool reset_por; | ||
213 | }; | 215 | }; |
214 | 216 | ||
215 | struct stfsm_seq { | 217 | struct stfsm_seq { |
@@ -521,6 +523,40 @@ static void stfsm_read_fifo(struct stfsm *fsm, uint32_t *buf, | |||
521 | } | 523 | } |
522 | } | 524 | } |
523 | 525 | ||
526 | /* | ||
527 | * SoC reset on 'boot-from-spi' systems | ||
528 | * | ||
529 | * Certain modes of operation cause the Flash device to enter a particular state | ||
530 | * for a period of time (e.g. 'Erase Sector', 'Quad Enable', and 'Enter 32-bit | ||
531 | * Addr' commands). On boot-from-spi systems, it is important to consider what | ||
532 | * happens if a warm reset occurs during this period. The SPIBoot controller | ||
533 | * assumes that Flash device is in its default reset state, 24-bit address mode, | ||
534 | * and ready to accept commands. This can be achieved using some form of | ||
535 | * on-board logic/controller to force a device POR in response to a SoC-level | ||
536 | * reset or by making use of the device reset signal if available (limited | ||
537 | * number of devices only). | ||
538 | * | ||
539 | * Failure to take such precautions can cause problems following a warm reset. | ||
540 | * For some operations (e.g. ERASE), there is little that can be done. For | ||
541 | * other modes of operation (e.g. 32-bit addressing), options are often | ||
542 | * available that can help minimise the window in which a reset could cause a | ||
543 | * problem. | ||
544 | * | ||
545 | */ | ||
546 | static bool stfsm_can_handle_soc_reset(struct stfsm *fsm) | ||
547 | { | ||
548 | /* Reset signal is available on the board and supported by the device */ | ||
549 | if (fsm->reset_signal && fsm->info->flags & FLASH_FLAG_RESET) | ||
550 | return true; | ||
551 | |||
552 | /* Board-level logic forces a power-on-reset */ | ||
553 | if (fsm->reset_por) | ||
554 | return true; | ||
555 | |||
556 | /* Reset is not properly handled and may result in failure to reboot */ | ||
557 | return false; | ||
558 | } | ||
559 | |||
524 | /* Configure 'addr_cfg' according to addressing mode */ | 560 | /* Configure 'addr_cfg' according to addressing mode */ |
525 | static void stfsm_prepare_erasesec_seq(struct stfsm *fsm, | 561 | static void stfsm_prepare_erasesec_seq(struct stfsm *fsm, |
526 | struct stfsm_seq *seq) | 562 | struct stfsm_seq *seq) |
@@ -786,6 +822,10 @@ static void stfsm_fetch_platform_configs(struct platform_device *pdev) | |||
786 | if (IS_ERR(regmap)) | 822 | if (IS_ERR(regmap)) |
787 | goto boot_device_fail; | 823 | goto boot_device_fail; |
788 | 824 | ||
825 | fsm->reset_signal = of_property_read_bool(np, "st,reset-signal"); | ||
826 | |||
827 | fsm->reset_por = of_property_read_bool(np, "st,reset-por"); | ||
828 | |||
789 | /* Where in the syscon the boot device information lives */ | 829 | /* Where in the syscon the boot device information lives */ |
790 | ret = of_property_read_u32(np, "st,boot-device-reg", &boot_device_reg); | 830 | ret = of_property_read_u32(np, "st,boot-device-reg", &boot_device_reg); |
791 | if (ret) | 831 | if (ret) |