summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2016-02-08 08:26:43 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2016-02-08 08:26:43 +0100
commit1379a5ef1e5229d9ea71293c7bb6cb89e6d706a4 (patch)
tree175268eaf70e2fbf7fa5fb6550464b0d13d95404 /drivers
parent79606b51ed58819bd71bc6ca7d1a41185f83c89c (diff)
parentb09ee0358cd41b833da9788acf26efdfb6abe40d (diff)
downloadbarebox-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.c37
-rw-r--r--drivers/of/platform.c7
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)