xref: /openbmc/linux/drivers/char/tlclk.c (revision 4b4193256c8d3bc3a5397b5cd9494c2ad386317d)
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/module.h>
31  #include <linux/init.h>
32  #include <linux/kernel.h>	/* printk() */
33  #include <linux/fs.h>		/* everything... */
34  #include <linux/errno.h>	/* error codes */
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>		/* inb/outb */
47  #include <linux/uaccess.h>
48  
49  MODULE_AUTHOR("Sebastien Bouchard <sebastien.bouchard@ca.kontron.com>");
50  MODULE_LICENSE("GPL");
51  
52  /*Hardware Reset of the PLL */
53  #define RESET_ON	0x00
54  #define RESET_OFF	0x01
55  
56  /* MODE SELECT */
57  #define NORMAL_MODE 	0x00
58  #define HOLDOVER_MODE	0x10
59  #define FREERUN_MODE	0x20
60  
61  /* FILTER SELECT */
62  #define FILTER_6HZ	0x04
63  #define FILTER_12HZ	0x00
64  
65  /* SELECT REFERENCE FREQUENCY */
66  #define REF_CLK1_8kHz		0x00
67  #define REF_CLK2_19_44MHz	0x02
68  
69  /* Select primary or secondary redundant clock */
70  #define PRIMARY_CLOCK	0x00
71  #define SECONDARY_CLOCK	0x01
72  
73  /* CLOCK TRANSMISSION DEFINE */
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  /* RECEIVED REFERENCE */
90  #define AMC_B1 0
91  #define AMC_B2 1
92  
93  /* HARDWARE SWITCHING DEFINE */
94  #define HW_ENABLE	0x80
95  #define HW_DISABLE	0x00
96  
97  /* HARDWARE SWITCHING MODE DEFINE */
98  #define PLL_HOLDOVER	0x40
99  #define LOST_CLOCK	0x00
100  
101  /* ALARMS DEFINE */
102  #define UNLOCK_MASK	0x10
103  #define HOLDOVER_MASK	0x20
104  #define SEC_LOST_MASK	0x40
105  #define PRI_LOST_MASK	0x80
106  
107  /* INTERRUPT CAUSE DEFINE */
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  
121  struct 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  /* Telecom clock I/O register definition */
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  /* 0 = Dynamic allocation of the major device number */
148  #define TLCLK_MAJOR 0
149  
150  /* sysfs interface definition:
151  Upon loading the driver will create a sysfs directory under
152  /sys/devices/platform/telco_clock.
153  
154  This directory exports the following interfaces.  There operation is
155  documented in the MCPBL0010 TPS under the Telecom Clock API section, 11.4.
156  alarms				:
157  current_ref			:
158  received_ref_clk3a		:
159  received_ref_clk3b		:
160  enable_clk3a_output		:
161  enable_clk3b_output		:
162  enable_clka0_output		:
163  enable_clka1_output		:
164  enable_clkb0_output		:
165  enable_clkb1_output		:
166  filter_select			:
167  hardware_switching		:
168  hardware_switching_mode		:
169  telclock_version		:
170  mode_select			:
171  refalign			:
172  reset				:
173  select_amcb1_transmit_clock	:
174  select_amcb2_transmit_clock	:
175  select_redundant_clock		:
176  select_ref_frequency		:
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(struct timer_list *t);
188  static struct timer_list switchover_timer;
189  static unsigned long tlclk_timer_data;
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);
198  
199  static DECLARE_WAIT_QUEUE_HEAD(wq);
200  
201  static unsigned long useflags;
202  static DEFINE_MUTEX(tlclk_mutex);
203  
tlclk_open(struct inode * inode,struct file * filp)204  static 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  		/* this legacy device is always one per system and it doesn't
212  		 * know how to handle multiple concurrent clients.
213  		 */
214  		goto out;
215  	}
216  
217  	/* Make sure there is no interrupt pending while
218  	 * initialising interrupt handler */
219  	inb(TLCLK_REG6);
220  
221  	/* This device is wired through the FPGA IO space of the ATCA blade
222  	 * we can't share this IRQ */
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);	/* Clear interrupt events */
229  
230  out:
231  	mutex_unlock(&tlclk_mutex);
232  	return result;
233  }
234  
tlclk_release(struct inode * inode,struct file * filp)235  static 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  
tlclk_read(struct file * filp,char __user * buf,size_t count,loff_t * f_pos)243  static 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  
265  static 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  
273  static struct miscdevice tlclk_miscdev = {
274  	.minor = MISC_DYNAMIC_MINOR,
275  	.name = "telco_clock",
276  	.fops = &tlclk_fops,
277  };
278  
show_current_ref(struct device * d,struct device_attribute * attr,char * buf)279  static 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  
292  static DEVICE_ATTR(current_ref, S_IRUGO, show_current_ref, NULL);
293  
294  
show_telclock_version(struct device * d,struct device_attribute * attr,char * buf)295  static 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  
308  static DEVICE_ATTR(telclock_version, S_IRUGO,
309  		show_telclock_version, NULL);
310  
show_alarms(struct device * d,struct device_attribute * attr,char * buf)311  static 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  
324  static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
325  
store_received_ref_clk3a(struct device * d,struct device_attribute * attr,const char * buf,size_t count)326  static 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  
344  static DEVICE_ATTR(received_ref_clk3a, (S_IWUSR|S_IWGRP), NULL,
345  		store_received_ref_clk3a);
346  
347  
store_received_ref_clk3b(struct device * d,struct device_attribute * attr,const char * buf,size_t count)348  static 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  
366  static DEVICE_ATTR(received_ref_clk3b, (S_IWUSR|S_IWGRP), NULL,
367  		store_received_ref_clk3b);
368  
369  
store_enable_clk3b_output(struct device * d,struct device_attribute * attr,const char * buf,size_t count)370  static 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  
388  static DEVICE_ATTR(enable_clk3b_output, (S_IWUSR|S_IWGRP), NULL,
389  		store_enable_clk3b_output);
390  
store_enable_clk3a_output(struct device * d,struct device_attribute * attr,const char * buf,size_t count)391  static 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  
409  static DEVICE_ATTR(enable_clk3a_output, (S_IWUSR|S_IWGRP), NULL,
410  		store_enable_clk3a_output);
411  
store_enable_clkb1_output(struct device * d,struct device_attribute * attr,const char * buf,size_t count)412  static 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  
430  static DEVICE_ATTR(enable_clkb1_output, (S_IWUSR|S_IWGRP), NULL,
431  		store_enable_clkb1_output);
432  
433  
store_enable_clka1_output(struct device * d,struct device_attribute * attr,const char * buf,size_t count)434  static 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  
452  static DEVICE_ATTR(enable_clka1_output, (S_IWUSR|S_IWGRP), NULL,
453  		store_enable_clka1_output);
454  
store_enable_clkb0_output(struct device * d,struct device_attribute * attr,const char * buf,size_t count)455  static 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  
473  static DEVICE_ATTR(enable_clkb0_output, (S_IWUSR|S_IWGRP), NULL,
474  		store_enable_clkb0_output);
475  
store_enable_clka0_output(struct device * d,struct device_attribute * attr,const char * buf,size_t count)476  static 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  
494  static DEVICE_ATTR(enable_clka0_output, (S_IWUSR|S_IWGRP), NULL,
495  		store_enable_clka0_output);
496  
store_select_amcb2_transmit_clock(struct device * d,struct device_attribute * attr,const char * buf,size_t count)497  static 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  
536  static DEVICE_ATTR(select_amcb2_transmit_clock, (S_IWUSR|S_IWGRP), NULL,
537  	store_select_amcb2_transmit_clock);
538  
store_select_amcb1_transmit_clock(struct device * d,struct device_attribute * attr,const char * buf,size_t count)539  static 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  
578  static DEVICE_ATTR(select_amcb1_transmit_clock, (S_IWUSR|S_IWGRP), NULL,
579  		store_select_amcb1_transmit_clock);
580  
store_select_redundant_clock(struct device * d,struct device_attribute * attr,const char * buf,size_t count)581  static 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  
599  static DEVICE_ATTR(select_redundant_clock, (S_IWUSR|S_IWGRP), NULL,
600  		store_select_redundant_clock);
601  
store_select_ref_frequency(struct device * d,struct device_attribute * attr,const char * buf,size_t count)602  static 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  
620  static DEVICE_ATTR(select_ref_frequency, (S_IWUSR|S_IWGRP), NULL,
621  		store_select_ref_frequency);
622  
store_filter_select(struct device * d,struct device_attribute * attr,const char * buf,size_t count)623  static 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  
641  static DEVICE_ATTR(filter_select, (S_IWUSR|S_IWGRP), NULL, store_filter_select);
642  
store_hardware_switching_mode(struct device * d,struct device_attribute * attr,const char * buf,size_t count)643  static 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  
661  static DEVICE_ATTR(hardware_switching_mode, (S_IWUSR|S_IWGRP), NULL,
662  		store_hardware_switching_mode);
663  
store_hardware_switching(struct device * d,struct device_attribute * attr,const char * buf,size_t count)664  static 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  
682  static DEVICE_ATTR(hardware_switching, (S_IWUSR|S_IWGRP), NULL,
683  		store_hardware_switching);
684  
store_refalign(struct device * d,struct device_attribute * attr,const char * buf,size_t count)685  static 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  
702  static DEVICE_ATTR(refalign, (S_IWUSR|S_IWGRP), NULL, store_refalign);
703  
store_mode_select(struct device * d,struct device_attribute * attr,const char * buf,size_t count)704  static 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  
722  static DEVICE_ATTR(mode_select, (S_IWUSR|S_IWGRP), NULL, store_mode_select);
723  
store_reset(struct device * d,struct device_attribute * attr,const char * buf,size_t count)724  static 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  
742  static DEVICE_ATTR(reset, (S_IWUSR|S_IWGRP), NULL, store_reset);
743  
744  static 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  
769  static const struct attribute_group tlclk_attribute_group = {
770  	.name = NULL,		/* put in device directory */
771  	.attrs = tlclk_sysfs_entries,
772  };
773  
774  static struct platform_device *tlclk_device;
775  
tlclk_init(void)776  static 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  	/* Read telecom clock IRQ number (Set by BIOS) */
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 ) { /* not MCPBL0010 ? */
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;
835  out5:
836  	platform_device_unregister(tlclk_device);
837  out4:
838  	misc_deregister(&tlclk_miscdev);
839  out3:
840  	release_region(TLCLK_BASE, 8);
841  out2:
842  	kfree(alarm_events);
843  	unregister_chrdev(tlclk_major, "telco_clock");
844  out1:
845  	return ret;
846  }
847  
tlclk_cleanup(void)848  static 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  
switchover_timeout(struct timer_list * unused)861  static 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  	/* Alarm processing is done, wake up read task */
874  	del_timer(&switchover_timer);
875  	got_event = 1;
876  	wake_up(&wq);
877  }
878  
tlclk_interrupt(int irq,void * dev_id)879  static irqreturn_t tlclk_interrupt(int irq, void *dev_id)
880  {
881  	unsigned long flags;
882  
883  	spin_lock_irqsave(&event_lock, flags);
884  	/* Read and clear interrupt events */
885  	int_events = inb(TLCLK_REG6);
886  
887  	/* Primary_Los changed from 0 to 1 ? */
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  	/* Primary_Los changed from 1 to 0 ? */
896  	if (int_events & PRI_LOS_10_MASK) {
897  		alarm_events->primary_clock_back++;
898  		SET_PORT_BITS(TLCLK_REG1, 0xFE, 1);
899  	}
900  	/* Secondary_Los changed from 0 to 1 ? */
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  	/* Secondary_Los changed from 1 to 0 ? */
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  	/* Holdover changed from 0 to 1 ? */
922  	if (int_events & HOLDOVER_01_MASK) {
923  		alarm_events->pll_holdover++;
924  
925  		/* TIMEOUT in ~10ms */
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  
938  module_init(tlclk_init);
939  module_exit(tlclk_cleanup);
940