/* 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "libflash.h"
#include "libflash-priv.h"
#include "ecc.h"
#include "blocklevel.h"

static const struct flash_info flash_info[] = {
	{ 0xc22018, 0x01000000, FL_ERASE_ALL | FL_CAN_4B, "Macronix MXxxL12835F"},
	{ 0xc22019, 0x02000000, FL_ERASE_ALL | FL_CAN_4B, "Macronix MXxxL25635F"},
	{ 0xc2201a, 0x04000000, FL_ERASE_ALL | FL_CAN_4B, "Macronix MXxxL51235F"},
	{ 0xc2201b, 0x08000000, FL_ERASE_ALL | FL_CAN_4B, "Macronix MX66L1G45G"},
	{ 0xef4018, 0x01000000, FL_ERASE_ALL,             "Winbond W25Q128BV"   },
	{ 0xef4019, 0x02000000, FL_ERASE_ALL | FL_ERASE_64K | FL_CAN_4B |
				FL_ERASE_BULK,
							"Winbond W25Q256BV"},
	{ 0x20ba20, 0x04000000, FL_ERASE_4K  | FL_ERASE_64K | FL_CAN_4B |
                                FL_ERASE_BULK | FL_MICRON_BUGS,
                                                          "Micron N25Qx512Ax"   },
	{ 0x20ba19, 0x02000000, FL_ERASE_4K  | FL_ERASE_64K | FL_CAN_4B |
                                FL_ERASE_BULK | FL_MICRON_BUGS,
                                                          "Micron N25Q256Ax"    },
	{ 0x1940ef, 0x02000000, FL_ERASE_4K  | FL_ERASE_64K | FL_CAN_4B |
				FL_ERASE_BULK | FL_MICRON_BUGS,
							"Micron N25Qx256Ax"   },
	{ 0x4d5444, 0x02000000, FL_ERASE_ALL | FL_CAN_4B, "File Abstraction"},
	{ 0x55aa55, 0x00100000, FL_ERASE_ALL | FL_CAN_4B, "TEST_FLASH" },
	{ 0xaa55aa, 0x02000000, FL_ERASE_ALL | FL_CAN_4B, "EMULATED_FLASH"},
};

struct flash_chip {
	struct spi_flash_ctrl	*ctrl;		/* Controller */
	struct flash_info	info;		/* Flash info */
	uint32_t		tsize;		/* Corrected flash size */
	uint32_t		min_erase_mask;	/* Minimum erase size */
	bool			mode_4b;	/* Flash currently in 4b mode */
	struct flash_req	*cur_req;	/* Current request */
	void			*smart_buf;	/* Buffer for smart writes */
	struct blocklevel_device bl;
};

#ifndef __SKIBOOT__
bool libflash_debug;
#endif

int fl_read_stat(struct spi_flash_ctrl *ct, uint8_t *stat)
{
	return ct->cmd_rd(ct, CMD_RDSR, false, 0, stat, 1);
}

static void fl_micron_status(struct spi_flash_ctrl *ct)
{
	uint8_t flst;

	/*
	 * After a success status on a write or erase, we
	 * need to do that command or some chip variants will
	 * lock
	 */
	ct->cmd_rd(ct, CMD_MIC_RDFLST, false, 0, &flst, 1);
}

/* Synchronous write completion, probably need a yield hook */
int fl_sync_wait_idle(struct spi_flash_ctrl *ct)
{
	uint8_t stat;
	int rc;

	/* XXX Add timeout */
	for (;;) {
		rc = fl_read_stat(ct, &stat);
		if (rc) return rc;
		if (!(stat & STAT_WIP)) {
			if (ct->finfo->flags & FL_MICRON_BUGS)
				fl_micron_status(ct);
			return 0;
		}
	}
	/* return FLASH_ERR_WIP_TIMEOUT; */
}

