1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/kernel.h>
33#include <linux/fs.h>
34#include <linux/errno.h>
35#include <linux/sched.h>
36#include <linux/slab.h>
37#include <linux/ioport.h>
38#include <linux/interrupt.h>
39#include <linux/spinlock.h>
40#include <linux/mutex.h>
41#include <linux/timer.h>
42#include <linux/sysfs.h>
43#include <linux/device.h>
44#include <linux/miscdevice.h>
45#include <linux/platform_device.h>
46#include <asm/io.h>
47#include <asm/uaccess.h>
48
49MODULE_AUTHOR("Sebastien Bouchard <sebastien.bouchard@ca.kontron.com>");
50MODULE_LICENSE("GPL");
51
52
53#define RESET_ON 0x00
54#define RESET_OFF 0x01
55
56
57#define NORMAL_MODE 0x00
58#define HOLDOVER_MODE 0x10
59#define FREERUN_MODE 0x20
60
61
62#define FILTER_6HZ 0x04
63#define FILTER_12HZ 0x00
64
65
66#define REF_CLK1_8kHz 0x00
67#define REF_CLK2_19_44MHz 0x02
68
69
70#define PRIMARY_CLOCK 0x00
71#define SECONDARY_CLOCK 0x01
72
73
74#define CLK_8kHz 0xff
75#define CLK_16_384MHz 0xfb
76
77#define CLK_1_544MHz 0x00
78#define CLK_2_048MHz 0x01
79#define CLK_4_096MHz 0x02
80#define CLK_6_312MHz 0x03
81#define CLK_8_192MHz 0x04
82#define CLK_19_440MHz 0x06
83
84#define CLK_8_592MHz 0x08
85#define CLK_11_184MHz 0x09
86#define CLK_34_368MHz 0x0b
87#define CLK_44_736MHz 0x0a
88
89
90#define AMC_B1 0
91#define AMC_B2 1
92
93
94#define HW_ENABLE 0x80
95#define HW_DISABLE 0x00
96
97
98#define PLL_HOLDOVER 0x40
99#define LOST_CLOCK 0x00
100
101
102#define UNLOCK_MASK 0x10
103#define HOLDOVER_MASK 0x20
104#define SEC_LOST_MASK 0x40
105#define PRI_LOST_MASK 0x80
106
107
108
109#define PRI_LOS_01_MASK 0x01
110#define PRI_LOS_10_MASK 0x02
111
112#define SEC_LOS_01_MASK 0x04
113#define SEC_LOS_10_MASK 0x08
114
115#define HOLDOVER_01_MASK 0x10
116#define HOLDOVER_10_MASK 0x20
117
118#define UNLOCK_01_MASK 0x40
119#define UNLOCK_10_MASK 0x80
120
121struct tlclk_alarms {
122 __u32 lost_clocks;
123 __u32 lost_primary_clock;
124 __u32 lost_secondary_clock;
125 __u32 primary_clock_back;
126 __u32 secondary_clock_back;
127 __u32 switchover_primary;
128 __u32 switchover_secondary;
129 __u32 pll_holdover;
130 __u32 pll_end_holdover;
131 __u32 pll_lost_sync;
132 __u32 pll_sync;
133};
134
135#define TLCLK_BASE 0xa08
136#define TLCLK_REG0 TLCLK_BASE
137#define TLCLK_REG1 (TLCLK_BASE+1)
138#define TLCLK_REG2 (TLCLK_BASE+2)
139#define TLCLK_REG3 (TLCLK_BASE+3)
140#define TLCLK_REG4 (TLCLK_BASE+4)
141#define TLCLK_REG5 (TLCLK_BASE+5)
142#define TLCLK_REG6 (TLCLK_BASE+6)
143#define TLCLK_REG7 (TLCLK_BASE+7)
144
145#define SET_PORT_BITS(port, mask, val) outb(((inb(port) & mask) | val), port)
146
147
148#define TLCLK_MAJOR 0
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182static unsigned int telclk_interrupt;
183
184static int int_events;
185static int got_event;
186
187static void switchover_timeout(unsigned long data);
188static struct timer_list switchover_timer =
189 TIMER_INITIALIZER(switchover_timeout , 0, 0);
190static unsigned long tlclk_timer_data;
191
192static struct tlclk_alarms *alarm_events;
193
194static DEFINE_SPINLOCK(event_lock);
195
196static int tlclk_major = TLCLK_MAJOR;
197
198static irqreturn_t tlclk_interrupt(int irq, void *dev_id);
199
200static DECLARE_WAIT_QUEUE_HEAD(wq);
201
202static unsigned long useflags;
203static DEFINE_MUTEX(tlclk_mutex);
204
205static int tlclk_open(struct inode *inode, struct file *filp)
206{
207 int result;
208
209 mutex_lock(&tlclk_mutex);
210 if (test_and_set_bit(0, &useflags)) {
211 result = -EBUSY;
212
213
214
215 goto out;
216 }
217
218
219
220 inb(TLCLK_REG6);
221
222
223
224 result = request_irq(telclk_interrupt, &tlclk_interrupt,
225 IRQF_DISABLED, "telco_clock", tlclk_interrupt);
226 if (result == -EBUSY)
227 printk(KERN_ERR "tlclk: Interrupt can't be reserved.\n");
228 else
229 inb(TLCLK_REG6);
230
231out:
232 mutex_unlock(&tlclk_mutex);
233 return result;
234}
235
236static int tlclk_release(struct inode *inode, struct file *filp)
237{
238 free_irq(telclk_interrupt, tlclk_interrupt);
239 clear_bit(0, &useflags);
240
241 return 0;
242}
243
244static ssize_t tlclk_read(struct file *filp, char __user *buf, size_t count,
245 loff_t *f_pos)
246{
247 if (count < sizeof(struct tlclk_alarms))
248 return -EIO;
249 if (mutex_lock_interruptible(&tlclk_mutex))
250 return -EINTR;
251
252
253 wait_event_interruptible(wq, got_event);
254 if (copy_to_user(buf, alarm_events, sizeof(struct tlclk_alarms))) {
255 mutex_unlock(&tlclk_mutex);
256 return -EFAULT;
257 }
258
259 memset(alarm_events, 0, sizeof(struct tlclk_alarms));
260 got_event = 0;
261
262 mutex_unlock(&tlclk_mutex);
263 return sizeof(struct tlclk_alarms);
264}
265
266static const struct file_operations tlclk_fops = {
267 .read = tlclk_read,
268 .open = tlclk_open,
269 .release = tlclk_release,
270 .llseek = noop_llseek,
271
272};
273
274static struct miscdevice tlclk_miscdev = {
275 .minor = MISC_DYNAMIC_MINOR,
276 .name = "telco_clock",
277 .fops = &tlclk_fops,
278};
279
280static ssize_t show_current_ref(struct device *d,
281 struct device_attribute *attr, char *buf)
282{
283 unsigned long ret_val;
284 unsigned long flags;
285
286 spin_lock_irqsave(&event_lock, flags);
287 ret_val = ((inb(TLCLK_REG1) & 0x08) >> 3);
288 spin_unlock_irqrestore(&event_lock, flags);
289
290 return sprintf(buf, "0x%lX\n", ret_val);
291}
292
293static DEVICE_ATTR(current_ref, S_IRUGO, show_current_ref, NULL);
294
295
296static ssize_t show_telclock_version(struct device *d,
297 struct device_attribute *attr, char *buf)
298{
299 unsigned long ret_val;
300 unsigned long flags;
301
302 spin_lock_irqsave(&event_lock, flags);
303 ret_val = inb(TLCLK_REG5);
304 spin_unlock_irqrestore(&event_lock, flags);
305
306 return sprintf(buf, "0x%lX\n", ret_val);
307}
308
309static DEVICE_ATTR(telclock_version, S_IRUGO,
310 show_telclock_version, NULL);
311
312static ssize_t show_alarms(struct device *d,
313 struct device_attribute *attr, char *buf)
314{
315 unsigned long ret_val;
316 unsigned long flags;
317
318 spin_lock_irqsave(&event_lock, flags);
319 ret_val = (inb(TLCLK_REG2) & 0xf0);
320 spin_unlock_irqrestore(&event_lock, flags);
321
322 return sprintf(buf, "0x%lX\n", ret_val);
323}
324
325static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
326
327static ssize_t store_received_ref_clk3a(struct device *d,
328 struct device_attribute *attr, const char *buf, size_t count)
329{
330 unsigned long tmp;
331 unsigned char val;
332 unsigned long flags;
333
334 sscanf(buf, "%lX", &tmp);
335 dev_dbg(d, ": tmp = 0x%lX\n", tmp);
336
337 val = (unsigned char)tmp;
338 spin_lock_irqsave(&event_lock, flags);
339 SET_PORT_BITS(TLCLK_REG1, 0xef, val);
340 spin_unlock_irqrestore(&event_lock, flags);
341
342 return strnlen(buf, count);
343}
344
345static DEVICE_ATTR(received_ref_clk3a, (S_IWUSR|S_IWGRP), NULL,
346 store_received_ref_clk3a);
347
348
349static ssize_t store_received_ref_clk3b(struct device *d,
350 struct device_attribute *attr, const char *buf, size_t count)
351{
352 unsigned long tmp;
353 unsigned char val;
354 unsigned long flags;
355
356 sscanf(buf, "%lX", &tmp);
357 dev_dbg(d, ": tmp = 0x%lX\n", tmp);
358
359 val = (unsigned char)tmp;
360 spin_lock_irqsave(&event_lock, flags);
361 SET_PORT_BITS(TLCLK_REG1, 0xdf, val << 1);
362 spin_unlock_irqrestore(&event_lock, flags);
363
364 return strnlen(buf, count);
365}
366
367static DEVICE_ATTR(received_ref_clk3b, (S_IWUSR|S_IWGRP), NULL,
368 store_received_ref_clk3b);
369
370
371static ssize_t store_enable_clk3b_output(struct device *d,
372 struct device_attribute *attr, const char *buf, size_t count)
373{
374 unsigned long tmp;
375 unsigned char val;
376 unsigned long flags;
377
378 sscanf(buf, "%lX", &tmp);
379 dev_dbg(d, ": tmp = 0x%lX\n", tmp);
380
381 val = (unsigned char)tmp;
382 spin_lock_irqsave(&event_lock, flags);
383 SET_PORT_BITS(TLCLK_REG3, 0x7f, val << 7);
384 spin_unlock_irqrestore(&event_lock, flags);
385
386 return strnlen(buf, count);
387}
388
389static DEVICE_ATTR(enable_clk3b_output, (S_IWUSR|S_IWGRP), NULL,
390 store_enable_clk3b_output);
391
392static ssize_t store_enable_clk3a_output(struct device *d,
393 struct device_attribute *attr, const char *buf, size_t count)
394{
395 unsigned long flags;
396 unsigned long tmp;
397 unsigned char val;
398
399 sscanf(buf, "%lX", &tmp);
400 dev_dbg(d, "tmp = 0x%lX\n", tmp);
401
402 val = (unsigned char)tmp;
403 spin_lock_irqsave(&event_lock, flags);
404 SET_PORT_BITS(TLCLK_REG3, 0xbf, val << 6);
405 spin_unlock_irqrestore(&event_lock, flags);
406
407 return strnlen(buf, count);
408}
409
410static DEVICE_ATTR(enable_clk3a_output, (S_IWUSR|S_IWGRP), NULL,
411 store_enable_clk3a_output);
412
413static ssize_t store_enable_clkb1_output(struct device *d,
414 struct device_attribute *attr, const char *buf, size_t count)
415{
416 unsigned long flags;
417 unsigned long tmp;
418 unsigned char val;
419
420 sscanf(buf, "%lX", &tmp);
421 dev_dbg(d, "tmp = 0x%lX\n", tmp);
422
423 val = (unsigned char)tmp;
424 spin_lock_irqsave(&event_lock, flags);
425 SET_PORT_BITS(TLCLK_REG2, 0xf7, val << 3);
426 spin_unlock_irqrestore(&event_lock, flags);
427
428 return strnlen(buf, count);
429}
430
431static DEVICE_ATTR(enable_clkb1_output, (S_IWUSR|S_IWGRP), NULL,
432 store_enable_clkb1_output);
433
434
435static ssize_t store_enable_clka1_output(struct device *d,
436 struct device_attribute *attr, const char *buf, size_t count)
437{
438 unsigned long flags;
439 unsigned long tmp;
440 unsigned char val;
441
442 sscanf(buf, "%lX", &tmp);
443 dev_dbg(d, "tmp = 0x%lX\n", tmp);
444
445 val = (unsigned char)tmp;
446 spin_lock_irqsave(&event_lock, flags);
447 SET_PORT_BITS(TLCLK_REG2, 0xfb, val << 2);
448 spin_unlock_irqrestore(&event_lock, flags);
449
450 return strnlen(buf, count);
451}
452
453static DEVICE_ATTR(enable_clka1_output, (S_IWUSR|S_IWGRP), NULL,
454 store_enable_clka1_output);
455
456static ssize_t store_enable_clkb0_output(struct device *d,
457 struct device_attribute *attr, const char *buf, size_t count)
458{
459 unsigned long flags;
460 unsigned long tmp;
461 unsigned char val;
462
463 sscanf(buf, "%lX", &tmp);
464 dev_dbg(d, "tmp = 0x%lX\n", tmp);
465
466 val = (unsigned char)tmp;
467 spin_lock_irqsave(&event_lock, flags);
468 SET_PORT_BITS(TLCLK_REG2, 0xfd, val << 1);
469 spin_unlock_irqrestore(&event_lock, flags);
470
471 return strnlen(buf, count);
472}
473
474static DEVICE_ATTR(enable_clkb0_output, (S_IWUSR|S_IWGRP), NULL,
475 store_enable_clkb0_output);
476
477static ssize_t store_enable_clka0_output(struct device *d,
478 struct device_attribute *attr, const char *buf, size_t count)
479{
480 unsigned long flags;
481 unsigned long tmp;
482 unsigned char val;
483
484 sscanf(buf, "%lX", &tmp);
485 dev_dbg(d, "tmp = 0x%lX\n", tmp);
486
487 val = (unsigned char)tmp;
488 spin_lock_irqsave(&event_lock, flags);
489 SET_PORT_BITS(TLCLK_REG2, 0xfe, val);
490 spin_unlock_irqrestore(&event_lock, flags);
491
492 return strnlen(buf, count);
493}
494
495static DEVICE_ATTR(enable_clka0_output, (S_IWUSR|S_IWGRP), NULL,
496 store_enable_clka0_output);
497
498static ssize_t store_select_amcb2_transmit_clock(struct device *d,
499 struct device_attribute *attr, const char *buf, size_t count)
500{
501 unsigned long flags;
502 unsigned long tmp;
503 unsigned char val;
504
505 sscanf(buf, "%lX", &tmp);
506 dev_dbg(d, "tmp = 0x%lX\n", tmp);
507
508 val = (unsigned char)tmp;
509 spin_lock_irqsave(&event_lock, flags);
510 if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) {
511 SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x28);
512 SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val);
513 } else if (val >= CLK_8_592MHz) {
514 SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x38);
515 switch (val) {
516 case CLK_8_592MHz:
517 SET_PORT_BITS(TLCLK_REG0, 0xfc, 2);
518 break;
519 case CLK_11_184MHz:
520 SET_PORT_BITS(TLCLK_REG0, 0xfc, 0);
521 break;
522 case CLK_34_368MHz:
523 SET_PORT_BITS(TLCLK_REG0, 0xfc, 3);
524 break;
525 case CLK_44_736MHz:
526 SET_PORT_BITS(TLCLK_REG0, 0xfc, 1);
527 break;
528 }
529 } else
530 SET_PORT_BITS(TLCLK_REG3, 0xc7, val << 3);
531
532 spin_unlock_irqrestore(&event_lock, flags);
533
534 return strnlen(buf, count);
535}
536
537static DEVICE_ATTR(select_amcb2_transmit_clock, (S_IWUSR|S_IWGRP), NULL,
538 store_select_amcb2_transmit_clock);
539
540static ssize_t store_select_amcb1_transmit_clock(struct device *d,
541 struct device_attribute *attr, const char *buf, size_t count)
542{
543 unsigned long tmp;
544 unsigned char val;
545 unsigned long flags;
546
547 sscanf(buf, "%lX", &tmp);
548 dev_dbg(d, "tmp = 0x%lX\n", tmp);
549
550 val = (unsigned char)tmp;
551 spin_lock_irqsave(&event_lock, flags);
552 if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) {
553 SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x5);
554 SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val);
555 } else if (val >= CLK_8_592MHz) {
556 SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x7);
557 switch (val) {
558 case CLK_8_592MHz:
559 SET_PORT_BITS(TLCLK_REG0, 0xfc, 2);
560 break;
561 case CLK_11_184MHz:
562 SET_PORT_BITS(TLCLK_REG0, 0xfc, 0);
563 break;
564 case CLK_34_368MHz:
565 SET_PORT_BITS(TLCLK_REG0, 0xfc, 3);
566 break;
567 case CLK_44_736MHz:
568 SET_PORT_BITS(TLCLK_REG0, 0xfc, 1);
569 break;
570 }
571 } else
572 SET_PORT_BITS(TLCLK_REG3, 0xf8, val);
573 spin_unlock_irqrestore(&event_lock, flags);
574
575 return strnlen(buf, count);
576}
577
578static DEVICE_ATTR(select_amcb1_transmit_clock, (S_IWUSR|S_IWGRP), NULL,
579 store_select_amcb1_transmit_clock);
580
581static ssize_t store_select_redundant_clock(struct device *d,
582 struct device_attribute *attr, const char *buf, size_t count)
583{
584 unsigned long tmp;
585 unsigned char val;
586 unsigned long flags;
587
588 sscanf(buf, "%lX", &tmp);
589 dev_dbg(d, "tmp = 0x%lX\n", tmp);
590
591 val = (unsigned char)tmp;
592 spin_lock_irqsave(&event_lock, flags);
593 SET_PORT_BITS(TLCLK_REG1, 0xfe, val);
594 spin_unlock_irqrestore(&event_lock, flags);
595
596 return strnlen(buf, count);
597}
598
599static DEVICE_ATTR(select_redundant_clock, (S_IWUSR|S_IWGRP), NULL,
600 store_select_redundant_clock);
601
602static ssize_t store_select_ref_frequency(struct device *d,
603 struct device_attribute *attr, const char *buf, size_t count)
604{
605 unsigned long tmp;
606 unsigned char val;
607 unsigned long flags;
608
609 sscanf(buf, "%lX", &tmp);
610 dev_dbg(d, "tmp = 0x%lX\n", tmp);
611
612 val = (unsigned char)tmp;
613 spin_lock_irqsave(&event_lock, flags);
614 SET_PORT_BITS(TLCLK_REG1, 0xfd, val);
615 spin_unlock_irqrestore(&event_lock, flags);
616
617 return strnlen(buf, count);
618}
619
620static DEVICE_ATTR(select_ref_frequency, (S_IWUSR|S_IWGRP), NULL,
621 store_select_ref_frequency);
622
623static ssize_t store_filter_select(struct device *d,
624 struct device_attribute *attr, const char *buf, size_t count)
625{
626 unsigned long tmp;
627 unsigned char val;
628 unsigned long flags;
629
630 sscanf(buf, "%lX", &tmp);
631 dev_dbg(d, "tmp = 0x%lX\n", tmp);
632
633 val = (unsigned char)tmp;
634 spin_lock_irqsave(&event_lock, flags);
635 SET_PORT_BITS(TLCLK_REG0, 0xfb, val);
636 spin_unlock_irqrestore(&event_lock, flags);
637
638 return strnlen(buf, count);
639}
640
641static DEVICE_ATTR(filter_select, (S_IWUSR|S_IWGRP), NULL, store_filter_select);
642
643static ssize_t store_hardware_switching_mode(struct device *d,
644 struct device_attribute *attr, const char *buf, size_t count)
645{
646 unsigned long tmp;
647 unsigned char val;
648 unsigned long flags;
649
650 sscanf(buf, "%lX", &tmp);
651 dev_dbg(d, "tmp = 0x%lX\n", tmp);
652
653 val = (unsigned char)tmp;
654 spin_lock_irqsave(&event_lock, flags);
655 SET_PORT_BITS(TLCLK_REG0, 0xbf, val);
656 spin_unlock_irqrestore(&event_lock, flags);
657
658 return strnlen(buf, count);
659}
660
661static DEVICE_ATTR(hardware_switching_mode, (S_IWUSR|S_IWGRP), NULL,
662 store_hardware_switching_mode);
663
664static ssize_t store_hardware_switching(struct device *d,
665 struct device_attribute *attr, const char *buf, size_t count)
666{
667 unsigned long tmp;
668 unsigned char val;
669 unsigned long flags;
670
671 sscanf(buf, "%lX", &tmp);
672 dev_dbg(d, "tmp = 0x%lX\n", tmp);
673
674 val = (unsigned char)tmp;
675 spin_lock_irqsave(&event_lock, flags);
676 SET_PORT_BITS(TLCLK_REG0, 0x7f, val);
677 spin_unlock_irqrestore(&event_lock, flags);
678
679 return strnlen(buf, count);
680}
681
682static DEVICE_ATTR(hardware_switching, (S_IWUSR|S_IWGRP), NULL,
683 store_hardware_switching);
684
685static ssize_t store_refalign (struct device *d,
686 struct device_attribute *attr, const char *buf, size_t count)
687{
688 unsigned long tmp;
689 unsigned long flags;
690
691 sscanf(buf, "%lX", &tmp);
692 dev_dbg(d, "tmp = 0x%lX\n", tmp);
693 spin_lock_irqsave(&event_lock, flags);
694 SET_PORT_BITS(TLCLK_REG0, 0xf7, 0);
695 SET_PORT_BITS(TLCLK_REG0, 0xf7, 0x08);
696 SET_PORT_BITS(TLCLK_REG0, 0xf7, 0);
697 spin_unlock_irqrestore(&event_lock, flags);
698
699 return strnlen(buf, count);
700}
701
702static DEVICE_ATTR(refalign, (S_IWUSR|S_IWGRP), NULL, store_refalign);
703
704static ssize_t store_mode_select (struct device *d,
705 struct device_attribute *attr, const char *buf, size_t count)
706{
707 unsigned long tmp;
708 unsigned char val;
709 unsigned long flags;
710
711 sscanf(buf, "%lX", &tmp);
712 dev_dbg(d, "tmp = 0x%lX\n", tmp);
713
714 val = (unsigned char)tmp;
715 spin_lock_irqsave(&event_lock, flags);
716 SET_PORT_BITS(TLCLK_REG0, 0xcf, val);
717 spin_unlock_irqrestore(&event_lock, flags);
718
719 return strnlen(buf, count);
720}
721
722static DEVICE_ATTR(mode_select, (S_IWUSR|S_IWGRP), NULL, store_mode_select);
723
724static ssize_t store_reset (struct device *d,
725 struct device_attribute *attr, const char *buf, size_t count)
726{
727 unsigned long tmp;
728 unsigned char val;
729 unsigned long flags;
730
731 sscanf(buf, "%lX", &tmp);
732 dev_dbg(d, "tmp = 0x%lX\n", tmp);
733
734 val = (unsigned char)tmp;
735 spin_lock_irqsave(&event_lock, flags);
736 SET_PORT_BITS(TLCLK_REG4, 0xfd, val);
737 spin_unlock_irqrestore(&event_lock, flags);
738
739 return strnlen(buf, count);
740}
741
742static DEVICE_ATTR(reset, (S_IWUSR|S_IWGRP), NULL, store_reset);
743
744static struct attribute *tlclk_sysfs_entries[] = {
745 &dev_attr_current_ref.attr,
746 &dev_attr_telclock_version.attr,
747 &dev_attr_alarms.attr,
748 &dev_attr_received_ref_clk3a.attr,
749 &dev_attr_received_ref_clk3b.attr,
750 &dev_attr_enable_clk3a_output.attr,
751 &dev_attr_enable_clk3b_output.attr,
752 &dev_attr_enable_clkb1_output.attr,
753 &dev_attr_enable_clka1_output.attr,
754 &dev_attr_enable_clkb0_output.attr,
755 &dev_attr_enable_clka0_output.attr,
756 &dev_attr_select_amcb1_transmit_clock.attr,
757 &dev_attr_select_amcb2_transmit_clock.attr,
758 &dev_attr_select_redundant_clock.attr,
759 &dev_attr_select_ref_frequency.attr,
760 &dev_attr_filter_select.attr,
761 &dev_attr_hardware_switching_mode.attr,
762 &dev_attr_hardware_switching.attr,
763 &dev_attr_refalign.attr,
764 &dev_attr_mode_select.attr,
765 &dev_attr_reset.attr,
766 NULL
767};
768
769static struct attribute_group tlclk_attribute_group = {
770 .name = NULL,
771 .attrs = tlclk_sysfs_entries,
772};
773
774static struct platform_device *tlclk_device;
775
776static int __init tlclk_init(void)
777{
778 int ret;
779
780 ret = register_chrdev(tlclk_major, "telco_clock", &tlclk_fops);
781 if (ret < 0) {
782 printk(KERN_ERR "tlclk: can't get major %d.\n", tlclk_major);
783 return ret;
784 }
785 tlclk_major = ret;
786 alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL);
787 if (!alarm_events)
788 goto out1;
789
790
791 if (!request_region(TLCLK_BASE, 8, "telco_clock")) {
792 printk(KERN_ERR "tlclk: request_region 0x%X failed.\n",
793 TLCLK_BASE);
794 ret = -EBUSY;
795 goto out2;
796 }
797 telclk_interrupt = (inb(TLCLK_REG7) & 0x0f);
798
799 if (0x0F == telclk_interrupt ) {
800 printk(KERN_ERR "telclk_interrupt = 0x%x non-mcpbl0010 hw.\n",
801 telclk_interrupt);
802 ret = -ENXIO;
803 goto out3;
804 }
805
806 init_timer(&switchover_timer);
807
808 ret = misc_register(&tlclk_miscdev);
809 if (ret < 0) {
810 printk(KERN_ERR "tlclk: misc_register returns %d.\n", ret);
811 goto out3;
812 }
813
814 tlclk_device = platform_device_register_simple("telco_clock",
815 -1, NULL, 0);
816 if (IS_ERR(tlclk_device)) {
817 printk(KERN_ERR "tlclk: platform_device_register failed.\n");
818 ret = PTR_ERR(tlclk_device);
819 goto out4;
820 }
821
822 ret = sysfs_create_group(&tlclk_device->dev.kobj,
823 &tlclk_attribute_group);
824 if (ret) {
825 printk(KERN_ERR "tlclk: failed to create sysfs device attributes.\n");
826 goto out5;
827 }
828
829 return 0;
830out5:
831 platform_device_unregister(tlclk_device);
832out4:
833 misc_deregister(&tlclk_miscdev);
834out3:
835 release_region(TLCLK_BASE, 8);
836out2:
837 kfree(alarm_events);
838out1:
839 unregister_chrdev(tlclk_major, "telco_clock");
840 return ret;
841}
842
843static void __exit tlclk_cleanup(void)
844{
845 sysfs_remove_group(&tlclk_device->dev.kobj, &tlclk_attribute_group);
846 platform_device_unregister(tlclk_device);
847 misc_deregister(&tlclk_miscdev);
848 unregister_chrdev(tlclk_major, "telco_clock");
849
850 release_region(TLCLK_BASE, 8);
851 del_timer_sync(&switchover_timer);
852 kfree(alarm_events);
853
854}
855
856static void switchover_timeout(unsigned long data)
857{
858 unsigned long flags = *(unsigned long *) data;
859
860 if ((flags & 1)) {
861 if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08))
862 alarm_events->switchover_primary++;
863 } else {
864 if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08))
865 alarm_events->switchover_secondary++;
866 }
867
868
869 del_timer(&switchover_timer);
870 got_event = 1;
871 wake_up(&wq);
872}
873
874static irqreturn_t tlclk_interrupt(int irq, void *dev_id)
875{
876 unsigned long flags;
877
878 spin_lock_irqsave(&event_lock, flags);
879
880 int_events = inb(TLCLK_REG6);
881
882
883 if (int_events & PRI_LOS_01_MASK) {
884 if (inb(TLCLK_REG2) & SEC_LOST_MASK)
885 alarm_events->lost_clocks++;
886 else
887 alarm_events->lost_primary_clock++;
888 }
889
890
891 if (int_events & PRI_LOS_10_MASK) {
892 alarm_events->primary_clock_back++;
893 SET_PORT_BITS(TLCLK_REG1, 0xFE, 1);
894 }
895
896 if (int_events & SEC_LOS_01_MASK) {
897 if (inb(TLCLK_REG2) & PRI_LOST_MASK)
898 alarm_events->lost_clocks++;
899 else
900 alarm_events->lost_secondary_clock++;
901 }
902
903 if (int_events & SEC_LOS_10_MASK) {
904 alarm_events->secondary_clock_back++;
905 SET_PORT_BITS(TLCLK_REG1, 0xFE, 0);
906 }
907 if (int_events & HOLDOVER_10_MASK)
908 alarm_events->pll_end_holdover++;
909
910 if (int_events & UNLOCK_01_MASK)
911 alarm_events->pll_lost_sync++;
912
913 if (int_events & UNLOCK_10_MASK)
914 alarm_events->pll_sync++;
915
916
917 if (int_events & HOLDOVER_01_MASK) {
918 alarm_events->pll_holdover++;
919
920
921 switchover_timer.expires = jiffies + msecs_to_jiffies(10);
922 tlclk_timer_data = inb(TLCLK_REG1);
923 switchover_timer.data = (unsigned long) &tlclk_timer_data;
924 mod_timer(&switchover_timer, switchover_timer.expires);
925 } else {
926 got_event = 1;
927 wake_up(&wq);
928 }
929 spin_unlock_irqrestore(&event_lock, flags);
930
931 return IRQ_HANDLED;
932}
933
934module_init(tlclk_init);
935module_exit(tlclk_cleanup);
936