diff --git a/core/Makefile.inc b/core/Makefile.inc
index 1a4e466..590780f 100644
--- a/core/Makefile.inc
+++ b/core/Makefile.inc
@@ -5,7 +5,7 @@ CORE_OBJS = relocate.o console.o stack.o init.o chip.o mem_region.o
 CORE_OBJS += malloc.o lock.o cpu.o utils.o fdt.o opal.o interrupts.o
 CORE_OBJS += timebase.o opal-msg.o pci.o pci-opal.o fast-reboot.o
 CORE_OBJS += device.o exceptions.o trace.o affinity.o vpd.o
-CORE_OBJS += hostservices.o platform.o nvram.o flash-nvram.o hmi.o
+CORE_OBJS += hostservices.o platform.o nvram.o hmi.o
 CORE_OBJS += console-log.o ipmi.o time-utils.o pel.o pool.o errorlog.o
 CORE_OBJS += timer.o i2c.o rtc.o flash.o
 CORE=core/built-in.o
diff --git a/core/flash-nvram.c b/core/flash-nvram.c
deleted file mode 100644
index 7e261b1..0000000
--- a/core/flash-nvram.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright 2013-2014 IBM Corp.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 	http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- * implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include <skiboot.h>
-#include <device.h>
-#include <console.h>
-#include <opal.h>
-#include <platform.h>
-#include <libflash/libflash.h>
-
-static struct flash_chip *fl_nv_chip;
-static uint32_t fl_nv_start, fl_nv_size;
-
-static int flash_nvram_info(uint32_t *total_size)
-{
-	if (!fl_nv_chip)
-		return OPAL_HARDWARE;
-	*total_size = fl_nv_size;
-	return OPAL_SUCCESS;
-}
-
-static int flash_nvram_start_read(void *dst, uint32_t src, uint32_t len)
-{
-	int rc;
-
-	if ((src + len) > fl_nv_size) {
-		prerror("FLASH_NVRAM: read out of bound (0x%x,0x%x)\n",
-			src, len);
-		return OPAL_PARAMETER;
-	}
-	rc = flash_read(fl_nv_chip, fl_nv_start + src, dst, len);
-	if (rc)
-		return rc;
-	nvram_read_complete(true);
-	return 0;
-}
-
-static int flash_nvram_write(uint32_t dst, void *src, uint32_t len)
-{
-	/* TODO: When we have async jobs for PRD, turn this into one */
-
-	if ((dst + len) > fl_nv_size) {
-		prerror("FLASH_NVRAM: write out of bound (0x%x,0x%x)\n",
-			dst, len);
-		return OPAL_PARAMETER;
-	}
-	return flash_smart_write(fl_nv_chip, fl_nv_start + dst, src, len);
-}
-
-int flash_nvram_init(struct flash_chip *chip, uint32_t start, uint32_t size)
-{
-	fl_nv_chip = chip;
-	fl_nv_start = start;
-	fl_nv_size = size;
-
-	platform.nvram_info = flash_nvram_info;
-	platform.nvram_start_read = flash_nvram_start_read;
-	platform.nvram_write = flash_nvram_write;
-
-	return 0;
-}
-
diff --git a/core/flash.c b/core/flash.c
index c6b01ad..b24ceaa 100644
--- a/core/flash.c
+++ b/core/flash.c
@@ -37,6 +37,105 @@ static struct flash *system_flash;
 /* Using a single lock as we only have one flash at present. */
 static struct lock flash_lock;
 
