summaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/mtd_blkdevs.c6
-rw-r--r--drivers/mtd/nand/davinci_nand.c6
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-lib.c5
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.c53
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.h28
-rw-r--r--drivers/mtd/nand/nand_base.c3
-rw-r--r--drivers/mtd/nand/nand_ecc.c2
-rw-r--r--drivers/mtd/nand/omap2.c2
8 files changed, 61 insertions, 44 deletions
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 0b2ccb68c0d0..d2f0da91a5bd 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -88,6 +88,9 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
if (req->cmd_type != REQ_TYPE_FS)
return -EIO;
+ if (req->cmd_flags & REQ_FLUSH)
+ return tr->flush(dev);
+
if (blk_rq_pos(req) + blk_rq_cur_sectors(req) >
get_capacity(req->rq_disk))
return -EIO;
@@ -408,6 +411,9 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
if (!new->rq)
goto error3;
+ if (tr->flush)
+ blk_queue_flush(new->rq, REQ_FLUSH);
+
new->rq->queuedata = new;
blk_queue_logical_block_size(new->rq, tr->blksize);
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index 4615d79fc93f..b922c8efcf40 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -523,6 +523,7 @@ static struct nand_ecclayout hwecc4_2048 = {
#if defined(CONFIG_OF)
static const struct of_device_id davinci_nand_of_match[] = {
{.compatible = "ti,davinci-nand", },
+ {.compatible = "ti,keystone-nand", },
{},
};
MODULE_DEVICE_TABLE(of, davinci_nand_of_match);
@@ -581,6 +582,11 @@ static struct davinci_nand_pdata
of_property_read_bool(pdev->dev.of_node,
"ti,davinci-nand-use-bbt"))
pdata->bbt_options = NAND_BBT_USE_FLASH;
+
+ if (of_device_is_compatible(pdev->dev.of_node,
+ "ti,keystone-nand")) {
+ pdata->options |= NAND_NO_SUBPAGE_WRITE;
+ }
}
return dev_get_platdata(&pdev->dev);
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
index dd1df605a1d6..ec4db2a359e5 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
@@ -861,7 +861,7 @@ static void gpmi_compute_edo_timing(struct gpmi_nand_data *this,
struct resources *r = &this->resources;
unsigned long rate = clk_get_rate(r->clock[0]);
int mode = this->timing_mode;
- int dll_threshold = 16; /* in ns */
+ int dll_threshold = this->devdata->max_chain_delay;
unsigned long delay;
unsigned long clk_period;
int t_rea;
@@ -886,9 +886,6 @@ static void gpmi_compute_edo_timing(struct gpmi_nand_data *this,
/* [3] for GPMI_HW_GPMI_CTRL1 */
hw->wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY;
- if (GPMI_IS_MX6Q(this))
- dll_threshold = 12;
-
/*
* Enlarge 10 times for the numerator and denominator in {3}.
* This make us to get more accurate result.
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index bb77f750e75a..e88d64e1e963 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -53,6 +53,24 @@ static struct nand_ecclayout gpmi_hw_ecclayout = {
.oobfree = { {.offset = 0, .length = 0} }
};
+static const struct gpmi_devdata gpmi_devdata_imx23 = {
+ .type = IS_MX23,
+ .bch_max_ecc_strength = 20,
+ .max_chain_delay = 16,
+};
+
+static const struct gpmi_devdata gpmi_devdata_imx28 = {
+ .type = IS_MX28,
+ .bch_max_ecc_strength = 20,
+ .max_chain_delay = 16,
+};
+
+static const struct gpmi_devdata gpmi_devdata_imx6q = {
+ .type = IS_MX6Q,
+ .bch_max_ecc_strength = 40,
+ .max_chain_delay = 12,
+};
+
static irqreturn_t bch_irq(int irq, void *cookie)
{
struct gpmi_nand_data *this = cookie;
@@ -102,14 +120,8 @@ static inline bool gpmi_check_ecc(struct gpmi_nand_data *this)
/* The mx23/mx28 only support the GF13. */
if (geo->gf_len == 14)
return false;
-
- if (geo->ecc_strength > MXS_ECC_STRENGTH_MAX)
- return false;
- } else if (GPMI_IS_MX6Q(this)) {
- if (geo->ecc_strength > MX6_ECC_STRENGTH_MAX)
- return false;
}
- return true;
+ return geo->ecc_strength <= this->devdata->bch_max_ecc_strength;
}
/*
@@ -270,8 +282,7 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)
"We can not support this nand chip."
" Its required ecc strength(%d) is beyond our"
" capability(%d).\n", geo->ecc_strength,
- (GPMI_IS_MX6Q(this) ? MX6_ECC_STRENGTH_MAX
- : MXS_ECC_STRENGTH_MAX));
+ this->devdata->bch_max_ecc_strength);
return -EINVAL;
}
@@ -1740,23 +1751,16 @@ err_out:
return ret;
}
-static const struct platform_device_id gpmi_ids[] = {
- { .name = "imx23-gpmi-nand", .driver_data = IS_MX23, },
- { .name = "imx28-gpmi-nand", .driver_data = IS_MX28, },
- { .name = "imx6q-gpmi-nand", .driver_data = IS_MX6Q, },
- {}
-};
-
static const struct of_device_id gpmi_nand_id_table[] = {
{
.compatible = "fsl,imx23-gpmi-nand",
- .data = (void *)&gpmi_ids[IS_MX23],
+ .data = (void *)&gpmi_devdata_imx23,
}, {
.compatible = "fsl,imx28-gpmi-nand",
- .data = (void *)&gpmi_ids[IS_MX28],
+ .data = (void *)&gpmi_devdata_imx28,
}, {
.compatible = "fsl,imx6q-gpmi-nand",
- .data = (void *)&gpmi_ids[IS_MX6Q],
+ .data = (void *)&gpmi_devdata_imx6q,
}, {}
};
MODULE_DEVICE_TABLE(of, gpmi_nand_id_table);
@@ -1767,18 +1771,18 @@ static int gpmi_nand_probe(struct platform_device *pdev)
const struct of_device_id *of_id;
int ret;
+ this = devm_kzalloc(&pdev->dev, sizeof(*this), GFP_KERNEL);
+ if (!this)
+ return -ENOMEM;
+
of_id = of_match_device(gpmi_nand_id_table, &pdev->dev);
if (of_id) {
- pdev->id_entry = of_id->data;
+ this->devdata = of_id->data;
} else {
dev_err(&pdev->dev, "Failed to find the right device id.\n");
return -ENODEV;
}
- this = devm_kzalloc(&pdev->dev, sizeof(*this), GFP_KERNEL);
- if (!this)
- return -ENOMEM;
-
platform_set_drvdata(pdev, this);
this->pdev = pdev;
this->dev = &pdev->dev;
@@ -1823,7 +1827,6 @@ static struct platform_driver gpmi_nand_driver = {
},
.probe = gpmi_nand_probe,
.remove = gpmi_nand_remove,
- .id_table = gpmi_ids,
};
module_platform_driver(gpmi_nand_driver);
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
index 4c801fa18725..7904e8329b67 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
@@ -119,11 +119,24 @@ struct nand_timing {
int8_t tRHOH_in_ns;
};
+enum gpmi_type {
+ IS_MX23,
+ IS_MX28,
+ IS_MX6Q
+};
+
+struct gpmi_devdata {
+ enum gpmi_type type;
+ int bch_max_ecc_strength;
+ int max_chain_delay; /* See the async EDO mode */
+};
+
struct gpmi_nand_data {
/* flags */
#define GPMI_ASYNC_EDO_ENABLED (1 << 0)
#define GPMI_TIMING_INIT_OK (1 << 1)
int flags;
+ const struct gpmi_devdata *devdata;
/* System Interface */
struct device *dev;
@@ -281,15 +294,8 @@ extern int gpmi_read_page(struct gpmi_nand_data *,
#define STATUS_ERASED 0xff
#define STATUS_UNCORRECTABLE 0xfe
-/* BCH's bit correction capability. */
-#define MXS_ECC_STRENGTH_MAX 20 /* mx23 and mx28 */
-#define MX6_ECC_STRENGTH_MAX 40
-
-/* Use the platform_id to distinguish different Archs. */
-#define IS_MX23 0x0
-#define IS_MX28 0x1
-#define IS_MX6Q 0x2
-#define GPMI_IS_MX23(x) ((x)->pdev->id_entry->driver_data == IS_MX23)
-#define GPMI_IS_MX28(x) ((x)->pdev->id_entry->driver_data == IS_MX28)
-#define GPMI_IS_MX6Q(x) ((x)->pdev->id_entry->driver_data == IS_MX6Q)
+/* Use the devdata to distinguish different Archs. */
+#define GPMI_IS_MX23(x) ((x)->devdata->type == IS_MX23)
+#define GPMI_IS_MX28(x) ((x)->devdata->type == IS_MX28)
+#define GPMI_IS_MX6Q(x) ((x)->devdata->type == IS_MX6Q)
#endif
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 9d01c4df838c..b8eabde8dbdc 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1204,8 +1204,7 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
* ecc.pos. Let's make sure that there are no gaps in ECC positions.
*/
for (i = 0; i < eccfrag_len - 1; i++) {
- if (eccpos[i + start_step * chip->ecc.bytes] + 1 !=
- eccpos[i + start_step * chip->ecc.bytes + 1]) {
+ if (eccpos[i + index] + 1 != eccpos[i + index + 1]) {
gaps = 1;
break;
}
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
index 053c9a2d47c3..97c4c0216c90 100644
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -506,7 +506,7 @@ int __nand_correct_data(unsigned char *buf,
if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) == 1)
return 1; /* error in ECC data; no action needed */
- pr_err("%s: uncorrectable ECC error", __func__);
+ pr_err("%s: uncorrectable ECC error\n", __func__);
return -1;
}
EXPORT_SYMBOL(__nand_correct_data);
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 1ff49b80bdaf..1b800bcda5a4 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1237,6 +1237,7 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
return 0;
}
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
/**
* erased_sector_bitflips - count bit flips
* @data: data sector buffer
@@ -1276,7 +1277,6 @@ static int erased_sector_bitflips(u_char *data, u_char *oob,
return flip_bits;
}
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
/**
* omap_elm_correct_data - corrects page data area in case error reported
* @mtd: MTD device structure
OpenPOWER on IntegriCloud