/* Exported for internal use */
int fl_wren(struct spi_flash_ctrl *ct)
{
	int i, rc;
	uint8_t stat;

	/* Some flashes need it to be hammered */
	for (i = 0; i < 1000; i++) {
		rc = ct->cmd_wr(ct, CMD_WREN, false, 0, NULL, 0);
		if (rc) return rc;
		rc = fl_read_stat(ct, &stat);
		if (rc) return rc;
		if (stat & STAT_WIP) {
			FL_ERR("LIBFLASH: WREN has WIP status set !\n");
			rc = fl_sync_wait_idle(ct);
			if (rc)
				return rc;
			continue;
		}
		if (stat & STAT_WEN)
			return 0;
	}
	return FLASH_ERR_WREN_TIMEOUT;
}

static int flash_read(struct blocklevel_device *bl, uint64_t pos, void *buf, uint64_t len)
{
	struct flash_chip *c = container_of(bl, struct flash_chip, bl);
	struct spi_flash_ctrl *ct = c->ctrl;

	/* XXX Add sanity/bound checking */

	/*
	 * If the controller supports read and either we are in 3b mode
	 * or we are in 4b *and* the controller supports it, then do a
	 * high level read.
	 */
	if ((!c->mode_4b || ct->set_4b) && ct->read)
		return ct->read(ct, pos, buf, len);

	/* Otherwise, go manual if supported */
	if (!ct->cmd_rd)
		return FLASH_ERR_CTRL_CMD_UNSUPPORTED;
	return ct->cmd_rd(ct, CMD_READ, true, pos, buf, len);
}

#define COPY_BUFFER_LENGTH 4096

/*
 * This provides a wrapper around flash_read on ECCed data
 * len is length of data without ECC attached
 */
int flash_read_corrected(struct blocklevel_device *bl, uint32_t pos, void *buf,
		uint32_t len, bool ecc)
{
	struct ecc64 *bufecc;
	uint32_t copylen;
	int rc;
	uint8_t ret;

	if (!ecc)
		return flash_read(bl, pos, buf, len);

	/* Copy the buffer in chunks */
	bufecc = malloc(ecc_buffer_size(COPY_BUFFER_LENGTH));
	if (!bufecc)
		return FLASH_ERR_MALLOC_FAILED;

	while (len > 0) {
		/* What's left to copy? */
		copylen = MIN(len, COPY_BUFFER_LENGTH);

		/* Read ECCed data from flash */
		rc = flash_read(bl, pos, bufecc, ecc_buffer_size(copylen));
		if (rc)
			goto err;

		/* Extract data from ECCed data */
		ret = memcpy_from_ecc(buf, bufecc, copylen);
		if (ret) {
			rc = FLASH_ERR_ECC_INVALID;
			goto err;
		}

		/* Update for next copy */
		len -= copylen;
		buf = (uint8_t *)buf + copylen;
		pos += ecc_buffer_size(copylen);
	}

	rc = 0;

err:
	free(bufecc);
	return rc;
}

static void fl_get_best_erase(struct flash_chip *c, uint32_t dst, uint32_t size,
			      uint32_t *chunk, uint8_t *cmd)
{
	/* Smaller than 32k, use 4k */
	if ((dst & 0x7fff) || (size < 0x8000)) {
		*chunk = 0x1000;
		*cmd = CMD_SE;
		return;
	}
	/* Smaller than 64k and 32k is supported, use it */
	if ((c->info.flags & FL_ERASE_32K) &&
	    ((dst & 0xffff) || (size < 0x10000))) {
		*chunk = 0x8000;
		*cmd = CMD_BE32K;
		return;
	}
	/* If 64K is not supported, use whatever smaller size is */
	if (!(c->info.flags & FL_ERASE_64K)) {
		if (c->info.flags & FL_ERASE_32K) {
			*chunk = 0x8000;
			*cmd = CMD_BE32K;
		} else {
			*chunk = 0x1000;
			*cmd = CMD_SE;
		}
		return;
	}
	/* Allright, let's go for 64K */
	*chunk = 0x10000;
	*cmd = CMD_BE;
}