+/* nvram-on-flash support */
+static struct flash *nvram_flash;
+static u32 nvram_offset, nvram_size;
+
+static int flash_nvram_info(uint32_t *total_size)
+{
+	int rc = OPAL_HARDWARE;
+
+	lock(&flash_lock);
+	if (nvram_flash) {
+		*total_size = nvram_size;
+		rc = OPAL_SUCCESS;
+	}
+	unlock(&flash_lock);
+
+	return rc;
+}
+
+static int flash_nvram_start_read(void *dst, uint32_t src, uint32_t len)
+{
+	int rc;
+
+	lock(&flash_lock);
+
+	if (!nvram_flash) {
+		rc = OPAL_HARDWARE;
+		goto out;
+	}
+
+	if ((src + len) > nvram_size) {
+		prerror("FLASH_NVRAM: read out of bound (0x%x,0x%x)\n",
+			src, len);
+		rc = OPAL_PARAMETER;
+		goto out;
+	}
+
+	rc = flash_read(nvram_flash->chip, nvram_offset + src, dst, len);
+
+out:
+	unlock(&flash_lock);
+	if (!rc)
+		nvram_read_complete(true);
+	return rc;
+}
+
+static int flash_nvram_write(uint32_t dst, void *src, uint32_t len)
+{
+	int rc;
+
+	lock(&flash_lock);
+
+	/* TODO: When we have async jobs for PRD, turn this into one */
+
+	if ((dst + len) > nvram_size) {
+		prerror("FLASH_NVRAM: write out of bound (0x%x,0x%x)\n",
+			dst, len);
+		rc = OPAL_PARAMETER;
+		goto out;
+	}
+	rc = flash_smart_write(nvram_flash->chip, nvram_offset + dst, src, len);
+
+out:
+	unlock(&flash_lock);
+	return rc;
+}
+
+static int flash_nvram_probe(struct flash *flash, struct ffs_handle *ffs)
+{
+	uint32_t start, size, part;
+	int rc;
+
+	prlog(PR_INFO, "FLASH: probing for NVRAM\n");
+
+	rc = ffs_lookup_part(ffs, "NVRAM", &part);
+	if (rc) {
+		prlog(PR_WARNING, "FLASH: no NVRAM partition found\n");
+		return OPAL_HARDWARE;
+	}
+
+	rc = ffs_part_info(ffs, part, NULL,
+			   &start, &size, NULL);
+	if (rc) {
+		prlog(PR_ERR, "FLASH: Can't parse ffs info for NVRAM\n");
+		return OPAL_HARDWARE;
+	}
+
+	nvram_flash = flash;
+	nvram_offset = start;
+	nvram_size = size;
+
+	platform.nvram_info = flash_nvram_info;
+	platform.nvram_start_read = flash_nvram_start_read;
+	platform.nvram_write = flash_nvram_write;
+
+	return 0;
+}
+
+/* core flash support */
+
 static void flash_add_dt_partition_node(struct dt_node *flash_node, char *name,
 		uint32_t start, uint32_t size)
 {
@@ -124,11 +223,13 @@ int flash_register(struct flash_chip *chip, bool is_system_flash)
 		ffs = NULL;
 	}
 
-	if (is_system_flash && !system_flash)
-		system_flash = flash;
-
 	flash_add_dt_node(flash, i, ffs);
 
+	if (is_system_flash && !system_flash) {
+		system_flash = flash;
+		flash_nvram_probe(flash, ffs);
+	}
+
 	ffs_close(ffs);
 
 	unlock(&flash_lock);
