aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
diff options
context:
space:
mode:
authorHuang Shijie <b32955@freescale.com>2014-03-21 01:30:21 -0400
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:58:04 -0400
commitad296e2a577d0ef82e15239df776130e6b5f4532 (patch)
tree570897f531cc6ce501d745203e5e3b2369419850 /drivers/mtd/nand/gpmi-nand/gpmi-nand.c
parent9997e70a44328a31aee41911810390832f54c951 (diff)
ENGR00304574-4 mtd: gpmi: add gpmi_devdata{} to simplify the code
More and more chips use the GPMI controller, but these chips may use different version of the IPs for GPMI and BCH. The different IPs have different features, such as the BCH's maximum ECC strength: imx23/imx28 -- the BCH's maximum ECC strength is 20 imx6q -- the BCH's maximum ECC strength is 40 imx6sx -- the BCH's maximum ECC strength is 62 This patch does the following things: [1] add a new data structure, gpmi_devdata{}, to store the information for each IP. Beside the IP version, we stores the following informations: <1> BCH's maximum ECC strength. <2> the maximum chain delay in the EDO mode. but we may add more information in future. [2] add the gpmi_devdata_imx{23|28|6q} to replace the gpmi_ids. [3] simplify the code by using the ECC strength from gpmi_devdata, such as gpmi_check_ecc() and legacy_set_geometry(); [4] use the maximum chain delay to initialize the EDO mode, see gpmi_compute_edo_timing(). [5] rewrite the macros, such GPMI_IS_MX{23|28|6Q}. Signed-off-by: Huang Shijie <b32955@freescale.com>
Diffstat (limited to 'drivers/mtd/nand/gpmi-nand/gpmi-nand.c')
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.c55
1 files changed, 29 insertions, 26 deletions
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index bb77f750e75a..de668d848f90 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Freescale GPMI NAND Flash Driver 2 * Freescale GPMI NAND Flash Driver
3 * 3 *
4 * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. 4 * Copyright (C) 2010-2014 Freescale Semiconductor, Inc.
5 * Copyright (C) 2008 Embedded Alley Solutions, Inc. 5 * Copyright (C) 2008 Embedded Alley Solutions, Inc.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -53,6 +53,24 @@ static struct nand_ecclayout gpmi_hw_ecclayout = {
53 .oobfree = { {.offset = 0, .length = 0} } 53 .oobfree = { {.offset = 0, .length = 0} }
54}; 54};
55 55
56static const struct gpmi_devdata gpmi_devdata_imx23 = {
57 .type = IS_MX23,
58 .bch_max_ecc_strength = 20,
59 .max_chain_delay = 16,
60};
61
62static const struct gpmi_devdata gpmi_devdata_imx28 = {
63 .type = IS_MX28,
64 .bch_max_ecc_strength = 20,
65 .max_chain_delay = 16,
66};
67
68static const struct gpmi_devdata gpmi_devdata_imx6q = {
69 .type = IS_MX6Q,
70 .bch_max_ecc_strength = 40,
71 .max_chain_delay = 12,
72};
73
56static irqreturn_t bch_irq(int irq, void *cookie) 74static irqreturn_t bch_irq(int irq, void *cookie)
57{ 75{
58 struct gpmi_nand_data *this = cookie; 76 struct gpmi_nand_data *this = cookie;
@@ -102,14 +120,8 @@ static inline bool gpmi_check_ecc(struct gpmi_nand_data *this)
102 /* The mx23/mx28 only support the GF13. */ 120 /* The mx23/mx28 only support the GF13. */
103 if (geo->gf_len == 14) 121 if (geo->gf_len == 14)
104 return false; 122 return false;
105
106 if (geo->ecc_strength > MXS_ECC_STRENGTH_MAX)
107 return false;
108 } else if (GPMI_IS_MX6Q(this)) {
109 if (geo->ecc_strength > MX6_ECC_STRENGTH_MAX)
110 return false;
111 } 123 }
112 return true; 124 return geo->ecc_strength <= this->devdata->bch_max_ecc_strength;
113} 125}
114 126
115/* 127/*
@@ -270,8 +282,7 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)
270 "We can not support this nand chip." 282 "We can not support this nand chip."
271 " Its required ecc strength(%d) is beyond our" 283 " Its required ecc strength(%d) is beyond our"
272 " capability(%d).\n", geo->ecc_strength, 284 " capability(%d).\n", geo->ecc_strength,
273 (GPMI_IS_MX6Q(this) ? MX6_ECC_STRENGTH_MAX 285 this->devdata->bch_max_ecc_strength);
274 : MXS_ECC_STRENGTH_MAX));
275 return -EINVAL; 286 return -EINVAL;
276 } 287 }
277 288
@@ -1740,23 +1751,16 @@ err_out:
1740 return ret; 1751 return ret;
1741} 1752}
1742 1753
1743static const struct platform_device_id gpmi_ids[] = {
1744 { .name = "imx23-gpmi-nand", .driver_data = IS_MX23, },
1745 { .name = "imx28-gpmi-nand", .driver_data = IS_MX28, },
1746 { .name = "imx6q-gpmi-nand", .driver_data = IS_MX6Q, },
1747 {}
1748};
1749
1750static const struct of_device_id gpmi_nand_id_table[] = { 1754static const struct of_device_id gpmi_nand_id_table[] = {
1751 { 1755 {
1752 .compatible = "fsl,imx23-gpmi-nand", 1756 .compatible = "fsl,imx23-gpmi-nand",
1753 .data = (void *)&gpmi_ids[IS_MX23], 1757 .data = (void *)&gpmi_devdata_imx23,
1754 }, { 1758 }, {
1755 .compatible = "fsl,imx28-gpmi-nand", 1759 .compatible = "fsl,imx28-gpmi-nand",
1756 .data = (void *)&gpmi_ids[IS_MX28], 1760 .data = (void *)&gpmi_devdata_imx28,
1757 }, { 1761 }, {
1758 .compatible = "fsl,imx6q-gpmi-nand", 1762 .compatible = "fsl,imx6q-gpmi-nand",
1759 .data = (void *)&gpmi_ids[IS_MX6Q], 1763 .data = (void *)&gpmi_devdata_imx6q,
1760 }, {} 1764 }, {}
1761}; 1765};
1762MODULE_DEVICE_TABLE(of, gpmi_nand_id_table); 1766MODULE_DEVICE_TABLE(of, gpmi_nand_id_table);
@@ -1767,18 +1771,18 @@ static int gpmi_nand_probe(struct platform_device *pdev)
1767 const struct of_device_id *of_id; 1771 const struct of_device_id *of_id;
1768 int ret; 1772 int ret;
1769 1773
1774 this = devm_kzalloc(&pdev->dev, sizeof(*this), GFP_KERNEL);
1775 if (!this)
1776 return -ENOMEM;
1777
1770 of_id = of_match_device(gpmi_nand_id_table, &pdev->dev); 1778 of_id = of_match_device(gpmi_nand_id_table, &pdev->dev);
1771 if (of_id) { 1779 if (of_id) {
1772 pdev->id_entry = of_id->data; 1780 this->devdata = of_id->data;
1773 } else { 1781 } else {
1774 dev_err(&pdev->dev, "Failed to find the right device id.\n"); 1782 dev_err(&pdev->dev, "Failed to find the right device id.\n");
1775 return -ENODEV; 1783 return -ENODEV;
1776 } 1784 }
1777 1785
1778 this = devm_kzalloc(&pdev->dev, sizeof(*this), GFP_KERNEL);
1779 if (!this)
1780 return -ENOMEM;
1781
1782 platform_set_drvdata(pdev, this); 1786 platform_set_drvdata(pdev, this);
1783 this->pdev = pdev; 1787 this->pdev = pdev;
1784 this->dev = &pdev->dev; 1788 this->dev = &pdev->dev;
@@ -1823,7 +1827,6 @@ static struct platform_driver gpmi_nand_driver = {
1823 }, 1827 },
1824 .probe = gpmi_nand_probe, 1828 .probe = gpmi_nand_probe,
1825 .remove = gpmi_nand_remove, 1829 .remove = gpmi_nand_remove,
1826 .id_table = gpmi_ids,
1827}; 1830};
1828module_platform_driver(gpmi_nand_driver); 1831module_platform_driver(gpmi_nand_driver);
1829 1832