|
@@ -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;
|
|
|
}
|