+ return -EINVAL;
+}
+
+static int nand_read_buffer(struct nfc_config *conf, uint32_t offs,
+ unsigned int size, void *dest)
+{
+ int first_seed, page, ret;
+
+ size = ALIGN(size, conf->page_size);
+ page = offs / conf->page_size;
+ first_seed = page % conf->nseeds;
+
+ for (; size; size -= conf->page_size) {
+ if (nand_load_page(conf, offs))
+ return -1;
+
+ ret = nand_read_page(conf, offs, dest, conf->page_size);
+ /*
+ * The ->nseeds value should be equal to the number of pages
+ * in an eraseblock. Since we don't know this information in
+ * advance we might have picked a wrong value.
+ */
+ if (ret < 0 && conf->randomize) {
+ int cur_seed = page % conf->nseeds;
+
+ /*
+ * We already tried all the seed values => we are
+ * facing a real corruption.
+ */
+ if (cur_seed < first_seed)
+ return -EIO;
+
+ /* Try to adjust ->nseeds and read the page again... */
+ conf->nseeds = cur_seed;
+
+ if (nand_reset_column())
+ return -EIO;
+
+ /* ... it still fails => it's a real corruption. */
+ if (nand_read_page(conf, offs, dest, conf->page_size))
+ return -EIO;
+ } else if (ret && conf->randomize) {
+ memset(dest, 0xff, conf->page_size);
+ }
+
+ page++;
+ offs += conf->page_size;
+ dest += conf->page_size;
+ }
+
+ return 0;
+}
+
+int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest)
+{
+ static struct nfc_config conf = { };
+ int ret;
+
+ ret = nand_detect_config(&conf, offs, dest);
+ if (ret)
+ return ret;
+
+ return nand_read_buffer(&conf, offs, size, dest);