static int flash_erase(struct blocklevel_device *bl, uint64_t dst, uint64_t size)
{
	struct flash_chip *c = container_of(bl, struct flash_chip, bl);
	struct spi_flash_ctrl *ct = c->ctrl;
	uint32_t chunk;
	uint8_t cmd;
	int rc;

	/* Some sanity checking */
	if (((dst + size) <= dst) || !size || (dst + size) > c->tsize)
		return FLASH_ERR_PARM_ERROR;

	/* Check boundaries fit erase blocks */
	if ((dst | size) & c->min_erase_mask)
		return FLASH_ERR_ERASE_BOUNDARY;

	FL_DBG("LIBFLASH: Erasing 0x%" PRIx64"..0%" PRIx64 "...\n",
	       dst, dst + size);

	/* Use controller erase if supported */
	if (ct->erase)
		return ct->erase(ct, dst, size);

	/* Allright, loop as long as there's something to erase */
	while(size) {
		/* How big can we make it based on alignent & size */
		fl_get_best_erase(c, dst, size, &chunk, &cmd);

		/* Poke write enable */
		rc = fl_wren(ct);
		if (rc)
			return rc;

		/* Send erase command */
		rc = ct->cmd_wr(ct, cmd, true, dst, NULL, 0);
		if (rc)
			return rc;

		/* Wait for write complete */
		rc = fl_sync_wait_idle(ct);
		if (rc)
			return rc;

		size -= chunk;
		dst += chunk;
	}
	return 0;
}

int flash_erase_chip(struct flash_chip *c)
{
	struct spi_flash_ctrl *ct = c->ctrl;
	int rc;

	/* XXX TODO: Fallback to using normal erases */
	if (!(c->info.flags & (FL_ERASE_CHIP|FL_ERASE_BULK)))
		return FLASH_ERR_CHIP_ER_NOT_SUPPORTED;

	FL_DBG("LIBFLASH: Erasing chip...\n");
	
	/* Use controller erase if supported */
	if (ct->erase)
		return ct->erase(ct, 0, 0xffffffff);

	rc = fl_wren(ct);
	if (rc) return rc;

	if (c->info.flags & FL_ERASE_CHIP)
		rc = ct->cmd_wr(ct, CMD_CE, false, 0, NULL, 0);
	else
		rc = ct->cmd_wr(ct, CMD_MIC_BULK_ERASE, false, 0, NULL, 0);
	if (rc)
		return rc;

	/* Wait for write complete */
	return fl_sync_wait_idle(ct);
}

static int fl_wpage(struct flash_chip *c, uint32_t dst, const void *src,
		    uint32_t size)
{
	struct spi_flash_ctrl *ct = c->ctrl;
	int rc;

	if (size < 1 || size > 0x100)
		return FLASH_ERR_BAD_PAGE_SIZE;

	rc = fl_wren(ct);
	if (rc) return rc;

	rc = ct->cmd_wr(ct, CMD_PP, true, dst, src, size);
	if (rc)
		return rc;

	/* Wait for write complete */
	return fl_sync_wait_idle(ct);
}