diff --git a/include/skiboot.h b/include/skiboot.h
index f6fcc63..a13b438 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -206,9 +206,6 @@ extern bool flash_load_resource(enum resource_id id, uint32_t subid,
 extern void nvram_init(void);
 extern void nvram_read_complete(bool success);
 
-/* NVRAM on flash helper */
-extern int flash_nvram_init(struct flash_chip *chip, uint32_t start,
-			    uint32_t size);
 /* UART stuff */
 extern void uart_irq(void);
 extern void uart_setup_linux_passthrough(void);
diff --git a/platforms/astbmc/pnor.c b/platforms/astbmc/pnor.c
index e5bc269..c64f41e 100644
--- a/platforms/astbmc/pnor.c
+++ b/platforms/astbmc/pnor.c
@@ -24,16 +24,13 @@
 
 #include "astbmc.h"
 
-static struct spi_flash_ctrl *pnor_ctrl;
-static struct flash_chip *pnor_chip;
-static struct ffs_handle *pnor_ffs;
-
 int pnor_init(void)
 {
-	uint32_t nv_part, nv_start, nv_size;
+	struct spi_flash_ctrl *pnor_ctrl;
+	struct flash_chip *pnor_chip;
 	int rc;
 
-	/* Open controller, flash and ffs */
+	/* Open controller and flash */
 	rc = ast_sf_open(AST_SF_TYPE_PNOR, &pnor_ctrl);
 	if (rc) {
 		prerror("PLAT: Failed to open PNOR flash controller\n");
@@ -44,42 +41,16 @@ int pnor_init(void)
 		prerror("PLAT: Failed to open init PNOR driver\n");
 		goto fail;
 	}
-	rc = ffs_open_flash(pnor_chip, 0, 0, &pnor_ffs);
-	if (rc) {
-		prerror("PLAT: Failed to parse FFS partition map\n");
-		goto fail;
-	}
 
-	/*
-	 * Grab NVRAM and initialize the flash_nvram module
-	 *
-	 * Note: Ignore actual size for now ... some images have
-	 * it setup incorrectly.
-	 */
-	rc = ffs_lookup_part(pnor_ffs, "NVRAM", &nv_part);
-	if (rc) {
-		prerror("PLAT: No NVRAM partition in PNOR\n");
-		return OPAL_HARDWARE;
-	}
-	rc = ffs_part_info(pnor_ffs, nv_part, NULL,
-			   &nv_start, &nv_size, NULL);
-	if (rc) {
-		prerror("PLAT: Failed to get NVRAM partition info\n");
-		return OPAL_HARDWARE;
-	}
-	flash_nvram_init(pnor_chip, nv_start, nv_size);
+	rc = flash_register(pnor_chip, true);
+	if (!rc)
+		return 0;
 
-	return 0;
  fail:
-	if (pnor_ffs)
-		ffs_close(pnor_ffs);
-	pnor_ffs = NULL;
 	if (pnor_chip)
 		flash_exit(pnor_chip);
-	pnor_chip = NULL;
 	if (pnor_ctrl)
 		ast_sf_close(pnor_ctrl);
-	pnor_ctrl = NULL;
 
 	return rc;
 }
diff --git a/platforms/rhesus/rhesus.c b/platforms/rhesus/rhesus.c
index 8385a0c..50769cf 100644
--- a/platforms/rhesus/rhesus.c
+++ b/platforms/rhesus/rhesus.c
@@ -38,10 +38,6 @@
 #define RHESUS_BOARD_REVISION3	EC_GPIO_PORT_E, 4
 #define RHESUS_BOARD_REVISION4	EC_GPIO_PORT_E, 1
 
-static struct spi_flash_ctrl *pnor_ctrl;
-static struct flash_chip *pnor_chip;
-static struct ffs_handle *pnor_ffs;
-
 
 /*
  * IO accessors for the EC driver
@@ -121,7 +117,8 @@ static int64_t rhesus_power_down(uint64_t request __unused)
 
 static int rhesus_pnor_init(void)
 {
-	uint32_t nv_part, nv_start, nv_size;
+	struct spi_flash_ctrl *pnor_ctrl;
+	struct flash_chip *pnor_chip;
 	int rc;
 
 	/* Open controller, flash and ffs */
@@ -135,42 +132,16 @@ static int rhesus_pnor_init(void)
 		prerror("PLAT: Failed to open init PNOR driver\n");
 		goto fail;
 	}
-	rc = ffs_open_flash(pnor_chip, 0, 0, &pnor_ffs);
-	if (rc) {
-		prerror("PLAT: Failed to parse FFS partition map\n");
-		goto fail;
-	}
 
-	/*
-	 * Grab NVRAM and initialize the flash_nvram module
-	 *
-	 * Note: Ignore actual size for now ... some images have
-	 * it setup incorrectly.
-	 */
-	rc = ffs_lookup_part(pnor_ffs, "NVRAM", &nv_part);
-	if (rc) {
-		prerror("PLAT: No NVRAM partition in PNOR\n");
-		return OPAL_HARDWARE;
-	}
-	rc = ffs_part_info(pnor_ffs, nv_part, NULL,
-			   &nv_start, &nv_size, NULL);
-	if (rc) {
-		prerror("PLAT: Failed to get NVRAM partition info\n");
-		return OPAL_HARDWARE;
-	}
-	flash_nvram_init(pnor_chip, nv_start, nv_size);
+	rc = flash_register(pnor_chip, true);
+	if (!rc)
+		return 0;
 
-	return 0;
  fail:
-	if (pnor_ffs)
-		ffs_close(pnor_ffs);
-	pnor_ffs = NULL;
 	if (pnor_chip)
 		flash_exit(pnor_chip);
-	pnor_chip = NULL;
 	if (pnor_ctrl)
 		sfc_close(pnor_ctrl);
-	pnor_ctrl = NULL;
 
 	return rc;
 }
