diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2016-02-08 08:26:43 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2016-02-08 08:26:43 +0100 |
commit | 1379a5ef1e5229d9ea71293c7bb6cb89e6d706a4 (patch) | |
tree | 175268eaf70e2fbf7fa5fb6550464b0d13d95404 /drivers | |
parent | 79606b51ed58819bd71bc6ca7d1a41185f83c89c (diff) | |
parent | b09ee0358cd41b833da9788acf26efdfb6abe40d (diff) | |
download | barebox-1379a5ef1e5229d9ea71293c7bb6cb89e6d706a4.tar.gz barebox-1379a5ef1e5229d9ea71293c7bb6cb89e6d706a4.tar.xz |
Merge branch 'for-next/misc'
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/spi-nor/spi-nor.c | 37 | ||||
-rw-r--r-- | drivers/of/platform.c | 7 |
2 files changed, 39 insertions, 5 deletions
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 27f4abc03e..908aacb6a2 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -15,6 +15,7 @@ #include <driver.h> #include <errno.h> #include <linux/err.h> +#include <linux/sizes.h> #include <linux/math64.h> #include <linux/mod_devicetable.h> #include <linux/mtd/mtd.h> @@ -25,6 +26,18 @@ #define SPI_NOR_MAX_ID_LEN 6 +/* + * For everything but full-chip erase; probably could be much smaller, but kept + * around for safety for now + */ +#define DEFAULT_READY_WAIT (40 * SECOND) + +/* + * For full-chip erase, calibrated to a 2MB flash (M25P16); should be scaled up + * for larger flash + */ +#define CHIP_ERASE_2MB_READY_WAIT (40 * SECOND) + struct flash_info { /* * This array stores the ID bytes. @@ -228,14 +241,15 @@ static int spi_nor_ready(struct spi_nor *nor) * Service routine to read status register until ready, or timeout occurs. * Returns non-zero if error. */ -static int spi_nor_wait_till_ready(struct spi_nor *nor) +static int spi_nor_wait_till_ready_with_timeout(struct spi_nor *nor, + uint64_t timeout_ns) { uint64_t start = get_time_ns(); int timeout = 0; int ret; while (!timeout) { - if (is_timeout(start, 40 * SECOND)) + if (is_timeout(start, timeout_ns)) timeout = 1; ret = spi_nor_ready(nor); @@ -250,6 +264,12 @@ static int spi_nor_wait_till_ready(struct spi_nor *nor) return -ETIMEDOUT; } +static int spi_nor_wait_till_ready(struct spi_nor *nor) +{ + return spi_nor_wait_till_ready_with_timeout(nor, + DEFAULT_READY_WAIT); +} + /* * Erase the whole flash memory * @@ -318,6 +338,8 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) /* whole-chip erase? */ if (len == mtd->size) { + uint64_t timeout; + write_enable(nor); if (erase_chip(nor)) { @@ -325,7 +347,16 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) goto erase_err; } - ret = spi_nor_wait_till_ready(nor); + /* + * Scale the timeout linearly with the size of the flash, with + * a minimum calibrated to an old 2MB flash. We could try to + * pull these from CFI/SFDP, but these values should be good + * enough for now. + */ + timeout = max(CHIP_ERASE_2MB_READY_WAIT, + CHIP_ERASE_2MB_READY_WAIT * + (uint64_t)(mtd->size / SZ_2M)); + ret = spi_nor_wait_till_ready_with_timeout(nor, timeout); if (ret) goto erase_err; diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 2c075dbae3..3f848a4396 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -123,6 +123,7 @@ struct device_d *of_platform_device_create(struct device_node *np, { struct device_d *dev; struct resource *res = NULL, temp_res; + resource_size_t resinval; int i, j, ret, num_reg = 0, match; if (!of_device_is_available(np)) @@ -183,9 +184,11 @@ struct device_d *of_platform_device_create(struct device_node *np, dev->num_resources = num_reg; of_device_make_bus_id(dev); - debug("%s: register device %s, io=" PRINTF_CONVERSION_RESOURCE "\n", + resinval = (-1); + + debug("%s: register device %s, io=%pa\n", __func__, dev_name(dev), - (num_reg) ? dev->resource[0].start : (-1)); + (num_reg) ? &dev->resource[0].start : &resinval); ret = platform_device_register(dev); if (!ret) |