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/smp_lock.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 lock_kernel();
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 unlock_kernel();
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
271};
272
273static struct miscdevice tlclk_miscdev = {
274 .minor = MISC_DYNAMIC_MINOR,
275 .name = "telco_clock",
276 .fops = &tlclk_fops,
277};
278
279static ssize_t show_current_ref(struct device *d,
280 struct device_attribute *attr, char *buf)
281{
282 unsigned long ret_val;
283 unsigned long flags;
284
285 spin_lock_irqsave(&event_lock, flags);
286 ret_val = ((inb(TLCLK_REG1) & 0x08) >> 3);
287 spin_unlock_irqrestore(&event_lock, flags);
288
289 return sprintf(buf, "0x%lX\n", ret_val);
290}
291
292static DEVICE_ATTR(current_ref, S_IRUGO, show_current_ref, NULL);
293
294
295static ssize_t show_telclock_version(struct device *d,
296 struct device_attribute *attr, char *buf)
297{
298 unsigned long ret_val;
299 unsigned long flags;
300
301 spin_lock_irqsave(&event_lock, flags);
302 ret_val = inb(TLCLK_REG5);
303 spin_unlock_irqrestore(&event_lock, flags);
304
305 return sprintf(buf, "0x%lX\n", ret_val);
306}
307
308static DEVICE_ATTR(telclock_version, S_IRUGO,
309 show_telclock_version, NULL);
310
311static ssize_t show_alarms(struct device *d,
312 struct device_attribute *attr, char *buf)
313{
314 unsigned long ret_val;
315 unsigned long flags;
316
317 spin_lock_irqsave(&event_lock, flags);
318 ret_val = (inb(TLCLK_REG2) & 0xf0);
319 spin_unlock_irqrestore(&event_lock, flags);
320
321 return sprintf(buf, "0x%lX\n", ret_val);
322}
323
324static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
325
326static ssize_t store_received_ref_clk3a(struct device *d,
327 struct device_attribute *attr, const char *buf, size_t count)
328{
329 unsigned long tmp;
330 unsigned char val;
331 unsigned long flags;
332
333 sscanf(buf, "%lX", &tmp);
334 dev_dbg(d, ": tmp = 0x%lX\n", tmp);
335
336 val = (unsigned char)tmp;
337 spin_lock_irqsave(&event_lock, flags);
338 SET_PORT_BITS(TLCLK_REG1, 0xef, val);
339 spin_unlock_irqrestore(&event_lock, flags);
340
341 return strnlen(buf, count);
342}
343
344static DEVICE_ATTR(received_ref_clk3a, (S_IWUSR|S_IWGRP), NULL,
345 store_received_ref_clk3a);
346
347
348static ssize_t store_received_ref_clk3b(struct device *d,
349 struct device_attribute *attr, const char *buf, size_t count)
350{
351 unsigned long tmp;
352 unsigned char val;
353 unsigned long flags;
354
355 sscanf(buf, "%lX", &tmp);
356 dev_dbg(d, ": tmp = 0x%lX\n", tmp);
357
358 val = (unsigned char)tmp;
359 spin_lock_irqsave(&event_lock, flags);
360 SET_PORT_BITS(TLCLK_REG1, 0xdf, val << 1);
361 spin_unlock_irqrestore(&event_lock, flags);
362
363 return strnlen(buf, count);
364}
365
366static DEVICE_ATTR(received_ref_clk3b, (S_IWUSR|S_IWGRP), NULL,
367 store_received_ref_clk3b);
368
369
370static ssize_t store_enable_clk3b_output(struct device *d,
371 struct device_attribute *attr, const char *buf, size_t count)
372{
373 unsigned long tmp;
374 unsigned char val;
375 unsigned long flags;
376
377 sscanf(buf, "%lX", &tmp);
378 dev_dbg(d, ": tmp = 0x%lX\n", tmp);
379
380 val = (unsigned char)tmp;
381 spin_lock_irqsave(&event_lock, flags);
382 SET_PORT_BITS(TLCLK_REG3, 0x7f, val << 7);
383 spin_unlock_irqrestore(&event_lock, flags);
384
385 return strnlen(buf, count);
386}
387
388static DEVICE_ATTR(enable_clk3b_output, (S_IWUSR|S_IWGRP), NULL,
389 store_enable_clk3b_output);
390
391static ssize_t store_enable_clk3a_output(struct device *d,
392 struct device_attribute *attr, const char *buf, size_t count)
393{
394 unsigned long flags;
395 unsigned long tmp;
396 unsigned char val;
397
398 sscanf(buf, "%lX", &tmp);
399 dev_dbg(d, "tmp = 0x%lX\n", tmp);
400
401 val = (unsigned char)tmp;
402 spin_lock_irqsave(&event_lock, flags);
403 SET_PORT_BITS(TLCLK_REG3, 0xbf, val << 6);
404 spin_unlock_irqrestore(&event_lock, flags);
405
406 return strnlen(buf, count);
407}
408
409static DEVICE_ATTR(enable_clk3a_output, (S_IWUSR|S_IWGRP), NULL,
410 store_enable_clk3a_output);
411
412static ssize_t store_enable_clkb1_output(struct device *d,
413 struct device_attribute *attr, const char *buf, size_t count)
414{
415 unsigned long flags;
416 unsigned long tmp;
417 unsigned char val;
418
419 sscanf(buf, "%lX", &tmp);
420 dev_dbg(d, "tmp = 0x%lX\n", tmp);
421
422 val = (unsigned char)tmp;
423 spin_lock_irqsave(&event_lock, flags);
424 SET_PORT_BITS(TLCLK_REG2, 0xf7, val << 3);
425 spin_unlock_irqrestore(&event_lock, flags);
426
427 return strnlen(buf, count);
428}
429
430static DEVICE_ATTR(enable_clkb1_output, (S_IWUSR|S_IWGRP), NULL,
431 store_enable_clkb1_output);
432
433
434static ssize_t store_enable_clka1_output(struct device *d,
435 struct device_attribute *attr, const char *buf, size_t count)
436{
437 unsigned long flags;
438 unsigned long tmp;
439 unsigned char val;
440
441 sscanf(buf, "%lX", &tmp);
442 dev_dbg(d, "tmp = 0x%lX\n", tmp);
443
444 val = (unsigned char)tmp;
445 spin_lock_irqsave(&event_lock, flags);
446 SET_PORT_BITS(TLCLK_REG2, 0xfb, val << 2);
447 spin_unlock_irqrestore(&event_lock, flags);
448
449 return strnlen(buf, count);
450}
451
452static DEVICE_ATTR(enable_clka1_output, (S_IWUSR|S_IWGRP), NULL,
453 store_enable_clka1_output);
454
455static ssize_t store_enable_clkb0_output(struct device *d,
456 struct device_attribute *attr, const char *buf, size_t count)
457{
458 unsigned long flags;
459 unsigned long tmp;
460 unsigned char val;
461
462 sscanf(buf, "%lX", &tmp);
463 dev_dbg(d, "tmp = 0x%lX\n", tmp);
464
465 val = (unsigned char)tmp;
466 spin_lock_irqsave(&event_lock, flags);
467 SET_PORT_BITS(TLCLK_REG2, 0xfd, val << 1);
468 spin_unlock_irqrestore(&event_lock, flags);
469
470 return strnlen(buf, count);
471}
472
473static DEVICE_ATTR(enable_clkb0_output, (S_IWUSR|S_IWGRP), NULL,
474 store_enable_clkb0_output);
475
476static ssize_t store_enable_clka0_output(struct device *d,
477 struct device_attribute *attr, const char *buf, size_t count)
478{
479 unsigned long flags;
480 unsigned long tmp;
481 unsigned char val;
482
483 sscanf(buf, "%lX", &tmp);
484 dev_dbg(d, "tmp = 0x%lX\n", tmp);
485
486 val = (unsigned char)tmp;
487 spin_lock_irqsave(&event_lock, flags);
488 SET_PORT_BITS(TLCLK_REG2, 0xfe, val);
489 spin_unlock_irqrestore(&event_lock, flags);
490
491 return strnlen(buf, count);
492}
493
494static DEVICE_ATTR(enable_clka0_output, (S_IWUSR|S_IWGRP), NULL,
495 store_enable_clka0_output);
496
497static ssize_t store_select_amcb2_transmit_clock(struct device *d,
498 struct device_attribute *attr, const char *buf, size_t count)
499{
500 unsigned long flags;
501 unsigned long tmp;
502 unsigned char val;
503
504 sscanf(buf, "%lX", &tmp);
505 dev_dbg(d, "tmp = 0x%lX\n", tmp);
506
507 val = (unsigned char)tmp;
508 spin_lock_irqsave(&event_lock, flags);
509 if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) {
510 SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x28);
511 SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val);
512 } else if (val >= CLK_8_592MHz) {
513 SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x38);
514 switch (val) {
515 case CLK_8_592MHz:
516 SET_PORT_BITS(TLCLK_REG0, 0xfc, 2);
517 break;
518 case CLK_11_184MHz:
519 SET_PORT_BITS(TLCLK_REG0, 0xfc, 0);
520 break;
521 case CLK_34_368MHz:
522 SET_PORT_BITS(TLCLK_REG0, 0xfc, 3);
523 break;
524 case CLK_44_736MHz:
525 SET_PORT_BITS(TLCLK_REG0, 0xfc, 1);
526 break;
527 }
528 } else
529 SET_PORT_BITS(TLCLK_REG3, 0xc7, val << 3);
530
531 spin_unlock_irqrestore(&event_lock, flags);
532
533 return strnlen(buf, count);
534}
535
536static DEVICE_ATTR(select_amcb2_transmit_clock, (S_IWUSR|S_IWGRP), NULL,
537 store_select_amcb2_transmit_clock);
538
539static ssize_t store_select_amcb1_transmit_clock(struct device *d,
540 struct device_attribute *attr, const char *buf, size_t count)
541{
542 unsigned long tmp;
543 unsigned char val;
544 unsigned long flags;
545
546 sscanf(buf, "%lX", &tmp);
547 dev_dbg(d, "tmp = 0x%lX\n", tmp);
548
549 val = (unsigned char)tmp;
550 spin_lock_irqsave(&event_lock, flags);
551 if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) {
552 SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x5);
553 SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val);
554 } else if (val >= CLK_8_592MHz) {
555 SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x7);
556 switch (val) {
557 case CLK_8_592MHz:
558 SET_PORT_BITS(TLCLK_REG0, 0xfc, 2);
559 break;
560 case CLK_11_184MHz:
561 SET_PORT_BITS(TLCLK_REG0, 0xfc, 0);
562 break;
563 case CLK_34_368MHz:
564 SET_PORT_BITS(TLCLK_REG0, 0xfc, 3);
565 break;
566 case CLK_44_736MHz:
567 SET_PORT_BITS(TLCLK_REG0, 0xfc, 1);
568 break;
569 }
570 } else
571 SET_PORT_BITS(TLCLK_REG3, 0xf8, val);
572 spin_unlock_irqrestore(&event_lock, flags);
573
574 return strnlen(buf, count);
575}
576
577static DEVICE_ATTR(select_amcb1_transmit_clock, (S_IWUSR|S_IWGRP), NULL,
578 store_select_amcb1_transmit_clock);
579
580static ssize_t store_select_redundant_clock(struct device *d,
581 struct device_attribute *attr, const char *buf, size_t count)
582{
583 unsigned long tmp;
584 unsigned char val;
585 unsigned long flags;
586
587 sscanf(buf, "%lX", &tmp);
588 dev_dbg(d, "tmp = 0x%lX\n", tmp);
589
590 val = (unsigned char)tmp;
591 spin_lock_irqsave(&event_lock, flags);
592 SET_PORT_BITS(TLCLK_REG1, 0xfe, val);
593 spin_unlock_irqrestore(&event_lock, flags);
594
595 return strnlen(buf, count);
596}
597
598static DEVICE_ATTR(select_redundant_clock, (S_IWUSR|S_IWGRP), NULL,
599 store_select_redundant_clock);
600
601static ssize_t store_select_ref_frequency(struct device *d,
602 struct device_attribute *attr, const char *buf, size_t count)
603{
604 unsigned long tmp;
605 unsigned char val;
606 unsigned long flags;
607
608 sscanf(buf, "%lX", &tmp);
609 dev_dbg(d, "tmp = 0x%lX\n", tmp);
610
611 val = (unsigned char)tmp;
612 spin_lock_irqsave(&event_lock, flags);
613 SET_PORT_BITS(TLCLK_REG1, 0xfd, val);
614 spin_unlock_irqrestore(&event_lock, flags);
615
616 return strnlen(buf, count);
617}
618
619static DEVICE_ATTR(select_ref_frequency, (S_IWUSR|S_IWGRP), NULL,
620 store_select_ref_frequency);
621
622static ssize_t store_filter_select(struct device *d,
623 struct device_attribute *attr, const char *buf, size_t count)
624{
625 unsigned long tmp;
626 unsigned char val;
627 unsigned long flags;
628
629 sscanf(buf, "%lX", &tmp);
630 dev_dbg(d, "tmp = 0x%lX\n", tmp);
631
632 val = (unsigned char)tmp;
633 spin_lock_irqsave(&event_lock, flags);
634 SET_PORT_BITS(TLCLK_REG0, 0xfb, val);
635 spin_unlock_irqrestore(&event_lock, flags);
636
637 return strnlen(buf, count);
638}
639
640static DEVICE_ATTR(filter_select, (S_IWUSR|S_IWGRP), NULL, store_filter_select);
641
642static ssize_t store_hardware_switching_mode(struct device *d,
643 struct device_attribute *attr, const char *buf, size_t count)
644{
645 unsigned long tmp;
646 unsigned char val;
647 unsigned long flags;
648
649 sscanf(buf, "%lX", &tmp);
650 dev_dbg(d, "tmp = 0x%lX\n", tmp);
651
652 val = (unsigned char)tmp;
653 spin_lock_irqsave(&event_lock, flags);
654 SET_PORT_BITS(TLCLK_REG0, 0xbf, val);
655 spin_unlock_irqrestore(&event_lock, flags);
656
657 return strnlen(buf, count);
658}
659
660static DEVICE_ATTR(hardware_switching_mode, (S_IWUSR|S_IWGRP), NULL,
661 store_hardware_switching_mode);
662
663static ssize_t store_hardware_switching(struct device *d,
664 struct device_attribute *attr, const char *buf, size_t count)
665{
666 unsigned long tmp;
667 unsigned char val;
668 unsigned long flags;
669
670 sscanf(buf, "%lX", &tmp);
671 dev_dbg(d, "tmp = 0x%lX\n", tmp);
672
673 val = (unsigned char)tmp;
674 spin_lock_irqsave(&event_lock, flags);
675 SET_PORT_BITS(TLCLK_REG0, 0x7f, val);
676 spin_unlock_irqrestore(&event_lock, flags);
677
678 return strnlen(buf, count);
679}
680
681static DEVICE_ATTR(hardware_switching, (S_IWUSR|S_IWGRP), NULL,
682 store_hardware_switching);
683
684static ssize_t store_refalign (struct device *d,
685 struct device_attribute *attr, const char *buf, size_t count)
686{
687 unsigned long tmp;
688 unsigned long flags;
689
690 sscanf(buf, "%lX", &tmp);
691 dev_dbg(d, "tmp = 0x%lX\n", tmp);
692 spin_lock_irqsave(&event_lock, flags);
693 SET_PORT_BITS(TLCLK_REG0, 0xf7, 0);
694 SET_PORT_BITS(TLCLK_REG0, 0xf7, 0x08);
695 SET_PORT_BITS(TLCLK_REG0, 0xf7, 0);
696 spin_unlock_irqrestore(&event_lock, flags);
697
698 return strnlen(buf, count);
699}
700
701static DEVICE_ATTR(refalign, (S_IWUSR|S_IWGRP), NULL, store_refalign);
702
703static ssize_t store_mode_select (struct device *d,
704 struct device_attribute *attr, const char *buf, size_t count)
705{
706 unsigned long tmp;
707 unsigned char val;
708 unsigned long flags;
709
710 sscanf(buf, "%lX", &tmp);
711 dev_dbg(d, "tmp = 0x%lX\n", tmp);
712
713 val = (unsigned char)tmp;
714 spin_lock_irqsave(&event_lock, flags);
715 SET_PORT_BITS(TLCLK_REG0, 0xcf, val);
716 spin_unlock_irqrestore(&event_lock, flags);
717
718 return strnlen(buf, count);
719}
720
721static DEVICE_ATTR(mode_select, (S_IWUSR|S_IWGRP), NULL, store_mode_select);
722
723static ssize_t store_reset (struct device *d,
724 struct device_attribute *attr, const char *buf, size_t count)
725{
726 unsigned long tmp;
727 unsigned char val;
728 unsigned long flags;
729
730 sscanf(buf, "%lX", &tmp);
731 dev_dbg(d, "tmp = 0x%lX\n", tmp);
732
733 val = (unsigned char)tmp;
734 spin_lock_irqsave(&event_lock, flags);
735 SET_PORT_BITS(TLCLK_REG4, 0xfd, val);
736 spin_unlock_irqrestore(&event_lock, flags);
737
738 return strnlen(buf, count);
739}
740
741static DEVICE_ATTR(reset, (S_IWUSR|S_IWGRP), NULL, store_reset);
742
743static struct attribute *tlclk_sysfs_entries[] = {
744 &dev_attr_current_ref.attr,
745 &dev_attr_telclock_version.attr,
746 &dev_attr_alarms.attr,
747 &dev_attr_received_ref_clk3a.attr,
748 &dev_attr_received_ref_clk3b.attr,
749 &dev_attr_enable_clk3a_output.attr,
750 &dev_attr_enable_clk3b_output.attr,
751 &dev_attr_enable_clkb1_output.attr,
752 &dev_attr_enable_clka1_output.attr,
753 &dev_attr_enable_clkb0_output.attr,
754 &dev_attr_enable_clka0_output.attr,
755 &dev_attr_select_amcb1_transmit_clock.attr,
756 &dev_attr_select_amcb2_transmit_clock.attr,
757 &dev_attr_select_redundant_clock.attr,
758 &dev_attr_select_ref_frequency.attr,
759 &dev_attr_filter_select.attr,
760 &dev_attr_hardware_switching_mode.attr,
761 &dev_attr_hardware_switching.attr,
762 &dev_attr_refalign.attr,
763 &dev_attr_mode_select.attr,
764 &dev_attr_reset.attr,
765 NULL
766};
767
768static struct attribute_group tlclk_attribute_group = {
769 .name = NULL,
770 .attrs = tlclk_sysfs_entries,
771};
772
773static struct platform_device *tlclk_device;
774
775static int __init tlclk_init(void)
776{
777 int ret;
778
779 ret = register_chrdev(tlclk_major, "telco_clock", &tlclk_fops);
780 if (ret < 0) {
781 printk(KERN_ERR "tlclk: can't get major %d.\n", tlclk_major);
782 return ret;
783 }
784 tlclk_major = ret;
785 alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL);
786 if (!alarm_events)
787 goto out1;
788
789
790 if (!request_region(TLCLK_BASE, 8, "telco_clock")) {
791 printk(KERN_ERR "tlclk: request_region 0x%X failed.\n",
792 TLCLK_BASE);
793 ret = -EBUSY;
794 goto out2;
795 }
796 telclk_interrupt = (inb(TLCLK_REG7) & 0x0f);
797
798 if (0x0F == telclk_interrupt ) {
799 printk(KERN_ERR "telclk_interrup = 0x%x non-mcpbl0010 hw.\n",
800 telclk_interrupt);
801 ret = -ENXIO;
802 goto out3;
803 }
804
805 init_timer(&switchover_timer);
806
807 ret = misc_register(&tlclk_miscdev);
808 if (ret < 0) {
809 printk(KERN_ERR "tlclk: misc_register returns %d.\n", ret);
810 goto out3;
811 }
812
813 tlclk_device = platform_device_register_simple("telco_clock",
814 -1, NULL, 0);
815 if (IS_ERR(tlclk_device)) {
816 printk(KERN_ERR "tlclk: platform_device_register failed.\n");
817 ret = PTR_ERR(tlclk_device);
818 goto out4;
819 }
820
821 ret = sysfs_create_group(&tlclk_device->dev.kobj,
822 &tlclk_attribute_group);
823 if (ret) {
824 printk(KERN_ERR "tlclk: failed to create sysfs device attributes.\n");
825 goto out5;
826 }
827
828 return 0;
829out5:
830 platform_device_unregister(tlclk_device);
831out4:
832 misc_deregister(&tlclk_miscdev);
833out3:
834 release_region(TLCLK_BASE, 8);
835out2:
836 kfree(alarm_events);
837out1:
838 unregister_chrdev(tlclk_major, "telco_clock");
839 return ret;
840}
841
842static void __exit tlclk_cleanup(void)
843{
844 sysfs_remove_group(&tlclk_device->dev.kobj, &tlclk_attribute_group);
845 platform_device_unregister(tlclk_device);
846 misc_deregister(&tlclk_miscdev);
847 unregister_chrdev(tlclk_major, "telco_clock");
848
849 release_region(TLCLK_BASE, 8);
850 del_timer_sync(&switchover_timer);
851 kfree(alarm_events);
852
853}
854
855static void switchover_timeout(unsigned long data)
856{
857 unsigned long flags = *(unsigned long *) data;
858
859 if ((flags & 1)) {
860 if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08))
861 alarm_events->switchover_primary++;
862 } else {
863 if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08))
864 alarm_events->switchover_secondary++;
865 }
866
867
868 del_timer(&switchover_timer);
869 got_event = 1;
870 wake_up(&wq);
871}
872
873static irqreturn_t tlclk_interrupt(int irq, void *dev_id)
874{
875 unsigned long flags;
876
877 spin_lock_irqsave(&event_lock, flags);
878
879 int_events = inb(TLCLK_REG6);
880
881
882 if (int_events & PRI_LOS_01_MASK) {
883 if (inb(TLCLK_REG2) & SEC_LOST_MASK)
884 alarm_events->lost_clocks++;
885 else
886 alarm_events->lost_primary_clock++;
887 }
888
889
890 if (int_events & PRI_LOS_10_MASK) {
891 alarm_events->primary_clock_back++;
892 SET_PORT_BITS(TLCLK_REG1, 0xFE, 1);
893 }
894
895 if (int_events & SEC_LOS_01_MASK) {
896 if (inb(TLCLK_REG2) & PRI_LOST_MASK)
897 alarm_events->lost_clocks++;
898 else
899 alarm_events->lost_secondary_clock++;
900 }
901
902 if (int_events & SEC_LOS_10_MASK) {
903 alarm_events->secondary_clock_back++;
904 SET_PORT_BITS(TLCLK_REG1, 0xFE, 0);
905 }
906 if (int_events & HOLDOVER_10_MASK)
907 alarm_events->pll_end_holdover++;
908
909 if (int_events & UNLOCK_01_MASK)
910 alarm_events->pll_lost_sync++;
911
912 if (int_events & UNLOCK_10_MASK)
913 alarm_events->pll_sync++;
914
915
916 if (int_events & HOLDOVER_01_MASK) {
917 alarm_events->pll_holdover++;
918
919
920 switchover_timer.expires = jiffies + msecs_to_jiffies(10);
921 tlclk_timer_data = inb(TLCLK_REG1);
922 switchover_timer.data = (unsigned long) &tlclk_timer_data;
923 mod_timer(&switchover_timer, switchover_timer.expires);
924 } else {
925 got_event = 1;
926 wake_up(&wq);
927 }
928 spin_unlock_irqrestore(&event_lock, flags);
929
930 return IRQ_HANDLED;
931}
932
933module_init(tlclk_init);
934module_exit(tlclk_cleanup);
935