]> git.karo-electronics.de Git - linux-beck.git/commitdiff
mtd: docg3 refactor cascade floors structure
authorRobert Jarzmik <robert.jarzmik@free.fr>
Thu, 22 Mar 2012 20:00:52 +0000 (21:00 +0100)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Tue, 27 Mar 2012 00:03:14 +0000 (01:03 +0100)
Group floors into a common cascade structure. This will provide a common
structure to store common data to all cascaded docg3 chips, like IO
addressing, locking protection.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
drivers/mtd/devices/docg3.c
drivers/mtd/devices/docg3.h

index be88eb6217cbcb664c9d5c5fa6206c2b4f33bc5b..935d4c6e9321e728340af2a0688a3b3deef84224 100644 (file)
@@ -80,14 +80,9 @@ static struct nand_ecclayout docg3_oobinfo = {
        .oobavail = 8,
 };
 
-/**
- * struct docg3_bch - BCH engine
- */
-static struct bch_control *docg3_bch;
-
 static inline u8 doc_readb(struct docg3 *docg3, u16 reg)
 {
-       u8 val = readb(docg3->base + reg);
+       u8 val = readb(docg3->cascade->base + reg);
 
        trace_docg3_io(0, 8, reg, (int)val);
        return val;
@@ -95,7 +90,7 @@ static inline u8 doc_readb(struct docg3 *docg3, u16 reg)
 
 static inline u16 doc_readw(struct docg3 *docg3, u16 reg)
 {
-       u16 val = readw(docg3->base + reg);
+       u16 val = readw(docg3->cascade->base + reg);
 
        trace_docg3_io(0, 16, reg, (int)val);
        return val;
@@ -103,13 +98,13 @@ static inline u16 doc_readw(struct docg3 *docg3, u16 reg)
 
 static inline void doc_writeb(struct docg3 *docg3, u8 val, u16 reg)
 {
-       writeb(val, docg3->base + reg);
+       writeb(val, docg3->cascade->base + reg);
        trace_docg3_io(1, 8, reg, val);
 }
 
 static inline void doc_writew(struct docg3 *docg3, u16 val, u16 reg)
 {
-       writew(val, docg3->base + reg);
+       writew(val, docg3->cascade->base + reg);
        trace_docg3_io(1, 16, reg, val);
 }
 
@@ -643,7 +638,8 @@ static int doc_ecc_bch_fix_data(struct docg3 *docg3, void *buf, u8 *hwecc)
 
        for (i = 0; i < DOC_ECC_BCH_SIZE; i++)
                ecc[i] = bitrev8(hwecc[i]);
-       numerrs = decode_bch(docg3_bch, NULL, DOC_ECC_BCH_COVERED_BYTES,
+       numerrs = decode_bch(docg3->cascade->bch, NULL,
+                            DOC_ECC_BCH_COVERED_BYTES,
                             NULL, ecc, NULL, errorpos);
        BUG_ON(numerrs == -EINVAL);
        if (numerrs < 0)
@@ -1599,13 +1595,13 @@ static struct device_attribute doc_sys_attrs[DOC_MAX_NBFLOORS][4] = {
 };
 
 static int doc_register_sysfs(struct platform_device *pdev,
-                             struct mtd_info **floors)
+                             struct docg3_cascade *cascade)
 {
        int ret = 0, floor, i = 0;
        struct device *dev = &pdev->dev;
 
-       for (floor = 0; !ret && floor < DOC_MAX_NBFLOORS && floors[floor];
-            floor++)
+       for (floor = 0; !ret && floor < DOC_MAX_NBFLOORS &&
+                    cascade->floors[floor]; floor++)
                for (i = 0; !ret && i < 4; i++)
                        ret = device_create_file(dev, &doc_sys_attrs[floor][i]);
        if (!ret)
@@ -1619,12 +1615,12 @@ static int doc_register_sysfs(struct platform_device *pdev,
 }
 
 static void doc_unregister_sysfs(struct platform_device *pdev,
-                                struct mtd_info **floors)
+                                struct docg3_cascade *cascade)
 {
        struct device *dev = &pdev->dev;
        int floor, i;
 
-       for (floor = 0; floor < DOC_MAX_NBFLOORS && floors[floor];
+       for (floor = 0; floor < DOC_MAX_NBFLOORS && cascade->floors[floor];
             floor++)
                for (i = 0; i < 4; i++)
                        device_remove_file(dev, &doc_sys_attrs[floor][i]);
@@ -1833,6 +1829,7 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd)
  * @base: the io space where the device is probed
  * @floor: the floor of the probed device
  * @dev: the device
+ * @cascade: the cascade of chips this devices will belong to
  *
  * Checks whether a device at the specified IO range, and floor is available.
  *
@@ -1841,7 +1838,7 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd)
  * launched.
  */
 static struct mtd_info * __init
-doc_probe_device(void __iomem *base, int floor, struct device *dev)
+doc_probe_device(struct docg3_cascade *cascade, int floor, struct device *dev)
 {
        int ret, bbt_nbpages;
        u16 chip_id, chip_id_inv;
@@ -1864,7 +1861,7 @@ doc_probe_device(void __iomem *base, int floor, struct device *dev)
 
        docg3->dev = dev;
        docg3->device_id = floor;
-       docg3->base = base;
+       docg3->cascade = cascade;
        doc_set_device_id(docg3, docg3->device_id);
        if (!floor)
                doc_set_asic_mode(docg3, DOC_ASICMODE_RESET);
@@ -1881,7 +1878,7 @@ doc_probe_device(void __iomem *base, int floor, struct device *dev)
        switch (chip_id) {
        case DOC_CHIPID_G3:
                doc_info("Found a G3 DiskOnChip at addr %p, floor %d\n",
-                        base, floor);
+                        docg3->cascade->base, floor);
                break;
        default:
                doc_err("Chip id %04x is not a DiskOnChip G3 chip\n", chip_id);
@@ -1926,10 +1923,12 @@ static void doc_release_device(struct mtd_info *mtd)
 static int docg3_resume(struct platform_device *pdev)
 {
        int i;
+       struct docg3_cascade *cascade;
        struct mtd_info **docg3_floors, *mtd;
        struct docg3 *docg3;
 
-       docg3_floors = platform_get_drvdata(pdev);
+       cascade = platform_get_drvdata(pdev);
+       docg3_floors = cascade->floors;
        mtd = docg3_floors[0];
        docg3 = mtd->priv;
 
@@ -1951,11 +1950,13 @@ static int docg3_resume(struct platform_device *pdev)
 static int docg3_suspend(struct platform_device *pdev, pm_message_t state)
 {
        int floor, i;
+       struct docg3_cascade *cascade;
        struct mtd_info **docg3_floors, *mtd;
        struct docg3 *docg3;
        u8 ctrl, pwr_down;
 
-       docg3_floors = platform_get_drvdata(pdev);
+       cascade = platform_get_drvdata(pdev);
+       docg3_floors = cascade->floors;
        for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) {
                mtd = docg3_floors[floor];
                if (!mtd)
@@ -2005,7 +2006,7 @@ static int __init docg3_probe(struct platform_device *pdev)
        struct resource *ress;
        void __iomem *base;
        int ret, floor, found = 0;
-       struct mtd_info **docg3_floors;
+       struct docg3_cascade *cascade;
 
        ret = -ENXIO;
        ress = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -2016,17 +2017,18 @@ static int __init docg3_probe(struct platform_device *pdev)
        base = ioremap(ress->start, DOC_IOSPACE_SIZE);
 
        ret = -ENOMEM;
-       docg3_floors = kzalloc(sizeof(*docg3_floors) * DOC_MAX_NBFLOORS,
-                              GFP_KERNEL);
-       if (!docg3_floors)
+       cascade = kzalloc(sizeof(*cascade) * DOC_MAX_NBFLOORS,
+                         GFP_KERNEL);
+       if (!cascade)
                goto nomem1;
-       docg3_bch = init_bch(DOC_ECC_BCH_M, DOC_ECC_BCH_T,
+       cascade->base = base;
+       cascade->bch = init_bch(DOC_ECC_BCH_M, DOC_ECC_BCH_T,
                             DOC_ECC_BCH_PRIMPOLY);
-       if (!docg3_bch)
+       if (!cascade->bch)
                goto nomem2;
 
        for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) {
-               mtd = doc_probe_device(base, floor, dev);
+               mtd = doc_probe_device(cascade, floor, dev);
                if (IS_ERR(mtd)) {
                        ret = PTR_ERR(mtd);
                        goto err_probe;
@@ -2037,7 +2039,7 @@ static int __init docg3_probe(struct platform_device *pdev)
                        else
                                continue;
                }
-               docg3_floors[floor] = mtd;
+               cascade->floors[floor] = mtd;
                ret = mtd_device_parse_register(mtd, part_probes, NULL, NULL,
                                                0);
                if (ret)
@@ -2045,26 +2047,26 @@ static int __init docg3_probe(struct platform_device *pdev)
                found++;
        }
 
-       ret = doc_register_sysfs(pdev, docg3_floors);
+       ret = doc_register_sysfs(pdev, cascade);
        if (ret)
                goto err_probe;
        if (!found)
                goto notfound;
 
-       platform_set_drvdata(pdev, docg3_floors);
-       doc_dbg_register(docg3_floors[0]->priv);
+       platform_set_drvdata(pdev, cascade);
+       doc_dbg_register(cascade->floors[0]->priv);
        return 0;
 
 notfound:
        ret = -ENODEV;
        dev_info(dev, "No supported DiskOnChip found\n");
 err_probe:
-       free_bch(docg3_bch);
+       kfree(cascade->bch);
        for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++)
-               if (docg3_floors[floor])
-                       doc_release_device(docg3_floors[floor]);
+               if (cascade->floors[floor])
+                       doc_release_device(cascade->floors[floor]);
 nomem2:
-       kfree(docg3_floors);
+       kfree(cascade);
 nomem1:
        iounmap(base);
 noress:
@@ -2079,19 +2081,19 @@ noress:
  */
 static int __exit docg3_release(struct platform_device *pdev)
 {
-       struct mtd_info **docg3_floors = platform_get_drvdata(pdev);
-       struct docg3 *docg3 = docg3_floors[0]->priv;
-       void __iomem *base = docg3->base;
+       struct docg3_cascade *cascade = platform_get_drvdata(pdev);
+       struct docg3 *docg3 = cascade->floors[0]->priv;
+       void __iomem *base = cascade->base;
        int floor;
 
-       doc_unregister_sysfs(pdev, docg3_floors);
+       doc_unregister_sysfs(pdev, cascade);
        doc_dbg_unregister(docg3);
        for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++)
-               if (docg3_floors[floor])
-                       doc_release_device(docg3_floors[floor]);
+               if (cascade->floors[floor])
+                       doc_release_device(cascade->floors[floor]);
 
-       kfree(docg3_floors);
-       free_bch(docg3_bch);
+       free_bch(docg3->cascade->bch);
+       kfree(cascade);
        iounmap(base);
        return 0;
 }
index db0da436b49332dbea30971e44392a5fa9887461..642e60667cfd183d1fa2d0835b95618ca371e2ef 100644 (file)
@@ -22,6 +22,8 @@
 #ifndef _MTD_DOCG3_H
 #define _MTD_DOCG3_H
 
+#include <linux/mtd/mtd.h>
+
 /*
  * Flash memory areas :
  *   - 0x0000 .. 0x07ff : IPL
  */
 #define DOC_LAYOUT_DPS_KEY_LENGTH      8
 
+/**
+ * struct docg3_cascade - Cascade of 1 to 4 docg3 chips
+ * @floors: floors (ie. one physical docg3 chip is one floor)
+ * @base: IO space to access all chips in the cascade
+ * @bch: the BCH correcting control structure
+ */
+struct docg3_cascade {
+       struct mtd_info *floors[DOC_MAX_NBFLOORS];
+       void __iomem *base;
+       struct bch_control *bch;
+};
+
 /**
  * struct docg3 - DiskOnChip driver private data
  * @dev: the device currently under control
- * @base: mapped IO space
+ * @cascade: the cascade this device belongs to
  * @device_id: number of the cascaded DoCG3 device (0, 1, 2 or 3)
  * @if_cfg: if true, reads are on 16bits, else reads are on 8bits
 
  */
 struct docg3 {
        struct device *dev;
-       void __iomem *base;
+       struct docg3_cascade *cascade;
        unsigned int device_id:4;
        unsigned int if_cfg:1;
        unsigned int reliable:2;