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