diff options
author | Lei Wen <leiwen@marvell.com> | 2011-03-02 22:08:30 -0500 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2011-03-11 09:22:50 -0500 |
commit | e353a20afaee1e3e67fc4fa663a76c68a4c1fb74 (patch) | |
tree | 2de3b53dee73418c5f516ca402d3ce0e3ffcf6da /drivers/mtd/nand/pxa3xx_nand.c | |
parent | e70727e442eb61581f836a9a0ca0c3b70d8a3ff2 (diff) |
mtd: pxa3xx_nand: make scan procedure more clear
The previous probe function is some kind of big part.
This patch seperate the resource allocation to keep the probe process
more clear than before.
Signed-off-by: Lei Wen <leiwen@marvell.com>
Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/nand/pxa3xx_nand.c')
-rw-r--r-- | drivers/mtd/nand/pxa3xx_nand.c | 99 |
1 files changed, 55 insertions, 44 deletions
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index ea2c288df3f6..f44044381360 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
@@ -126,6 +126,7 @@ struct pxa3xx_nand_info { | |||
126 | unsigned int buf_start; | 126 | unsigned int buf_start; |
127 | unsigned int buf_count; | 127 | unsigned int buf_count; |
128 | 128 | ||
129 | struct mtd_info *mtd; | ||
129 | /* DMA information */ | 130 | /* DMA information */ |
130 | int drcmr_dat; | 131 | int drcmr_dat; |
131 | int drcmr_cmd; | 132 | int drcmr_cmd; |
@@ -1044,34 +1045,27 @@ static void pxa3xx_nand_init_mtd(struct mtd_info *mtd, | |||
1044 | this->chip_delay = 25; | 1045 | this->chip_delay = 25; |
1045 | } | 1046 | } |
1046 | 1047 | ||
1047 | static int pxa3xx_nand_probe(struct platform_device *pdev) | 1048 | static |
1049 | struct pxa3xx_nand_info *alloc_nand_resource(struct platform_device *pdev) | ||
1048 | { | 1050 | { |
1049 | struct pxa3xx_nand_platform_data *pdata; | 1051 | struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data; |
1050 | struct pxa3xx_nand_info *info; | 1052 | struct pxa3xx_nand_info *info; |
1051 | struct nand_chip *this; | ||
1052 | struct mtd_info *mtd; | 1053 | struct mtd_info *mtd; |
1053 | struct resource *r; | 1054 | struct resource *r; |
1054 | int ret = 0, irq; | 1055 | int ret, irq; |
1055 | |||
1056 | pdata = pdev->dev.platform_data; | ||
1057 | |||
1058 | if (!pdata) { | ||
1059 | dev_err(&pdev->dev, "no platform data defined\n"); | ||
1060 | return -ENODEV; | ||
1061 | } | ||
1062 | 1056 | ||
1063 | mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct pxa3xx_nand_info), | 1057 | mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct pxa3xx_nand_info), |
1064 | GFP_KERNEL); | 1058 | GFP_KERNEL); |
1065 | if (!mtd) { | 1059 | if (!mtd) { |
1066 | dev_err(&pdev->dev, "failed to allocate memory\n"); | 1060 | dev_err(&pdev->dev, "failed to allocate memory\n"); |
1067 | return -ENOMEM; | 1061 | return NULL; |
1068 | } | 1062 | } |
1069 | 1063 | ||
1070 | info = (struct pxa3xx_nand_info *)(&mtd[1]); | 1064 | info = (struct pxa3xx_nand_info *)(&mtd[1]); |
1071 | info->pdev = pdev; | 1065 | info->pdev = pdev; |
1072 | 1066 | ||
1073 | this = &info->nand_chip; | ||
1074 | mtd->priv = info; | 1067 | mtd->priv = info; |
1068 | info->mtd = mtd; | ||
1075 | mtd->owner = THIS_MODULE; | 1069 | mtd->owner = THIS_MODULE; |
1076 | 1070 | ||
1077 | info->clk = clk_get(&pdev->dev, NULL); | 1071 | info->clk = clk_get(&pdev->dev, NULL); |
@@ -1149,31 +1143,9 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) | |||
1149 | } | 1143 | } |
1150 | 1144 | ||
1151 | pxa3xx_nand_init_mtd(mtd, info); | 1145 | pxa3xx_nand_init_mtd(mtd, info); |
1146 | platform_set_drvdata(pdev, info); | ||
1152 | 1147 | ||
1153 | platform_set_drvdata(pdev, mtd); | 1148 | return info; |
1154 | |||
1155 | if (nand_scan(mtd, 1)) { | ||
1156 | dev_err(&pdev->dev, "failed to scan nand\n"); | ||
1157 | ret = -ENXIO; | ||
1158 | goto fail_free_irq; | ||
1159 | } | ||
1160 | |||
1161 | #ifdef CONFIG_MTD_PARTITIONS | ||
1162 | if (mtd_has_cmdlinepart()) { | ||
1163 | static const char *probes[] = { "cmdlinepart", NULL }; | ||
1164 | struct mtd_partition *parts; | ||
1165 | int nr_parts; | ||
1166 | |||
1167 | nr_parts = parse_mtd_partitions(mtd, probes, &parts, 0); | ||
1168 | |||
1169 | if (nr_parts) | ||
1170 | return add_mtd_partitions(mtd, parts, nr_parts); | ||
1171 | } | ||
1172 | |||
1173 | return add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts); | ||
1174 | #else | ||
1175 | return 0; | ||
1176 | #endif | ||
1177 | 1149 | ||
1178 | fail_free_irq: | 1150 | fail_free_irq: |
1179 | free_irq(irq, info); | 1151 | free_irq(irq, info); |
@@ -1193,13 +1165,13 @@ fail_put_clk: | |||
1193 | clk_put(info->clk); | 1165 | clk_put(info->clk); |
1194 | fail_free_mtd: | 1166 | fail_free_mtd: |
1195 | kfree(mtd); | 1167 | kfree(mtd); |
1196 | return ret; | 1168 | return NULL; |
1197 | } | 1169 | } |
1198 | 1170 | ||
1199 | static int pxa3xx_nand_remove(struct platform_device *pdev) | 1171 | static int pxa3xx_nand_remove(struct platform_device *pdev) |
1200 | { | 1172 | { |
1201 | struct mtd_info *mtd = platform_get_drvdata(pdev); | 1173 | struct pxa3xx_nand_info *info = platform_get_drvdata(pdev); |
1202 | struct pxa3xx_nand_info *info = mtd->priv; | 1174 | struct mtd_info *mtd = info->mtd; |
1203 | struct resource *r; | 1175 | struct resource *r; |
1204 | int irq; | 1176 | int irq; |
1205 | 1177 | ||
@@ -1230,11 +1202,50 @@ static int pxa3xx_nand_remove(struct platform_device *pdev) | |||
1230 | return 0; | 1202 | return 0; |
1231 | } | 1203 | } |
1232 | 1204 | ||
1205 | static int pxa3xx_nand_probe(struct platform_device *pdev) | ||
1206 | { | ||
1207 | struct pxa3xx_nand_platform_data *pdata; | ||
1208 | struct pxa3xx_nand_info *info; | ||
1209 | |||
1210 | pdata = pdev->dev.platform_data; | ||
1211 | if (!pdata) { | ||
1212 | dev_err(&pdev->dev, "no platform data defined\n"); | ||
1213 | return -ENODEV; | ||
1214 | } | ||
1215 | |||
1216 | info = alloc_nand_resource(pdev); | ||
1217 | if (info == NULL) | ||
1218 | return -ENOMEM; | ||
1219 | |||
1220 | if (nand_scan(info->mtd, 1)) { | ||
1221 | dev_err(&pdev->dev, "failed to scan nand\n"); | ||
1222 | pxa3xx_nand_remove(pdev); | ||
1223 | return -ENODEV; | ||
1224 | } | ||
1225 | |||
1226 | #ifdef CONFIG_MTD_PARTITIONS | ||
1227 | if (mtd_has_cmdlinepart()) { | ||
1228 | const char *probes[] = { "cmdlinepart", NULL }; | ||
1229 | struct mtd_partition *parts; | ||
1230 | int nr_parts; | ||
1231 | |||
1232 | nr_parts = parse_mtd_partitions(info->mtd, probes, &parts, 0); | ||
1233 | |||
1234 | if (nr_parts) | ||
1235 | return add_mtd_partitions(mtd, parts, nr_parts); | ||
1236 | } | ||
1237 | |||
1238 | return add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts); | ||
1239 | #else | ||
1240 | return 0; | ||
1241 | #endif | ||
1242 | } | ||
1243 | |||
1233 | #ifdef CONFIG_PM | 1244 | #ifdef CONFIG_PM |
1234 | static int pxa3xx_nand_suspend(struct platform_device *pdev, pm_message_t state) | 1245 | static int pxa3xx_nand_suspend(struct platform_device *pdev, pm_message_t state) |
1235 | { | 1246 | { |
1236 | struct mtd_info *mtd = (struct mtd_info *)platform_get_drvdata(pdev); | 1247 | struct pxa3xx_nand_info *info = platform_get_drvdata(pdev); |
1237 | struct pxa3xx_nand_info *info = mtd->priv; | 1248 | struct mtd_info *mtd = info->mtd; |
1238 | 1249 | ||
1239 | if (info->state != STATE_READY) { | 1250 | if (info->state != STATE_READY) { |
1240 | dev_err(&pdev->dev, "driver busy, state = %d\n", info->state); | 1251 | dev_err(&pdev->dev, "driver busy, state = %d\n", info->state); |
@@ -1246,8 +1257,8 @@ static int pxa3xx_nand_suspend(struct platform_device *pdev, pm_message_t state) | |||
1246 | 1257 | ||
1247 | static int pxa3xx_nand_resume(struct platform_device *pdev) | 1258 | static int pxa3xx_nand_resume(struct platform_device *pdev) |
1248 | { | 1259 | { |
1249 | struct mtd_info *mtd = (struct mtd_info *)platform_get_drvdata(pdev); | 1260 | struct pxa3xx_nand_info *info = platform_get_drvdata(pdev); |
1250 | struct pxa3xx_nand_info *info = mtd->priv; | 1261 | struct mtd_info *mtd = info->mtd; |
1251 | 1262 | ||
1252 | nand_writel(info, NDTR0CS0, info->ndtr0cs0); | 1263 | nand_writel(info, NDTR0CS0, info->ndtr0cs0); |
1253 | nand_writel(info, NDTR1CS0, info->ndtr1cs0); | 1264 | nand_writel(info, NDTR1CS0, info->ndtr1cs0); |