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 <linux/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(struct timer_list *t);
188static struct timer_list switchover_timer;
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 mutex_lock(&tlclk_mutex);
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 0, "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 mutex_unlock(&tlclk_mutex);
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 .llseek = noop_llseek,
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 }
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 const 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 telclk_interrupt = (inb(TLCLK_REG7) & 0x0f);
781
782 alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL);
783 if (!alarm_events) {
784 ret = -ENOMEM;
785 goto out1;
786 }
787
788 ret = register_chrdev(tlclk_major, "telco_clock", &tlclk_fops);
789 if (ret < 0) {
790 printk(KERN_ERR "tlclk: can't get major %d.\n", tlclk_major);
791 kfree(alarm_events);
792 return ret;
793 }
794 tlclk_major = ret;
795
796
797 if (!request_region(TLCLK_BASE, 8, "telco_clock")) {
798 printk(KERN_ERR "tlclk: request_region 0x%X failed.\n",
799 TLCLK_BASE);
800 ret = -EBUSY;
801 goto out2;
802 }
803
804 if (0x0F == telclk_interrupt ) {
805 printk(KERN_ERR "telclk_interrupt = 0x%x non-mcpbl0010 hw.\n",
806 telclk_interrupt);
807 ret = -ENXIO;
808 goto out3;
809 }
810
811 timer_setup(&switchover_timer, switchover_timeout, 0);
812
813 ret = misc_register(&tlclk_miscdev);
814 if (ret < 0) {
815 printk(KERN_ERR "tlclk: misc_register returns %d.\n", ret);
816 goto out3;
817 }
818
819 tlclk_device = platform_device_register_simple("telco_clock",
820 -1, NULL, 0);
821 if (IS_ERR(tlclk_device)) {
822 printk(KERN_ERR "tlclk: platform_device_register failed.\n");
823 ret = PTR_ERR(tlclk_device);
824 goto out4;
825 }
826
827 ret = sysfs_create_group(&tlclk_device->dev.kobj,
828 &tlclk_attribute_group);
829 if (ret) {
830 printk(KERN_ERR "tlclk: failed to create sysfs device attributes.\n");
831 goto out5;
832 }
833
834 return 0;
835out5:
836 platform_device_unregister(tlclk_device);
837out4:
838 misc_deregister(&tlclk_miscdev);
839out3:
840 release_region(TLCLK_BASE, 8);
841out2:
842 kfree(alarm_events);
843 unregister_chrdev(tlclk_major, "telco_clock");
844out1:
845 return ret;
846}
847
848static void __exit tlclk_cleanup(void)
849{
850 sysfs_remove_group(&tlclk_device->dev.kobj, &tlclk_attribute_group);
851 platform_device_unregister(tlclk_device);
852 misc_deregister(&tlclk_miscdev);
853 unregister_chrdev(tlclk_major, "telco_clock");
854
855 release_region(TLCLK_BASE, 8);
856 del_timer_sync(&switchover_timer);
857 kfree(alarm_events);
858
859}
860
861static void switchover_timeout(struct timer_list *unused)
862{
863 unsigned long flags = tlclk_timer_data;
864
865 if ((flags & 1)) {
866 if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08))
867 alarm_events->switchover_primary++;
868 } else {
869 if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08))
870 alarm_events->switchover_secondary++;
871 }
872
873
874 del_timer(&switchover_timer);
875 got_event = 1;
876 wake_up(&wq);
877}
878
879static irqreturn_t tlclk_interrupt(int irq, void *dev_id)
880{
881 unsigned long flags;
882
883 spin_lock_irqsave(&event_lock, flags);
884
885 int_events = inb(TLCLK_REG6);
886
887
888 if (int_events & PRI_LOS_01_MASK) {
889 if (inb(TLCLK_REG2) & SEC_LOST_MASK)
890 alarm_events->lost_clocks++;
891 else
892 alarm_events->lost_primary_clock++;
893 }
894
895
896 if (int_events & PRI_LOS_10_MASK) {
897 alarm_events->primary_clock_back++;
898 SET_PORT_BITS(TLCLK_REG1, 0xFE, 1);
899 }
900
901 if (int_events & SEC_LOS_01_MASK) {
902 if (inb(TLCLK_REG2) & PRI_LOST_MASK)
903 alarm_events->lost_clocks++;
904 else
905 alarm_events->lost_secondary_clock++;
906 }
907
908 if (int_events & SEC_LOS_10_MASK) {
909 alarm_events->secondary_clock_back++;
910 SET_PORT_BITS(TLCLK_REG1, 0xFE, 0);
911 }
912 if (int_events & HOLDOVER_10_MASK)
913 alarm_events->pll_end_holdover++;
914
915 if (int_events & UNLOCK_01_MASK)
916 alarm_events->pll_lost_sync++;
917
918 if (int_events & UNLOCK_10_MASK)
919 alarm_events->pll_sync++;
920
921
922 if (int_events & HOLDOVER_01_MASK) {
923 alarm_events->pll_holdover++;
924
925
926 switchover_timer.expires = jiffies + msecs_to_jiffies(10);
927 tlclk_timer_data = inb(TLCLK_REG1);
928 mod_timer(&switchover_timer, switchover_timer.expires);
929 } else {
930 got_event = 1;
931 wake_up(&wq);
932 }
933 spin_unlock_irqrestore(&event_lock, flags);
934
935 return IRQ_HANDLED;
936}
937
938module_init(tlclk_init);
939module_exit(tlclk_cleanup);
940