aboutsummaryrefslogtreecommitdiff
path: root/core/flash.c
diff options
context:
space:
mode:
authorStewart Smith <stewart@linux.vnet.ibm.com>2015-03-06 14:18:45 +1100
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-03-06 14:18:45 +1100
commitdaa340ae58bbf774628d87505b2696e6f63f75d1 (patch)
tree757209560a71e40cffbe92a3e779232d4a0b5574 /core/flash.c
parent6cf8b663e7d7cb1e827b6d9c90e694ea583f6f87 (diff)
parent9a3f68b499e686ff3b543633f59192890f6c740b (diff)
downloadskiboot-daa340ae58bbf774628d87505b2696e6f63f75d1.zip
skiboot-daa340ae58bbf774628d87505b2696e6f63f75d1.tar.gz
skiboot-daa340ae58bbf774628d87505b2696e6f63f75d1.tar.bz2
Merge branch 'openpower'
Diffstat (limited to 'core/flash.c')
-rw-r--r--core/flash.c58
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;