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