diff options
Diffstat (limited to 'drivers/mtd/nand/atmel_nand.c')
-rw-r--r-- | drivers/mtd/nand/atmel_nand.c | 67 |
1 files changed, 14 insertions, 53 deletions
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index bd1ce7d13702..d78a97d4153a 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c | |||
@@ -1062,56 +1062,28 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd) | |||
1062 | } | 1062 | } |
1063 | 1063 | ||
1064 | /* | 1064 | /* |
1065 | * Get ECC requirement in ONFI parameters, returns -1 if ONFI | 1065 | * Get minimum ecc requirements from NAND. |
1066 | * parameters is not supported. | ||
1067 | * return 0 if success to get the ECC requirement. | ||
1068 | */ | ||
1069 | static int get_onfi_ecc_param(struct nand_chip *chip, | ||
1070 | int *ecc_bits, int *sector_size) | ||
1071 | { | ||
1072 | *ecc_bits = *sector_size = 0; | ||
1073 | |||
1074 | if (chip->onfi_params.ecc_bits == 0xff) | ||
1075 | /* TODO: the sector_size and ecc_bits need to be find in | ||
1076 | * extended ecc parameter, currently we don't support it. | ||
1077 | */ | ||
1078 | return -1; | ||
1079 | |||
1080 | *ecc_bits = chip->onfi_params.ecc_bits; | ||
1081 | |||
1082 | /* The default sector size (ecc codeword size) is 512 */ | ||
1083 | *sector_size = 512; | ||
1084 | |||
1085 | return 0; | ||
1086 | } | ||
1087 | |||
1088 | /* | ||
1089 | * Get ecc requirement from ONFI parameters ecc requirement. | ||
1090 | * If pmecc-cap, pmecc-sector-size in DTS are not specified, this function | 1066 | * If pmecc-cap, pmecc-sector-size in DTS are not specified, this function |
1091 | * will set them according to ONFI ecc requirement. Otherwise, use the | 1067 | * will set them according to minimum ecc requirement. Otherwise, use the |
1092 | * value in DTS file. | 1068 | * value in DTS file. |
1093 | * return 0 if success. otherwise return error code. | 1069 | * return 0 if success. otherwise return error code. |
1094 | */ | 1070 | */ |
1095 | static int pmecc_choose_ecc(struct atmel_nand_host *host, | 1071 | static int pmecc_choose_ecc(struct atmel_nand_host *host, |
1096 | int *cap, int *sector_size) | 1072 | int *cap, int *sector_size) |
1097 | { | 1073 | { |
1098 | /* Get ECC requirement from ONFI parameters */ | 1074 | /* Get minimum ECC requirements */ |
1099 | *cap = *sector_size = 0; | 1075 | if (host->nand_chip.ecc_strength_ds) { |
1100 | if (host->nand_chip.onfi_version) { | 1076 | *cap = host->nand_chip.ecc_strength_ds; |
1101 | if (!get_onfi_ecc_param(&host->nand_chip, cap, sector_size)) | 1077 | *sector_size = host->nand_chip.ecc_step_ds; |
1102 | dev_info(host->dev, "ONFI params, minimum required ECC: %d bits in %d bytes\n", | 1078 | dev_info(host->dev, "minimum ECC: %d bits in %d bytes\n", |
1103 | *cap, *sector_size); | 1079 | *cap, *sector_size); |
1104 | else | ||
1105 | dev_info(host->dev, "NAND chip ECC reqirement is in Extended ONFI parameter, we don't support yet.\n"); | ||
1106 | } else { | 1080 | } else { |
1107 | dev_info(host->dev, "NAND chip is not ONFI compliant, assume ecc_bits is 2 in 512 bytes"); | ||
1108 | } | ||
1109 | if (*cap == 0 && *sector_size == 0) { | ||
1110 | *cap = 2; | 1081 | *cap = 2; |
1111 | *sector_size = 512; | 1082 | *sector_size = 512; |
1083 | dev_info(host->dev, "can't detect min. ECC, assume 2 bits in 512 bytes\n"); | ||
1112 | } | 1084 | } |
1113 | 1085 | ||
1114 | /* If dts file doesn't specify then use the one in ONFI parameters */ | 1086 | /* If device tree doesn't specify, use NAND's minimum ECC parameters */ |
1115 | if (host->pmecc_corr_cap == 0) { | 1087 | if (host->pmecc_corr_cap == 0) { |
1116 | /* use the most fitable ecc bits (the near bigger one ) */ | 1088 | /* use the most fitable ecc bits (the near bigger one ) */ |
1117 | if (*cap <= 2) | 1089 | if (*cap <= 2) |
@@ -1449,7 +1421,6 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode) | |||
1449 | ecc_writel(host->ecc, CR, ATMEL_ECC_RST); | 1421 | ecc_writel(host->ecc, CR, ATMEL_ECC_RST); |
1450 | } | 1422 | } |
1451 | 1423 | ||
1452 | #if defined(CONFIG_OF) | ||
1453 | static int atmel_of_init_port(struct atmel_nand_host *host, | 1424 | static int atmel_of_init_port(struct atmel_nand_host *host, |
1454 | struct device_node *np) | 1425 | struct device_node *np) |
1455 | { | 1426 | { |
@@ -1457,7 +1428,7 @@ static int atmel_of_init_port(struct atmel_nand_host *host, | |||
1457 | u32 offset[2]; | 1428 | u32 offset[2]; |
1458 | int ecc_mode; | 1429 | int ecc_mode; |
1459 | struct atmel_nand_data *board = &host->board; | 1430 | struct atmel_nand_data *board = &host->board; |
1460 | enum of_gpio_flags flags; | 1431 | enum of_gpio_flags flags = 0; |
1461 | 1432 | ||
1462 | if (of_property_read_u32(np, "atmel,nand-addr-offset", &val) == 0) { | 1433 | if (of_property_read_u32(np, "atmel,nand-addr-offset", &val) == 0) { |
1463 | if (val >= 32) { | 1434 | if (val >= 32) { |
@@ -1540,13 +1511,6 @@ static int atmel_of_init_port(struct atmel_nand_host *host, | |||
1540 | 1511 | ||
1541 | return 0; | 1512 | return 0; |
1542 | } | 1513 | } |
1543 | #else | ||
1544 | static int atmel_of_init_port(struct atmel_nand_host *host, | ||
1545 | struct device_node *np) | ||
1546 | { | ||
1547 | return -EINVAL; | ||
1548 | } | ||
1549 | #endif | ||
1550 | 1514 | ||
1551 | static int atmel_hw_nand_init_params(struct platform_device *pdev, | 1515 | static int atmel_hw_nand_init_params(struct platform_device *pdev, |
1552 | struct atmel_nand_host *host) | 1516 | struct atmel_nand_host *host) |
@@ -2019,7 +1983,8 @@ static int atmel_nand_probe(struct platform_device *pdev) | |||
2019 | mtd = &host->mtd; | 1983 | mtd = &host->mtd; |
2020 | nand_chip = &host->nand_chip; | 1984 | nand_chip = &host->nand_chip; |
2021 | host->dev = &pdev->dev; | 1985 | host->dev = &pdev->dev; |
2022 | if (pdev->dev.of_node) { | 1986 | if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { |
1987 | /* Only when CONFIG_OF is enabled of_node can be parsed */ | ||
2023 | res = atmel_of_init_port(host, pdev->dev.of_node); | 1988 | res = atmel_of_init_port(host, pdev->dev.of_node); |
2024 | if (res) | 1989 | if (res) |
2025 | goto err_nand_ioremap; | 1990 | goto err_nand_ioremap; |
@@ -2177,7 +2142,6 @@ err_no_card: | |||
2177 | if (host->dma_chan) | 2142 | if (host->dma_chan) |
2178 | dma_release_channel(host->dma_chan); | 2143 | dma_release_channel(host->dma_chan); |
2179 | err_nand_ioremap: | 2144 | err_nand_ioremap: |
2180 | platform_driver_unregister(&atmel_nand_nfc_driver); | ||
2181 | return res; | 2145 | return res; |
2182 | } | 2146 | } |
2183 | 2147 | ||
@@ -2207,14 +2171,12 @@ static int atmel_nand_remove(struct platform_device *pdev) | |||
2207 | return 0; | 2171 | return 0; |
2208 | } | 2172 | } |
2209 | 2173 | ||
2210 | #if defined(CONFIG_OF) | ||
2211 | static const struct of_device_id atmel_nand_dt_ids[] = { | 2174 | static const struct of_device_id atmel_nand_dt_ids[] = { |
2212 | { .compatible = "atmel,at91rm9200-nand" }, | 2175 | { .compatible = "atmel,at91rm9200-nand" }, |
2213 | { /* sentinel */ } | 2176 | { /* sentinel */ } |
2214 | }; | 2177 | }; |
2215 | 2178 | ||
2216 | MODULE_DEVICE_TABLE(of, atmel_nand_dt_ids); | 2179 | MODULE_DEVICE_TABLE(of, atmel_nand_dt_ids); |
2217 | #endif | ||
2218 | 2180 | ||
2219 | static int atmel_nand_nfc_probe(struct platform_device *pdev) | 2181 | static int atmel_nand_nfc_probe(struct platform_device *pdev) |
2220 | { | 2182 | { |
@@ -2253,12 +2215,11 @@ static int atmel_nand_nfc_probe(struct platform_device *pdev) | |||
2253 | return 0; | 2215 | return 0; |
2254 | } | 2216 | } |
2255 | 2217 | ||
2256 | #if defined(CONFIG_OF) | 2218 | static const struct of_device_id atmel_nand_nfc_match[] = { |
2257 | static struct of_device_id atmel_nand_nfc_match[] = { | ||
2258 | { .compatible = "atmel,sama5d3-nfc" }, | 2219 | { .compatible = "atmel,sama5d3-nfc" }, |
2259 | { /* sentinel */ } | 2220 | { /* sentinel */ } |
2260 | }; | 2221 | }; |
2261 | #endif | 2222 | MODULE_DEVICE_TABLE(of, atmel_nand_nfc_match); |
2262 | 2223 | ||
2263 | static struct platform_driver atmel_nand_nfc_driver = { | 2224 | static struct platform_driver atmel_nand_nfc_driver = { |
2264 | .driver = { | 2225 | .driver = { |