rk: ion: change ion's debug node for other r/w
[firefly-linux-kernel-4.4.55.git] / drivers / staging / dgrp / dgrp_sysfs.c
1 /*
2  * Copyright 2004 Digi International (www.digi.com)
3  *      Scott H Kilau <Scott_Kilau at digi dot com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2, or (at your option)
8  * any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
12  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13  * PURPOSE.  See the GNU General Public License for more details.
14  *
15  */
16
17 #include "dgrp_common.h"
18
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/ctype.h>
22 #include <linux/string.h>
23 #include <linux/serial_reg.h>
24 #include <linux/pci.h>
25 #include <linux/kdev_t.h>
26
27
28 #define PORTSERVER_DIVIDEND 1843200
29 #define SERIAL_TYPE_NORMAL      1
30 #define SERIAL_TYPE_CALLOUT     2
31 #define SERIAL_TYPE_XPRINT      3
32
33
34 static struct class *dgrp_class;
35 static struct device *dgrp_class_nodes_dev;
36 static struct device *dgrp_class_global_settings_dev;
37
38
39 static ssize_t dgrp_class_version_show(struct class *class,
40                                        struct class_attribute *attr, char *buf)
41 {
42         return snprintf(buf, PAGE_SIZE, "%s\n", DIGI_VERSION);
43 }
44 static CLASS_ATTR(driver_version, 0400, dgrp_class_version_show, NULL);
45
46
47 static ssize_t dgrp_class_register_with_sysfs_show(struct device *c,
48                                                    struct device_attribute *attr,
49                                                    char *buf)
50 {
51         return snprintf(buf, PAGE_SIZE, "1\n");
52 }
53 static DEVICE_ATTR(register_with_sysfs, 0400,
54                    dgrp_class_register_with_sysfs_show, NULL);
55
56
57 static ssize_t dgrp_class_pollrate_show(struct device *c,
58                                         struct device_attribute *attr,
59                                         char *buf)
60 {
61         return snprintf(buf, PAGE_SIZE, "%d\n", dgrp_poll_tick);
62 }
63
64 static ssize_t dgrp_class_pollrate_store(struct device *c,
65                                          struct device_attribute *attr,
66                                          const char *buf, size_t count)
67 {
68         sscanf(buf, "0x%x\n", &dgrp_poll_tick);
69         return count;
70 }
71 static DEVICE_ATTR(pollrate, 0600, dgrp_class_pollrate_show,
72                    dgrp_class_pollrate_store);
73
74 static struct attribute *dgrp_sysfs_global_settings_entries[] = {
75         &dev_attr_pollrate.attr,
76         &dev_attr_register_with_sysfs.attr,
77         NULL
78 };
79
80
81 static struct attribute_group dgrp_global_settings_attribute_group = {
82         .name = NULL,
83         .attrs = dgrp_sysfs_global_settings_entries,
84 };
85
86
87
88 int dgrp_create_class_sysfs_files(void)
89 {
90         int ret = 0;
91         int max_majors = 1U << (32 - MINORBITS);
92
93         dgrp_class = class_create(THIS_MODULE, "digi_realport");
94         if (IS_ERR(dgrp_class))
95                 return PTR_ERR(dgrp_class);
96         ret = class_create_file(dgrp_class, &class_attr_driver_version);
97         if (ret)
98                 goto err_class;
99
100         dgrp_class_global_settings_dev = device_create(dgrp_class, NULL,
101                 MKDEV(0, max_majors + 1), NULL, "driver_settings");
102         if (IS_ERR(dgrp_class_global_settings_dev)) {
103                 ret = PTR_ERR(dgrp_class_global_settings_dev);
104                 goto err_file;
105         }
106         ret = sysfs_create_group(&dgrp_class_global_settings_dev->kobj,
107                 &dgrp_global_settings_attribute_group);
108         if (ret) {
109                 pr_alert("%s: failed to create sysfs global settings device attributes.\n",
110                         __func__);
111                 goto err_dev1;
112         }
113
114         dgrp_class_nodes_dev = device_create(dgrp_class, NULL,
115                 MKDEV(0, max_majors + 2), NULL, "nodes");
116         if (IS_ERR(dgrp_class_nodes_dev)) {
117                 ret = PTR_ERR(dgrp_class_nodes_dev);
118                 goto err_group;
119         }
120
121         return 0;
122 err_group:
123         sysfs_remove_group(&dgrp_class_global_settings_dev->kobj,
124                 &dgrp_global_settings_attribute_group);
125 err_dev1:
126         device_destroy(dgrp_class, MKDEV(0, max_majors + 1));
127 err_file:
128         class_remove_file(dgrp_class, &class_attr_driver_version);
129 err_class:
130         class_destroy(dgrp_class);
131         return ret;
132 }
133
134
135 void dgrp_remove_class_sysfs_files(void)
136 {
137         struct nd_struct *nd;
138         int max_majors = 1U << (32 - MINORBITS);
139
140         list_for_each_entry(nd, &nd_struct_list, list)
141                 dgrp_remove_node_class_sysfs_files(nd);
142
143         sysfs_remove_group(&dgrp_class_global_settings_dev->kobj,
144                 &dgrp_global_settings_attribute_group);
145
146         class_remove_file(dgrp_class, &class_attr_driver_version);
147
148         device_destroy(dgrp_class, MKDEV(0, max_majors + 1));
149         device_destroy(dgrp_class, MKDEV(0, max_majors + 2));
150         class_destroy(dgrp_class);
151 }
152
153 static ssize_t dgrp_node_state_show(struct device *c,
154                                     struct device_attribute *attr, char *buf)
155 {
156         struct nd_struct *nd;
157
158         if (!c)
159                 return 0;
160         nd = (struct nd_struct *) dev_get_drvdata(c);
161         if (!nd)
162                 return 0;
163
164         return snprintf(buf, PAGE_SIZE, "%s\n", ND_STATE_STR(nd->nd_state));
165 }
166
167 static DEVICE_ATTR(state, 0600, dgrp_node_state_show, NULL);
168
169 static ssize_t dgrp_node_description_show(struct device *c,
170                                           struct device_attribute *attr,
171                                           char *buf)
172 {
173         struct nd_struct *nd;
174
175         if (!c)
176                 return 0;
177         nd = (struct nd_struct *) dev_get_drvdata(c);
178         if (!nd)
179                 return 0;
180
181         if (nd->nd_state == NS_READY)
182                 return snprintf(buf, PAGE_SIZE, "%s\n", nd->nd_ps_desc);
183         return 0;
184 }
185 static DEVICE_ATTR(description_info, 0600, dgrp_node_description_show, NULL);
186
187 static ssize_t dgrp_node_hw_version_show(struct device *c,
188                                          struct device_attribute *attr,
189                                          char *buf)
190 {
191         struct nd_struct *nd;
192
193         if (!c)
194                 return 0;
195         nd = (struct nd_struct *) dev_get_drvdata(c);
196         if (!nd)
197                 return 0;
198
199         if (nd->nd_state == NS_READY)
200                 return snprintf(buf, PAGE_SIZE, "%d.%d\n",
201                                 (nd->nd_hw_ver >> 8) & 0xff,
202                                 nd->nd_hw_ver & 0xff);
203
204         return 0;
205 }
206 static DEVICE_ATTR(hw_version_info, 0600, dgrp_node_hw_version_show, NULL);
207
208 static ssize_t dgrp_node_hw_id_show(struct device *c,
209                                     struct device_attribute *attr, char *buf)
210 {
211         struct nd_struct *nd;
212
213         if (!c)
214                 return 0;
215         nd = (struct nd_struct *) dev_get_drvdata(c);
216         if (!nd)
217                 return 0;
218
219
220         if (nd->nd_state == NS_READY)
221                 return snprintf(buf, PAGE_SIZE, "%d\n", nd->nd_hw_id);
222         return 0;
223 }
224 static DEVICE_ATTR(hw_id_info, 0600, dgrp_node_hw_id_show, NULL);
225
226 static ssize_t dgrp_node_sw_version_show(struct device *c,
227                                          struct device_attribute *attr,
228                                          char *buf)
229 {
230         struct nd_struct *nd;
231
232         if (!c)
233                 return 0;
234
235         nd = (struct nd_struct *) dev_get_drvdata(c);
236         if (!nd)
237                 return 0;
238
239         if (nd->nd_state == NS_READY)
240                 return snprintf(buf, PAGE_SIZE, "%d.%d\n",
241                                 (nd->nd_sw_ver >> 8) & 0xff,
242                                 nd->nd_sw_ver & 0xff);
243
244         return 0;
245 }
246 static DEVICE_ATTR(sw_version_info, 0600, dgrp_node_sw_version_show, NULL);
247
248
249 static struct attribute *dgrp_sysfs_node_entries[] = {
250         &dev_attr_state.attr,
251         &dev_attr_description_info.attr,
252         &dev_attr_hw_version_info.attr,
253         &dev_attr_hw_id_info.attr,
254         &dev_attr_sw_version_info.attr,
255         NULL
256 };
257
258
259 static struct attribute_group dgrp_node_attribute_group = {
260         .name = NULL,
261         .attrs = dgrp_sysfs_node_entries,
262 };
263
264
265 void dgrp_create_node_class_sysfs_files(struct nd_struct *nd)
266 {
267         int ret;
268         char name[10];
269
270         if (nd->nd_ID)
271                 ID_TO_CHAR(nd->nd_ID, name);
272         else
273                 sprintf(name, "node%ld", nd->nd_major);
274
275         nd->nd_class_dev = device_create(dgrp_class, dgrp_class_nodes_dev,
276                 MKDEV(0, nd->nd_major), NULL, name);
277
278         ret = sysfs_create_group(&nd->nd_class_dev->kobj,
279                                  &dgrp_node_attribute_group);
280
281         if (ret) {
282                 pr_alert("%s: failed to create sysfs node device attributes.\n",
283                         __func__);
284                 sysfs_remove_group(&nd->nd_class_dev->kobj,
285                                    &dgrp_node_attribute_group);
286                 return;
287         }
288
289         dev_set_drvdata(nd->nd_class_dev, nd);
290
291 }
292
293
294 void dgrp_remove_node_class_sysfs_files(struct nd_struct *nd)
295 {
296         if (nd->nd_class_dev) {
297                 sysfs_remove_group(&nd->nd_class_dev->kobj,
298                                    &dgrp_node_attribute_group);
299
300                 device_destroy(dgrp_class, MKDEV(0, nd->nd_major));
301                 nd->nd_class_dev = NULL;
302         }
303 }
304
305
306
307 static ssize_t dgrp_tty_state_show(struct device *d,
308                                    struct device_attribute *attr, char *buf)
309 {
310         struct un_struct *un;
311
312         if (!d)
313                 return 0;
314         un = (struct un_struct *) dev_get_drvdata(d);
315         if (!un)
316                 return 0;
317
318         return snprintf(buf, PAGE_SIZE, "%s\n",
319                         un->un_open_count ? "Open" : "Closed");
320 }
321 static DEVICE_ATTR(state_info, 0600, dgrp_tty_state_show, NULL);
322
323 static ssize_t dgrp_tty_baud_show(struct device *d,
324                                   struct device_attribute *attr, char *buf)
325 {
326         struct ch_struct *ch;
327         struct un_struct *un;
328
329         if (!d)
330                 return 0;
331         un = (struct un_struct *) dev_get_drvdata(d);
332         if (!un)
333                 return 0;
334         ch = un->un_ch;
335         if (!ch)
336                 return 0;
337         return snprintf(buf, PAGE_SIZE, "%d\n",
338                 un->un_open_count ? (PORTSERVER_DIVIDEND / ch->ch_s_brate) : 0);
339 }
340 static DEVICE_ATTR(baud_info, 0400, dgrp_tty_baud_show, NULL);
341
342
343 static ssize_t dgrp_tty_msignals_show(struct device *d,
344                                       struct device_attribute *attr, char *buf)
345 {
346         struct ch_struct *ch;
347         struct un_struct *un;
348
349         if (!d)
350                 return 0;
351         un = (struct un_struct *) dev_get_drvdata(d);
352         if (!un)
353                 return 0;
354         ch = un->un_ch;
355         if (!ch)
356                 return 0;
357
358         if (ch->ch_open_count) {
359                 return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
360                         (ch->ch_s_mlast & DM_RTS) ? "RTS" : "",
361                         (ch->ch_s_mlast & DM_CTS) ? "CTS" : "",
362                         (ch->ch_s_mlast & DM_DTR) ? "DTR" : "",
363                         (ch->ch_s_mlast & DM_DSR) ? "DSR" : "",
364                         (ch->ch_s_mlast & DM_CD) ? "DCD" : "",
365                         (ch->ch_s_mlast & DM_RI)  ? "RI"  : "");
366         }
367         return 0;
368 }
369 static DEVICE_ATTR(msignals_info, 0400, dgrp_tty_msignals_show, NULL);
370
371
372 static ssize_t dgrp_tty_iflag_show(struct device *d,
373                                    struct device_attribute *attr, char *buf)
374 {
375         struct ch_struct *ch;
376         struct un_struct *un;
377
378         if (!d)
379                 return 0;
380         un = (struct un_struct *) dev_get_drvdata(d);
381         if (!un)
382                 return 0;
383         ch = un->un_ch;
384         if (!ch)
385                 return 0;
386         return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_iflag);
387 }
388 static DEVICE_ATTR(iflag_info, 0600, dgrp_tty_iflag_show, NULL);
389
390
391 static ssize_t dgrp_tty_cflag_show(struct device *d,
392                                    struct device_attribute *attr, char *buf)
393 {
394         struct ch_struct *ch;
395         struct un_struct *un;
396
397         if (!d)
398                 return 0;
399         un = (struct un_struct *) dev_get_drvdata(d);
400         if (!un)
401                 return 0;
402         ch = un->un_ch;
403         if (!ch)
404                 return 0;
405         return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_cflag);
406 }
407 static DEVICE_ATTR(cflag_info, 0600, dgrp_tty_cflag_show, NULL);
408
409
410 static ssize_t dgrp_tty_oflag_show(struct device *d,
411                                    struct device_attribute *attr, char *buf)
412 {
413         struct ch_struct *ch;
414         struct un_struct *un;
415
416         if (!d)
417                 return 0;
418         un = (struct un_struct *) dev_get_drvdata(d);
419         if (!un)
420                 return 0;
421         ch = un->un_ch;
422         if (!ch)
423                 return 0;
424         return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_oflag);
425 }
426 static DEVICE_ATTR(oflag_info, 0600, dgrp_tty_oflag_show, NULL);
427
428
429 static ssize_t dgrp_tty_digi_flag_show(struct device *d,
430                                        struct device_attribute *attr, char *buf)
431 {
432         struct ch_struct *ch;
433         struct un_struct *un;
434
435         if (!d)
436                 return 0;
437         un = (struct un_struct *) dev_get_drvdata(d);
438         if (!un)
439                 return 0;
440         ch = un->un_ch;
441         if (!ch)
442                 return 0;
443         return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
444 }
445 static DEVICE_ATTR(digi_flag_info, 0600, dgrp_tty_digi_flag_show, NULL);
446
447
448 static ssize_t dgrp_tty_rxcount_show(struct device *d,
449                                      struct device_attribute *attr, char *buf)
450 {
451         struct ch_struct *ch;
452         struct un_struct *un;
453
454         if (!d)
455                 return 0;
456         un = (struct un_struct *) dev_get_drvdata(d);
457         if (!un)
458                 return 0;
459         ch = un->un_ch;
460         if (!ch)
461                 return 0;
462         return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_rxcount);
463 }
464 static DEVICE_ATTR(rxcount_info, 0600, dgrp_tty_rxcount_show, NULL);
465
466
467 static ssize_t dgrp_tty_txcount_show(struct device *d,
468                                      struct device_attribute *attr, char *buf)
469 {
470         struct ch_struct *ch;
471         struct un_struct *un;
472
473         if (!d)
474                 return 0;
475         un = (struct un_struct *) dev_get_drvdata(d);
476         if (!un)
477                 return 0;
478         ch = un->un_ch;
479         if (!ch)
480                 return 0;
481         return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_txcount);
482 }
483 static DEVICE_ATTR(txcount_info, 0600, dgrp_tty_txcount_show, NULL);
484
485
486 static ssize_t dgrp_tty_name_show(struct device *d,
487                                   struct device_attribute *attr, char *buf)
488 {
489         struct nd_struct *nd;
490         struct ch_struct *ch;
491         struct un_struct *un;
492         char name[10];
493
494         if (!d)
495                 return 0;
496         un = (struct un_struct *) dev_get_drvdata(d);
497         if (!un)
498                 return 0;
499         ch = un->un_ch;
500         if (!ch)
501                 return 0;
502         nd = ch->ch_nd;
503         if (!nd)
504                 return 0;
505
506         ID_TO_CHAR(nd->nd_ID, name);
507
508         return snprintf(buf, PAGE_SIZE, "%s%s%02d\n",
509                 un->un_type == SERIAL_TYPE_XPRINT ? "pr" : "tty",
510                 name, ch->ch_portnum);
511 }
512 static DEVICE_ATTR(custom_name, 0600, dgrp_tty_name_show, NULL);
513
514
515 static struct attribute *dgrp_sysfs_tty_entries[] = {
516         &dev_attr_state_info.attr,
517         &dev_attr_baud_info.attr,
518         &dev_attr_msignals_info.attr,
519         &dev_attr_iflag_info.attr,
520         &dev_attr_cflag_info.attr,
521         &dev_attr_oflag_info.attr,
522         &dev_attr_digi_flag_info.attr,
523         &dev_attr_rxcount_info.attr,
524         &dev_attr_txcount_info.attr,
525         &dev_attr_custom_name.attr,
526         NULL
527 };
528
529
530 static struct attribute_group dgrp_tty_attribute_group = {
531         .name = NULL,
532         .attrs = dgrp_sysfs_tty_entries,
533 };
534
535
536 void dgrp_create_tty_sysfs(struct un_struct *un, struct device *c)
537 {
538         int ret;
539
540         ret = sysfs_create_group(&c->kobj, &dgrp_tty_attribute_group);
541         if (ret) {
542                 pr_alert("%s: failed to create sysfs tty device attributes.\n",
543                         __func__);
544                 sysfs_remove_group(&c->kobj, &dgrp_tty_attribute_group);
545                 return;
546         }
547
548         dev_set_drvdata(c, un);
549
550 }
551
552
553 void dgrp_remove_tty_sysfs(struct device *c)
554 {
555         sysfs_remove_group(&c->kobj, &dgrp_tty_attribute_group);
556 }