static int flash_write(struct blocklevel_device *bl, uint32_t dst, const void *src,
		uint32_t size, bool verify)
{
	struct flash_chip *c = container_of(bl, struct flash_chip, bl);
	struct spi_flash_ctrl *ct = c->ctrl;
	uint32_t todo = size;
	uint32_t d = dst;
	const void *s = src;
	uint8_t vbuf[0x100];
	int rc;	

	/* Some sanity checking */
	if (((dst + size) <= dst) || !size || (dst + size) > c->tsize)
		return FLASH_ERR_PARM_ERROR;

	FL_DBG("LIBFLASH: Writing to 0x%08x..0%08x...\n", dst, dst + size);

	/*
	 * If the controller supports write and either we are in 3b mode
	 * or we are in 4b *and* the controller supports it, then do a
	 * high level write.
	 */
	if ((!c->mode_4b || ct->set_4b) && ct->write) {
		rc = ct->write(ct, dst, src, size);
		if (rc)
			return rc;
		goto writing_done;
	}

	/* Otherwise, go manual if supported */
	if (!ct->cmd_wr)
		return FLASH_ERR_CTRL_CMD_UNSUPPORTED;

	/* Iterate for each page to write */
	while(todo) {
		uint32_t chunk;

		/* Handle misaligned start */
		chunk = 0x100 - (d & 0xff);
		if (chunk > todo)
			chunk = todo;

		rc = fl_wpage(c, d, s, chunk);
		if (rc) return rc;
		d += chunk;
		s += chunk;
		todo -= chunk;
	}

 writing_done:
	if (!verify)
		return 0;

	/* Verify */
	FL_DBG("LIBFLASH: Verifying...\n");

	while(size) {
		uint32_t chunk;

		chunk = sizeof(vbuf);
		if (chunk > size)
			chunk = size;
		rc = flash_read(bl, dst, vbuf, chunk);
		if (rc) return rc;
		if (memcmp(vbuf, src, chunk)) {
			FL_ERR("LIBFLASH: Miscompare at 0x%08x\n", dst);
			return FLASH_ERR_VERIFY_FAILURE;
		}
		dst += chunk;
		src += chunk;
		size -= chunk;
	}
	return 0;
}

int flash_write_corrected(struct blocklevel_device *bl, uint32_t pos, const void *buf,
		uint32_t len, bool verify, bool ecc)
{
	struct ecc64 *bufecc;
	uint32_t copylen, copylen_minus_ecc;
	int rc;
	uint8_t ret;

	if (!ecc)
		return flash_write(bl, pos, buf, len, verify);

	/* Copy the buffer in chunks */
	bufecc = malloc(ecc_buffer_size(COPY_BUFFER_LENGTH));
	if (!bufecc)
		return FLASH_ERR_MALLOC_FAILED;

	while (len > 0) {
		/* What's left to copy? */
		copylen = MIN(len, COPY_BUFFER_LENGTH);
		copylen_minus_ecc = ecc_buffer_size_minus_ecc(copylen);

		/* Add the ecc byte to the data */
		ret = memcpy_to_ecc(bufecc, buf, copylen_minus_ecc);
		if (ret) {
			rc = FLASH_ERR_ECC_INVALID;
			goto err;
		}

		/* Write ECCed data to the flash */
		rc = flash_write(bl, pos, bufecc, copylen, verify);
		if (rc)
			goto err;

		/* Update for next copy */
		len -= copylen_minus_ecc;
		buf = (uint8_t *)buf + copylen_minus_ecc;
		pos += copylen;
	}

	rc = 0;

err:
	free(bufecc);
	return rc;
}

enum sm_comp_res {
	sm_no_change,
	sm_need_write,
	sm_need_erase,
};

static enum sm_comp_res flash_smart_comp(struct flash_chip *c,
					 const void *src,
					 uint32_t offset, uint32_t size)
{
	uint8_t *b = c->smart_buf + offset;
	const uint8_t *s = src;
	bool is_same = true;
	uint32_t i;

	/* SRC DEST  NEED_ERASE
	 *  0   1       0
	 *  1   1       0
         *  0   0       0
         *  1   0       1
         */
	for (i = 0; i < size; i++) {
		/* Any bit need to be set, need erase */
		if (s[i] & ~b[i])
			return sm_need_erase;
		if (is_same && (b[i] != s[i]))
			is_same = false;
	}
	return is_same ? sm_no_change : sm_need_write;
}

