aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/pxa3xx_nand.c
diff options
context:
space:
mode:
authorLei Wen <leiwen@marvell.com>2011-03-02 22:08:30 -0500
committerDavid Woodhouse <David.Woodhouse@intel.com>2011-03-11 09:22:50 -0500
commite353a20afaee1e3e67fc4fa663a76c68a4c1fb74 (patch)
tree2de3b53dee73418c5f516ca402d3ce0e3ffcf6da /drivers/mtd/nand/pxa3xx_nand.c
parente70727e442eb61581f836a9a0ca0c3b70d8a3ff2 (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.c99
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
1047static int pxa3xx_nand_probe(struct platform_device *pdev) 1048static
1049struct 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
1178fail_free_irq: 1150fail_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);
1194fail_free_mtd: 1166fail_free_mtd:
1195 kfree(mtd); 1167 kfree(mtd);
1196 return ret; 1168 return NULL;
1197} 1169}
1198 1170
1199static int pxa3xx_nand_remove(struct platform_device *pdev) 1171static 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
1205static 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
1234static int pxa3xx_nand_suspend(struct platform_device *pdev, pm_message_t state) 1245static 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
1247static int pxa3xx_nand_resume(struct platform_device *pdev) 1258static 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);