diff options
author | Josh Wu <josh.wu@atmel.com> | 2013-01-23 07:47:11 -0500 |
---|---|---|
committer | Artem Bityutskiy <artem.bityutskiy@linux.intel.com> | 2013-02-12 10:00:54 -0500 |
commit | e66b4318f8fc0e12421de6287c557cdd92789010 (patch) | |
tree | 40aa90c935f9e0b86f645f0a38a5fff1facc1b9b /drivers/mtd | |
parent | c0cf787f10c6ffb050e85c8ac9c0a8161cb06cb9 (diff) |
mtd: atmel_nand: make pmecc-cap, pmecc-sector-size in dts is optional.
If those two are not specified in dts file, driver will report an error.
TODO: in this case, driver will find ecc requirement in NAND ONFI parameters.
Signed-off-by: Josh Wu <josh.wu@atmel.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/atmel_nand.c | 52 |
1 files changed, 31 insertions, 21 deletions
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 1d989dba4ce5..f186a371e437 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c | |||
@@ -101,6 +101,8 @@ struct atmel_nand_host { | |||
101 | u8 pmecc_corr_cap; | 101 | u8 pmecc_corr_cap; |
102 | u16 pmecc_sector_size; | 102 | u16 pmecc_sector_size; |
103 | u32 pmecc_lookup_table_offset; | 103 | u32 pmecc_lookup_table_offset; |
104 | u32 pmecc_lookup_table_offset_512; | ||
105 | u32 pmecc_lookup_table_offset_1024; | ||
104 | 106 | ||
105 | int pmecc_bytes_per_sector; | 107 | int pmecc_bytes_per_sector; |
106 | int pmecc_sector_number; | 108 | int pmecc_sector_number; |
@@ -916,8 +918,16 @@ static int __init atmel_pmecc_nand_init_params(struct platform_device *pdev, | |||
916 | struct resource *regs, *regs_pmerr, *regs_rom; | 918 | struct resource *regs, *regs_pmerr, *regs_rom; |
917 | int cap, sector_size, err_no; | 919 | int cap, sector_size, err_no; |
918 | 920 | ||
921 | if (host->pmecc_corr_cap == 0 || host->pmecc_sector_size == 0) | ||
922 | /* TODO: Should use ONFI ecc parameters. */ | ||
923 | return -EINVAL; | ||
924 | |||
919 | cap = host->pmecc_corr_cap; | 925 | cap = host->pmecc_corr_cap; |
920 | sector_size = host->pmecc_sector_size; | 926 | sector_size = host->pmecc_sector_size; |
927 | host->pmecc_lookup_table_offset = (sector_size == 512) ? | ||
928 | host->pmecc_lookup_table_offset_512 : | ||
929 | host->pmecc_lookup_table_offset_1024; | ||
930 | |||
921 | dev_info(host->dev, "Initialize PMECC params, cap: %d, sector: %d\n", | 931 | dev_info(host->dev, "Initialize PMECC params, cap: %d, sector: %d\n", |
922 | cap, sector_size); | 932 | cap, sector_size); |
923 | 933 | ||
@@ -1259,29 +1269,29 @@ static int atmel_of_init_port(struct atmel_nand_host *host, | |||
1259 | 1269 | ||
1260 | /* use PMECC, get correction capability, sector size and lookup | 1270 | /* use PMECC, get correction capability, sector size and lookup |
1261 | * table offset. | 1271 | * table offset. |
1272 | * If correction bits and sector size are not specified, then find | ||
1273 | * them from NAND ONFI parameters. | ||
1262 | */ | 1274 | */ |
1263 | if (of_property_read_u32(np, "atmel,pmecc-cap", &val) != 0) { | 1275 | if (of_property_read_u32(np, "atmel,pmecc-cap", &val) == 0) { |
1264 | dev_err(host->dev, "Cannot decide PMECC Capability\n"); | 1276 | if ((val != 2) && (val != 4) && (val != 8) && (val != 12) && |
1265 | return -EINVAL; | 1277 | (val != 24)) { |
1266 | } else if ((val != 2) && (val != 4) && (val != 8) && (val != 12) && | 1278 | dev_err(host->dev, |
1267 | (val != 24)) { | 1279 | "Unsupported PMECC correction capability: %d; should be 2, 4, 8, 12 or 24\n", |
1268 | dev_err(host->dev, | 1280 | val); |
1269 | "Unsupported PMECC correction capability: %d; should be 2, 4, 8, 12 or 24\n", | 1281 | return -EINVAL; |
1270 | val); | 1282 | } |
1271 | return -EINVAL; | 1283 | host->pmecc_corr_cap = (u8)val; |
1272 | } | 1284 | } |
1273 | host->pmecc_corr_cap = (u8)val; | ||
1274 | 1285 | ||
1275 | if (of_property_read_u32(np, "atmel,pmecc-sector-size", &val) != 0) { | 1286 | if (of_property_read_u32(np, "atmel,pmecc-sector-size", &val) == 0) { |
1276 | dev_err(host->dev, "Cannot decide PMECC Sector Size\n"); | 1287 | if ((val != 512) && (val != 1024)) { |
1277 | return -EINVAL; | 1288 | dev_err(host->dev, |
1278 | } else if ((val != 512) && (val != 1024)) { | 1289 | "Unsupported PMECC sector size: %d; should be 512 or 1024 bytes\n", |
1279 | dev_err(host->dev, | 1290 | val); |
1280 | "Unsupported PMECC sector size: %d; should be 512 or 1024 bytes\n", | 1291 | return -EINVAL; |
1281 | val); | 1292 | } |
1282 | return -EINVAL; | 1293 | host->pmecc_sector_size = (u16)val; |
1283 | } | 1294 | } |
1284 | host->pmecc_sector_size = (u16)val; | ||
1285 | 1295 | ||
1286 | if (of_property_read_u32_array(np, "atmel,pmecc-lookup-table-offset", | 1296 | if (of_property_read_u32_array(np, "atmel,pmecc-lookup-table-offset", |
1287 | offset, 2) != 0) { | 1297 | offset, 2) != 0) { |
@@ -1292,8 +1302,8 @@ static int atmel_of_init_port(struct atmel_nand_host *host, | |||
1292 | dev_err(host->dev, "Invalid PMECC lookup table offset\n"); | 1302 | dev_err(host->dev, "Invalid PMECC lookup table offset\n"); |
1293 | return -EINVAL; | 1303 | return -EINVAL; |
1294 | } | 1304 | } |
1295 | host->pmecc_lookup_table_offset = | 1305 | host->pmecc_lookup_table_offset_512 = offset[0]; |
1296 | (host->pmecc_sector_size == 512) ? offset[0] : offset[1]; | 1306 | host->pmecc_lookup_table_offset_1024 = offset[1]; |
1297 | 1307 | ||
1298 | return 0; | 1308 | return 0; |
1299 | } | 1309 | } |