0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 #include <linux/module.h>
0031 #include <linux/init.h>
0032 #include <linux/kernel.h> /* printk() */
0033 #include <linux/fs.h> /* everything... */
0034 #include <linux/errno.h> /* error codes */
0035 #include <linux/sched.h>
0036 #include <linux/slab.h>
0037 #include <linux/ioport.h>
0038 #include <linux/interrupt.h>
0039 #include <linux/spinlock.h>
0040 #include <linux/mutex.h>
0041 #include <linux/timer.h>
0042 #include <linux/sysfs.h>
0043 #include <linux/device.h>
0044 #include <linux/miscdevice.h>
0045 #include <linux/platform_device.h>
0046 #include <asm/io.h> /* inb/outb */
0047 #include <linux/uaccess.h>
0048
0049 MODULE_AUTHOR("Sebastien Bouchard <sebastien.bouchard@ca.kontron.com>");
0050 MODULE_LICENSE("GPL");
0051
0052
0053 #define RESET_ON 0x00
0054 #define RESET_OFF 0x01
0055
0056
0057 #define NORMAL_MODE 0x00
0058 #define HOLDOVER_MODE 0x10
0059 #define FREERUN_MODE 0x20
0060
0061
0062 #define FILTER_6HZ 0x04
0063 #define FILTER_12HZ 0x00
0064
0065
0066 #define REF_CLK1_8kHz 0x00
0067 #define REF_CLK2_19_44MHz 0x02
0068
0069
0070 #define PRIMARY_CLOCK 0x00
0071 #define SECONDARY_CLOCK 0x01
0072
0073
0074 #define CLK_8kHz 0xff
0075 #define CLK_16_384MHz 0xfb
0076
0077 #define CLK_1_544MHz 0x00
0078 #define CLK_2_048MHz 0x01
0079 #define CLK_4_096MHz 0x02
0080 #define CLK_6_312MHz 0x03
0081 #define CLK_8_192MHz 0x04
0082 #define CLK_19_440MHz 0x06
0083
0084 #define CLK_8_592MHz 0x08
0085 #define CLK_11_184MHz 0x09
0086 #define CLK_34_368MHz 0x0b
0087 #define CLK_44_736MHz 0x0a
0088
0089
0090 #define AMC_B1 0
0091 #define AMC_B2 1
0092
0093
0094 #define HW_ENABLE 0x80
0095 #define HW_DISABLE 0x00
0096
0097
0098 #define PLL_HOLDOVER 0x40
0099 #define LOST_CLOCK 0x00
0100
0101
0102 #define UNLOCK_MASK 0x10
0103 #define HOLDOVER_MASK 0x20
0104 #define SEC_LOST_MASK 0x40
0105 #define PRI_LOST_MASK 0x80
0106
0107
0108
0109 #define PRI_LOS_01_MASK 0x01
0110 #define PRI_LOS_10_MASK 0x02
0111
0112 #define SEC_LOS_01_MASK 0x04
0113 #define SEC_LOS_10_MASK 0x08
0114
0115 #define HOLDOVER_01_MASK 0x10
0116 #define HOLDOVER_10_MASK 0x20
0117
0118 #define UNLOCK_01_MASK 0x40
0119 #define UNLOCK_10_MASK 0x80
0120
0121 struct tlclk_alarms {
0122 __u32 lost_clocks;
0123 __u32 lost_primary_clock;
0124 __u32 lost_secondary_clock;
0125 __u32 primary_clock_back;
0126 __u32 secondary_clock_back;
0127 __u32 switchover_primary;
0128 __u32 switchover_secondary;
0129 __u32 pll_holdover;
0130 __u32 pll_end_holdover;
0131 __u32 pll_lost_sync;
0132 __u32 pll_sync;
0133 };
0134
0135 #define TLCLK_BASE 0xa08
0136 #define TLCLK_REG0 TLCLK_BASE
0137 #define TLCLK_REG1 (TLCLK_BASE+1)
0138 #define TLCLK_REG2 (TLCLK_BASE+2)
0139 #define TLCLK_REG3 (TLCLK_BASE+3)
0140 #define TLCLK_REG4 (TLCLK_BASE+4)
0141 #define TLCLK_REG5 (TLCLK_BASE+5)
0142 #define TLCLK_REG6 (TLCLK_BASE+6)
0143 #define TLCLK_REG7 (TLCLK_BASE+7)
0144
0145 #define SET_PORT_BITS(port, mask, val) outb(((inb(port) & mask) | val), port)
0146
0147
0148 #define TLCLK_MAJOR 0
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182 static unsigned int telclk_interrupt;
0183
0184 static int int_events;
0185 static int got_event;
0186
0187 static void switchover_timeout(struct timer_list *t);
0188 static struct timer_list switchover_timer;
0189 static unsigned long tlclk_timer_data;
0190
0191 static struct tlclk_alarms *alarm_events;
0192
0193 static DEFINE_SPINLOCK(event_lock);
0194
0195 static int tlclk_major = TLCLK_MAJOR;
0196
0197 static irqreturn_t tlclk_interrupt(int irq, void *dev_id);
0198
0199 static DECLARE_WAIT_QUEUE_HEAD(wq);
0200
0201 static unsigned long useflags;
0202 static DEFINE_MUTEX(tlclk_mutex);
0203
0204 static int tlclk_open(struct inode *inode, struct file *filp)
0205 {
0206 int result;
0207
0208 mutex_lock(&tlclk_mutex);
0209 if (test_and_set_bit(0, &useflags)) {
0210 result = -EBUSY;
0211
0212
0213
0214 goto out;
0215 }
0216
0217
0218
0219 inb(TLCLK_REG6);
0220
0221
0222
0223 result = request_irq(telclk_interrupt, &tlclk_interrupt,
0224 0, "telco_clock", tlclk_interrupt);
0225 if (result == -EBUSY)
0226 printk(KERN_ERR "tlclk: Interrupt can't be reserved.\n");
0227 else
0228 inb(TLCLK_REG6);
0229
0230 out:
0231 mutex_unlock(&tlclk_mutex);
0232 return result;
0233 }
0234
0235 static int tlclk_release(struct inode *inode, struct file *filp)
0236 {
0237 free_irq(telclk_interrupt, tlclk_interrupt);
0238 clear_bit(0, &useflags);
0239
0240 return 0;
0241 }
0242
0243 static ssize_t tlclk_read(struct file *filp, char __user *buf, size_t count,
0244 loff_t *f_pos)
0245 {
0246 if (count < sizeof(struct tlclk_alarms))
0247 return -EIO;
0248 if (mutex_lock_interruptible(&tlclk_mutex))
0249 return -EINTR;
0250
0251
0252 wait_event_interruptible(wq, got_event);
0253 if (copy_to_user(buf, alarm_events, sizeof(struct tlclk_alarms))) {
0254 mutex_unlock(&tlclk_mutex);
0255 return -EFAULT;
0256 }
0257
0258 memset(alarm_events, 0, sizeof(struct tlclk_alarms));
0259 got_event = 0;
0260
0261 mutex_unlock(&tlclk_mutex);
0262 return sizeof(struct tlclk_alarms);
0263 }
0264
0265 static const struct file_operations tlclk_fops = {
0266 .read = tlclk_read,
0267 .open = tlclk_open,
0268 .release = tlclk_release,
0269 .llseek = noop_llseek,
0270
0271 };
0272
0273 static struct miscdevice tlclk_miscdev = {
0274 .minor = MISC_DYNAMIC_MINOR,
0275 .name = "telco_clock",
0276 .fops = &tlclk_fops,
0277 };
0278
0279 static ssize_t show_current_ref(struct device *d,
0280 struct device_attribute *attr, char *buf)
0281 {
0282 unsigned long ret_val;
0283 unsigned long flags;
0284
0285 spin_lock_irqsave(&event_lock, flags);
0286 ret_val = ((inb(TLCLK_REG1) & 0x08) >> 3);
0287 spin_unlock_irqrestore(&event_lock, flags);
0288
0289 return sprintf(buf, "0x%lX\n", ret_val);
0290 }
0291
0292 static DEVICE_ATTR(current_ref, S_IRUGO, show_current_ref, NULL);
0293
0294
0295 static ssize_t show_telclock_version(struct device *d,
0296 struct device_attribute *attr, char *buf)
0297 {
0298 unsigned long ret_val;
0299 unsigned long flags;
0300
0301 spin_lock_irqsave(&event_lock, flags);
0302 ret_val = inb(TLCLK_REG5);
0303 spin_unlock_irqrestore(&event_lock, flags);
0304
0305 return sprintf(buf, "0x%lX\n", ret_val);
0306 }
0307
0308 static DEVICE_ATTR(telclock_version, S_IRUGO,
0309 show_telclock_version, NULL);
0310
0311 static ssize_t show_alarms(struct device *d,
0312 struct device_attribute *attr, char *buf)
0313 {
0314 unsigned long ret_val;
0315 unsigned long flags;
0316
0317 spin_lock_irqsave(&event_lock, flags);
0318 ret_val = (inb(TLCLK_REG2) & 0xf0);
0319 spin_unlock_irqrestore(&event_lock, flags);
0320
0321 return sprintf(buf, "0x%lX\n", ret_val);
0322 }
0323
0324 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
0325
0326 static ssize_t store_received_ref_clk3a(struct device *d,
0327 struct device_attribute *attr, const char *buf, size_t count)
0328 {
0329 unsigned long tmp;
0330 unsigned char val;
0331 unsigned long flags;
0332
0333 sscanf(buf, "%lX", &tmp);
0334 dev_dbg(d, ": tmp = 0x%lX\n", tmp);
0335
0336 val = (unsigned char)tmp;
0337 spin_lock_irqsave(&event_lock, flags);
0338 SET_PORT_BITS(TLCLK_REG1, 0xef, val);
0339 spin_unlock_irqrestore(&event_lock, flags);
0340
0341 return strnlen(buf, count);
0342 }
0343
0344 static DEVICE_ATTR(received_ref_clk3a, (S_IWUSR|S_IWGRP), NULL,
0345 store_received_ref_clk3a);
0346
0347
0348 static ssize_t store_received_ref_clk3b(struct device *d,
0349 struct device_attribute *attr, const char *buf, size_t count)
0350 {
0351 unsigned long tmp;
0352 unsigned char val;
0353 unsigned long flags;
0354
0355 sscanf(buf, "%lX", &tmp);
0356 dev_dbg(d, ": tmp = 0x%lX\n", tmp);
0357
0358 val = (unsigned char)tmp;
0359 spin_lock_irqsave(&event_lock, flags);
0360 SET_PORT_BITS(TLCLK_REG1, 0xdf, val << 1);
0361 spin_unlock_irqrestore(&event_lock, flags);
0362
0363 return strnlen(buf, count);
0364 }
0365
0366 static DEVICE_ATTR(received_ref_clk3b, (S_IWUSR|S_IWGRP), NULL,
0367 store_received_ref_clk3b);
0368
0369
0370 static ssize_t store_enable_clk3b_output(struct device *d,
0371 struct device_attribute *attr, const char *buf, size_t count)
0372 {
0373 unsigned long tmp;
0374 unsigned char val;
0375 unsigned long flags;
0376
0377 sscanf(buf, "%lX", &tmp);
0378 dev_dbg(d, ": tmp = 0x%lX\n", tmp);
0379
0380 val = (unsigned char)tmp;
0381 spin_lock_irqsave(&event_lock, flags);
0382 SET_PORT_BITS(TLCLK_REG3, 0x7f, val << 7);
0383 spin_unlock_irqrestore(&event_lock, flags);
0384
0385 return strnlen(buf, count);
0386 }
0387
0388 static DEVICE_ATTR(enable_clk3b_output, (S_IWUSR|S_IWGRP), NULL,
0389 store_enable_clk3b_output);
0390
0391 static ssize_t store_enable_clk3a_output(struct device *d,
0392 struct device_attribute *attr, const char *buf, size_t count)
0393 {
0394 unsigned long flags;
0395 unsigned long tmp;
0396 unsigned char val;
0397
0398 sscanf(buf, "%lX", &tmp);
0399 dev_dbg(d, "tmp = 0x%lX\n", tmp);
0400
0401 val = (unsigned char)tmp;
0402 spin_lock_irqsave(&event_lock, flags);
0403 SET_PORT_BITS(TLCLK_REG3, 0xbf, val << 6);
0404 spin_unlock_irqrestore(&event_lock, flags);
0405
0406 return strnlen(buf, count);
0407 }
0408
0409 static DEVICE_ATTR(enable_clk3a_output, (S_IWUSR|S_IWGRP), NULL,
0410 store_enable_clk3a_output);
0411
0412 static ssize_t store_enable_clkb1_output(struct device *d,
0413 struct device_attribute *attr, const char *buf, size_t count)
0414 {
0415 unsigned long flags;
0416 unsigned long tmp;
0417 unsigned char val;
0418
0419 sscanf(buf, "%lX", &tmp);
0420 dev_dbg(d, "tmp = 0x%lX\n", tmp);
0421
0422 val = (unsigned char)tmp;
0423 spin_lock_irqsave(&event_lock, flags);
0424 SET_PORT_BITS(TLCLK_REG2, 0xf7, val << 3);
0425 spin_unlock_irqrestore(&event_lock, flags);
0426
0427 return strnlen(buf, count);
0428 }
0429
0430 static DEVICE_ATTR(enable_clkb1_output, (S_IWUSR|S_IWGRP), NULL,
0431 store_enable_clkb1_output);
0432
0433
0434 static ssize_t store_enable_clka1_output(struct device *d,
0435 struct device_attribute *attr, const char *buf, size_t count)
0436 {
0437 unsigned long flags;
0438 unsigned long tmp;
0439 unsigned char val;
0440
0441 sscanf(buf, "%lX", &tmp);
0442 dev_dbg(d, "tmp = 0x%lX\n", tmp);
0443
0444 val = (unsigned char)tmp;
0445 spin_lock_irqsave(&event_lock, flags);
0446 SET_PORT_BITS(TLCLK_REG2, 0xfb, val << 2);
0447 spin_unlock_irqrestore(&event_lock, flags);
0448
0449 return strnlen(buf, count);
0450 }
0451
0452 static DEVICE_ATTR(enable_clka1_output, (S_IWUSR|S_IWGRP), NULL,
0453 store_enable_clka1_output);
0454
0455 static ssize_t store_enable_clkb0_output(struct device *d,
0456 struct device_attribute *attr, const char *buf, size_t count)
0457 {
0458 unsigned long flags;
0459 unsigned long tmp;
0460 unsigned char val;
0461
0462 sscanf(buf, "%lX", &tmp);
0463 dev_dbg(d, "tmp = 0x%lX\n", tmp);
0464
0465 val = (unsigned char)tmp;
0466 spin_lock_irqsave(&event_lock, flags);
0467 SET_PORT_BITS(TLCLK_REG2, 0xfd, val << 1);
0468 spin_unlock_irqrestore(&event_lock, flags);
0469
0470 return strnlen(buf, count);
0471 }
0472
0473 static DEVICE_ATTR(enable_clkb0_output, (S_IWUSR|S_IWGRP), NULL,
0474 store_enable_clkb0_output);
0475
0476 static ssize_t store_enable_clka0_output(struct device *d,
0477 struct device_attribute *attr, const char *buf, size_t count)
0478 {
0479 unsigned long flags;
0480 unsigned long tmp;
0481 unsigned char val;
0482
0483 sscanf(buf, "%lX", &tmp);
0484 dev_dbg(d, "tmp = 0x%lX\n", tmp);
0485
0486 val = (unsigned char)tmp;
0487 spin_lock_irqsave(&event_lock, flags);
0488 SET_PORT_BITS(TLCLK_REG2, 0xfe, val);
0489 spin_unlock_irqrestore(&event_lock, flags);
0490
0491 return strnlen(buf, count);
0492 }
0493
0494 static DEVICE_ATTR(enable_clka0_output, (S_IWUSR|S_IWGRP), NULL,
0495 store_enable_clka0_output);
0496
0497 static ssize_t store_select_amcb2_transmit_clock(struct device *d,
0498 struct device_attribute *attr, const char *buf, size_t count)
0499 {
0500 unsigned long flags;
0501 unsigned long tmp;
0502 unsigned char val;
0503
0504 sscanf(buf, "%lX", &tmp);
0505 dev_dbg(d, "tmp = 0x%lX\n", tmp);
0506
0507 val = (unsigned char)tmp;
0508 spin_lock_irqsave(&event_lock, flags);
0509 if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) {
0510 SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x28);
0511 SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val);
0512 } else if (val >= CLK_8_592MHz) {
0513 SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x38);
0514 switch (val) {
0515 case CLK_8_592MHz:
0516 SET_PORT_BITS(TLCLK_REG0, 0xfc, 2);
0517 break;
0518 case CLK_11_184MHz:
0519 SET_PORT_BITS(TLCLK_REG0, 0xfc, 0);
0520 break;
0521 case CLK_34_368MHz:
0522 SET_PORT_BITS(TLCLK_REG0, 0xfc, 3);
0523 break;
0524 case CLK_44_736MHz:
0525 SET_PORT_BITS(TLCLK_REG0, 0xfc, 1);
0526 break;
0527 }
0528 } else {
0529 SET_PORT_BITS(TLCLK_REG3, 0xc7, val << 3);
0530 }
0531 spin_unlock_irqrestore(&event_lock, flags);
0532
0533 return strnlen(buf, count);
0534 }
0535
0536 static DEVICE_ATTR(select_amcb2_transmit_clock, (S_IWUSR|S_IWGRP), NULL,
0537 store_select_amcb2_transmit_clock);
0538
0539 static ssize_t store_select_amcb1_transmit_clock(struct device *d,
0540 struct device_attribute *attr, const char *buf, size_t count)
0541 {
0542 unsigned long tmp;
0543 unsigned char val;
0544 unsigned long flags;
0545
0546 sscanf(buf, "%lX", &tmp);
0547 dev_dbg(d, "tmp = 0x%lX\n", tmp);
0548
0549 val = (unsigned char)tmp;
0550 spin_lock_irqsave(&event_lock, flags);
0551 if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) {
0552 SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x5);
0553 SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val);
0554 } else if (val >= CLK_8_592MHz) {
0555 SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x7);
0556 switch (val) {
0557 case CLK_8_592MHz:
0558 SET_PORT_BITS(TLCLK_REG0, 0xfc, 2);
0559 break;
0560 case CLK_11_184MHz:
0561 SET_PORT_BITS(TLCLK_REG0, 0xfc, 0);
0562 break;
0563 case CLK_34_368MHz:
0564 SET_PORT_BITS(TLCLK_REG0, 0xfc, 3);
0565 break;
0566 case CLK_44_736MHz:
0567 SET_PORT_BITS(TLCLK_REG0, 0xfc, 1);
0568 break;
0569 }
0570 } else {
0571 SET_PORT_BITS(TLCLK_REG3, 0xf8, val);
0572 }
0573 spin_unlock_irqrestore(&event_lock, flags);
0574
0575 return strnlen(buf, count);
0576 }
0577
0578 static DEVICE_ATTR(select_amcb1_transmit_clock, (S_IWUSR|S_IWGRP), NULL,
0579 store_select_amcb1_transmit_clock);
0580
0581 static ssize_t store_select_redundant_clock(struct device *d,
0582 struct device_attribute *attr, const char *buf, size_t count)
0583 {
0584 unsigned long tmp;
0585 unsigned char val;
0586 unsigned long flags;
0587
0588 sscanf(buf, "%lX", &tmp);
0589 dev_dbg(d, "tmp = 0x%lX\n", tmp);
0590
0591 val = (unsigned char)tmp;
0592 spin_lock_irqsave(&event_lock, flags);
0593 SET_PORT_BITS(TLCLK_REG1, 0xfe, val);
0594 spin_unlock_irqrestore(&event_lock, flags);
0595
0596 return strnlen(buf, count);
0597 }
0598
0599 static DEVICE_ATTR(select_redundant_clock, (S_IWUSR|S_IWGRP), NULL,
0600 store_select_redundant_clock);
0601
0602 static ssize_t store_select_ref_frequency(struct device *d,
0603 struct device_attribute *attr, const char *buf, size_t count)
0604 {
0605 unsigned long tmp;
0606 unsigned char val;
0607 unsigned long flags;
0608
0609 sscanf(buf, "%lX", &tmp);
0610 dev_dbg(d, "tmp = 0x%lX\n", tmp);
0611
0612 val = (unsigned char)tmp;
0613 spin_lock_irqsave(&event_lock, flags);
0614 SET_PORT_BITS(TLCLK_REG1, 0xfd, val);
0615 spin_unlock_irqrestore(&event_lock, flags);
0616
0617 return strnlen(buf, count);
0618 }
0619
0620 static DEVICE_ATTR(select_ref_frequency, (S_IWUSR|S_IWGRP), NULL,
0621 store_select_ref_frequency);
0622
0623 static ssize_t store_filter_select(struct device *d,
0624 struct device_attribute *attr, const char *buf, size_t count)
0625 {
0626 unsigned long tmp;
0627 unsigned char val;
0628 unsigned long flags;
0629
0630 sscanf(buf, "%lX", &tmp);
0631 dev_dbg(d, "tmp = 0x%lX\n", tmp);
0632
0633 val = (unsigned char)tmp;
0634 spin_lock_irqsave(&event_lock, flags);
0635 SET_PORT_BITS(TLCLK_REG0, 0xfb, val);
0636 spin_unlock_irqrestore(&event_lock, flags);
0637
0638 return strnlen(buf, count);
0639 }
0640
0641 static DEVICE_ATTR(filter_select, (S_IWUSR|S_IWGRP), NULL, store_filter_select);
0642
0643 static ssize_t store_hardware_switching_mode(struct device *d,
0644 struct device_attribute *attr, const char *buf, size_t count)
0645 {
0646 unsigned long tmp;
0647 unsigned char val;
0648 unsigned long flags;
0649
0650 sscanf(buf, "%lX", &tmp);
0651 dev_dbg(d, "tmp = 0x%lX\n", tmp);
0652
0653 val = (unsigned char)tmp;
0654 spin_lock_irqsave(&event_lock, flags);
0655 SET_PORT_BITS(TLCLK_REG0, 0xbf, val);
0656 spin_unlock_irqrestore(&event_lock, flags);
0657
0658 return strnlen(buf, count);
0659 }
0660
0661 static DEVICE_ATTR(hardware_switching_mode, (S_IWUSR|S_IWGRP), NULL,
0662 store_hardware_switching_mode);
0663
0664 static ssize_t store_hardware_switching(struct device *d,
0665 struct device_attribute *attr, const char *buf, size_t count)
0666 {
0667 unsigned long tmp;
0668 unsigned char val;
0669 unsigned long flags;
0670
0671 sscanf(buf, "%lX", &tmp);
0672 dev_dbg(d, "tmp = 0x%lX\n", tmp);
0673
0674 val = (unsigned char)tmp;
0675 spin_lock_irqsave(&event_lock, flags);
0676 SET_PORT_BITS(TLCLK_REG0, 0x7f, val);
0677 spin_unlock_irqrestore(&event_lock, flags);
0678
0679 return strnlen(buf, count);
0680 }
0681
0682 static DEVICE_ATTR(hardware_switching, (S_IWUSR|S_IWGRP), NULL,
0683 store_hardware_switching);
0684
0685 static ssize_t store_refalign (struct device *d,
0686 struct device_attribute *attr, const char *buf, size_t count)
0687 {
0688 unsigned long tmp;
0689 unsigned long flags;
0690
0691 sscanf(buf, "%lX", &tmp);
0692 dev_dbg(d, "tmp = 0x%lX\n", tmp);
0693 spin_lock_irqsave(&event_lock, flags);
0694 SET_PORT_BITS(TLCLK_REG0, 0xf7, 0);
0695 SET_PORT_BITS(TLCLK_REG0, 0xf7, 0x08);
0696 SET_PORT_BITS(TLCLK_REG0, 0xf7, 0);
0697 spin_unlock_irqrestore(&event_lock, flags);
0698
0699 return strnlen(buf, count);
0700 }
0701
0702 static DEVICE_ATTR(refalign, (S_IWUSR|S_IWGRP), NULL, store_refalign);
0703
0704 static ssize_t store_mode_select (struct device *d,
0705 struct device_attribute *attr, const char *buf, size_t count)
0706 {
0707 unsigned long tmp;
0708 unsigned char val;
0709 unsigned long flags;
0710
0711 sscanf(buf, "%lX", &tmp);
0712 dev_dbg(d, "tmp = 0x%lX\n", tmp);
0713
0714 val = (unsigned char)tmp;
0715 spin_lock_irqsave(&event_lock, flags);
0716 SET_PORT_BITS(TLCLK_REG0, 0xcf, val);
0717 spin_unlock_irqrestore(&event_lock, flags);
0718
0719 return strnlen(buf, count);
0720 }
0721
0722 static DEVICE_ATTR(mode_select, (S_IWUSR|S_IWGRP), NULL, store_mode_select);
0723
0724 static ssize_t store_reset (struct device *d,
0725 struct device_attribute *attr, const char *buf, size_t count)
0726 {
0727 unsigned long tmp;
0728 unsigned char val;
0729 unsigned long flags;
0730
0731 sscanf(buf, "%lX", &tmp);
0732 dev_dbg(d, "tmp = 0x%lX\n", tmp);
0733
0734 val = (unsigned char)tmp;
0735 spin_lock_irqsave(&event_lock, flags);
0736 SET_PORT_BITS(TLCLK_REG4, 0xfd, val);
0737 spin_unlock_irqrestore(&event_lock, flags);
0738
0739 return strnlen(buf, count);
0740 }
0741
0742 static DEVICE_ATTR(reset, (S_IWUSR|S_IWGRP), NULL, store_reset);
0743
0744 static struct attribute *tlclk_sysfs_entries[] = {
0745 &dev_attr_current_ref.attr,
0746 &dev_attr_telclock_version.attr,
0747 &dev_attr_alarms.attr,
0748 &dev_attr_received_ref_clk3a.attr,
0749 &dev_attr_received_ref_clk3b.attr,
0750 &dev_attr_enable_clk3a_output.attr,
0751 &dev_attr_enable_clk3b_output.attr,
0752 &dev_attr_enable_clkb1_output.attr,
0753 &dev_attr_enable_clka1_output.attr,
0754 &dev_attr_enable_clkb0_output.attr,
0755 &dev_attr_enable_clka0_output.attr,
0756 &dev_attr_select_amcb1_transmit_clock.attr,
0757 &dev_attr_select_amcb2_transmit_clock.attr,
0758 &dev_attr_select_redundant_clock.attr,
0759 &dev_attr_select_ref_frequency.attr,
0760 &dev_attr_filter_select.attr,
0761 &dev_attr_hardware_switching_mode.attr,
0762 &dev_attr_hardware_switching.attr,
0763 &dev_attr_refalign.attr,
0764 &dev_attr_mode_select.attr,
0765 &dev_attr_reset.attr,
0766 NULL
0767 };
0768
0769 static const struct attribute_group tlclk_attribute_group = {
0770 .name = NULL,
0771 .attrs = tlclk_sysfs_entries,
0772 };
0773
0774 static struct platform_device *tlclk_device;
0775
0776 static int __init tlclk_init(void)
0777 {
0778 int ret;
0779
0780 telclk_interrupt = (inb(TLCLK_REG7) & 0x0f);
0781
0782 alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL);
0783 if (!alarm_events) {
0784 ret = -ENOMEM;
0785 goto out1;
0786 }
0787
0788 ret = register_chrdev(tlclk_major, "telco_clock", &tlclk_fops);
0789 if (ret < 0) {
0790 printk(KERN_ERR "tlclk: can't get major %d.\n", tlclk_major);
0791 kfree(alarm_events);
0792 return ret;
0793 }
0794 tlclk_major = ret;
0795
0796
0797 if (!request_region(TLCLK_BASE, 8, "telco_clock")) {
0798 printk(KERN_ERR "tlclk: request_region 0x%X failed.\n",
0799 TLCLK_BASE);
0800 ret = -EBUSY;
0801 goto out2;
0802 }
0803
0804 if (0x0F == telclk_interrupt ) {
0805 printk(KERN_ERR "telclk_interrupt = 0x%x non-mcpbl0010 hw.\n",
0806 telclk_interrupt);
0807 ret = -ENXIO;
0808 goto out3;
0809 }
0810
0811 timer_setup(&switchover_timer, switchover_timeout, 0);
0812
0813 ret = misc_register(&tlclk_miscdev);
0814 if (ret < 0) {
0815 printk(KERN_ERR "tlclk: misc_register returns %d.\n", ret);
0816 goto out3;
0817 }
0818
0819 tlclk_device = platform_device_register_simple("telco_clock",
0820 -1, NULL, 0);
0821 if (IS_ERR(tlclk_device)) {
0822 printk(KERN_ERR "tlclk: platform_device_register failed.\n");
0823 ret = PTR_ERR(tlclk_device);
0824 goto out4;
0825 }
0826
0827 ret = sysfs_create_group(&tlclk_device->dev.kobj,
0828 &tlclk_attribute_group);
0829 if (ret) {
0830 printk(KERN_ERR "tlclk: failed to create sysfs device attributes.\n");
0831 goto out5;
0832 }
0833
0834 return 0;
0835 out5:
0836 platform_device_unregister(tlclk_device);
0837 out4:
0838 misc_deregister(&tlclk_miscdev);
0839 out3:
0840 release_region(TLCLK_BASE, 8);
0841 out2:
0842 kfree(alarm_events);
0843 unregister_chrdev(tlclk_major, "telco_clock");
0844 out1:
0845 return ret;
0846 }
0847
0848 static void __exit tlclk_cleanup(void)
0849 {
0850 sysfs_remove_group(&tlclk_device->dev.kobj, &tlclk_attribute_group);
0851 platform_device_unregister(tlclk_device);
0852 misc_deregister(&tlclk_miscdev);
0853 unregister_chrdev(tlclk_major, "telco_clock");
0854
0855 release_region(TLCLK_BASE, 8);
0856 del_timer_sync(&switchover_timer);
0857 kfree(alarm_events);
0858
0859 }
0860
0861 static void switchover_timeout(struct timer_list *unused)
0862 {
0863 unsigned long flags = tlclk_timer_data;
0864
0865 if ((flags & 1)) {
0866 if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08))
0867 alarm_events->switchover_primary++;
0868 } else {
0869 if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08))
0870 alarm_events->switchover_secondary++;
0871 }
0872
0873
0874 del_timer(&switchover_timer);
0875 got_event = 1;
0876 wake_up(&wq);
0877 }
0878
0879 static irqreturn_t tlclk_interrupt(int irq, void *dev_id)
0880 {
0881 unsigned long flags;
0882
0883 spin_lock_irqsave(&event_lock, flags);
0884
0885 int_events = inb(TLCLK_REG6);
0886
0887
0888 if (int_events & PRI_LOS_01_MASK) {
0889 if (inb(TLCLK_REG2) & SEC_LOST_MASK)
0890 alarm_events->lost_clocks++;
0891 else
0892 alarm_events->lost_primary_clock++;
0893 }
0894
0895
0896 if (int_events & PRI_LOS_10_MASK) {
0897 alarm_events->primary_clock_back++;
0898 SET_PORT_BITS(TLCLK_REG1, 0xFE, 1);
0899 }
0900
0901 if (int_events & SEC_LOS_01_MASK) {
0902 if (inb(TLCLK_REG2) & PRI_LOST_MASK)
0903 alarm_events->lost_clocks++;
0904 else
0905 alarm_events->lost_secondary_clock++;
0906 }
0907
0908 if (int_events & SEC_LOS_10_MASK) {
0909 alarm_events->secondary_clock_back++;
0910 SET_PORT_BITS(TLCLK_REG1, 0xFE, 0);
0911 }
0912 if (int_events & HOLDOVER_10_MASK)
0913 alarm_events->pll_end_holdover++;
0914
0915 if (int_events & UNLOCK_01_MASK)
0916 alarm_events->pll_lost_sync++;
0917
0918 if (int_events & UNLOCK_10_MASK)
0919 alarm_events->pll_sync++;
0920
0921
0922 if (int_events & HOLDOVER_01_MASK) {
0923 alarm_events->pll_holdover++;
0924
0925
0926 switchover_timer.expires = jiffies + msecs_to_jiffies(10);
0927 tlclk_timer_data = inb(TLCLK_REG1);
0928 mod_timer(&switchover_timer, switchover_timer.expires);
0929 } else {
0930 got_event = 1;
0931 wake_up(&wq);
0932 }
0933 spin_unlock_irqrestore(&event_lock, flags);
0934
0935 return IRQ_HANDLED;
0936 }
0937
0938 module_init(tlclk_init);
0939 module_exit(tlclk_cleanup);