static int flash_smart_write(struct blocklevel_device *bl, uint64_t dst, const void *src, uint64_t size)
{
	struct flash_chip *c = container_of(bl, struct flash_chip, bl);
	uint32_t er_size = c->min_erase_mask + 1;
	uint32_t end = dst + size;
	int rc;

	/* Some sanity checking */
	if (end <= dst || !size || end > c->tsize) {
		FL_DBG("LIBFLASH: Smart write param error\n");
		return FLASH_ERR_PARM_ERROR;
	}

	FL_DBG("LIBFLASH: Smart writing to 0x%" PRIx64 "..0%" PRIx64 "...\n",
	       dst, dst + size);

	/* As long as we have something to write ... */
	while(dst < end) {
		uint32_t page, off, chunk;
		enum sm_comp_res sr;

		/* Figure out which erase page we are in and read it */
		page = dst & ~c->min_erase_mask;
		off = dst & c->min_erase_mask;
		FL_DBG("LIBFLASH:   reading page 0x%08x..0x%08x...",
		       page, page + er_size);
		rc = flash_read(bl, page, c->smart_buf, er_size);
		if (rc) {
			FL_DBG(" error %d!\n", rc);
			return rc;
		}

		/* Locate the chunk of data we are working on */
		chunk = er_size - off;
		if (size < chunk)
			chunk = size;

		/* Compare against what we are writing and ff */
		sr = flash_smart_comp(c, src, off, chunk);
		switch(sr) {
		case sm_no_change:
			/* Identical, skip it */
			FL_DBG(" same !\n");
			break;
		case sm_need_write:
			/* Just needs writing over */
			FL_DBG(" need write !\n");
			rc = flash_write(bl, dst, src, chunk, true);
			if (rc) {
				FL_DBG("LIBFLASH: Write error %d !\n", rc);
				return rc;
			}
			break;
		case sm_need_erase:
			FL_DBG(" need erase !\n");
			rc = flash_erase(bl, page, er_size);
			if (rc) {
				FL_DBG("LIBFLASH: erase error %d !\n", rc);
				return rc;
			}
			/* Then update the portion of the buffer and write the block */
			memcpy(c->smart_buf + off, src, chunk);
			rc = flash_write(bl, page, c->smart_buf, er_size, true);
			if (rc) {
				FL_DBG("LIBFLASH: write error %d !\n", rc);
				return rc;
			}
			break;
		}
		dst += chunk;
		src += chunk;
		size -= chunk;
	}
	return 0;
}

int flash_smart_write_corrected(struct blocklevel_device *bl, uint32_t dst, const void *src,
		      uint32_t size, bool ecc)
{
	struct ecc64 *buf;
	int rc;

	if (!ecc)
		return flash_smart_write(bl, dst, src, size);

	buf = malloc(ecc_buffer_size(size));
	if (!buf)
		return FLASH_ERR_MALLOC_FAILED;

	rc = memcpy_to_ecc(buf, src, size);
	if (rc) {
		rc = FLASH_ERR_ECC_INVALID;
		goto out;
	}

	rc = flash_smart_write(bl, dst, buf, ecc_buffer_size(size));

out:
	free(buf);
	return rc;
}

static int fl_chip_id(struct spi_flash_ctrl *ct, uint8_t *id_buf,
		      uint32_t *id_size)
{
	int rc;
	uint8_t stat;

	/* Check initial status */
	rc = fl_read_stat(ct, &stat);
	if (rc)
		return rc;

	/* If stuck writing, wait for idle */
	if (stat & STAT_WIP) {
		FL_ERR("LIBFLASH: Flash in writing state ! Waiting...\n");
		rc = fl_sync_wait_idle(ct);
		if (rc)
			return rc;
	} else
		FL_DBG("LIBFLASH: Init status: %02x\n", stat);

	/* Fallback to get ID manually */
	rc = ct->cmd_rd(ct, CMD_RDID, false, 0, id_buf, 3);
	if (rc)
		return rc;
	*id_size = 3;

	return 0;
}

