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