diff options
author | Ashok Reddy Soma | 2019-09-17 00:11:02 -0600 |
---|---|---|
committer | Michal Simek | 2020-01-14 09:05:54 +0100 |
commit | 4d9b1afa415ddf998f6f40283f95770106cef35b (patch) | |
tree | 64dc6a003e8189d2cb7fd163da4483652df06553 /drivers | |
parent | 312f2c5b14fa3fac1cbf942fad3a08ab6358d025 (diff) |
spi: Fix manual relocation calling more times
When two instances of AXI QSPI with flash are added and tested
simultaneously the spi driver operations are relocated twice.
As a result code is accessing addresses outside of RAM when
relocated second time which is causing a crash.
Tested on Microblaze.
Similar change was done in past by:
commit f238b3f0fbc9 ("watchdog: dm: Support manual relocation for watchdogs")
commit 2588f2ddfd60 ("dm: sf: Add support for all targets which requires MANUAL_RELOC")
commit 1b4c2aa25bdf ("gpio: dm: Support manual relocation for gpio")
Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/spi/spi-uclass.c | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index af910e9efce..0ca108ee3d4 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -170,21 +170,25 @@ static int spi_post_probe(struct udevice *bus) #endif #if defined(CONFIG_NEEDS_MANUAL_RELOC) struct dm_spi_ops *ops = spi_get_ops(bus); - - if (ops->claim_bus) - ops->claim_bus += gd->reloc_off; - if (ops->release_bus) - ops->release_bus += gd->reloc_off; - if (ops->set_wordlen) - ops->set_wordlen += gd->reloc_off; - if (ops->xfer) - ops->xfer += gd->reloc_off; - if (ops->set_speed) - ops->set_speed += gd->reloc_off; - if (ops->set_mode) - ops->set_mode += gd->reloc_off; - if (ops->cs_info) - ops->cs_info += gd->reloc_off; + static int reloc_done; + + if (!reloc_done) { + if (ops->claim_bus) + ops->claim_bus += gd->reloc_off; + if (ops->release_bus) + ops->release_bus += gd->reloc_off; + if (ops->set_wordlen) + ops->set_wordlen += gd->reloc_off; + if (ops->xfer) + ops->xfer += gd->reloc_off; + if (ops->set_speed) + ops->set_speed += gd->reloc_off; + if (ops->set_mode) + ops->set_mode += gd->reloc_off; + if (ops->cs_info) + ops->cs_info += gd->reloc_off; + reloc_done++; + } #endif return 0; |