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