hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/mtd/nand/raw/ams-delta.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
34 *
....@@ -8,10 +9,6 @@
89 * Converted to platform driver by Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
910 * Partially stolen from plat_nand.c
1011 *
11
- * This program is free software; you can redistribute it and/or modify
12
- * it under the terms of the GNU General Public License version 2 as
13
- * published by the Free Software Foundation.
14
- *
1512 * Overview:
1613 * This is a device driver for the NAND flash device found on the
1714 * Amstrad E3 (Delta).
....@@ -20,272 +17,433 @@
2017 #include <linux/slab.h>
2118 #include <linux/module.h>
2219 #include <linux/delay.h>
20
+#include <linux/gpio/consumer.h>
2321 #include <linux/mtd/mtd.h>
22
+#include <linux/mtd/nand-gpio.h>
2423 #include <linux/mtd/rawnand.h>
2524 #include <linux/mtd/partitions.h>
26
-#include <linux/gpio.h>
27
-#include <linux/platform_data/gpio-omap.h>
28
-
29
-#include <asm/io.h>
30
-#include <asm/sizes.h>
31
-
32
-#include <mach/board-ams-delta.h>
33
-
34
-#include <mach/hardware.h>
25
+#include <linux/of_device.h>
26
+#include <linux/platform_device.h>
27
+#include <linux/sizes.h>
3528
3629 /*
3730 * MTD structure for E3 (Delta)
3831 */
39
-static struct mtd_info *ams_delta_mtd = NULL;
40
-
41
-/*
42
- * Define partitions for flash devices
43
- */
44
-
45
-static const struct mtd_partition partition_info[] = {
46
- { .name = "Kernel",
47
- .offset = 0,
48
- .size = 3 * SZ_1M + SZ_512K },
49
- { .name = "u-boot",
50
- .offset = 3 * SZ_1M + SZ_512K,
51
- .size = SZ_256K },
52
- { .name = "u-boot params",
53
- .offset = 3 * SZ_1M + SZ_512K + SZ_256K,
54
- .size = SZ_256K },
55
- { .name = "Amstrad LDR",
56
- .offset = 4 * SZ_1M,
57
- .size = SZ_256K },
58
- { .name = "File system",
59
- .offset = 4 * SZ_1M + 1 * SZ_256K,
60
- .size = 27 * SZ_1M },
61
- { .name = "PBL reserved",
62
- .offset = 32 * SZ_1M - 3 * SZ_256K,
63
- .size = 3 * SZ_256K },
32
+struct gpio_nand {
33
+ struct nand_controller base;
34
+ struct nand_chip nand_chip;
35
+ struct gpio_desc *gpiod_rdy;
36
+ struct gpio_desc *gpiod_nce;
37
+ struct gpio_desc *gpiod_nre;
38
+ struct gpio_desc *gpiod_nwp;
39
+ struct gpio_desc *gpiod_nwe;
40
+ struct gpio_desc *gpiod_ale;
41
+ struct gpio_desc *gpiod_cle;
42
+ struct gpio_descs *data_gpiods;
43
+ bool data_in;
44
+ unsigned int tRP;
45
+ unsigned int tWP;
46
+ u8 (*io_read)(struct gpio_nand *this);
47
+ void (*io_write)(struct gpio_nand *this, u8 byte);
6448 };
6549
66
-static void ams_delta_write_byte(struct mtd_info *mtd, u_char byte)
50
+static void gpio_nand_write_commit(struct gpio_nand *priv)
6751 {
68
- struct nand_chip *this = mtd_to_nand(mtd);
69
- void __iomem *io_base = (void __iomem *)nand_get_controller_data(this);
70
-
71
- writew(0, io_base + OMAP_MPUIO_IO_CNTL);
72
- writew(byte, this->IO_ADDR_W);
73
- gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NWE, 0);
74
- ndelay(40);
75
- gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NWE, 1);
52
+ gpiod_set_value(priv->gpiod_nwe, 1);
53
+ ndelay(priv->tWP);
54
+ gpiod_set_value(priv->gpiod_nwe, 0);
7655 }
7756
78
-static u_char ams_delta_read_byte(struct mtd_info *mtd)
57
+static void gpio_nand_io_write(struct gpio_nand *priv, u8 byte)
7958 {
80
- u_char res;
81
- struct nand_chip *this = mtd_to_nand(mtd);
82
- void __iomem *io_base = (void __iomem *)nand_get_controller_data(this);
59
+ struct gpio_descs *data_gpiods = priv->data_gpiods;
60
+ DECLARE_BITMAP(values, BITS_PER_TYPE(byte)) = { byte, };
8361
84
- gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NRE, 0);
85
- ndelay(40);
86
- writew(~0, io_base + OMAP_MPUIO_IO_CNTL);
87
- res = readw(this->IO_ADDR_R);
88
- gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NRE, 1);
62
+ gpiod_set_raw_array_value(data_gpiods->ndescs, data_gpiods->desc,
63
+ data_gpiods->info, values);
8964
65
+ gpio_nand_write_commit(priv);
66
+}
67
+
68
+static void gpio_nand_dir_output(struct gpio_nand *priv, u8 byte)
69
+{
70
+ struct gpio_descs *data_gpiods = priv->data_gpiods;
71
+ DECLARE_BITMAP(values, BITS_PER_TYPE(byte)) = { byte, };
72
+ int i;
73
+
74
+ for (i = 0; i < data_gpiods->ndescs; i++)
75
+ gpiod_direction_output_raw(data_gpiods->desc[i],
76
+ test_bit(i, values));
77
+
78
+ gpio_nand_write_commit(priv);
79
+
80
+ priv->data_in = false;
81
+}
82
+
83
+static u8 gpio_nand_io_read(struct gpio_nand *priv)
84
+{
85
+ u8 res;
86
+ struct gpio_descs *data_gpiods = priv->data_gpiods;
87
+ DECLARE_BITMAP(values, BITS_PER_TYPE(res)) = { 0, };
88
+
89
+ gpiod_set_value(priv->gpiod_nre, 1);
90
+ ndelay(priv->tRP);
91
+
92
+ gpiod_get_raw_array_value(data_gpiods->ndescs, data_gpiods->desc,
93
+ data_gpiods->info, values);
94
+
95
+ gpiod_set_value(priv->gpiod_nre, 0);
96
+
97
+ res = values[0];
9098 return res;
9199 }
92100
93
-static void ams_delta_write_buf(struct mtd_info *mtd, const u_char *buf,
94
- int len)
101
+static void gpio_nand_dir_input(struct gpio_nand *priv)
102
+{
103
+ struct gpio_descs *data_gpiods = priv->data_gpiods;
104
+ int i;
105
+
106
+ for (i = 0; i < data_gpiods->ndescs; i++)
107
+ gpiod_direction_input(data_gpiods->desc[i]);
108
+
109
+ priv->data_in = true;
110
+}
111
+
112
+static void gpio_nand_write_buf(struct gpio_nand *priv, const u8 *buf, int len)
113
+{
114
+ int i = 0;
115
+
116
+ if (len > 0 && priv->data_in)
117
+ gpio_nand_dir_output(priv, buf[i++]);
118
+
119
+ while (i < len)
120
+ priv->io_write(priv, buf[i++]);
121
+}
122
+
123
+static void gpio_nand_read_buf(struct gpio_nand *priv, u8 *buf, int len)
95124 {
96125 int i;
97126
98
- for (i=0; i<len; i++)
99
- ams_delta_write_byte(mtd, buf[i]);
127
+ if (priv->data_gpiods && !priv->data_in)
128
+ gpio_nand_dir_input(priv);
129
+
130
+ for (i = 0; i < len; i++)
131
+ buf[i] = priv->io_read(priv);
100132 }
101133
102
-static void ams_delta_read_buf(struct mtd_info *mtd, u_char *buf, int len)
134
+static void gpio_nand_ctrl_cs(struct gpio_nand *priv, bool assert)
103135 {
104
- int i;
105
-
106
- for (i=0; i<len; i++)
107
- buf[i] = ams_delta_read_byte(mtd);
136
+ gpiod_set_value(priv->gpiod_nce, assert);
108137 }
109138
110
-/*
111
- * Command control function
112
- *
113
- * ctrl:
114
- * NAND_NCE: bit 0 -> bit 2
115
- * NAND_CLE: bit 1 -> bit 7
116
- * NAND_ALE: bit 2 -> bit 6
117
- */
118
-static void ams_delta_hwcontrol(struct mtd_info *mtd, int cmd,
119
- unsigned int ctrl)
139
+static int gpio_nand_exec_op(struct nand_chip *this,
140
+ const struct nand_operation *op, bool check_only)
120141 {
142
+ struct gpio_nand *priv = nand_get_controller_data(this);
143
+ const struct nand_op_instr *instr;
144
+ int ret = 0;
121145
122
- if (ctrl & NAND_CTRL_CHANGE) {
123
- gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NCE,
124
- (ctrl & NAND_NCE) == 0);
125
- gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_CLE,
126
- (ctrl & NAND_CLE) != 0);
127
- gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_ALE,
128
- (ctrl & NAND_ALE) != 0);
146
+ if (check_only)
147
+ return 0;
148
+
149
+ gpio_nand_ctrl_cs(priv, 1);
150
+
151
+ for (instr = op->instrs; instr < op->instrs + op->ninstrs; instr++) {
152
+ switch (instr->type) {
153
+ case NAND_OP_CMD_INSTR:
154
+ gpiod_set_value(priv->gpiod_cle, 1);
155
+ gpio_nand_write_buf(priv, &instr->ctx.cmd.opcode, 1);
156
+ gpiod_set_value(priv->gpiod_cle, 0);
157
+ break;
158
+
159
+ case NAND_OP_ADDR_INSTR:
160
+ gpiod_set_value(priv->gpiod_ale, 1);
161
+ gpio_nand_write_buf(priv, instr->ctx.addr.addrs,
162
+ instr->ctx.addr.naddrs);
163
+ gpiod_set_value(priv->gpiod_ale, 0);
164
+ break;
165
+
166
+ case NAND_OP_DATA_IN_INSTR:
167
+ gpio_nand_read_buf(priv, instr->ctx.data.buf.in,
168
+ instr->ctx.data.len);
169
+ break;
170
+
171
+ case NAND_OP_DATA_OUT_INSTR:
172
+ gpio_nand_write_buf(priv, instr->ctx.data.buf.out,
173
+ instr->ctx.data.len);
174
+ break;
175
+
176
+ case NAND_OP_WAITRDY_INSTR:
177
+ ret = priv->gpiod_rdy ?
178
+ nand_gpio_waitrdy(this, priv->gpiod_rdy,
179
+ instr->ctx.waitrdy.timeout_ms) :
180
+ nand_soft_waitrdy(this,
181
+ instr->ctx.waitrdy.timeout_ms);
182
+ break;
183
+ }
184
+
185
+ if (ret)
186
+ break;
129187 }
130188
131
- if (cmd != NAND_CMD_NONE)
132
- ams_delta_write_byte(mtd, cmd);
189
+ gpio_nand_ctrl_cs(priv, 0);
190
+
191
+ return ret;
133192 }
134193
135
-static int ams_delta_nand_ready(struct mtd_info *mtd)
194
+static int gpio_nand_setup_interface(struct nand_chip *this, int csline,
195
+ const struct nand_interface_config *cf)
136196 {
137
- return gpio_get_value(AMS_DELTA_GPIO_PIN_NAND_RB);
197
+ struct gpio_nand *priv = nand_get_controller_data(this);
198
+ const struct nand_sdr_timings *sdr = nand_get_sdr_timings(cf);
199
+ struct device *dev = &nand_to_mtd(this)->dev;
200
+
201
+ if (IS_ERR(sdr))
202
+ return PTR_ERR(sdr);
203
+
204
+ if (csline == NAND_DATA_IFACE_CHECK_ONLY)
205
+ return 0;
206
+
207
+ if (priv->gpiod_nre) {
208
+ priv->tRP = DIV_ROUND_UP(sdr->tRP_min, 1000);
209
+ dev_dbg(dev, "using %u ns read pulse width\n", priv->tRP);
210
+ }
211
+
212
+ priv->tWP = DIV_ROUND_UP(sdr->tWP_min, 1000);
213
+ dev_dbg(dev, "using %u ns write pulse width\n", priv->tWP);
214
+
215
+ return 0;
138216 }
139217
140
-static const struct gpio _mandatory_gpio[] = {
141
- {
142
- .gpio = AMS_DELTA_GPIO_PIN_NAND_NCE,
143
- .flags = GPIOF_OUT_INIT_HIGH,
144
- .label = "nand_nce",
145
- },
146
- {
147
- .gpio = AMS_DELTA_GPIO_PIN_NAND_NRE,
148
- .flags = GPIOF_OUT_INIT_HIGH,
149
- .label = "nand_nre",
150
- },
151
- {
152
- .gpio = AMS_DELTA_GPIO_PIN_NAND_NWP,
153
- .flags = GPIOF_OUT_INIT_HIGH,
154
- .label = "nand_nwp",
155
- },
156
- {
157
- .gpio = AMS_DELTA_GPIO_PIN_NAND_NWE,
158
- .flags = GPIOF_OUT_INIT_HIGH,
159
- .label = "nand_nwe",
160
- },
161
- {
162
- .gpio = AMS_DELTA_GPIO_PIN_NAND_ALE,
163
- .flags = GPIOF_OUT_INIT_LOW,
164
- .label = "nand_ale",
165
- },
166
- {
167
- .gpio = AMS_DELTA_GPIO_PIN_NAND_CLE,
168
- .flags = GPIOF_OUT_INIT_LOW,
169
- .label = "nand_cle",
170
- },
218
+static int gpio_nand_attach_chip(struct nand_chip *chip)
219
+{
220
+ if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
221
+ chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
222
+ chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
223
+
224
+ return 0;
225
+}
226
+
227
+static const struct nand_controller_ops gpio_nand_ops = {
228
+ .exec_op = gpio_nand_exec_op,
229
+ .attach_chip = gpio_nand_attach_chip,
230
+ .setup_interface = gpio_nand_setup_interface,
171231 };
172232
173233 /*
174234 * Main initialization routine
175235 */
176
-static int ams_delta_init(struct platform_device *pdev)
236
+static int gpio_nand_probe(struct platform_device *pdev)
177237 {
238
+ struct gpio_nand_platdata *pdata = dev_get_platdata(&pdev->dev);
239
+ const struct mtd_partition *partitions = NULL;
240
+ int num_partitions = 0;
241
+ struct gpio_nand *priv;
178242 struct nand_chip *this;
179
- struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
180
- void __iomem *io_base;
243
+ struct mtd_info *mtd;
244
+ int (*probe)(struct platform_device *pdev, struct gpio_nand *priv);
181245 int err = 0;
182246
183
- if (!res)
184
- return -ENXIO;
247
+ if (pdata) {
248
+ partitions = pdata->parts;
249
+ num_partitions = pdata->num_parts;
250
+ }
185251
186252 /* Allocate memory for MTD device structure and private data */
187
- this = kzalloc(sizeof(struct nand_chip), GFP_KERNEL);
188
- if (!this) {
189
- pr_warn("Unable to allocate E3 NAND MTD device structure.\n");
190
- err = -ENOMEM;
191
- goto out;
253
+ priv = devm_kzalloc(&pdev->dev, sizeof(struct gpio_nand),
254
+ GFP_KERNEL);
255
+ if (!priv)
256
+ return -ENOMEM;
257
+
258
+ this = &priv->nand_chip;
259
+
260
+ mtd = nand_to_mtd(this);
261
+ mtd->dev.parent = &pdev->dev;
262
+
263
+ nand_set_controller_data(this, priv);
264
+ nand_set_flash_node(this, pdev->dev.of_node);
265
+
266
+ priv->gpiod_rdy = devm_gpiod_get_optional(&pdev->dev, "rdy", GPIOD_IN);
267
+ if (IS_ERR(priv->gpiod_rdy)) {
268
+ err = PTR_ERR(priv->gpiod_rdy);
269
+ dev_warn(&pdev->dev, "RDY GPIO request failed (%d)\n", err);
270
+ return err;
192271 }
193272
194
- ams_delta_mtd = nand_to_mtd(this);
195
- ams_delta_mtd->owner = THIS_MODULE;
273
+ platform_set_drvdata(pdev, priv);
274
+
275
+ /* Set chip enabled but write protected */
276
+ priv->gpiod_nwp = devm_gpiod_get_optional(&pdev->dev, "nwp",
277
+ GPIOD_OUT_HIGH);
278
+ if (IS_ERR(priv->gpiod_nwp)) {
279
+ err = PTR_ERR(priv->gpiod_nwp);
280
+ dev_err(&pdev->dev, "NWP GPIO request failed (%d)\n", err);
281
+ return err;
282
+ }
283
+
284
+ priv->gpiod_nce = devm_gpiod_get_optional(&pdev->dev, "nce",
285
+ GPIOD_OUT_LOW);
286
+ if (IS_ERR(priv->gpiod_nce)) {
287
+ err = PTR_ERR(priv->gpiod_nce);
288
+ dev_err(&pdev->dev, "NCE GPIO request failed (%d)\n", err);
289
+ return err;
290
+ }
291
+
292
+ priv->gpiod_nre = devm_gpiod_get_optional(&pdev->dev, "nre",
293
+ GPIOD_OUT_LOW);
294
+ if (IS_ERR(priv->gpiod_nre)) {
295
+ err = PTR_ERR(priv->gpiod_nre);
296
+ dev_err(&pdev->dev, "NRE GPIO request failed (%d)\n", err);
297
+ return err;
298
+ }
299
+
300
+ priv->gpiod_nwe = devm_gpiod_get_optional(&pdev->dev, "nwe",
301
+ GPIOD_OUT_LOW);
302
+ if (IS_ERR(priv->gpiod_nwe)) {
303
+ err = PTR_ERR(priv->gpiod_nwe);
304
+ dev_err(&pdev->dev, "NWE GPIO request failed (%d)\n", err);
305
+ return err;
306
+ }
307
+
308
+ priv->gpiod_ale = devm_gpiod_get(&pdev->dev, "ale", GPIOD_OUT_LOW);
309
+ if (IS_ERR(priv->gpiod_ale)) {
310
+ err = PTR_ERR(priv->gpiod_ale);
311
+ dev_err(&pdev->dev, "ALE GPIO request failed (%d)\n", err);
312
+ return err;
313
+ }
314
+
315
+ priv->gpiod_cle = devm_gpiod_get(&pdev->dev, "cle", GPIOD_OUT_LOW);
316
+ if (IS_ERR(priv->gpiod_cle)) {
317
+ err = PTR_ERR(priv->gpiod_cle);
318
+ dev_err(&pdev->dev, "CLE GPIO request failed (%d)\n", err);
319
+ return err;
320
+ }
321
+
322
+ /* Request array of data pins, initialize them as input */
323
+ priv->data_gpiods = devm_gpiod_get_array_optional(&pdev->dev, "data",
324
+ GPIOD_IN);
325
+ if (IS_ERR(priv->data_gpiods)) {
326
+ err = PTR_ERR(priv->data_gpiods);
327
+ dev_err(&pdev->dev, "data GPIO request failed: %d\n", err);
328
+ return err;
329
+ }
330
+ if (priv->data_gpiods) {
331
+ if (!priv->gpiod_nwe) {
332
+ dev_err(&pdev->dev,
333
+ "mandatory NWE pin not provided by platform\n");
334
+ return -ENODEV;
335
+ }
336
+
337
+ priv->io_read = gpio_nand_io_read;
338
+ priv->io_write = gpio_nand_io_write;
339
+ priv->data_in = true;
340
+ }
341
+
342
+ if (pdev->id_entry)
343
+ probe = (void *) pdev->id_entry->driver_data;
344
+ else
345
+ probe = of_device_get_match_data(&pdev->dev);
346
+ if (probe)
347
+ err = probe(pdev, priv);
348
+ if (err)
349
+ return err;
350
+
351
+ if (!priv->io_read || !priv->io_write) {
352
+ dev_err(&pdev->dev, "incomplete device configuration\n");
353
+ return -ENODEV;
354
+ }
355
+
356
+ /* Initialize the NAND controller object embedded in gpio_nand. */
357
+ priv->base.ops = &gpio_nand_ops;
358
+ nand_controller_init(&priv->base);
359
+ this->controller = &priv->base;
196360
197361 /*
198
- * Don't try to request the memory region from here,
199
- * it should have been already requested from the
200
- * gpio-omap driver and requesting it again would fail.
362
+ * FIXME: We should release write protection only after nand_scan() to
363
+ * be on the safe side but we can't do that until we have a generic way
364
+ * to assert/deassert WP from the core. Even if the core shouldn't
365
+ * write things in the nand_scan() path, it should have control on this
366
+ * pin just in case we ever need to disable write protection during
367
+ * chip detection/initialization.
201368 */
369
+ /* Release write protection */
370
+ gpiod_set_value(priv->gpiod_nwp, 0);
202371
203
- io_base = ioremap(res->start, resource_size(res));
204
- if (io_base == NULL) {
205
- dev_err(&pdev->dev, "ioremap failed\n");
206
- err = -EIO;
207
- goto out_free;
208
- }
209
-
210
- nand_set_controller_data(this, (void *)io_base);
211
-
212
- /* Set address of NAND IO lines */
213
- this->IO_ADDR_R = io_base + OMAP_MPUIO_INPUT_LATCH;
214
- this->IO_ADDR_W = io_base + OMAP_MPUIO_OUTPUT;
215
- this->read_byte = ams_delta_read_byte;
216
- this->write_buf = ams_delta_write_buf;
217
- this->read_buf = ams_delta_read_buf;
218
- this->cmd_ctrl = ams_delta_hwcontrol;
219
- if (gpio_request(AMS_DELTA_GPIO_PIN_NAND_RB, "nand_rdy") == 0) {
220
- this->dev_ready = ams_delta_nand_ready;
221
- } else {
222
- this->dev_ready = NULL;
223
- pr_notice("Couldn't request gpio for Delta NAND ready.\n");
224
- }
225
- /* 25 us command delay time */
226
- this->chip_delay = 30;
227
- this->ecc.mode = NAND_ECC_SOFT;
228
- this->ecc.algo = NAND_ECC_HAMMING;
229
-
230
- platform_set_drvdata(pdev, io_base);
231
-
232
- /* Set chip enabled, but */
233
- err = gpio_request_array(_mandatory_gpio, ARRAY_SIZE(_mandatory_gpio));
234
- if (err)
235
- goto out_gpio;
372
+ /*
373
+ * This driver assumes that the default ECC engine should be TYPE_SOFT.
374
+ * Set ->engine_type before registering the NAND devices in order to
375
+ * provide a driver specific default value.
376
+ */
377
+ this->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
236378
237379 /* Scan to find existence of the device */
238380 err = nand_scan(this, 1);
239381 if (err)
240
- goto out_mtd;
382
+ return err;
241383
242384 /* Register the partitions */
243
- mtd_device_register(ams_delta_mtd, partition_info,
244
- ARRAY_SIZE(partition_info));
385
+ err = mtd_device_register(mtd, partitions, num_partitions);
386
+ if (err)
387
+ goto err_nand_cleanup;
245388
246
- goto out;
389
+ return 0;
247390
248
- out_mtd:
249
- gpio_free_array(_mandatory_gpio, ARRAY_SIZE(_mandatory_gpio));
250
-out_gpio:
251
- gpio_free(AMS_DELTA_GPIO_PIN_NAND_RB);
252
- iounmap(io_base);
253
-out_free:
254
- kfree(this);
255
- out:
391
+err_nand_cleanup:
392
+ nand_cleanup(this);
393
+
256394 return err;
257395 }
258396
259397 /*
260398 * Clean up routine
261399 */
262
-static int ams_delta_cleanup(struct platform_device *pdev)
400
+static int gpio_nand_remove(struct platform_device *pdev)
263401 {
264
- void __iomem *io_base = platform_get_drvdata(pdev);
402
+ struct gpio_nand *priv = platform_get_drvdata(pdev);
403
+ struct mtd_info *mtd = nand_to_mtd(&priv->nand_chip);
404
+ int ret;
265405
266
- /* Release resources, unregister device */
267
- nand_release(mtd_to_nand(ams_delta_mtd));
406
+ /* Apply write protection */
407
+ gpiod_set_value(priv->gpiod_nwp, 1);
268408
269
- gpio_free_array(_mandatory_gpio, ARRAY_SIZE(_mandatory_gpio));
270
- gpio_free(AMS_DELTA_GPIO_PIN_NAND_RB);
271
- iounmap(io_base);
272
-
273
- /* Free the MTD device structure */
274
- kfree(mtd_to_nand(ams_delta_mtd));
409
+ /* Unregister device */
410
+ ret = mtd_device_unregister(mtd);
411
+ WARN_ON(ret);
412
+ nand_cleanup(mtd_to_nand(mtd));
275413
276414 return 0;
277415 }
278416
279
-static struct platform_driver ams_delta_nand_driver = {
280
- .probe = ams_delta_init,
281
- .remove = ams_delta_cleanup,
417
+#ifdef CONFIG_OF
418
+static const struct of_device_id gpio_nand_of_id_table[] = {
419
+ {
420
+ /* sentinel */
421
+ },
422
+};
423
+MODULE_DEVICE_TABLE(of, gpio_nand_of_id_table);
424
+#endif
425
+
426
+static const struct platform_device_id gpio_nand_plat_id_table[] = {
427
+ {
428
+ .name = "ams-delta-nand",
429
+ }, {
430
+ /* sentinel */
431
+ },
432
+};
433
+MODULE_DEVICE_TABLE(platform, gpio_nand_plat_id_table);
434
+
435
+static struct platform_driver gpio_nand_driver = {
436
+ .probe = gpio_nand_probe,
437
+ .remove = gpio_nand_remove,
438
+ .id_table = gpio_nand_plat_id_table,
282439 .driver = {
283440 .name = "ams-delta-nand",
441
+ .of_match_table = of_match_ptr(gpio_nand_of_id_table),
284442 },
285443 };
286444
287
-module_platform_driver(ams_delta_nand_driver);
445
+module_platform_driver(gpio_nand_driver);
288446
289
-MODULE_LICENSE("GPL");
447
+MODULE_LICENSE("GPL v2");
290448 MODULE_AUTHOR("Jonathan McDowell <noodles@earth.li>");
291449 MODULE_DESCRIPTION("Glue layer for NAND flash on Amstrad E3 (Delta)");