static int flash_identify(struct flash_chip *c)
{
	struct spi_flash_ctrl *ct = c->ctrl;
	const struct flash_info *info = NULL;
	uint32_t iid, id_size;
#define MAX_ID_SIZE	16
	uint8_t id[MAX_ID_SIZE];
	int rc, i;

	if (ct->chip_id) {
		/* High level controller interface */
		id_size = MAX_ID_SIZE;
		rc = ct->chip_id(ct, id, &id_size);
	} else
		rc = fl_chip_id(ct, id, &id_size);
	if (rc)
		return rc;
	if (id_size < 3)
		return FLASH_ERR_CHIP_UNKNOWN;

	/* Convert to a dword for lookup */
	iid = id[0];
	iid = (iid << 8) | id[1];
	iid = (iid << 8) | id[2];

	FL_DBG("LIBFLASH: Flash ID: %02x.%02x.%02x (%06x)\n",
	       id[0], id[1], id[2], iid);

	/* Lookup in flash_info */
	for (i = 0; i < ARRAY_SIZE(flash_info); i++) {
		info = &flash_info[i];
		if (info->id == iid)
			break;		
	}
	if (!info || info->id != iid)
		return FLASH_ERR_CHIP_UNKNOWN;

	c->info = *info;
	c->tsize = info->size;
	ct->finfo = &c->info;

	/*
	 * Let controller know about our settings and possibly
	 * override them
	 */
	if (ct->setup) {
		rc = ct->setup(ct, &c->tsize);
		if (rc)
			return rc;
	}

	/* Calculate min erase granularity */
	if (c->info.flags & FL_ERASE_4K)
		c->min_erase_mask = 0xfff;
	else if (c->info.flags & FL_ERASE_32K)
		c->min_erase_mask = 0x7fff;
	else if (c->info.flags & FL_ERASE_64K)
		c->min_erase_mask = 0xffff;
	else {
		/* No erase size ? oops ... */
		FL_ERR("LIBFLASH: No erase sizes !\n");
		return FLASH_ERR_CTRL_CONFIG_MISMATCH;
	}

	FL_DBG("LIBFLASH: Found chip %s size %dM erase granule: %dK\n",
	       c->info.name, c->tsize >> 20, (c->min_erase_mask + 1) >> 10);

	return 0;
}

static int flash_set_4b(struct flash_chip *c, bool enable)
{
	struct spi_flash_ctrl *ct = c->ctrl;
	int rc;

	/* Don't have low level interface, assume all is well */
	if (!ct->cmd_wr)
		return 0;

	/* Some flash chips want this */
	rc = fl_wren(ct);
	if (rc) {
		FL_ERR("LIBFLASH: Error %d enabling write for set_4b\n", rc);
		/* Ignore the error & move on (could be wrprotect chip) */
	}

	/* Ignore error in case chip is write protected */
	return ct->cmd_wr(ct, enable ? CMD_EN4B : CMD_EX4B, false, 0, NULL, 0);
}

int flash_force_4b_mode(struct flash_chip *c, bool enable_4b)
{
	struct spi_flash_ctrl *ct = c->ctrl;
	int rc = FLASH_ERR_4B_NOT_SUPPORTED;

	/*
	 * We only allow force 4b if both controller and flash do 4b
	 * as this is mainly used if a 3rd party tries to directly
	 * access a direct mapped read region
	 */
	if (enable_4b && !((c->info.flags & FL_CAN_4B) && ct->set_4b))
		return rc;

	/* Only send to flash directly on controllers that implement
	 * the low level callbacks
	 */
	if (ct->cmd_wr) {
		rc = flash_set_4b(c, enable_4b);
		if (rc)
			return rc;
	}

	/* Then inform the controller */
	if (ct->set_4b)
		rc = ct->set_4b(ct, enable_4b);
	return rc;
}

