1*abcc2f3cSThomas Zimmermann // SPDX-License-Identifier: GPL-2.0
2*abcc2f3cSThomas Zimmermann 
3*abcc2f3cSThomas Zimmermann #include <linux/proc_fs.h>
4*abcc2f3cSThomas Zimmermann 
5*abcc2f3cSThomas Zimmermann #include "fb_internal.h"
6*abcc2f3cSThomas Zimmermann 
7*abcc2f3cSThomas Zimmermann static struct proc_dir_entry *fb_proc_dir_entry;
8*abcc2f3cSThomas Zimmermann 
fb_seq_start(struct seq_file * m,loff_t * pos)9*abcc2f3cSThomas Zimmermann static void *fb_seq_start(struct seq_file *m, loff_t *pos)
10*abcc2f3cSThomas Zimmermann {
11*abcc2f3cSThomas Zimmermann 	mutex_lock(&registration_lock);
12*abcc2f3cSThomas Zimmermann 
13*abcc2f3cSThomas Zimmermann 	return (*pos < FB_MAX) ? pos : NULL;
14*abcc2f3cSThomas Zimmermann }
15*abcc2f3cSThomas Zimmermann 
fb_seq_stop(struct seq_file * m,void * v)16*abcc2f3cSThomas Zimmermann static void fb_seq_stop(struct seq_file *m, void *v)
17*abcc2f3cSThomas Zimmermann {
18*abcc2f3cSThomas Zimmermann 	mutex_unlock(&registration_lock);
19*abcc2f3cSThomas Zimmermann }
20*abcc2f3cSThomas Zimmermann 
fb_seq_next(struct seq_file * m,void * v,loff_t * pos)21*abcc2f3cSThomas Zimmermann static void *fb_seq_next(struct seq_file *m, void *v, loff_t *pos)
22*abcc2f3cSThomas Zimmermann {
23*abcc2f3cSThomas Zimmermann 	(*pos)++;
24*abcc2f3cSThomas Zimmermann 
25*abcc2f3cSThomas Zimmermann 	return (*pos < FB_MAX) ? pos : NULL;
26*abcc2f3cSThomas Zimmermann }
27*abcc2f3cSThomas Zimmermann 
fb_seq_show(struct seq_file * m,void * v)28*abcc2f3cSThomas Zimmermann static int fb_seq_show(struct seq_file *m, void *v)
29*abcc2f3cSThomas Zimmermann {
30*abcc2f3cSThomas Zimmermann 	int i = *(loff_t *)v;
31*abcc2f3cSThomas Zimmermann 	struct fb_info *fi = registered_fb[i];
32*abcc2f3cSThomas Zimmermann 
33*abcc2f3cSThomas Zimmermann 	if (fi)
34*abcc2f3cSThomas Zimmermann 		seq_printf(m, "%d %s\n", fi->node, fi->fix.id);
35*abcc2f3cSThomas Zimmermann 
36*abcc2f3cSThomas Zimmermann 	return 0;
37*abcc2f3cSThomas Zimmermann }
38*abcc2f3cSThomas Zimmermann 
39*abcc2f3cSThomas Zimmermann static const struct seq_operations __maybe_unused fb_proc_seq_ops = {
40*abcc2f3cSThomas Zimmermann 	.start	= fb_seq_start,
41*abcc2f3cSThomas Zimmermann 	.stop	= fb_seq_stop,
42*abcc2f3cSThomas Zimmermann 	.next	= fb_seq_next,
43*abcc2f3cSThomas Zimmermann 	.show	= fb_seq_show,
44*abcc2f3cSThomas Zimmermann };
45*abcc2f3cSThomas Zimmermann 
fb_init_procfs(void)46*abcc2f3cSThomas Zimmermann int fb_init_procfs(void)
47*abcc2f3cSThomas Zimmermann {
48*abcc2f3cSThomas Zimmermann 	struct proc_dir_entry *proc;
49*abcc2f3cSThomas Zimmermann 
50*abcc2f3cSThomas Zimmermann 	proc = proc_create_seq("fb", 0, NULL, &fb_proc_seq_ops);
51*abcc2f3cSThomas Zimmermann 	if (!proc)
52*abcc2f3cSThomas Zimmermann 		return -ENOMEM;
53*abcc2f3cSThomas Zimmermann 
54*abcc2f3cSThomas Zimmermann 	fb_proc_dir_entry = proc;
55*abcc2f3cSThomas Zimmermann 
56*abcc2f3cSThomas Zimmermann 	return 0;
57*abcc2f3cSThomas Zimmermann }
58*abcc2f3cSThomas Zimmermann 
fb_cleanup_procfs(void)59*abcc2f3cSThomas Zimmermann void fb_cleanup_procfs(void)
60*abcc2f3cSThomas Zimmermann {
61*abcc2f3cSThomas Zimmermann 	proc_remove(fb_proc_dir_entry);
62*abcc2f3cSThomas Zimmermann }
63