1 /* Copyright (c) 2014 Samsung Electronics Co., Ltd */
3 #include <linux/gpio_debug.h>
4 #include <linux/version.h>
5 #include <linux/kernel.h>
6 #include <linux/module.h>
7 #include <linux/platform_device.h>
9 #include <linux/of_gpio.h>
10 #include <linux/gpio.h>
12 #include <linux/debugfs.h>
13 #include <linux/slab.h>
14 #include <linux/mutex.h>
16 struct gpio_debug_data
;
18 struct gpio_debug_event
{
21 struct gpio_debug_event_def def
;
22 struct gpio_debug_data
*data
;
26 struct gpio_debug_data
{
29 struct dentry
*gpio_debug_dir
;
30 struct dentry
*gpio_debug_events_dir
;
31 struct platform_device
*pdev
;
32 struct gpio_debug_event
*events
;
37 static struct gpio_debug_data debug_data
;
39 DEFINE_MUTEX(debug_lock
);
42 GPIO_DEBUG_TOGGLE_100
,
43 GPIO_DEBUG_TOGGLE_200
,
46 static struct gpio_debug_event_def debug_events_table
[] = {
47 [GPIO_DEBUG_TOGGLE_100
] = {
49 .description
= "Toggle the GPIO 100 times at initialisation",
51 [GPIO_DEBUG_TOGGLE_200
] = {
53 .description
= "Toggle the GPIO 200 times at initialisation",
57 static void gpio_debug_event(int gpio
, int state
)
60 gpio_set_value(gpio
, state
);
63 static void gpio_debug_event_exec(int event_id
, int state
)
65 if ((event_id
>= 0) && (event_id
< debug_data
.event_count
) && debug_data
.events
)
66 gpio_debug_event(debug_data
.events
[event_id
].gpio
, state
);
69 void gpio_debug_event_enter(int base
, int id
)
71 gpio_debug_event_exec(base
+ id
, 0);
74 void gpio_debug_event_exit(int base
, int id
)
76 gpio_debug_event_exec(base
+ id
, 1);
79 int gpio_debug_event_enabled(int base
, int id
)
81 int event_id
= base
+ id
;
83 if ((event_id
>= 0) &&
84 (event_id
< debug_data
.event_count
) &&
86 debug_data
.events
[event_id
].gpio
>= 0)
92 static int gpio_debug_event_link(struct gpio_debug_event
*event
, int gpio_index
)
94 struct gpio_debug_data
*data
= event
->data
;
96 if (gpio_index
>= data
->gpio_count
)
100 event
->gpio
= data
->gpios
[gpio_index
];
104 event
->gpio_idx
= gpio_index
;
109 static ssize_t
event_read(struct file
*file
, char __user
*user_buf
, size_t count
, loff_t
*ppos
)
112 struct gpio_debug_event
*event
= file
->f_inode
->i_private
;
116 mutex_lock(&debug_lock
);
118 pos
= snprintf(buf
, sizeof(buf
), "Description:\n%s\n\nEvent is mapped to GPIO index %d with number %d\n", event
->def
.description
, event
->gpio_idx
, event
->gpio
);
119 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
121 mutex_unlock(&debug_lock
);
126 static ssize_t
event_write(struct file
*file
, const char __user
*user_buf
, size_t count
, loff_t
*ppos
)
130 struct gpio_debug_event
*event
= file
->f_inode
->i_private
;
133 mutex_lock(&debug_lock
);
135 user_string
= kmalloc(count
+ 1, GFP_KERNEL
);
136 memory_read_from_buffer(user_string
, count
, ppos
, user_buf
, count
);
138 user_string
[count
] = '\0';
139 ret
= (ssize_t
)strnlen(user_string
, count
+ 1);
141 if (kstrtou32(user_string
, 10, &new_index
)) {
144 gpio_debug_event_link(event
, new_index
);
147 mutex_unlock(&debug_lock
);
152 static const struct file_operations event_ops
= {
154 .write
= event_write
,
157 static void create_event_file(struct gpio_debug_event
*event
)
159 struct gpio_debug_data
*data
= event
->data
;
161 if (data
&& data
->gpio_debug_events_dir
) {
162 event
->file
= debugfs_create_file(event
->def
.name
, 0660, data
->gpio_debug_events_dir
, event
, &event_ops
);
163 if (IS_ERR_OR_NULL(event
->file
)) {
165 pr_warn("%s: Could not create debugfs file for %s\n", __func__
, event
->def
.name
);
170 static void remove_event_file(struct gpio_debug_event
*event
)
172 if (event
&& event
->file
) {
173 debugfs_remove(event
->file
);
178 static void gpio_debug_init_event(struct gpio_debug_data
*data
, struct gpio_debug_event_def
*event
, struct gpio_debug_event
*event_save
)
180 event_save
->def
.description
= event
->description
;
181 event_save
->def
.name
= event
->name
;
182 event_save
->gpio
= -1;
183 event_save
->gpio_idx
= -1;
184 event_save
->data
= data
;
186 create_event_file(event_save
);
189 static void gpio_debug_destroy_event(struct gpio_debug_event
*event
)
191 remove_event_file(event
);
192 event
->def
.description
= NULL
;
193 event
->def
.name
= NULL
;
195 event
->gpio_idx
= -1;
199 int gpio_debug_event_list_register(struct gpio_debug_event_def
*events
, int event_count
)
201 struct gpio_debug_data
*data
= &debug_data
;
202 int start_index
= data
->event_count
;
203 struct gpio_debug_event
*new_events
;
204 int new_event_count
= data
->event_count
+ event_count
;
207 mutex_lock(&debug_lock
);
210 for (i
= 0; i
< data
->event_count
; i
++)
211 remove_event_file(&data
->events
[i
]);
213 new_events
= krealloc(data
->events
, new_event_count
* sizeof(struct gpio_debug_event
), GFP_KERNEL
);
215 pr_warn("%s: Could not expand for extra events\n", __func__
);
216 /* If krealloc fails, data->events is unchanged, so just exit */
219 data
->events
= new_events
;
220 for (i
= 0; i
< data
->event_count
; i
++)
221 create_event_file(&data
->events
[i
]);
223 data
->event_count
= new_event_count
;
225 for (i
= 0, j
= start_index
; (i
< event_count
) && (j
< data
->event_count
); i
++, j
++)
226 gpio_debug_init_event(data
, &events
[i
], &data
->events
[j
]);
228 mutex_unlock(&debug_lock
);
232 void gpio_debug_event_list_unregister(int base
, int event_count
)
235 struct gpio_debug_data
*data
= &debug_data
;
237 mutex_lock(&debug_lock
);
239 for (i
= base
; (i
< (event_count
+ base
)) && (i
< data
->event_count
); i
++)
240 gpio_debug_destroy_event(&data
->events
[i
]);
242 mutex_unlock(&debug_lock
);
245 static ssize_t
event_list_read(struct file
*file
, char __user
*user_buf
, size_t count
, loff_t
*ppos
)
251 struct gpio_debug_data
*data
= file
->f_inode
->i_private
;
252 struct device
*dev
= &data
->pdev
->dev
;
253 char headline
[] = " gpio event\n";
255 mutex_lock(&debug_lock
);
257 length
+= strlen(headline
);
259 for (i
= 0; i
< data
->event_count
; i
++)
260 if (data
->events
[i
].def
.name
)
261 length
+= strlen(data
->events
[i
].def
.name
) + 7;
262 length
++; /* Reserve space for NULL termination */
264 buf
= devm_kzalloc(dev
, length
, GFP_KERNEL
);
266 snprintf(buf
, length
, "%s", headline
);
267 for (i
= 0; i
< data
->event_count
; i
++)
268 if (data
->events
[i
].data
) {
269 if (data
->events
[i
].gpio_idx
>= 0)
270 snprintf(buf
, length
, "%s%5d %s\n", buf
, data
->events
[i
].gpio_idx
, data
->events
[i
].def
.name
);
272 snprintf(buf
, length
, "%s %s\n", buf
, data
->events
[i
].def
.name
);
274 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, length
);
275 devm_kfree(dev
, buf
);
277 mutex_unlock(&debug_lock
);
282 static const struct file_operations event_list_ops
= {
283 .read
= event_list_read
,
286 static ssize_t
num_gpios_read(struct file
*file
, char __user
*user_buf
, size_t count
, loff_t
*ppos
)
289 struct gpio_debug_data
*data
= file
->f_inode
->i_private
;
293 pos
= snprintf(buf
, sizeof(buf
), "%d\n", data
->gpio_count
);
294 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
298 static const struct file_operations num_gpios_ops
= {
299 .read
= num_gpios_read
,
302 static int gpio_debug_probe(struct platform_device
*pdev
)
304 struct device_node
*np
= pdev
->dev
.of_node
;
305 struct device
*dev
= &pdev
->dev
;
307 struct gpio_debug_data
*data
= &debug_data
;
310 mutex_lock(&debug_lock
);
312 count
= of_gpio_count(np
);
314 count
= 0; /* Errors register as no GPIOs available */
316 data
->gpio_count
= count
;
321 data
->gpios
= devm_kzalloc(dev
, count
* sizeof(int), GFP_KERNEL
);
322 for (i
= 0; i
< count
; i
++) {
323 data
->gpios
[i
] = of_get_gpio(np
, i
);
324 dev_info(dev
, "GPIO at index %d has number %d\n", i
, data
->gpios
[i
]);
325 if (gpio_is_valid(data
->gpios
[i
])) {
328 sprintf(label
, "debug-gpio-%d", i
);
329 dev_info(dev
, "Requesting GPIO %d index %d with label %s\n", data
->gpios
[i
], i
, label
);
330 if (devm_gpio_request(dev
, data
->gpios
[i
], label
))
331 dev_err(dev
, "GPIO [%d] request failed\n", data
->gpios
[i
]);
332 gpio_set_value(data
->gpios
[i
], 1);
334 dev_warn(dev
, "GPIO at index %d is invalid\n", i
);
338 data
->gpio_debug_dir
= debugfs_create_dir("gpio_debug", NULL
);
339 if (!IS_ERR_OR_NULL(data
->gpio_debug_dir
)) {
340 data
->gpio_debug_events_dir
= debugfs_create_dir("events", data
->gpio_debug_dir
);
341 if (IS_ERR_OR_NULL(data
->gpio_debug_events_dir
)) {
342 data
->gpio_debug_events_dir
= NULL
;
343 dev_err(dev
, "Debugfs cannot create subdir\n");
345 debugfs_create_file("event_list", 0440, data
->gpio_debug_dir
, data
, &event_list_ops
);
346 debugfs_create_file("num_gpios", 0440, data
->gpio_debug_dir
, data
, &num_gpios_ops
);
348 data
->gpio_debug_dir
= NULL
;
349 dev_warn(dev
, "Debugfs is not available, configuration of GPIO debug is not possible\n");
352 for (i
= 0; i
< data
->event_count
; i
++)
353 create_event_file(&data
->events
[i
]);
355 mutex_unlock(&debug_lock
);
357 data
->event_base
= gpio_debug_event_list_register(debug_events_table
, ARRAY_SIZE(debug_events_table
));
359 for (i
= 0; i
< count
; i
++) {
360 gpio_debug_event_link(&data
->events
[data
->event_base
+ GPIO_DEBUG_TOGGLE_100
], i
);
361 for (j
= 0; j
< 100; j
++) {
362 gpio_debug_event_enter(data
->event_base
, GPIO_DEBUG_TOGGLE_100
);
363 gpio_debug_event_exit(data
->event_base
, GPIO_DEBUG_TOGGLE_100
);
366 gpio_debug_event_link(&data
->events
[data
->event_base
+ GPIO_DEBUG_TOGGLE_100
], -1);
368 for (i
= 0; i
< count
; i
++) {
369 gpio_debug_event_link(&data
->events
[data
->event_base
+ GPIO_DEBUG_TOGGLE_200
], i
);
370 for (j
= 0; j
< 200; j
++) {
371 gpio_debug_event_enter(data
->event_base
, GPIO_DEBUG_TOGGLE_200
);
372 gpio_debug_event_exit(data
->event_base
, GPIO_DEBUG_TOGGLE_200
);
375 gpio_debug_event_link(&data
->events
[data
->event_base
+ GPIO_DEBUG_TOGGLE_200
], -1);
380 static int gpio_debug_remove(struct platform_device
*pdev
)
382 struct device
*dev
= &pdev
->dev
;
383 struct gpio_debug_data
*data
= &debug_data
;
385 mutex_lock(&debug_lock
);
386 debugfs_remove_recursive(data
->gpio_debug_dir
);
387 data
->gpio_debug_dir
= NULL
;
388 data
->gpio_debug_events_dir
= NULL
;
393 for (i
= 0; i
< data
->gpio_count
; i
++)
394 if (gpio_is_valid(data
->gpios
[i
]))
395 devm_gpio_free(dev
, data
->gpios
[i
]);
396 devm_kfree(dev
, data
->gpios
);
398 data
->gpio_count
= 0;
403 data
->event_count
= 0;
404 mutex_unlock(&debug_lock
);
409 static const struct of_device_id gpio_debug_match
[] = {
410 { .compatible
= "samsung,gpio-debug", },
413 MODULE_DEVICE_TABLE(of
, gpio_debug_match
);
415 static struct platform_driver gpio_debug_driver
= {
416 .probe
= gpio_debug_probe
,
417 .remove
= gpio_debug_remove
,
419 .name
= "gpio_debug",
420 .of_match_table
= gpio_debug_match
,
423 module_platform_driver(gpio_debug_driver
);
425 MODULE_DESCRIPTION("GPIO Debug framework");
426 MODULE_AUTHOR("Samsung Electronics Co., Ltd");
427 MODULE_LICENSE("GPL and additional rights");