diff options
author | Hauke Mehrtens <hauke@hauke-m.de> | 2016-06-20 17:32:08 -0400 |
---|---|---|
committer | Boris Brezillon <boris.brezillon@free-electrons.com> | 2016-07-11 02:40:14 -0400 |
commit | 024366750c2e04fdcda8bca685194ef0196b35fe (patch) | |
tree | 8d9bee89f5bdf2bea5774ac241516b30af6b1d35 | |
parent | 3d8cec2234ea76a48ed259e6984887570cbaff09 (diff) |
mtd: nand: xway: convert to normal platform driver
Instead of hacking this into the plat_nand driver just make this a
normal nand driver.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
-rw-r--r-- | drivers/mtd/nand/Kconfig | 1 | ||||
-rw-r--r-- | drivers/mtd/nand/xway_nand.c | 116 |
2 files changed, 80 insertions, 37 deletions
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 3c26e899789e..ee76f922fb9b 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -539,7 +539,6 @@ config MTD_NAND_FSMC | |||
539 | config MTD_NAND_XWAY | 539 | config MTD_NAND_XWAY |
540 | tristate "Support for NAND on Lantiq XWAY SoC" | 540 | tristate "Support for NAND on Lantiq XWAY SoC" |
541 | depends on LANTIQ && SOC_TYPE_XWAY | 541 | depends on LANTIQ && SOC_TYPE_XWAY |
542 | select MTD_NAND_PLATFORM | ||
543 | help | 542 | help |
544 | Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached | 543 | Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached |
545 | to the External Bus Unit (EBU). | 544 | to the External Bus Unit (EBU). |
diff --git a/drivers/mtd/nand/xway_nand.c b/drivers/mtd/nand/xway_nand.c index 2d746373c444..ec189e5b4459 100644 --- a/drivers/mtd/nand/xway_nand.c +++ b/drivers/mtd/nand/xway_nand.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright © 2012 John Crispin <blogic@openwrt.org> | 6 | * Copyright © 2012 John Crispin <blogic@openwrt.org> |
7 | * Copyright © 2016 Hauke Mehrtens <hauke@hauke-m.de> | ||
7 | */ | 8 | */ |
8 | 9 | ||
9 | #include <linux/mtd/nand.h> | 10 | #include <linux/mtd/nand.h> |
@@ -63,6 +64,10 @@ | |||
63 | #define NAND_CON_CSMUX (1 << 1) | 64 | #define NAND_CON_CSMUX (1 << 1) |
64 | #define NAND_CON_NANDM 1 | 65 | #define NAND_CON_NANDM 1 |
65 | 66 | ||
67 | struct xway_nand_data { | ||
68 | struct nand_chip chip; | ||
69 | }; | ||
70 | |||
66 | static void xway_reset_chip(struct nand_chip *chip) | 71 | static void xway_reset_chip(struct nand_chip *chip) |
67 | { | 72 | { |
68 | unsigned long nandaddr = (unsigned long) chip->IO_ADDR_W; | 73 | unsigned long nandaddr = (unsigned long) chip->IO_ADDR_W; |
@@ -139,16 +144,51 @@ static unsigned char xway_read_byte(struct mtd_info *mtd) | |||
139 | return ret; | 144 | return ret; |
140 | } | 145 | } |
141 | 146 | ||
147 | /* | ||
148 | * Probe for the NAND device. | ||
149 | */ | ||
142 | static int xway_nand_probe(struct platform_device *pdev) | 150 | static int xway_nand_probe(struct platform_device *pdev) |
143 | { | 151 | { |
144 | struct nand_chip *this = platform_get_drvdata(pdev); | 152 | struct xway_nand_data *data; |
145 | unsigned long nandaddr = (unsigned long) this->IO_ADDR_W; | 153 | struct mtd_info *mtd; |
146 | const __be32 *cs = of_get_property(pdev->dev.of_node, | 154 | struct resource *res; |
147 | "lantiq,cs", NULL); | 155 | int err; |
156 | void __iomem *nandaddr; | ||
157 | u32 cs; | ||
148 | u32 cs_flag = 0; | 158 | u32 cs_flag = 0; |
149 | 159 | ||
160 | /* Allocate memory for the device structure (and zero it) */ | ||
161 | data = devm_kzalloc(&pdev->dev, sizeof(struct xway_nand_data), | ||
162 | GFP_KERNEL); | ||
163 | if (!data) | ||
164 | return -ENOMEM; | ||
165 | |||
166 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
167 | nandaddr = devm_ioremap_resource(&pdev->dev, res); | ||
168 | if (IS_ERR(nandaddr)) | ||
169 | return PTR_ERR(nandaddr); | ||
170 | |||
171 | nand_set_flash_node(&data->chip, pdev->dev.of_node); | ||
172 | mtd = nand_to_mtd(&data->chip); | ||
173 | mtd->dev.parent = &pdev->dev; | ||
174 | |||
175 | data->chip.IO_ADDR_R = nandaddr; | ||
176 | data->chip.IO_ADDR_W = nandaddr; | ||
177 | data->chip.cmd_ctrl = xway_cmd_ctrl; | ||
178 | data->chip.dev_ready = xway_dev_ready; | ||
179 | data->chip.select_chip = xway_select_chip; | ||
180 | data->chip.read_byte = xway_read_byte; | ||
181 | data->chip.chip_delay = 30; | ||
182 | |||
183 | data->chip.ecc.mode = NAND_ECC_SOFT; | ||
184 | data->chip.ecc.algo = NAND_ECC_HAMMING; | ||
185 | |||
186 | platform_set_drvdata(pdev, data); | ||
187 | nand_set_controller_data(&data->chip, data); | ||
188 | |||
150 | /* load our CS from the DT. Either we find a valid 1 or default to 0 */ | 189 | /* load our CS from the DT. Either we find a valid 1 or default to 0 */ |
151 | if (cs && (*cs == 1)) | 190 | err = of_property_read_u32(pdev->dev.of_node, "lantiq,cs", &cs); |
191 | if (!err && cs == 1) | ||
152 | cs_flag = NAND_CON_IN_CS1 | NAND_CON_OUT_CS1; | 192 | cs_flag = NAND_CON_IN_CS1 | NAND_CON_OUT_CS1; |
153 | 193 | ||
154 | /* setup the EBU to run in NAND mode on our base addr */ | 194 | /* setup the EBU to run in NAND mode on our base addr */ |
@@ -164,43 +204,47 @@ static int xway_nand_probe(struct platform_device *pdev) | |||
164 | | cs_flag, EBU_NAND_CON); | 204 | | cs_flag, EBU_NAND_CON); |
165 | 205 | ||
166 | /* finish with a reset */ | 206 | /* finish with a reset */ |
167 | xway_reset_chip(this); | 207 | xway_reset_chip(&data->chip); |
168 | 208 | ||
169 | return 0; | 209 | /* Scan to find existence of the device */ |
170 | } | 210 | err = nand_scan(mtd, 1); |
211 | if (err) | ||
212 | return err; | ||
171 | 213 | ||
172 | static struct platform_nand_data xway_nand_data = { | 214 | err = mtd_device_register(mtd, NULL, 0); |
173 | .chip = { | 215 | if (err) |
174 | .nr_chips = 1, | 216 | nand_release(mtd); |
175 | .chip_delay = 30, | 217 | |
176 | }, | 218 | return err; |
177 | .ctrl = { | 219 | } |
178 | .probe = xway_nand_probe, | ||
179 | .cmd_ctrl = xway_cmd_ctrl, | ||
180 | .dev_ready = xway_dev_ready, | ||
181 | .select_chip = xway_select_chip, | ||
182 | .read_byte = xway_read_byte, | ||
183 | } | ||
184 | }; | ||
185 | 220 | ||
186 | /* | 221 | /* |
187 | * Try to find the node inside the DT. If it is available attach out | 222 | * Remove a NAND device. |
188 | * platform_nand_data | ||
189 | */ | 223 | */ |
190 | static int __init xway_register_nand(void) | 224 | static int xway_nand_remove(struct platform_device *pdev) |
191 | { | 225 | { |
192 | struct device_node *node; | 226 | struct xway_nand_data *data = platform_get_drvdata(pdev); |
193 | struct platform_device *pdev; | 227 | |
194 | 228 | nand_release(nand_to_mtd(&data->chip)); | |
195 | node = of_find_compatible_node(NULL, NULL, "lantiq,nand-xway"); | 229 | |
196 | if (!node) | ||
197 | return -ENOENT; | ||
198 | pdev = of_find_device_by_node(node); | ||
199 | if (!pdev) | ||
200 | return -EINVAL; | ||
201 | pdev->dev.platform_data = &xway_nand_data; | ||
202 | of_node_put(node); | ||
203 | return 0; | 230 | return 0; |
204 | } | 231 | } |
205 | 232 | ||
206 | subsys_initcall(xway_register_nand); | 233 | static const struct of_device_id xway_nand_match[] = { |
234 | { .compatible = "lantiq,nand-xway" }, | ||
235 | {}, | ||
236 | }; | ||
237 | MODULE_DEVICE_TABLE(of, xway_nand_match); | ||
238 | |||
239 | static struct platform_driver xway_nand_driver = { | ||
240 | .probe = xway_nand_probe, | ||
241 | .remove = xway_nand_remove, | ||
242 | .driver = { | ||
243 | .name = "lantiq,nand-xway", | ||
244 | .of_match_table = xway_nand_match, | ||
245 | }, | ||
246 | }; | ||
247 | |||
248 | module_platform_driver(xway_nand_driver); | ||
249 | |||
250 | MODULE_LICENSE("GPL"); | ||