hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/gpio/gpio-mockup.c
....@@ -1,4 +1,4 @@
1
-// SPDX-License-Identifier: GPL-2.0+
1
+// SPDX-License-Identifier: GPL-2.0-or-later
22 /*
33 * GPIO Testing Device Driver
44 *
....@@ -7,63 +7,55 @@
77 * Copyright (C) 2017 Bartosz Golaszewski <brgl@bgdev.pl>
88 */
99
10
-#include <linux/init.h>
11
-#include <linux/module.h>
10
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11
+
12
+#include <linux/debugfs.h>
1213 #include <linux/gpio/driver.h>
13
-#include <linux/gpio/consumer.h>
14
-#include <linux/platform_device.h>
15
-#include <linux/slab.h>
1614 #include <linux/interrupt.h>
1715 #include <linux/irq.h>
1816 #include <linux/irq_sim.h>
19
-#include <linux/debugfs.h>
17
+#include <linux/irqdomain.h>
18
+#include <linux/module.h>
19
+#include <linux/platform_device.h>
20
+#include <linux/property.h>
21
+#include <linux/slab.h>
22
+#include <linux/string_helpers.h>
2023 #include <linux/uaccess.h>
2124
2225 #include "gpiolib.h"
2326
24
-#define GPIO_MOCKUP_NAME "gpio-mockup"
2527 #define GPIO_MOCKUP_MAX_GC 10
2628 /*
2729 * We're storing two values per chip: the GPIO base and the number
2830 * of GPIO lines.
2931 */
3032 #define GPIO_MOCKUP_MAX_RANGES (GPIO_MOCKUP_MAX_GC * 2)
31
-
32
-#define gpio_mockup_err(...) pr_err(GPIO_MOCKUP_NAME ": " __VA_ARGS__)
33
-
34
-enum {
35
- GPIO_MOCKUP_DIR_IN = 0,
36
- GPIO_MOCKUP_DIR_OUT = 1,
37
-};
33
+/* Maximum of four properties + the sentinel. */
34
+#define GPIO_MOCKUP_MAX_PROP 5
3835
3936 /*
4037 * struct gpio_pin_status - structure describing a GPIO status
41
- * @dir: Configures direction of gpio as "in" or "out", 0=in, 1=out
38
+ * @dir: Configures direction of gpio as "in" or "out"
4239 * @value: Configures status of the gpio as 0(low) or 1(high)
4340 */
4441 struct gpio_mockup_line_status {
4542 int dir;
4643 int value;
44
+ int pull;
4745 };
4846
4947 struct gpio_mockup_chip {
5048 struct gpio_chip gc;
5149 struct gpio_mockup_line_status *lines;
52
- struct irq_sim irqsim;
50
+ struct irq_domain *irq_sim_domain;
5351 struct dentry *dbg_dir;
52
+ struct mutex lock;
5453 };
5554
5655 struct gpio_mockup_dbgfs_private {
5756 struct gpio_mockup_chip *chip;
5857 struct gpio_desc *desc;
59
- int offset;
60
-};
61
-
62
-struct gpio_mockup_platform_data {
63
- int base;
64
- int ngpio;
65
- int index;
66
- bool named_lines;
58
+ unsigned int offset;
6759 };
6860
6961 static int gpio_mockup_ranges[GPIO_MOCKUP_MAX_RANGES];
....@@ -86,29 +78,133 @@
8678 return gpio_mockup_ranges[index * 2 + 1];
8779 }
8880
89
-static int gpio_mockup_get(struct gpio_chip *gc, unsigned int offset)
81
+static int __gpio_mockup_get(struct gpio_mockup_chip *chip,
82
+ unsigned int offset)
9083 {
91
- struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
92
-
9384 return chip->lines[offset].value;
9485 }
9586
87
+static int gpio_mockup_get(struct gpio_chip *gc, unsigned int offset)
88
+{
89
+ struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
90
+ int val;
91
+
92
+ mutex_lock(&chip->lock);
93
+ val = __gpio_mockup_get(chip, offset);
94
+ mutex_unlock(&chip->lock);
95
+
96
+ return val;
97
+}
98
+
99
+static int gpio_mockup_get_multiple(struct gpio_chip *gc,
100
+ unsigned long *mask, unsigned long *bits)
101
+{
102
+ struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
103
+ unsigned int bit, val;
104
+
105
+ mutex_lock(&chip->lock);
106
+ for_each_set_bit(bit, mask, gc->ngpio) {
107
+ val = __gpio_mockup_get(chip, bit);
108
+ __assign_bit(bit, bits, val);
109
+ }
110
+ mutex_unlock(&chip->lock);
111
+
112
+ return 0;
113
+}
114
+
115
+static void __gpio_mockup_set(struct gpio_mockup_chip *chip,
116
+ unsigned int offset, int value)
117
+{
118
+ chip->lines[offset].value = !!value;
119
+}
120
+
96121 static void gpio_mockup_set(struct gpio_chip *gc,
97
- unsigned int offset, int value)
122
+ unsigned int offset, int value)
98123 {
99124 struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
100125
101
- chip->lines[offset].value = !!value;
126
+ mutex_lock(&chip->lock);
127
+ __gpio_mockup_set(chip, offset, value);
128
+ mutex_unlock(&chip->lock);
102129 }
103130
104131 static void gpio_mockup_set_multiple(struct gpio_chip *gc,
105132 unsigned long *mask, unsigned long *bits)
106133 {
134
+ struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
107135 unsigned int bit;
108136
137
+ mutex_lock(&chip->lock);
109138 for_each_set_bit(bit, mask, gc->ngpio)
110
- gpio_mockup_set(gc, bit, test_bit(bit, bits));
139
+ __gpio_mockup_set(chip, bit, test_bit(bit, bits));
140
+ mutex_unlock(&chip->lock);
141
+}
111142
143
+static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip,
144
+ unsigned int offset, int value)
145
+{
146
+ int curr, irq, irq_type, ret = 0;
147
+ struct gpio_desc *desc;
148
+ struct gpio_chip *gc;
149
+
150
+ gc = &chip->gc;
151
+ desc = &gc->gpiodev->descs[offset];
152
+
153
+ mutex_lock(&chip->lock);
154
+
155
+ if (test_bit(FLAG_REQUESTED, &desc->flags) &&
156
+ !test_bit(FLAG_IS_OUT, &desc->flags)) {
157
+ curr = __gpio_mockup_get(chip, offset);
158
+ if (curr == value)
159
+ goto out;
160
+
161
+ irq = irq_find_mapping(chip->irq_sim_domain, offset);
162
+ if (!irq)
163
+ /*
164
+ * This is fine - it just means, nobody is listening
165
+ * for interrupts on this line, otherwise
166
+ * irq_create_mapping() would have been called from
167
+ * the to_irq() callback.
168
+ */
169
+ goto set_value;
170
+
171
+ irq_type = irq_get_trigger_type(irq);
172
+
173
+ if ((value == 1 && (irq_type & IRQ_TYPE_EDGE_RISING)) ||
174
+ (value == 0 && (irq_type & IRQ_TYPE_EDGE_FALLING))) {
175
+ ret = irq_set_irqchip_state(irq, IRQCHIP_STATE_PENDING,
176
+ true);
177
+ if (ret)
178
+ goto out;
179
+ }
180
+ }
181
+
182
+set_value:
183
+ /* Change the value unless we're actively driving the line. */
184
+ if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
185
+ !test_bit(FLAG_IS_OUT, &desc->flags))
186
+ __gpio_mockup_set(chip, offset, value);
187
+
188
+out:
189
+ chip->lines[offset].pull = value;
190
+ mutex_unlock(&chip->lock);
191
+ return ret;
192
+}
193
+
194
+static int gpio_mockup_set_config(struct gpio_chip *gc,
195
+ unsigned int offset, unsigned long config)
196
+{
197
+ struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
198
+
199
+ switch (pinconf_to_config_param(config)) {
200
+ case PIN_CONFIG_BIAS_PULL_UP:
201
+ return gpio_mockup_apply_pull(chip, offset, 1);
202
+ case PIN_CONFIG_BIAS_PULL_DOWN:
203
+ return gpio_mockup_apply_pull(chip, offset, 0);
204
+ default:
205
+ break;
206
+ }
207
+ return -ENOTSUPP;
112208 }
113209
114210 static int gpio_mockup_dirout(struct gpio_chip *gc,
....@@ -116,8 +212,10 @@
116212 {
117213 struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
118214
119
- gpio_mockup_set(gc, offset, value);
120
- chip->lines[offset].dir = GPIO_MOCKUP_DIR_OUT;
215
+ mutex_lock(&chip->lock);
216
+ chip->lines[offset].dir = GPIO_LINE_DIRECTION_OUT;
217
+ __gpio_mockup_set(chip, offset, value);
218
+ mutex_unlock(&chip->lock);
121219
122220 return 0;
123221 }
....@@ -126,7 +224,9 @@
126224 {
127225 struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
128226
129
- chip->lines[offset].dir = GPIO_MOCKUP_DIR_IN;
227
+ mutex_lock(&chip->lock);
228
+ chip->lines[offset].dir = GPIO_LINE_DIRECTION_IN;
229
+ mutex_unlock(&chip->lock);
130230
131231 return 0;
132232 }
....@@ -134,26 +234,64 @@
134234 static int gpio_mockup_get_direction(struct gpio_chip *gc, unsigned int offset)
135235 {
136236 struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
237
+ int direction;
137238
138
- return !chip->lines[offset].dir;
239
+ mutex_lock(&chip->lock);
240
+ direction = chip->lines[offset].dir;
241
+ mutex_unlock(&chip->lock);
242
+
243
+ return direction;
139244 }
140245
141246 static int gpio_mockup_to_irq(struct gpio_chip *gc, unsigned int offset)
142247 {
143248 struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
144249
145
- return irq_sim_irqnum(&chip->irqsim, offset);
250
+ return irq_create_mapping(chip->irq_sim_domain, offset);
146251 }
147252
148
-static ssize_t gpio_mockup_event_write(struct file *file,
149
- const char __user *usr_buf,
150
- size_t size, loff_t *ppos)
253
+static void gpio_mockup_free(struct gpio_chip *gc, unsigned int offset)
254
+{
255
+ struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
256
+
257
+ __gpio_mockup_set(chip, offset, chip->lines[offset].pull);
258
+}
259
+
260
+static ssize_t gpio_mockup_debugfs_read(struct file *file,
261
+ char __user *usr_buf,
262
+ size_t size, loff_t *ppos)
151263 {
152264 struct gpio_mockup_dbgfs_private *priv;
153265 struct gpio_mockup_chip *chip;
154266 struct seq_file *sfile;
155
- struct gpio_desc *desc;
267
+ struct gpio_chip *gc;
268
+ int val, cnt;
269
+ char buf[3];
270
+
271
+ if (*ppos != 0)
272
+ return 0;
273
+
274
+ sfile = file->private_data;
275
+ priv = sfile->private;
276
+ chip = priv->chip;
277
+ gc = &chip->gc;
278
+
279
+ val = gpio_mockup_get(gc, priv->offset);
280
+ cnt = snprintf(buf, sizeof(buf), "%d\n", val);
281
+
282
+ return simple_read_from_buffer(usr_buf, size, ppos, buf, cnt);
283
+}
284
+
285
+static ssize_t gpio_mockup_debugfs_write(struct file *file,
286
+ const char __user *usr_buf,
287
+ size_t size, loff_t *ppos)
288
+{
289
+ struct gpio_mockup_dbgfs_private *priv;
156290 int rv, val;
291
+ struct seq_file *sfile;
292
+
293
+ if (*ppos != 0)
294
+ return -EINVAL;
157295
158296 rv = kstrtoint_from_user(usr_buf, size, 0, &val);
159297 if (rv)
....@@ -163,32 +301,52 @@
163301
164302 sfile = file->private_data;
165303 priv = sfile->private;
166
- desc = priv->desc;
167
- chip = priv->chip;
168
-
169
- gpiod_set_value_cansleep(desc, val);
170
- irq_sim_fire(&chip->irqsim, priv->offset);
304
+ rv = gpio_mockup_apply_pull(priv->chip, priv->offset, val);
305
+ if (rv)
306
+ return rv;
171307
172308 return size;
173309 }
174310
175
-static int gpio_mockup_event_open(struct inode *inode, struct file *file)
311
+static int gpio_mockup_debugfs_open(struct inode *inode, struct file *file)
176312 {
177313 return single_open(file, NULL, inode->i_private);
178314 }
179315
180
-static const struct file_operations gpio_mockup_event_ops = {
316
+/*
317
+ * Each mockup chip is represented by a directory named after the chip's device
318
+ * name under /sys/kernel/debug/gpio-mockup/. Each line is represented by
319
+ * a file using the line's offset as the name under the chip's directory.
320
+ *
321
+ * Reading from the line's file yields the current *value*, writing to the
322
+ * line's file changes the current *pull*. Default pull for mockup lines is
323
+ * down.
324
+ *
325
+ * Examples:
326
+ * - when a line pulled down is requested in output mode and driven high, its
327
+ * value will return to 0 once it's released
328
+ * - when the line is requested in output mode and driven high, writing 0 to
329
+ * the corresponding debugfs file will change the pull to down but the
330
+ * reported value will still be 1 until the line is released
331
+ * - line requested in input mode always reports the same value as its pull
332
+ * configuration
333
+ * - when the line is requested in input mode and monitored for events, writing
334
+ * the same value to the debugfs file will be a noop, while writing the
335
+ * opposite value will generate a dummy interrupt with an appropriate edge
336
+ */
337
+static const struct file_operations gpio_mockup_debugfs_ops = {
181338 .owner = THIS_MODULE,
182
- .open = gpio_mockup_event_open,
183
- .write = gpio_mockup_event_write,
339
+ .open = gpio_mockup_debugfs_open,
340
+ .read = gpio_mockup_debugfs_read,
341
+ .write = gpio_mockup_debugfs_write,
184342 .llseek = no_llseek,
343
+ .release = single_release,
185344 };
186345
187346 static void gpio_mockup_debugfs_setup(struct device *dev,
188347 struct gpio_mockup_chip *chip)
189348 {
190349 struct gpio_mockup_dbgfs_private *priv;
191
- struct dentry *evfile, *link;
192350 struct gpio_chip *gc;
193351 const char *devname;
194352 char *name;
....@@ -198,83 +356,73 @@
198356 devname = dev_name(&gc->gpiodev->dev);
199357
200358 chip->dbg_dir = debugfs_create_dir(devname, gpio_mockup_dbg_dir);
201
- if (IS_ERR_OR_NULL(chip->dbg_dir))
202
- goto err;
203
-
204
- link = debugfs_create_symlink(gc->label, gpio_mockup_dbg_dir, devname);
205
- if (IS_ERR_OR_NULL(link))
206
- goto err;
207359
208360 for (i = 0; i < gc->ngpio; i++) {
209361 name = devm_kasprintf(dev, GFP_KERNEL, "%d", i);
210362 if (!name)
211
- goto err;
363
+ return;
212364
213365 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
214366 if (!priv)
215
- goto err;
367
+ return;
216368
217369 priv->chip = chip;
218370 priv->offset = i;
219371 priv->desc = &gc->gpiodev->descs[i];
220372
221
- evfile = debugfs_create_file(name, 0200, chip->dbg_dir, priv,
222
- &gpio_mockup_event_ops);
223
- if (IS_ERR_OR_NULL(evfile))
224
- goto err;
373
+ debugfs_create_file(name, 0600, chip->dbg_dir, priv,
374
+ &gpio_mockup_debugfs_ops);
225375 }
226
-
227
- return;
228
-
229
-err:
230
- dev_err(dev, "error creating debugfs event files\n");
231376 }
232377
233
-static int gpio_mockup_name_lines(struct device *dev,
234
- struct gpio_mockup_chip *chip)
378
+static void gpio_mockup_debugfs_cleanup(void *data)
235379 {
236
- struct gpio_chip *gc = &chip->gc;
237
- char **names;
238
- int i;
380
+ struct gpio_mockup_chip *chip = data;
239381
240
- names = devm_kcalloc(dev, gc->ngpio, sizeof(char *), GFP_KERNEL);
241
- if (!names)
242
- return -ENOMEM;
382
+ debugfs_remove_recursive(chip->dbg_dir);
383
+}
384
+
385
+static void gpio_mockup_dispose_mappings(void *data)
386
+{
387
+ struct gpio_mockup_chip *chip = data;
388
+ struct gpio_chip *gc = &chip->gc;
389
+ int i, irq;
243390
244391 for (i = 0; i < gc->ngpio; i++) {
245
- names[i] = devm_kasprintf(dev, GFP_KERNEL,
246
- "%s-%d", gc->label, i);
247
- if (!names[i])
248
- return -ENOMEM;
392
+ irq = irq_find_mapping(chip->irq_sim_domain, i);
393
+ if (irq)
394
+ irq_dispose_mapping(irq);
249395 }
250
-
251
- gc->names = (const char *const *)names;
252
-
253
- return 0;
254396 }
255397
256398 static int gpio_mockup_probe(struct platform_device *pdev)
257399 {
258
- struct gpio_mockup_platform_data *pdata;
259400 struct gpio_mockup_chip *chip;
260401 struct gpio_chip *gc;
261
- int rv, base, ngpio;
262402 struct device *dev;
263
- char *name;
403
+ const char *name;
404
+ int rv, base, i;
405
+ u16 ngpio;
264406
265407 dev = &pdev->dev;
266
- pdata = dev_get_platdata(dev);
267
- base = pdata->base;
268
- ngpio = pdata->ngpio;
408
+
409
+ rv = device_property_read_u32(dev, "gpio-base", &base);
410
+ if (rv)
411
+ base = -1;
412
+
413
+ rv = device_property_read_u16(dev, "nr-gpios", &ngpio);
414
+ if (rv)
415
+ return rv;
416
+
417
+ rv = device_property_read_string(dev, "chip-label", &name);
418
+ if (rv)
419
+ name = dev_name(dev);
269420
270421 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
271422 if (!chip)
272423 return -ENOMEM;
273424
274
- name = devm_kasprintf(dev, GFP_KERNEL, "%s-%c",
275
- pdev->name, pdata->index);
276
- if (!name)
277
- return -ENOMEM;
425
+ mutex_init(&chip->lock);
278426
279427 gc = &chip->gc;
280428 gc->base = base;
....@@ -284,40 +432,44 @@
284432 gc->parent = dev;
285433 gc->get = gpio_mockup_get;
286434 gc->set = gpio_mockup_set;
435
+ gc->get_multiple = gpio_mockup_get_multiple;
287436 gc->set_multiple = gpio_mockup_set_multiple;
288437 gc->direction_output = gpio_mockup_dirout;
289438 gc->direction_input = gpio_mockup_dirin;
290439 gc->get_direction = gpio_mockup_get_direction;
440
+ gc->set_config = gpio_mockup_set_config;
291441 gc->to_irq = gpio_mockup_to_irq;
442
+ gc->free = gpio_mockup_free;
292443
293444 chip->lines = devm_kcalloc(dev, gc->ngpio,
294445 sizeof(*chip->lines), GFP_KERNEL);
295446 if (!chip->lines)
296447 return -ENOMEM;
297448
298
- if (pdata->named_lines) {
299
- rv = gpio_mockup_name_lines(dev, chip);
300
- if (rv)
301
- return rv;
302
- }
449
+ for (i = 0; i < gc->ngpio; i++)
450
+ chip->lines[i].dir = GPIO_LINE_DIRECTION_IN;
303451
304
- rv = devm_irq_sim_init(dev, &chip->irqsim, gc->ngpio);
305
- if (rv < 0)
452
+ chip->irq_sim_domain = devm_irq_domain_create_sim(dev, NULL,
453
+ gc->ngpio);
454
+ if (IS_ERR(chip->irq_sim_domain))
455
+ return PTR_ERR(chip->irq_sim_domain);
456
+
457
+ rv = devm_add_action_or_reset(dev, gpio_mockup_dispose_mappings, chip);
458
+ if (rv)
306459 return rv;
307460
308461 rv = devm_gpiochip_add_data(dev, &chip->gc, chip);
309462 if (rv)
310463 return rv;
311464
312
- if (!IS_ERR_OR_NULL(gpio_mockup_dbg_dir))
313
- gpio_mockup_debugfs_setup(dev, chip);
465
+ gpio_mockup_debugfs_setup(dev, chip);
314466
315
- return 0;
467
+ return devm_add_action_or_reset(dev, gpio_mockup_debugfs_cleanup, chip);
316468 }
317469
318470 static struct platform_driver gpio_mockup_driver = {
319471 .driver = {
320
- .name = GPIO_MOCKUP_NAME,
472
+ .name = "gpio-mockup",
321473 },
322474 .probe = gpio_mockup_probe,
323475 };
....@@ -337,11 +489,79 @@
337489 }
338490 }
339491
492
+static __init char **gpio_mockup_make_line_names(const char *label,
493
+ unsigned int num_lines)
494
+{
495
+ unsigned int i;
496
+ char **names;
497
+
498
+ names = kcalloc(num_lines + 1, sizeof(char *), GFP_KERNEL);
499
+ if (!names)
500
+ return NULL;
501
+
502
+ for (i = 0; i < num_lines; i++) {
503
+ names[i] = kasprintf(GFP_KERNEL, "%s-%u", label, i);
504
+ if (!names[i]) {
505
+ kfree_strarray(names, i);
506
+ return NULL;
507
+ }
508
+ }
509
+
510
+ return names;
511
+}
512
+
513
+static int __init gpio_mockup_register_chip(int idx)
514
+{
515
+ struct property_entry properties[GPIO_MOCKUP_MAX_PROP];
516
+ struct platform_device_info pdevinfo;
517
+ struct platform_device *pdev;
518
+ char **line_names = NULL;
519
+ char chip_label[32];
520
+ int prop = 0, base;
521
+ u16 ngpio;
522
+
523
+ memset(properties, 0, sizeof(properties));
524
+ memset(&pdevinfo, 0, sizeof(pdevinfo));
525
+
526
+ snprintf(chip_label, sizeof(chip_label), "gpio-mockup-%c", idx + 'A');
527
+ properties[prop++] = PROPERTY_ENTRY_STRING("chip-label", chip_label);
528
+
529
+ base = gpio_mockup_range_base(idx);
530
+ if (base >= 0)
531
+ properties[prop++] = PROPERTY_ENTRY_U32("gpio-base", base);
532
+
533
+ ngpio = base < 0 ? gpio_mockup_range_ngpio(idx)
534
+ : gpio_mockup_range_ngpio(idx) - base;
535
+ properties[prop++] = PROPERTY_ENTRY_U16("nr-gpios", ngpio);
536
+
537
+ if (gpio_mockup_named_lines) {
538
+ line_names = gpio_mockup_make_line_names(chip_label, ngpio);
539
+ if (!line_names)
540
+ return -ENOMEM;
541
+
542
+ properties[prop++] = PROPERTY_ENTRY_STRING_ARRAY_LEN(
543
+ "gpio-line-names", line_names, ngpio);
544
+ }
545
+
546
+ pdevinfo.name = "gpio-mockup";
547
+ pdevinfo.id = idx;
548
+ pdevinfo.properties = properties;
549
+
550
+ pdev = platform_device_register_full(&pdevinfo);
551
+ kfree_strarray(line_names, ngpio);
552
+ if (IS_ERR(pdev)) {
553
+ pr_err("error registering device");
554
+ return PTR_ERR(pdev);
555
+ }
556
+
557
+ gpio_mockup_pdevs[idx] = pdev;
558
+
559
+ return 0;
560
+}
561
+
340562 static int __init gpio_mockup_init(void)
341563 {
342
- int i, num_chips, err = 0, index = 'A';
343
- struct gpio_mockup_platform_data pdata;
344
- struct platform_device *pdev;
564
+ int i, num_chips, err;
345565
346566 if ((gpio_mockup_num_ranges < 2) ||
347567 (gpio_mockup_num_ranges % 2) ||
....@@ -360,38 +580,23 @@
360580 return -EINVAL;
361581 }
362582
363
- gpio_mockup_dbg_dir = debugfs_create_dir("gpio-mockup-event", NULL);
364
- if (IS_ERR_OR_NULL(gpio_mockup_dbg_dir))
365
- gpio_mockup_err("error creating debugfs directory\n");
583
+ gpio_mockup_dbg_dir = debugfs_create_dir("gpio-mockup", NULL);
366584
367585 err = platform_driver_register(&gpio_mockup_driver);
368586 if (err) {
369
- gpio_mockup_err("error registering platform driver\n");
587
+ pr_err("error registering platform driver\n");
370588 debugfs_remove_recursive(gpio_mockup_dbg_dir);
371589 return err;
372590 }
373591
374592 for (i = 0; i < num_chips; i++) {
375
- pdata.index = index++;
376
- pdata.base = gpio_mockup_range_base(i);
377
- pdata.ngpio = pdata.base < 0
378
- ? gpio_mockup_range_ngpio(i)
379
- : gpio_mockup_range_ngpio(i) - pdata.base;
380
- pdata.named_lines = gpio_mockup_named_lines;
381
-
382
- pdev = platform_device_register_resndata(NULL,
383
- GPIO_MOCKUP_NAME,
384
- i, NULL, 0, &pdata,
385
- sizeof(pdata));
386
- if (IS_ERR(pdev)) {
387
- gpio_mockup_err("error registering device");
593
+ err = gpio_mockup_register_chip(i);
594
+ if (err) {
388595 platform_driver_unregister(&gpio_mockup_driver);
389596 gpio_mockup_unregister_pdevs();
390597 debugfs_remove_recursive(gpio_mockup_dbg_dir);
391
- return PTR_ERR(pdev);
598
+ return err;
392599 }
393
-
394
- gpio_mockup_pdevs[i] = pdev;
395600 }
396601
397602 return 0;
....@@ -399,9 +604,9 @@
399604
400605 static void __exit gpio_mockup_exit(void)
401606 {
607
+ gpio_mockup_unregister_pdevs();
402608 debugfs_remove_recursive(gpio_mockup_dbg_dir);
403609 platform_driver_unregister(&gpio_mockup_driver);
404
- gpio_mockup_unregister_pdevs();
405610 }
406611
407612 module_init(gpio_mockup_init);