diff options
author | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-03-06 14:18:45 +1100 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-03-06 14:18:45 +1100 |
commit | daa340ae58bbf774628d87505b2696e6f63f75d1 (patch) | |
tree | 757209560a71e40cffbe92a3e779232d4a0b5574 /core/flash.c | |
parent | 6cf8b663e7d7cb1e827b6d9c90e694ea583f6f87 (diff) | |
parent | 9a3f68b499e686ff3b543633f59192890f6c740b (diff) | |
download | skiboot-daa340ae58bbf774628d87505b2696e6f63f75d1.zip skiboot-daa340ae58bbf774628d87505b2696e6f63f75d1.tar.gz skiboot-daa340ae58bbf774628d87505b2696e6f63f75d1.tar.bz2 |
Merge branch 'openpower'
Diffstat (limited to 'core/flash.c')
-rw-r--r-- | core/flash.c | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/core/flash.c b/core/flash.c index 37827b3..f2d7501 100644 --- a/core/flash.c +++ b/core/flash.c @@ -26,6 +26,7 @@ struct flash { bool registered; + bool busy; struct flash_chip *chip; uint32_t size; uint32_t block_size; @@ -42,12 +43,39 @@ static struct lock flash_lock; static struct flash *nvram_flash; static u32 nvram_offset, nvram_size; +bool flash_reserve(void) +{ + bool rc = false; + + if (!try_lock(&flash_lock)) + return false; + + if (!system_flash->busy) { + system_flash->busy = true; + rc = true; + } + unlock(&flash_lock); + + return rc; +} + +void flash_release(void) +{ + lock(&flash_lock); + system_flash->busy = false; + unlock(&flash_lock); +} + static int flash_nvram_info(uint32_t *total_size) { - int rc = OPAL_HARDWARE; + int rc; lock(&flash_lock); - if (nvram_flash) { + if (!nvram_flash) { + rc = OPAL_HARDWARE; + } else if (nvram_flash->busy) { + rc = OPAL_BUSY; + } else { *total_size = nvram_size; rc = OPAL_SUCCESS; } @@ -60,13 +88,19 @@ static int flash_nvram_start_read(void *dst, uint32_t src, uint32_t len) { int rc; - lock(&flash_lock); + if (!try_lock(&flash_lock)) + return OPAL_BUSY; if (!nvram_flash) { rc = OPAL_HARDWARE; goto out; } + if (nvram_flash->busy) { + rc = OPAL_BUSY; + goto out; + } + if ((src + len) > nvram_size) { prerror("FLASH_NVRAM: read out of bound (0x%x,0x%x)\n", src, len); @@ -87,7 +121,13 @@ static int flash_nvram_write(uint32_t dst, void *src, uint32_t len) { int rc; - lock(&flash_lock); + if (!try_lock(&flash_lock)) + return OPAL_BUSY; + + if (nvram_flash->busy) { + rc = OPAL_BUSY; + goto out; + } /* TODO: When we have async jobs for PRD, turn this into one */ @@ -235,6 +275,7 @@ int flash_register(struct flash_chip *chip, bool is_system_flash) flash = &flashes[i]; flash->registered = true; + flash->busy = false; flash->chip = chip; flash->size = size; flash->block_size = block_size; @@ -286,6 +327,12 @@ static int64_t opal_flash_op(enum flash_op op, uint64_t id, uint64_t offset, return OPAL_BUSY; flash = &flashes[id]; + + if (flash->busy) { + rc = OPAL_BUSY; + goto err; + } + if (!flash->registered) { rc = OPAL_PARAMETER; goto err; @@ -493,6 +540,9 @@ bool flash_load_resource(enum resource_id id, uint32_t subid, flash = system_flash; + if (flash->busy) + goto out_unlock; + for (i = 0, name = NULL; i < ARRAY_SIZE(part_name_map); i++) { if (part_name_map[i].id == id) { name = part_name_map[i].name; |