diff options
Diffstat (limited to 'drivers/mtd/nand/plat_nand.c')
-rw-r--r-- | drivers/mtd/nand/plat_nand.c | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c index 4e16c6f5bdd5..8d467315f02b 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/plat_nand.c | |||
@@ -34,7 +34,12 @@ static int __devinit plat_nand_probe(struct platform_device *pdev) | |||
34 | { | 34 | { |
35 | struct platform_nand_data *pdata = pdev->dev.platform_data; | 35 | struct platform_nand_data *pdata = pdev->dev.platform_data; |
36 | struct plat_nand_data *data; | 36 | struct plat_nand_data *data; |
37 | int res = 0; | 37 | struct resource *res; |
38 | int err = 0; | ||
39 | |||
40 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
41 | if (!res) | ||
42 | return -ENXIO; | ||
38 | 43 | ||
39 | /* Allocate memory for the device structure (and zero it) */ | 44 | /* Allocate memory for the device structure (and zero it) */ |
40 | data = kzalloc(sizeof(struct plat_nand_data), GFP_KERNEL); | 45 | data = kzalloc(sizeof(struct plat_nand_data), GFP_KERNEL); |
@@ -43,12 +48,18 @@ static int __devinit plat_nand_probe(struct platform_device *pdev) | |||
43 | return -ENOMEM; | 48 | return -ENOMEM; |
44 | } | 49 | } |
45 | 50 | ||
46 | data->io_base = ioremap(pdev->resource[0].start, | 51 | if (!request_mem_region(res->start, resource_size(res), |
47 | pdev->resource[0].end - pdev->resource[0].start + 1); | 52 | dev_name(&pdev->dev))) { |
53 | dev_err(&pdev->dev, "request_mem_region failed\n"); | ||
54 | err = -EBUSY; | ||
55 | goto out_free; | ||
56 | } | ||
57 | |||
58 | data->io_base = ioremap(res->start, resource_size(res)); | ||
48 | if (data->io_base == NULL) { | 59 | if (data->io_base == NULL) { |
49 | dev_err(&pdev->dev, "ioremap failed\n"); | 60 | dev_err(&pdev->dev, "ioremap failed\n"); |
50 | kfree(data); | 61 | err = -EIO; |
51 | return -EIO; | 62 | goto out_release_io; |
52 | } | 63 | } |
53 | 64 | ||
54 | data->chip.priv = &data; | 65 | data->chip.priv = &data; |
@@ -74,24 +85,24 @@ static int __devinit plat_nand_probe(struct platform_device *pdev) | |||
74 | 85 | ||
75 | /* Handle any platform specific setup */ | 86 | /* Handle any platform specific setup */ |
76 | if (pdata->ctrl.probe) { | 87 | if (pdata->ctrl.probe) { |
77 | res = pdata->ctrl.probe(pdev); | 88 | err = pdata->ctrl.probe(pdev); |
78 | if (res) | 89 | if (err) |
79 | goto out; | 90 | goto out; |
80 | } | 91 | } |
81 | 92 | ||
82 | /* Scan to find existance of the device */ | 93 | /* Scan to find existance of the device */ |
83 | if (nand_scan(&data->mtd, 1)) { | 94 | if (nand_scan(&data->mtd, 1)) { |
84 | res = -ENXIO; | 95 | err = -ENXIO; |
85 | goto out; | 96 | goto out; |
86 | } | 97 | } |
87 | 98 | ||
88 | #ifdef CONFIG_MTD_PARTITIONS | 99 | #ifdef CONFIG_MTD_PARTITIONS |
89 | if (pdata->chip.part_probe_types) { | 100 | if (pdata->chip.part_probe_types) { |
90 | res = parse_mtd_partitions(&data->mtd, | 101 | err = parse_mtd_partitions(&data->mtd, |
91 | pdata->chip.part_probe_types, | 102 | pdata->chip.part_probe_types, |
92 | &data->parts, 0); | 103 | &data->parts, 0); |
93 | if (res > 0) { | 104 | if (err > 0) { |
94 | add_mtd_partitions(&data->mtd, data->parts, res); | 105 | add_mtd_partitions(&data->mtd, data->parts, err); |
95 | return 0; | 106 | return 0; |
96 | } | 107 | } |
97 | } | 108 | } |
@@ -99,14 +110,14 @@ static int __devinit plat_nand_probe(struct platform_device *pdev) | |||
99 | pdata->chip.set_parts(data->mtd.size, &pdata->chip); | 110 | pdata->chip.set_parts(data->mtd.size, &pdata->chip); |
100 | if (pdata->chip.partitions) { | 111 | if (pdata->chip.partitions) { |
101 | data->parts = pdata->chip.partitions; | 112 | data->parts = pdata->chip.partitions; |
102 | res = add_mtd_partitions(&data->mtd, data->parts, | 113 | err = add_mtd_partitions(&data->mtd, data->parts, |
103 | pdata->chip.nr_partitions); | 114 | pdata->chip.nr_partitions); |
104 | } else | 115 | } else |
105 | #endif | 116 | #endif |
106 | res = add_mtd_device(&data->mtd); | 117 | err = add_mtd_device(&data->mtd); |
107 | 118 | ||
108 | if (!res) | 119 | if (!err) |
109 | return res; | 120 | return err; |
110 | 121 | ||
111 | nand_release(&data->mtd); | 122 | nand_release(&data->mtd); |
112 | out: | 123 | out: |
@@ -114,8 +125,11 @@ out: | |||
114 | pdata->ctrl.remove(pdev); | 125 | pdata->ctrl.remove(pdev); |
115 | platform_set_drvdata(pdev, NULL); | 126 | platform_set_drvdata(pdev, NULL); |
116 | iounmap(data->io_base); | 127 | iounmap(data->io_base); |
128 | out_release_io: | ||
129 | release_mem_region(res->start, resource_size(res)); | ||
130 | out_free: | ||
117 | kfree(data); | 131 | kfree(data); |
118 | return res; | 132 | return err; |
119 | } | 133 | } |
120 | 134 | ||
121 | /* | 135 | /* |
@@ -125,6 +139,9 @@ static int __devexit plat_nand_remove(struct platform_device *pdev) | |||
125 | { | 139 | { |
126 | struct plat_nand_data *data = platform_get_drvdata(pdev); | 140 | struct plat_nand_data *data = platform_get_drvdata(pdev); |
127 | struct platform_nand_data *pdata = pdev->dev.platform_data; | 141 | struct platform_nand_data *pdata = pdev->dev.platform_data; |
142 | struct resource *res; | ||
143 | |||
144 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
128 | 145 | ||
129 | nand_release(&data->mtd); | 146 | nand_release(&data->mtd); |
130 | #ifdef CONFIG_MTD_PARTITIONS | 147 | #ifdef CONFIG_MTD_PARTITIONS |
@@ -134,6 +151,7 @@ static int __devexit plat_nand_remove(struct platform_device *pdev) | |||
134 | if (pdata->ctrl.remove) | 151 | if (pdata->ctrl.remove) |
135 | pdata->ctrl.remove(pdev); | 152 | pdata->ctrl.remove(pdev); |
136 | iounmap(data->io_base); | 153 | iounmap(data->io_base); |
154 | release_mem_region(res->start, resource_size(res)); | ||
137 | kfree(data); | 155 | kfree(data); |
138 | 156 | ||
139 | return 0; | 157 | return 0; |