aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/devices
diff options
context:
space:
mode:
authorRobert Jarzmik <robert.jarzmik@free.fr>2012-03-22 16:00:52 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-03-26 20:03:14 -0400
commit1b15a5f93bbd9a6f5346cfa449720a7e32115f86 (patch)
treed04e9b90f2fe443cbe3079abf3730cd58bd84a2f /drivers/mtd/devices
parenta2b3d284ed65b9ada18fd2ffb66daffe9c0ff168 (diff)
mtd: docg3 refactor cascade floors structure
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>
Diffstat (limited to 'drivers/mtd/devices')
-rw-r--r--drivers/mtd/devices/docg3.c88
-rw-r--r--drivers/mtd/devices/docg3.h18
2 files changed, 61 insertions, 45 deletions
diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index be88eb6217cb..935d4c6e9321 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -80,14 +80,9 @@ static struct nand_ecclayout docg3_oobinfo = {
80 .oobavail = 8, 80 .oobavail = 8,
81}; 81};
82 82
83/**
84 * struct docg3_bch - BCH engine
85 */
86static struct bch_control *docg3_bch;
87
88static inline u8 doc_readb(struct docg3 *docg3, u16 reg) 83static inline u8 doc_readb(struct docg3 *docg3, u16 reg)
89{ 84{
90 u8 val = readb(docg3->base + reg); 85 u8 val = readb(docg3->cascade->base + reg);
91 86
92 trace_docg3_io(0, 8, reg, (int)val); 87 trace_docg3_io(0, 8, reg, (int)val);
93 return val; 88 return val;
@@ -95,7 +90,7 @@ static inline u8 doc_readb(struct docg3 *docg3, u16 reg)
95 90
96static inline u16 doc_readw(struct docg3 *docg3, u16 reg) 91static inline u16 doc_readw(struct docg3 *docg3, u16 reg)
97{ 92{
98 u16 val = readw(docg3->base + reg); 93 u16 val = readw(docg3->cascade->base + reg);
99 94
100 trace_docg3_io(0, 16, reg, (int)val); 95 trace_docg3_io(0, 16, reg, (int)val);
101 return val; 96 return val;
@@ -103,13 +98,13 @@ static inline u16 doc_readw(struct docg3 *docg3, u16 reg)
103 98
104static inline void doc_writeb(struct docg3 *docg3, u8 val, u16 reg) 99static inline void doc_writeb(struct docg3 *docg3, u8 val, u16 reg)
105{ 100{
106 writeb(val, docg3->base + reg); 101 writeb(val, docg3->cascade->base + reg);
107 trace_docg3_io(1, 8, reg, val); 102 trace_docg3_io(1, 8, reg, val);
108} 103}
109 104
110static inline void doc_writew(struct docg3 *docg3, u16 val, u16 reg) 105static inline void doc_writew(struct docg3 *docg3, u16 val, u16 reg)
111{ 106{
112 writew(val, docg3->base + reg); 107 writew(val, docg3->cascade->base + reg);
113 trace_docg3_io(1, 16, reg, val); 108 trace_docg3_io(1, 16, reg, val);
114} 109}
115 110
@@ -643,7 +638,8 @@ static int doc_ecc_bch_fix_data(struct docg3 *docg3, void *buf, u8 *hwecc)
643 638
644 for (i = 0; i < DOC_ECC_BCH_SIZE; i++) 639 for (i = 0; i < DOC_ECC_BCH_SIZE; i++)
645 ecc[i] = bitrev8(hwecc[i]); 640 ecc[i] = bitrev8(hwecc[i]);
646 numerrs = decode_bch(docg3_bch, NULL, DOC_ECC_BCH_COVERED_BYTES, 641 numerrs = decode_bch(docg3->cascade->bch, NULL,
642 DOC_ECC_BCH_COVERED_BYTES,
647 NULL, ecc, NULL, errorpos); 643 NULL, ecc, NULL, errorpos);
648 BUG_ON(numerrs == -EINVAL); 644 BUG_ON(numerrs == -EINVAL);
649 if (numerrs < 0) 645 if (numerrs < 0)
@@ -1599,13 +1595,13 @@ static struct device_attribute doc_sys_attrs[DOC_MAX_NBFLOORS][4] = {
1599}; 1595};
1600 1596
1601static int doc_register_sysfs(struct platform_device *pdev, 1597static int doc_register_sysfs(struct platform_device *pdev,
1602 struct mtd_info **floors) 1598 struct docg3_cascade *cascade)
1603{ 1599{
1604 int ret = 0, floor, i = 0; 1600 int ret = 0, floor, i = 0;
1605 struct device *dev = &pdev->dev; 1601 struct device *dev = &pdev->dev;
1606 1602
1607 for (floor = 0; !ret && floor < DOC_MAX_NBFLOORS && floors[floor]; 1603 for (floor = 0; !ret && floor < DOC_MAX_NBFLOORS &&
1608 floor++) 1604 cascade->floors[floor]; floor++)
1609 for (i = 0; !ret && i < 4; i++) 1605 for (i = 0; !ret && i < 4; i++)
1610 ret = device_create_file(dev, &doc_sys_attrs[floor][i]); 1606 ret = device_create_file(dev, &doc_sys_attrs[floor][i]);
1611 if (!ret) 1607 if (!ret)
@@ -1619,12 +1615,12 @@ static int doc_register_sysfs(struct platform_device *pdev,
1619} 1615}
1620 1616
1621static void doc_unregister_sysfs(struct platform_device *pdev, 1617static void doc_unregister_sysfs(struct platform_device *pdev,
1622 struct mtd_info **floors) 1618 struct docg3_cascade *cascade)
1623{ 1619{
1624 struct device *dev = &pdev->dev; 1620 struct device *dev = &pdev->dev;
1625 int floor, i; 1621 int floor, i;
1626 1622
1627 for (floor = 0; floor < DOC_MAX_NBFLOORS && floors[floor]; 1623 for (floor = 0; floor < DOC_MAX_NBFLOORS && cascade->floors[floor];
1628 floor++) 1624 floor++)
1629 for (i = 0; i < 4; i++) 1625 for (i = 0; i < 4; i++)
1630 device_remove_file(dev, &doc_sys_attrs[floor][i]); 1626 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)
1833 * @base: the io space where the device is probed 1829 * @base: the io space where the device is probed
1834 * @floor: the floor of the probed device 1830 * @floor: the floor of the probed device
1835 * @dev: the device 1831 * @dev: the device
1832 * @cascade: the cascade of chips this devices will belong to
1836 * 1833 *
1837 * Checks whether a device at the specified IO range, and floor is available. 1834 * Checks whether a device at the specified IO range, and floor is available.
1838 * 1835 *
@@ -1841,7 +1838,7 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd)
1841 * launched. 1838 * launched.
1842 */ 1839 */
1843static struct mtd_info * __init 1840static struct mtd_info * __init
1844doc_probe_device(void __iomem *base, int floor, struct device *dev) 1841doc_probe_device(struct docg3_cascade *cascade, int floor, struct device *dev)
1845{ 1842{
1846 int ret, bbt_nbpages; 1843 int ret, bbt_nbpages;
1847 u16 chip_id, chip_id_inv; 1844 u16 chip_id, chip_id_inv;
@@ -1864,7 +1861,7 @@ doc_probe_device(void __iomem *base, int floor, struct device *dev)
1864 1861
1865 docg3->dev = dev; 1862 docg3->dev = dev;
1866 docg3->device_id = floor; 1863 docg3->device_id = floor;
1867 docg3->base = base; 1864 docg3->cascade = cascade;
1868 doc_set_device_id(docg3, docg3->device_id); 1865 doc_set_device_id(docg3, docg3->device_id);
1869 if (!floor) 1866 if (!floor)
1870 doc_set_asic_mode(docg3, DOC_ASICMODE_RESET); 1867 doc_set_asic_mode(docg3, DOC_ASICMODE_RESET);
@@ -1881,7 +1878,7 @@ doc_probe_device(void __iomem *base, int floor, struct device *dev)
1881 switch (chip_id) { 1878 switch (chip_id) {
1882 case DOC_CHIPID_G3: 1879 case DOC_CHIPID_G3:
1883 doc_info("Found a G3 DiskOnChip at addr %p, floor %d\n", 1880 doc_info("Found a G3 DiskOnChip at addr %p, floor %d\n",
1884 base, floor); 1881 docg3->cascade->base, floor);
1885 break; 1882 break;
1886 default: 1883 default:
1887 doc_err("Chip id %04x is not a DiskOnChip G3 chip\n", chip_id); 1884 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)
1926static int docg3_resume(struct platform_device *pdev) 1923static int docg3_resume(struct platform_device *pdev)
1927{ 1924{
1928 int i; 1925 int i;
1926 struct docg3_cascade *cascade;
1929 struct mtd_info **docg3_floors, *mtd; 1927 struct mtd_info **docg3_floors, *mtd;
1930 struct docg3 *docg3; 1928 struct docg3 *docg3;
1931 1929
1932 docg3_floors = platform_get_drvdata(pdev); 1930 cascade = platform_get_drvdata(pdev);
1931 docg3_floors = cascade->floors;
1933 mtd = docg3_floors[0]; 1932 mtd = docg3_floors[0];
1934 docg3 = mtd->priv; 1933 docg3 = mtd->priv;
1935 1934
@@ -1951,11 +1950,13 @@ static int docg3_resume(struct platform_device *pdev)
1951static int docg3_suspend(struct platform_device *pdev, pm_message_t state) 1950static int docg3_suspend(struct platform_device *pdev, pm_message_t state)
1952{ 1951{
1953 int floor, i; 1952 int floor, i;
1953 struct docg3_cascade *cascade;
1954 struct mtd_info **docg3_floors, *mtd; 1954 struct mtd_info **docg3_floors, *mtd;
1955 struct docg3 *docg3; 1955 struct docg3 *docg3;
1956 u8 ctrl, pwr_down; 1956 u8 ctrl, pwr_down;
1957 1957
1958 docg3_floors = platform_get_drvdata(pdev); 1958 cascade = platform_get_drvdata(pdev);
1959 docg3_floors = cascade->floors;
1959 for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) { 1960 for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) {
1960 mtd = docg3_floors[floor]; 1961 mtd = docg3_floors[floor];
1961 if (!mtd) 1962 if (!mtd)
@@ -2005,7 +2006,7 @@ static int __init docg3_probe(struct platform_device *pdev)
2005 struct resource *ress; 2006 struct resource *ress;
2006 void __iomem *base; 2007 void __iomem *base;
2007 int ret, floor, found = 0; 2008 int ret, floor, found = 0;
2008 struct mtd_info **docg3_floors; 2009 struct docg3_cascade *cascade;
2009 2010
2010 ret = -ENXIO; 2011 ret = -ENXIO;
2011 ress = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2012 ress = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -2016,17 +2017,18 @@ static int __init docg3_probe(struct platform_device *pdev)
2016 base = ioremap(ress->start, DOC_IOSPACE_SIZE); 2017 base = ioremap(ress->start, DOC_IOSPACE_SIZE);
2017 2018
2018 ret = -ENOMEM; 2019 ret = -ENOMEM;
2019 docg3_floors = kzalloc(sizeof(*docg3_floors) * DOC_MAX_NBFLOORS, 2020 cascade = kzalloc(sizeof(*cascade) * DOC_MAX_NBFLOORS,
2020 GFP_KERNEL); 2021 GFP_KERNEL);
2021 if (!docg3_floors) 2022 if (!cascade)
2022 goto nomem1; 2023 goto nomem1;
2023 docg3_bch = init_bch(DOC_ECC_BCH_M, DOC_ECC_BCH_T, 2024 cascade->base = base;
2025 cascade->bch = init_bch(DOC_ECC_BCH_M, DOC_ECC_BCH_T,
2024 DOC_ECC_BCH_PRIMPOLY); 2026 DOC_ECC_BCH_PRIMPOLY);
2025 if (!docg3_bch) 2027 if (!cascade->bch)
2026 goto nomem2; 2028 goto nomem2;
2027 2029
2028 for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) { 2030 for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) {
2029 mtd = doc_probe_device(base, floor, dev); 2031 mtd = doc_probe_device(cascade, floor, dev);
2030 if (IS_ERR(mtd)) { 2032 if (IS_ERR(mtd)) {
2031 ret = PTR_ERR(mtd); 2033 ret = PTR_ERR(mtd);
2032 goto err_probe; 2034 goto err_probe;
@@ -2037,7 +2039,7 @@ static int __init docg3_probe(struct platform_device *pdev)
2037 else 2039 else
2038 continue; 2040 continue;
2039 } 2041 }
2040 docg3_floors[floor] = mtd; 2042 cascade->floors[floor] = mtd;
2041 ret = mtd_device_parse_register(mtd, part_probes, NULL, NULL, 2043 ret = mtd_device_parse_register(mtd, part_probes, NULL, NULL,
2042 0); 2044 0);
2043 if (ret) 2045 if (ret)
@@ -2045,26 +2047,26 @@ static int __init docg3_probe(struct platform_device *pdev)
2045 found++; 2047 found++;
2046 } 2048 }
2047 2049
2048 ret = doc_register_sysfs(pdev, docg3_floors); 2050 ret = doc_register_sysfs(pdev, cascade);
2049 if (ret) 2051 if (ret)
2050 goto err_probe; 2052 goto err_probe;
2051 if (!found) 2053 if (!found)
2052 goto notfound; 2054 goto notfound;
2053 2055
2054 platform_set_drvdata(pdev, docg3_floors); 2056 platform_set_drvdata(pdev, cascade);
2055 doc_dbg_register(docg3_floors[0]->priv); 2057 doc_dbg_register(cascade->floors[0]->priv);
2056 return 0; 2058 return 0;
2057 2059
2058notfound: 2060notfound:
2059 ret = -ENODEV; 2061 ret = -ENODEV;
2060 dev_info(dev, "No supported DiskOnChip found\n"); 2062 dev_info(dev, "No supported DiskOnChip found\n");
2061err_probe: 2063err_probe:
2062 free_bch(docg3_bch); 2064 kfree(cascade->bch);
2063 for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) 2065 for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++)
2064 if (docg3_floors[floor]) 2066 if (cascade->floors[floor])
2065 doc_release_device(docg3_floors[floor]); 2067 doc_release_device(cascade->floors[floor]);
2066nomem2: 2068nomem2:
2067 kfree(docg3_floors); 2069 kfree(cascade);
2068nomem1: 2070nomem1:
2069 iounmap(base); 2071 iounmap(base);
2070noress: 2072noress:
@@ -2079,19 +2081,19 @@ noress:
2079 */ 2081 */
2080static int __exit docg3_release(struct platform_device *pdev) 2082static int __exit docg3_release(struct platform_device *pdev)
2081{ 2083{
2082 struct mtd_info **docg3_floors = platform_get_drvdata(pdev); 2084 struct docg3_cascade *cascade = platform_get_drvdata(pdev);
2083 struct docg3 *docg3 = docg3_floors[0]->priv; 2085 struct docg3 *docg3 = cascade->floors[0]->priv;
2084 void __iomem *base = docg3->base; 2086 void __iomem *base = cascade->base;
2085 int floor; 2087 int floor;
2086 2088
2087 doc_unregister_sysfs(pdev, docg3_floors); 2089 doc_unregister_sysfs(pdev, cascade);
2088 doc_dbg_unregister(docg3); 2090 doc_dbg_unregister(docg3);
2089 for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) 2091 for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++)
2090 if (docg3_floors[floor]) 2092 if (cascade->floors[floor])
2091 doc_release_device(docg3_floors[floor]); 2093 doc_release_device(cascade->floors[floor]);
2092 2094
2093 kfree(docg3_floors); 2095 free_bch(docg3->cascade->bch);
2094 free_bch(docg3_bch); 2096 kfree(cascade);
2095 iounmap(base); 2097 iounmap(base);
2096 return 0; 2098 return 0;
2097} 2099}
diff --git a/drivers/mtd/devices/docg3.h b/drivers/mtd/devices/docg3.h
index db0da436b493..642e60667cfd 100644
--- a/drivers/mtd/devices/docg3.h
+++ b/drivers/mtd/devices/docg3.h
@@ -22,6 +22,8 @@
22#ifndef _MTD_DOCG3_H 22#ifndef _MTD_DOCG3_H
23#define _MTD_DOCG3_H 23#define _MTD_DOCG3_H
24 24
25#include <linux/mtd/mtd.h>
26
25/* 27/*
26 * Flash memory areas : 28 * Flash memory areas :
27 * - 0x0000 .. 0x07ff : IPL 29 * - 0x0000 .. 0x07ff : IPL
@@ -267,9 +269,21 @@
267#define DOC_LAYOUT_DPS_KEY_LENGTH 8 269#define DOC_LAYOUT_DPS_KEY_LENGTH 8
268 270
269/** 271/**
272 * struct docg3_cascade - Cascade of 1 to 4 docg3 chips
273 * @floors: floors (ie. one physical docg3 chip is one floor)
274 * @base: IO space to access all chips in the cascade
275 * @bch: the BCH correcting control structure
276 */
277struct docg3_cascade {
278 struct mtd_info *floors[DOC_MAX_NBFLOORS];
279 void __iomem *base;
280 struct bch_control *bch;
281};
282
283/**
270 * struct docg3 - DiskOnChip driver private data 284 * struct docg3 - DiskOnChip driver private data
271 * @dev: the device currently under control 285 * @dev: the device currently under control
272 * @base: mapped IO space 286 * @cascade: the cascade this device belongs to
273 * @device_id: number of the cascaded DoCG3 device (0, 1, 2 or 3) 287 * @device_id: number of the cascaded DoCG3 device (0, 1, 2 or 3)
274 * @if_cfg: if true, reads are on 16bits, else reads are on 8bits 288 * @if_cfg: if true, reads are on 16bits, else reads are on 8bits
275 289
@@ -287,7 +301,7 @@
287 */ 301 */
288struct docg3 { 302struct docg3 {
289 struct device *dev; 303 struct device *dev;
290 void __iomem *base; 304 struct docg3_cascade *cascade;
291 unsigned int device_id:4; 305 unsigned int device_id:4;
292 unsigned int if_cfg:1; 306 unsigned int if_cfg:1;
293 unsigned int reliable:2; 307 unsigned int reliable:2;