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/slab.h> 36 #include <linux/ioport.h> 37 #include <linux/interrupt.h> 38 #include <linux/spinlock.h> 39 #include <linux/smp_lock.h> 40 #include <linux/timer.h> 41 #include <linux/sysfs.h> 42 #include <linux/device.h> 43 #include <linux/miscdevice.h> 44 #include <linux/platform_device.h> 45 #include <asm/io.h> /* inb/outb */ 46 #include <asm/uaccess.h> 47 48 MODULE_AUTHOR("Sebastien Bouchard <sebastien.bouchard@ca.kontron.com>"); 49 MODULE_LICENSE("GPL"); 50 51 /*Hardware Reset of the PLL */ 52 #define RESET_ON 0x00 53 #define RESET_OFF 0x01 54 55 /* MODE SELECT */ 56 #define NORMAL_MODE 0x00 57 #define HOLDOVER_MODE 0x10 58 #define FREERUN_MODE 0x20 59 60 /* FILTER SELECT */ 61 #define FILTER_6HZ 0x04 62 #define FILTER_12HZ 0x00 63 64 /* SELECT REFERENCE FREQUENCY */ 65 #define REF_CLK1_8kHz 0x00 66 #define REF_CLK2_19_44MHz 0x02 67 68 /* Select primary or secondary redundant clock */ 69 #define PRIMARY_CLOCK 0x00 70 #define SECONDARY_CLOCK 0x01 71 72 /* CLOCK TRANSMISSION DEFINE */ 73 #define CLK_8kHz 0xff 74 #define CLK_16_384MHz 0xfb 75 76 #define CLK_1_544MHz 0x00 77 #define CLK_2_048MHz 0x01 78 #define CLK_4_096MHz 0x02 79 #define CLK_6_312MHz 0x03 80 #define CLK_8_192MHz 0x04 81 #define CLK_19_440MHz 0x06 82 83 #define CLK_8_592MHz 0x08 84 #define CLK_11_184MHz 0x09 85 #define CLK_34_368MHz 0x0b 86 #define CLK_44_736MHz 0x0a 87 88 /* RECEIVED REFERENCE */ 89 #define AMC_B1 0 90 #define AMC_B2 1 91 92 /* HARDWARE SWITCHING DEFINE */ 93 #define HW_ENABLE 0x80 94 #define HW_DISABLE 0x00 95 96 /* HARDWARE SWITCHING MODE DEFINE */ 97 #define PLL_HOLDOVER 0x40 98 #define LOST_CLOCK 0x00 99 100 /* ALARMS DEFINE */ 101 #define UNLOCK_MASK 0x10 102 #define HOLDOVER_MASK 0x20 103 #define SEC_LOST_MASK 0x40 104 #define PRI_LOST_MASK 0x80 105 106 /* INTERRUPT CAUSE DEFINE */ 107 108 #define PRI_LOS_01_MASK 0x01 109 #define PRI_LOS_10_MASK 0x02 110 111 #define SEC_LOS_01_MASK 0x04 112 #define SEC_LOS_10_MASK 0x08 113 114 #define HOLDOVER_01_MASK 0x10 115 #define HOLDOVER_10_MASK 0x20 116 117 #define UNLOCK_01_MASK 0x40 118 #define UNLOCK_10_MASK 0x80 119 120 struct tlclk_alarms { 121 __u32 lost_clocks; 122 __u32 lost_primary_clock; 123 __u32 lost_secondary_clock; 124 __u32 primary_clock_back; 125 __u32 secondary_clock_back; 126 __u32 switchover_primary; 127 __u32 switchover_secondary; 128 __u32 pll_holdover; 129 __u32 pll_end_holdover; 130 __u32 pll_lost_sync; 131 __u32 pll_sync; 132 }; 133 /* Telecom clock I/O register definition */ 134 #define TLCLK_BASE 0xa08 135 #define TLCLK_REG0 TLCLK_BASE 136 #define TLCLK_REG1 (TLCLK_BASE+1) 137 #define TLCLK_REG2 (TLCLK_BASE+2) 138 #define TLCLK_REG3 (TLCLK_BASE+3) 139 #define TLCLK_REG4 (TLCLK_BASE+4) 140 #define TLCLK_REG5 (TLCLK_BASE+5) 141 #define TLCLK_REG6 (TLCLK_BASE+6) 142 #define TLCLK_REG7 (TLCLK_BASE+7) 143 144 #define SET_PORT_BITS(port, mask, val) outb(((inb(port) & mask) | val), port) 145 146 /* 0 = Dynamic allocation of the major device number */ 147 #define TLCLK_MAJOR 0 148 149 /* sysfs interface definition: 150 Upon loading the driver will create a sysfs directory under 151 /sys/devices/platform/telco_clock. 152 153 This directory exports the following interfaces. There operation is 154 documented in the MCPBL0010 TPS under the Telecom Clock API section, 11.4. 155 alarms : 156 current_ref : 157 received_ref_clk3a : 158 received_ref_clk3b : 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 telclock_version : 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 177 All sysfs interfaces are integers in hex format, i.e echo 99 > refalign 178 has the same effect as echo 0x99 > refalign. 179 */ 180 181 static unsigned int telclk_interrupt; 182 183 static int int_events; /* Event that generate a interrupt */ 184 static int got_event; /* if events processing have been done */ 185 186 static void switchover_timeout(unsigned long data); 187 static struct timer_list switchover_timer = 188 TIMER_INITIALIZER(switchover_timeout , 0, 0); 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 204 static int tlclk_open(struct inode *inode, struct file *filp) 205 { 206 int result; 207 208 lock_kernel(); 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 IRQF_DISABLED, "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 unlock_kernel(); 232 return result; 233 } 234 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 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 270 }; 271 272 static struct miscdevice tlclk_miscdev = { 273 .minor = MISC_DYNAMIC_MINOR, 274 .name = "telco_clock", 275 .fops = &tlclk_fops, 276 }; 277 278 static ssize_t show_current_ref(struct device *d, 279 struct device_attribute *attr, char *buf) 280 { 281 unsigned long ret_val; 282 unsigned long flags; 283 284 spin_lock_irqsave(&event_lock, flags); 285 ret_val = ((inb(TLCLK_REG1) & 0x08) >> 3); 286 spin_unlock_irqrestore(&event_lock, flags); 287 288 return sprintf(buf, "0x%lX\n", ret_val); 289 } 290 291 static DEVICE_ATTR(current_ref, S_IRUGO, show_current_ref, NULL); 292 293 294 static ssize_t show_telclock_version(struct device *d, 295 struct device_attribute *attr, char *buf) 296 { 297 unsigned long ret_val; 298 unsigned long flags; 299 300 spin_lock_irqsave(&event_lock, flags); 301 ret_val = inb(TLCLK_REG5); 302 spin_unlock_irqrestore(&event_lock, flags); 303 304 return sprintf(buf, "0x%lX\n", ret_val); 305 } 306 307 static DEVICE_ATTR(telclock_version, S_IRUGO, 308 show_telclock_version, NULL); 309 310 static ssize_t show_alarms(struct device *d, 311 struct device_attribute *attr, char *buf) 312 { 313 unsigned long ret_val; 314 unsigned long flags; 315 316 spin_lock_irqsave(&event_lock, flags); 317 ret_val = (inb(TLCLK_REG2) & 0xf0); 318 spin_unlock_irqrestore(&event_lock, flags); 319 320 return sprintf(buf, "0x%lX\n", ret_val); 321 } 322 323 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); 324 325 static ssize_t store_received_ref_clk3a(struct device *d, 326 struct device_attribute *attr, const char *buf, size_t count) 327 { 328 unsigned long tmp; 329 unsigned char val; 330 unsigned long flags; 331 332 sscanf(buf, "%lX", &tmp); 333 dev_dbg(d, ": tmp = 0x%lX\n", tmp); 334 335 val = (unsigned char)tmp; 336 spin_lock_irqsave(&event_lock, flags); 337 SET_PORT_BITS(TLCLK_REG1, 0xef, val); 338 spin_unlock_irqrestore(&event_lock, flags); 339 340 return strnlen(buf, count); 341 } 342 343 static DEVICE_ATTR(received_ref_clk3a, (S_IWUSR|S_IWGRP), NULL, 344 store_received_ref_clk3a); 345 346 347 static ssize_t store_received_ref_clk3b(struct device *d, 348 struct device_attribute *attr, const char *buf, size_t count) 349 { 350 unsigned long tmp; 351 unsigned char val; 352 unsigned long flags; 353 354 sscanf(buf, "%lX", &tmp); 355 dev_dbg(d, ": tmp = 0x%lX\n", tmp); 356 357 val = (unsigned char)tmp; 358 spin_lock_irqsave(&event_lock, flags); 359 SET_PORT_BITS(TLCLK_REG1, 0xdf, val << 1); 360 spin_unlock_irqrestore(&event_lock, flags); 361 362 return strnlen(buf, count); 363 } 364 365 static DEVICE_ATTR(received_ref_clk3b, (S_IWUSR|S_IWGRP), NULL, 366 store_received_ref_clk3b); 367 368 369 static ssize_t store_enable_clk3b_output(struct device *d, 370 struct device_attribute *attr, const char *buf, size_t count) 371 { 372 unsigned long tmp; 373 unsigned char val; 374 unsigned long flags; 375 376 sscanf(buf, "%lX", &tmp); 377 dev_dbg(d, ": tmp = 0x%lX\n", tmp); 378 379 val = (unsigned char)tmp; 380 spin_lock_irqsave(&event_lock, flags); 381 SET_PORT_BITS(TLCLK_REG3, 0x7f, val << 7); 382 spin_unlock_irqrestore(&event_lock, flags); 383 384 return strnlen(buf, count); 385 } 386 387 static DEVICE_ATTR(enable_clk3b_output, (S_IWUSR|S_IWGRP), NULL, 388 store_enable_clk3b_output); 389 390 static ssize_t store_enable_clk3a_output(struct device *d, 391 struct device_attribute *attr, const char *buf, size_t count) 392 { 393 unsigned long flags; 394 unsigned long tmp; 395 unsigned char val; 396 397 sscanf(buf, "%lX", &tmp); 398 dev_dbg(d, "tmp = 0x%lX\n", tmp); 399 400 val = (unsigned char)tmp; 401 spin_lock_irqsave(&event_lock, flags); 402 SET_PORT_BITS(TLCLK_REG3, 0xbf, val << 6); 403 spin_unlock_irqrestore(&event_lock, flags); 404 405 return strnlen(buf, count); 406 } 407 408 static DEVICE_ATTR(enable_clk3a_output, (S_IWUSR|S_IWGRP), NULL, 409 store_enable_clk3a_output); 410 411 static ssize_t store_enable_clkb1_output(struct device *d, 412 struct device_attribute *attr, const char *buf, size_t count) 413 { 414 unsigned long flags; 415 unsigned long tmp; 416 unsigned char val; 417 418 sscanf(buf, "%lX", &tmp); 419 dev_dbg(d, "tmp = 0x%lX\n", tmp); 420 421 val = (unsigned char)tmp; 422 spin_lock_irqsave(&event_lock, flags); 423 SET_PORT_BITS(TLCLK_REG2, 0xf7, val << 3); 424 spin_unlock_irqrestore(&event_lock, flags); 425 426 return strnlen(buf, count); 427 } 428 429 static DEVICE_ATTR(enable_clkb1_output, (S_IWUSR|S_IWGRP), NULL, 430 store_enable_clkb1_output); 431 432 433 static ssize_t store_enable_clka1_output(struct device *d, 434 struct device_attribute *attr, const char *buf, size_t count) 435 { 436 unsigned long flags; 437 unsigned long tmp; 438 unsigned char val; 439 440 sscanf(buf, "%lX", &tmp); 441 dev_dbg(d, "tmp = 0x%lX\n", tmp); 442 443 val = (unsigned char)tmp; 444 spin_lock_irqsave(&event_lock, flags); 445 SET_PORT_BITS(TLCLK_REG2, 0xfb, val << 2); 446 spin_unlock_irqrestore(&event_lock, flags); 447 448 return strnlen(buf, count); 449 } 450 451 static DEVICE_ATTR(enable_clka1_output, (S_IWUSR|S_IWGRP), NULL, 452 store_enable_clka1_output); 453 454 static ssize_t store_enable_clkb0_output(struct device *d, 455 struct device_attribute *attr, const char *buf, size_t count) 456 { 457 unsigned long flags; 458 unsigned long tmp; 459 unsigned char val; 460 461 sscanf(buf, "%lX", &tmp); 462 dev_dbg(d, "tmp = 0x%lX\n", tmp); 463 464 val = (unsigned char)tmp; 465 spin_lock_irqsave(&event_lock, flags); 466 SET_PORT_BITS(TLCLK_REG2, 0xfd, val << 1); 467 spin_unlock_irqrestore(&event_lock, flags); 468 469 return strnlen(buf, count); 470 } 471 472 static DEVICE_ATTR(enable_clkb0_output, (S_IWUSR|S_IWGRP), NULL, 473 store_enable_clkb0_output); 474 475 static ssize_t store_enable_clka0_output(struct device *d, 476 struct device_attribute *attr, const char *buf, size_t count) 477 { 478 unsigned long flags; 479 unsigned long tmp; 480 unsigned char val; 481 482 sscanf(buf, "%lX", &tmp); 483 dev_dbg(d, "tmp = 0x%lX\n", tmp); 484 485 val = (unsigned char)tmp; 486 spin_lock_irqsave(&event_lock, flags); 487 SET_PORT_BITS(TLCLK_REG2, 0xfe, val); 488 spin_unlock_irqrestore(&event_lock, flags); 489 490 return strnlen(buf, count); 491 } 492 493 static DEVICE_ATTR(enable_clka0_output, (S_IWUSR|S_IWGRP), NULL, 494 store_enable_clka0_output); 495 496 static ssize_t store_select_amcb2_transmit_clock(struct device *d, 497 struct device_attribute *attr, const char *buf, size_t count) 498 { 499 unsigned long flags; 500 unsigned long tmp; 501 unsigned char val; 502 503 sscanf(buf, "%lX", &tmp); 504 dev_dbg(d, "tmp = 0x%lX\n", tmp); 505 506 val = (unsigned char)tmp; 507 spin_lock_irqsave(&event_lock, flags); 508 if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) { 509 SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x28); 510 SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val); 511 } else if (val >= CLK_8_592MHz) { 512 SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x38); 513 switch (val) { 514 case CLK_8_592MHz: 515 SET_PORT_BITS(TLCLK_REG0, 0xfc, 2); 516 break; 517 case CLK_11_184MHz: 518 SET_PORT_BITS(TLCLK_REG0, 0xfc, 0); 519 break; 520 case CLK_34_368MHz: 521 SET_PORT_BITS(TLCLK_REG0, 0xfc, 3); 522 break; 523 case CLK_44_736MHz: 524 SET_PORT_BITS(TLCLK_REG0, 0xfc, 1); 525 break; 526 } 527 } else 528 SET_PORT_BITS(TLCLK_REG3, 0xc7, val << 3); 529 530 spin_unlock_irqrestore(&event_lock, flags); 531 532 return strnlen(buf, count); 533 } 534 535 static DEVICE_ATTR(select_amcb2_transmit_clock, (S_IWUSR|S_IWGRP), NULL, 536 store_select_amcb2_transmit_clock); 537 538 static ssize_t store_select_amcb1_transmit_clock(struct device *d, 539 struct device_attribute *attr, const char *buf, size_t count) 540 { 541 unsigned long tmp; 542 unsigned char val; 543 unsigned long flags; 544 545 sscanf(buf, "%lX", &tmp); 546 dev_dbg(d, "tmp = 0x%lX\n", tmp); 547 548 val = (unsigned char)tmp; 549 spin_lock_irqsave(&event_lock, flags); 550 if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) { 551 SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x5); 552 SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val); 553 } else if (val >= CLK_8_592MHz) { 554 SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x7); 555 switch (val) { 556 case CLK_8_592MHz: 557 SET_PORT_BITS(TLCLK_REG0, 0xfc, 2); 558 break; 559 case CLK_11_184MHz: 560 SET_PORT_BITS(TLCLK_REG0, 0xfc, 0); 561 break; 562 case CLK_34_368MHz: 563 SET_PORT_BITS(TLCLK_REG0, 0xfc, 3); 564 break; 565 case CLK_44_736MHz: 566 SET_PORT_BITS(TLCLK_REG0, 0xfc, 1); 567 break; 568 } 569 } else 570 SET_PORT_BITS(TLCLK_REG3, 0xf8, val); 571 spin_unlock_irqrestore(&event_lock, flags); 572 573 return strnlen(buf, count); 574 } 575 576 static DEVICE_ATTR(select_amcb1_transmit_clock, (S_IWUSR|S_IWGRP), NULL, 577 store_select_amcb1_transmit_clock); 578 579 static ssize_t store_select_redundant_clock(struct device *d, 580 struct device_attribute *attr, const char *buf, size_t count) 581 { 582 unsigned long tmp; 583 unsigned char val; 584 unsigned long flags; 585 586 sscanf(buf, "%lX", &tmp); 587 dev_dbg(d, "tmp = 0x%lX\n", tmp); 588 589 val = (unsigned char)tmp; 590 spin_lock_irqsave(&event_lock, flags); 591 SET_PORT_BITS(TLCLK_REG1, 0xfe, val); 592 spin_unlock_irqrestore(&event_lock, flags); 593 594 return strnlen(buf, count); 595 } 596 597 static DEVICE_ATTR(select_redundant_clock, (S_IWUSR|S_IWGRP), NULL, 598 store_select_redundant_clock); 599 600 static ssize_t store_select_ref_frequency(struct device *d, 601 struct device_attribute *attr, const char *buf, size_t count) 602 { 603 unsigned long tmp; 604 unsigned char val; 605 unsigned long flags; 606 607 sscanf(buf, "%lX", &tmp); 608 dev_dbg(d, "tmp = 0x%lX\n", tmp); 609 610 val = (unsigned char)tmp; 611 spin_lock_irqsave(&event_lock, flags); 612 SET_PORT_BITS(TLCLK_REG1, 0xfd, val); 613 spin_unlock_irqrestore(&event_lock, flags); 614 615 return strnlen(buf, count); 616 } 617 618 static DEVICE_ATTR(select_ref_frequency, (S_IWUSR|S_IWGRP), NULL, 619 store_select_ref_frequency); 620 621 static ssize_t store_filter_select(struct device *d, 622 struct device_attribute *attr, const char *buf, size_t count) 623 { 624 unsigned long tmp; 625 unsigned char val; 626 unsigned long flags; 627 628 sscanf(buf, "%lX", &tmp); 629 dev_dbg(d, "tmp = 0x%lX\n", tmp); 630 631 val = (unsigned char)tmp; 632 spin_lock_irqsave(&event_lock, flags); 633 SET_PORT_BITS(TLCLK_REG0, 0xfb, val); 634 spin_unlock_irqrestore(&event_lock, flags); 635 636 return strnlen(buf, count); 637 } 638 639 static DEVICE_ATTR(filter_select, (S_IWUSR|S_IWGRP), NULL, store_filter_select); 640 641 static ssize_t store_hardware_switching_mode(struct device *d, 642 struct device_attribute *attr, const char *buf, size_t count) 643 { 644 unsigned long tmp; 645 unsigned char val; 646 unsigned long flags; 647 648 sscanf(buf, "%lX", &tmp); 649 dev_dbg(d, "tmp = 0x%lX\n", tmp); 650 651 val = (unsigned char)tmp; 652 spin_lock_irqsave(&event_lock, flags); 653 SET_PORT_BITS(TLCLK_REG0, 0xbf, val); 654 spin_unlock_irqrestore(&event_lock, flags); 655 656 return strnlen(buf, count); 657 } 658 659 static DEVICE_ATTR(hardware_switching_mode, (S_IWUSR|S_IWGRP), NULL, 660 store_hardware_switching_mode); 661 662 static ssize_t store_hardware_switching(struct device *d, 663 struct device_attribute *attr, const char *buf, size_t count) 664 { 665 unsigned long tmp; 666 unsigned char val; 667 unsigned long flags; 668 669 sscanf(buf, "%lX", &tmp); 670 dev_dbg(d, "tmp = 0x%lX\n", tmp); 671 672 val = (unsigned char)tmp; 673 spin_lock_irqsave(&event_lock, flags); 674 SET_PORT_BITS(TLCLK_REG0, 0x7f, val); 675 spin_unlock_irqrestore(&event_lock, flags); 676 677 return strnlen(buf, count); 678 } 679 680 static DEVICE_ATTR(hardware_switching, (S_IWUSR|S_IWGRP), NULL, 681 store_hardware_switching); 682 683 static ssize_t store_refalign (struct device *d, 684 struct device_attribute *attr, const char *buf, size_t count) 685 { 686 unsigned long tmp; 687 unsigned long flags; 688 689 sscanf(buf, "%lX", &tmp); 690 dev_dbg(d, "tmp = 0x%lX\n", tmp); 691 spin_lock_irqsave(&event_lock, flags); 692 SET_PORT_BITS(TLCLK_REG0, 0xf7, 0); 693 SET_PORT_BITS(TLCLK_REG0, 0xf7, 0x08); 694 SET_PORT_BITS(TLCLK_REG0, 0xf7, 0); 695 spin_unlock_irqrestore(&event_lock, flags); 696 697 return strnlen(buf, count); 698 } 699 700 static DEVICE_ATTR(refalign, (S_IWUSR|S_IWGRP), NULL, store_refalign); 701 702 static ssize_t store_mode_select (struct device *d, 703 struct device_attribute *attr, const char *buf, size_t count) 704 { 705 unsigned long tmp; 706 unsigned char val; 707 unsigned long flags; 708 709 sscanf(buf, "%lX", &tmp); 710 dev_dbg(d, "tmp = 0x%lX\n", tmp); 711 712 val = (unsigned char)tmp; 713 spin_lock_irqsave(&event_lock, flags); 714 SET_PORT_BITS(TLCLK_REG0, 0xcf, val); 715 spin_unlock_irqrestore(&event_lock, flags); 716 717 return strnlen(buf, count); 718 } 719 720 static DEVICE_ATTR(mode_select, (S_IWUSR|S_IWGRP), NULL, store_mode_select); 721 722 static ssize_t store_reset (struct device *d, 723 struct device_attribute *attr, const char *buf, size_t count) 724 { 725 unsigned long tmp; 726 unsigned char val; 727 unsigned long flags; 728 729 sscanf(buf, "%lX", &tmp); 730 dev_dbg(d, "tmp = 0x%lX\n", tmp); 731 732 val = (unsigned char)tmp; 733 spin_lock_irqsave(&event_lock, flags); 734 SET_PORT_BITS(TLCLK_REG4, 0xfd, val); 735 spin_unlock_irqrestore(&event_lock, flags); 736 737 return strnlen(buf, count); 738 } 739 740 static DEVICE_ATTR(reset, (S_IWUSR|S_IWGRP), NULL, store_reset); 741 742 static struct attribute *tlclk_sysfs_entries[] = { 743 &dev_attr_current_ref.attr, 744 &dev_attr_telclock_version.attr, 745 &dev_attr_alarms.attr, 746 &dev_attr_received_ref_clk3a.attr, 747 &dev_attr_received_ref_clk3b.attr, 748 &dev_attr_enable_clk3a_output.attr, 749 &dev_attr_enable_clk3b_output.attr, 750 &dev_attr_enable_clkb1_output.attr, 751 &dev_attr_enable_clka1_output.attr, 752 &dev_attr_enable_clkb0_output.attr, 753 &dev_attr_enable_clka0_output.attr, 754 &dev_attr_select_amcb1_transmit_clock.attr, 755 &dev_attr_select_amcb2_transmit_clock.attr, 756 &dev_attr_select_redundant_clock.attr, 757 &dev_attr_select_ref_frequency.attr, 758 &dev_attr_filter_select.attr, 759 &dev_attr_hardware_switching_mode.attr, 760 &dev_attr_hardware_switching.attr, 761 &dev_attr_refalign.attr, 762 &dev_attr_mode_select.attr, 763 &dev_attr_reset.attr, 764 NULL 765 }; 766 767 static struct attribute_group tlclk_attribute_group = { 768 .name = NULL, /* put in device directory */ 769 .attrs = tlclk_sysfs_entries, 770 }; 771 772 static struct platform_device *tlclk_device; 773 774 static int __init tlclk_init(void) 775 { 776 int ret; 777 778 ret = register_chrdev(tlclk_major, "telco_clock", &tlclk_fops); 779 if (ret < 0) { 780 printk(KERN_ERR "tlclk: can't get major %d.\n", tlclk_major); 781 return ret; 782 } 783 tlclk_major = ret; 784 alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL); 785 if (!alarm_events) 786 goto out1; 787 788 /* Read telecom clock IRQ number (Set by BIOS) */ 789 if (!request_region(TLCLK_BASE, 8, "telco_clock")) { 790 printk(KERN_ERR "tlclk: request_region 0x%X failed.\n", 791 TLCLK_BASE); 792 ret = -EBUSY; 793 goto out2; 794 } 795 telclk_interrupt = (inb(TLCLK_REG7) & 0x0f); 796 797 if (0x0F == telclk_interrupt ) { /* not MCPBL0010 ? */ 798 printk(KERN_ERR "telclk_interrup = 0x%x non-mcpbl0010 hw.\n", 799 telclk_interrupt); 800 ret = -ENXIO; 801 goto out3; 802 } 803 804 init_timer(&switchover_timer); 805 806 ret = misc_register(&tlclk_miscdev); 807 if (ret < 0) { 808 printk(KERN_ERR "tlclk: misc_register returns %d.\n", ret); 809 goto out3; 810 } 811 812 tlclk_device = platform_device_register_simple("telco_clock", 813 -1, NULL, 0); 814 if (IS_ERR(tlclk_device)) { 815 printk(KERN_ERR "tlclk: platform_device_register failed.\n"); 816 ret = PTR_ERR(tlclk_device); 817 goto out4; 818 } 819 820 ret = sysfs_create_group(&tlclk_device->dev.kobj, 821 &tlclk_attribute_group); 822 if (ret) { 823 printk(KERN_ERR "tlclk: failed to create sysfs device attributes.\n"); 824 goto out5; 825 } 826 827 return 0; 828 out5: 829 platform_device_unregister(tlclk_device); 830 out4: 831 misc_deregister(&tlclk_miscdev); 832 out3: 833 release_region(TLCLK_BASE, 8); 834 out2: 835 kfree(alarm_events); 836 out1: 837 unregister_chrdev(tlclk_major, "telco_clock"); 838 return ret; 839 } 840 841 static void __exit tlclk_cleanup(void) 842 { 843 sysfs_remove_group(&tlclk_device->dev.kobj, &tlclk_attribute_group); 844 platform_device_unregister(tlclk_device); 845 misc_deregister(&tlclk_miscdev); 846 unregister_chrdev(tlclk_major, "telco_clock"); 847 848 release_region(TLCLK_BASE, 8); 849 del_timer_sync(&switchover_timer); 850 kfree(alarm_events); 851 852 } 853 854 static void switchover_timeout(unsigned long data) 855 { 856 unsigned long flags = *(unsigned long *) data; 857 858 if ((flags & 1)) { 859 if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08)) 860 alarm_events->switchover_primary++; 861 } else { 862 if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08)) 863 alarm_events->switchover_secondary++; 864 } 865 866 /* Alarm processing is done, wake up read task */ 867 del_timer(&switchover_timer); 868 got_event = 1; 869 wake_up(&wq); 870 } 871 872 static irqreturn_t tlclk_interrupt(int irq, void *dev_id) 873 { 874 unsigned long flags; 875 876 spin_lock_irqsave(&event_lock, flags); 877 /* Read and clear interrupt events */ 878 int_events = inb(TLCLK_REG6); 879 880 /* Primary_Los changed from 0 to 1 ? */ 881 if (int_events & PRI_LOS_01_MASK) { 882 if (inb(TLCLK_REG2) & SEC_LOST_MASK) 883 alarm_events->lost_clocks++; 884 else 885 alarm_events->lost_primary_clock++; 886 } 887 888 /* Primary_Los changed from 1 to 0 ? */ 889 if (int_events & PRI_LOS_10_MASK) { 890 alarm_events->primary_clock_back++; 891 SET_PORT_BITS(TLCLK_REG1, 0xFE, 1); 892 } 893 /* Secondary_Los changed from 0 to 1 ? */ 894 if (int_events & SEC_LOS_01_MASK) { 895 if (inb(TLCLK_REG2) & PRI_LOST_MASK) 896 alarm_events->lost_clocks++; 897 else 898 alarm_events->lost_secondary_clock++; 899 } 900 /* Secondary_Los changed from 1 to 0 ? */ 901 if (int_events & SEC_LOS_10_MASK) { 902 alarm_events->secondary_clock_back++; 903 SET_PORT_BITS(TLCLK_REG1, 0xFE, 0); 904 } 905 if (int_events & HOLDOVER_10_MASK) 906 alarm_events->pll_end_holdover++; 907 908 if (int_events & UNLOCK_01_MASK) 909 alarm_events->pll_lost_sync++; 910 911 if (int_events & UNLOCK_10_MASK) 912 alarm_events->pll_sync++; 913 914 /* Holdover changed from 0 to 1 ? */ 915 if (int_events & HOLDOVER_01_MASK) { 916 alarm_events->pll_holdover++; 917 918 /* TIMEOUT in ~10ms */ 919 switchover_timer.expires = jiffies + msecs_to_jiffies(10); 920 tlclk_timer_data = inb(TLCLK_REG1); 921 switchover_timer.data = (unsigned long) &tlclk_timer_data; 922 mod_timer(&switchover_timer, switchover_timer.expires); 923 } else { 924 got_event = 1; 925 wake_up(&wq); 926 } 927 spin_unlock_irqrestore(&event_lock, flags); 928 929 return IRQ_HANDLED; 930 } 931 932 module_init(tlclk_init); 933 module_exit(tlclk_cleanup); 934