static int flash_configure(struct flash_chip *c)
{
	struct spi_flash_ctrl *ct = c->ctrl;
	int rc;

	/* Crop flash size if necessary */
	if (c->tsize > 0x01000000 && !(c->info.flags & FL_CAN_4B)) {
		FL_ERR("LIBFLASH: Flash chip cropped to 16M, no 4b mode\n");
		c->tsize = 0x01000000;
	}

	/* If flash chip > 16M, enable 4b mode */
	if (c->tsize > 0x01000000) {
		FL_DBG("LIBFLASH: Flash >16MB, enabling 4B mode...\n");

		/* Set flash to 4b mode if we can */
		if (ct->cmd_wr) {
			rc = flash_set_4b(c, true);
			if (rc) {
				FL_ERR("LIBFLASH: Failed to set flash 4b mode\n");
				return rc;
			}
		}


		/* Set controller to 4b mode if supported */
		if (ct->set_4b) {
			FL_DBG("LIBFLASH: Enabling controller 4B mode...\n");
			rc = ct->set_4b(ct, true);
			if (rc) {
				FL_ERR("LIBFLASH: Failed to set controller 4b mode\n");
				return rc;
			}
		}
	} else {
		FL_DBG("LIBFLASH: Flash <=16MB, disabling 4B mode...\n");

		/*
		 * If flash chip supports 4b mode, make sure we disable
		 * it in case it was left over by the previous user
		 */
		if (c->info.flags & FL_CAN_4B) {
			rc = flash_set_4b(c, false);
			if (rc) {
				FL_ERR("LIBFLASH: Failed to"
				       " clear flash 4b mode\n");
				return rc;
			}
		}
		/* Set controller to 3b mode if mode switch is supported */
		if (ct->set_4b) {
			FL_DBG("LIBFLASH: Disabling controller 4B mode...\n");
			rc = ct->set_4b(ct, false);
			if (rc) {
				FL_ERR("LIBFLASH: Failed to"
				       " clear controller 4b mode\n");
				return rc;
			}
		}
	}
	return 0;
}

static int flash_get_info(struct blocklevel_device *bl, const char **name,
		   uint64_t *total_size, uint32_t *erase_granule)
{
	struct flash_chip *c = container_of(bl, struct flash_chip, bl);
	if (name)
		*name = c->info.name;
	if (total_size)
		*total_size = c->tsize;
	if (erase_granule)
		*erase_granule = c->min_erase_mask + 1;
	return 0;
}

int flash_init(struct spi_flash_ctrl *ctrl, struct blocklevel_device **bl,
		struct flash_chip **flash_chip)
{
	struct flash_chip *c;
	int rc;

	if (!bl)
		return FLASH_ERR_PARM_ERROR;

	*bl = NULL;

	c = malloc(sizeof(struct flash_chip));
	if (!c)
		return FLASH_ERR_MALLOC_FAILED;
	memset(c, 0, sizeof(*c));
	c->ctrl = ctrl;

	rc = flash_identify(c);
	if (rc) {
		FL_ERR("LIBFLASH: Flash identification failed\n");
		goto bail;
	}
	c->smart_buf = malloc(c->min_erase_mask + 1);
	if (!c->smart_buf) {
		FL_ERR("LIBFLASH: Failed to allocate smart buffer !\n");
		rc = FLASH_ERR_MALLOC_FAILED;
		goto bail;
	}
	rc = flash_configure(c);
	if (rc)
		FL_ERR("LIBFLASH: Flash configuration failed\n");
bail:
	if (rc) {
		free(c);
		return rc;
	}

	/* The flash backend doesn't support reiniting it */
	c->bl.keep_alive = true;
	c->bl.reacquire = NULL;
	c->bl.release = NULL;
	c->bl.read = &flash_read;
	c->bl.write = &flash_smart_write;
	c->bl.erase = &flash_erase;
	c->bl.get_info = &flash_get_info;
	c->bl.erase_mask = c->min_erase_mask;
	c->bl.flags = WRITE_NEED_ERASE;

	*bl = &(c->bl);
	if (flash_chip)
		*flash_chip = c;

	return 0;
}

void flash_exit(struct blocklevel_device *bl)
{
	/* XXX Make sure we are idle etc... */
	if (bl) {
		struct flash_chip *c = container_of(bl, struct flash_chip, bl);
		free(c->smart_buf);
		free(c);
	}
}

void flash_exit_close(struct blocklevel_device *bl, void (*close)(struct spi_flash_ctrl *ctrl))
{
	if (bl) {
		struct flash_chip *c = container_of(bl, struct flash_chip, bl);
		close(c->ctrl);
		free(c);
	}
}
