1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 /* 28 * The "todds1287" module has implementation for both tod 29 * and power button (pbio) interfaces. This driver controls 30 * RTC & APC units of National Semiconductor's 87317 SuperI/O 31 * chip. The tod interface accesses the RTC unit and pbio 32 * interface accesses the APC unit of SuperI/O. Since both 33 * units are implemented in the same Logical Device, registers 34 * for both units are accessible through a common set of index 35 * address & data registers. That is why both interfaces are 36 * implemented in a same driver. 37 * 38 * The APC unit is used to implement the power button. When the 39 * button momentarily is pressed, an interrupt is generated and 40 * at the same time a Fail-safe timer starts to run. If the 41 * timer is not stopped in 21 seconds, the power to system is 42 * turned off. So the first task in the interrupt handler is to 43 * reset the Fail-safe timer. Note that OBP is not clearing 44 * the Fail-safe timer due to limitation in handling interrupts, 45 * so when OBP is running, the power button should be pressed 46 * and held for 4 seconds for the power to go off, otherwise 47 * a momentarily press will delay the power-off for 21 seconds. 48 * 49 * PSARC/1999/393 describes the pbio(7I) interface. 50 */ 51 52 #include <sys/types.h> 53 #include <sys/conf.h> 54 #include <sys/kmem.h> 55 #include <sys/open.h> 56 #include <sys/ddi.h> 57 #include <sys/sunddi.h> 58 59 #include <sys/todds1287.h> 60 #include <sys/modctl.h> 61 #include <sys/stat.h> 62 #include <sys/clock.h> 63 #include <sys/reboot.h> 64 #include <sys/machsystm.h> 65 #include <sys/poll.h> 66 #include <sys/pbio.h> 67 68 #define ABORT_INCREMENT_DELAY 10 69 70 static timestruc_t todds_get(void); 71 static void todds_set(timestruc_t); 72 static uint_t todds_set_watchdog_timer(uint_t); 73 static uint_t todds_clear_watchdog_timer(void); 74 static void todds_set_power_alarm(timestruc_t); 75 static void todds_clear_power_alarm(void); 76 static uint64_t todds_get_cpufrequency(void); 77 78 extern uint64_t find_cpufrequency(volatile uint8_t *); 79 80 /* 81 * External variables 82 */ 83 extern int watchdog_activated; 84 extern uint_t watchdog_timeout_seconds; 85 extern volatile uint8_t *v_pmc_addr_reg; 86 87 /* 88 * Global variables 89 */ 90 int ds1287_debug_flags; 91 int ds1287_caddr_warn; 92 93 /* 94 * cb ops 95 */ 96 static int ds1287_open(dev_t *, int, int, cred_t *); 97 static int ds1287_close(dev_t, int, int, cred_t *); 98 static int ds1287_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); 99 static int ds1287_chpoll(dev_t, short, int, short *, struct pollhead **); 100 101 static void read_rtc(struct rtc_t *); 102 static void write_rtc_time(struct rtc_t *); 103 static void write_rtc_alarm(struct rtc_t *); 104 static void select_bank(int bank); 105 static uint_t ds1287_intr(caddr_t); 106 static uint_t ds1287_softintr(caddr_t); 107 static void ds1287_timeout(caddr_t); 108 static uint_t ds1287_issue_shutdown(caddr_t); 109 static void ds1287_log_message(void); 110 111 static struct cb_ops ds1287_cbops = { 112 ds1287_open, /* open */ 113 ds1287_close, /* close */ 114 nodev, /* strategy */ 115 nodev, /* print */ 116 nodev, /* dump */ 117 nodev, /* read */ 118 nodev, /* write */ 119 ds1287_ioctl, /* ioctl */ 120 nodev, /* devmap */ 121 nodev, /* mmap */ 122 nodev, /* segmap */ 123 ds1287_chpoll, /* poll */ 124 ddi_prop_op, /* cb_prop_op */ 125 NULL, /* streamtab */ 126 D_NEW | D_MP, /* Driver compatibility flag */ 127 CB_REV, /* rev */ 128 nodev, /* int (*cb_aread)() */ 129 nodev /* int (*cb_awrite)() */ 130 }; 131 132 /* 133 * dev ops 134 */ 135 static int ds1287_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 136 static int ds1287_attach(dev_info_t *, ddi_attach_cmd_t); 137 static int ds1287_detach(dev_info_t *, ddi_detach_cmd_t); 138 139 static struct dev_ops ds1287_ops = { 140 DEVO_REV, /* devo_rev */ 141 0, /* refcnt */ 142 ds1287_getinfo, /* getinfo */ 143 nulldev, /* identify */ 144 nulldev, /* probe */ 145 ds1287_attach, /* attach */ 146 ds1287_detach, /* detach */ 147 nodev, /* reset */ 148 &ds1287_cbops, /* cb_ops */ 149 (struct bus_ops *)NULL, /* bus_ops */ 150 NULL, /* power */ 151 ddi_quiesce_not_supported, /* devo_quiesce */ 152 }; 153 154 155 static void *ds1287_state; 156 static int instance = -1; 157 158 /* Driver Tunables */ 159 static int ds1287_interrupt_priority = 15; 160 static int ds1287_softint_priority = 2; 161 static hrtime_t power_button_debounce = MSEC2NSEC(10); 162 static hrtime_t power_button_abort_interval = 1.5 * NANOSEC; 163 static int power_button_abort_presses = 3; 164 static int power_button_abort_enable = 1; 165 static int power_button_enable = 1; 166 167 static int power_button_pressed = 0; 168 static int power_button_cancel = 0; 169 static int power_button_timeouts = 0; 170 static int timeout_cancel = 0; 171 static int additional_presses = 0; 172 173 static ddi_iblock_cookie_t ds1287_lo_iblock; 174 static ddi_iblock_cookie_t ds1287_hi_iblock; 175 static ddi_softintr_t ds1287_softintr_id; 176 static kmutex_t ds1287_reg_mutex; /* Protects ds1287 Registers */ 177 178 static struct modldrv modldrv = { 179 &mod_driverops, /* Type of module. This one is a driver */ 180 "ds1287 clock driver", /* Name of the module. */ 181 &ds1287_ops, /* driver ops */ 182 }; 183 184 static struct modlinkage modlinkage = { 185 MODREV_1, &modldrv, NULL 186 }; 187 188 189 int 190 _init(void) 191 { 192 int status; 193 194 status = ddi_soft_state_init(&ds1287_state, sizeof (struct ds1287), 0); 195 if (status != 0) { 196 return (status); 197 } 198 199 if ((status = mod_install(&modlinkage)) != 0) { 200 ddi_soft_state_fini(&ds1287_state); 201 return (status); 202 } 203 204 205 ds1287_hi_iblock = (ddi_iblock_cookie_t)(uintptr_t) 206 ipltospl(ds1287_interrupt_priority); 207 mutex_init(&ds1287_reg_mutex, NULL, MUTEX_DRIVER, ds1287_hi_iblock); 208 209 mutex_enter(&ds1287_reg_mutex); 210 /* Select Bank 1 */ 211 select_bank(1); 212 DS1287_ADDR_REG = RTC_B; 213 DS1287_DATA_REG = (RTC_DM | RTC_HM); 214 mutex_exit(&ds1287_reg_mutex); 215 216 tod_ops.tod_get = todds_get; 217 tod_ops.tod_set = todds_set; 218 219 /* 220 * If v_pmc_addr_reg isn't set, it's because it wasn't set in 221 * sun4u/os/fillsysinfo.c:have_pmc(). This means the real (pmc) 222 * watchdog routines (sun4u/io/pmc.c) will not be used. If the 223 * user were to set watchdog_enable in /etc/system, we'll need to 224 * use our own NOP routines. 225 */ 226 if (v_pmc_addr_reg == NULL) { 227 tod_ops.tod_set_watchdog_timer = todds_set_watchdog_timer; 228 tod_ops.tod_clear_watchdog_timer = todds_clear_watchdog_timer; 229 } 230 tod_ops.tod_set_power_alarm = todds_set_power_alarm; 231 tod_ops.tod_clear_power_alarm = todds_clear_power_alarm; 232 tod_ops.tod_get_cpufrequency = todds_get_cpufrequency; 233 234 return (status); 235 } 236 237 int 238 _fini(void) 239 { 240 if (strcmp(tod_module_name, "todds1287") == 0) 241 return (EBUSY); 242 243 return (mod_remove(&modlinkage)); 244 } 245 246 /* 247 * The loadable-module _info(9E) entry point 248 */ 249 int 250 _info(struct modinfo *modinfop) 251 { 252 return (mod_info(&modlinkage, modinfop)); 253 } 254 255 /*ARGSUSED*/ 256 static int 257 ds1287_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, 258 void **result) 259 { 260 struct ds1287 *softsp; 261 262 if (instance == -1) 263 return (DDI_FAILURE); 264 265 switch (infocmd) { 266 case DDI_INFO_DEVT2DEVINFO: 267 if ((softsp = ddi_get_soft_state(ds1287_state, instance)) 268 == NULL) 269 return (DDI_FAILURE); 270 *result = (void *)softsp->dip; 271 return (DDI_SUCCESS); 272 273 case DDI_INFO_DEVT2INSTANCE: 274 *result = (void *)(uintptr_t)instance; 275 return (DDI_SUCCESS); 276 277 default: 278 return (DDI_FAILURE); 279 } 280 } 281 282 static int 283 ds1287_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 284 { 285 struct ds1287 *softsp; 286 287 DPRINTF("ds1287_attach\n"); 288 switch (cmd) { 289 case DDI_ATTACH: 290 break; 291 case DDI_RESUME: 292 return (DDI_SUCCESS); 293 default: 294 return (DDI_FAILURE); 295 } 296 297 if (instance != -1) { 298 cmn_err(CE_WARN, "ds1287_attach: Another instance is already " 299 "attached."); 300 return (DDI_FAILURE); 301 } 302 303 instance = ddi_get_instance(dip); 304 305 if (v_rtc_addr_reg == NULL) { 306 cmn_err(CE_WARN, "ds1287_attach: v_rtc_addr_reg is NULL"); 307 return (DDI_FAILURE); 308 } 309 310 /* 311 * Allocate softc information. 312 */ 313 if (ddi_soft_state_zalloc(ds1287_state, instance) != DDI_SUCCESS) { 314 cmn_err(CE_WARN, "ds1287_attach: Failed to allocate " 315 "soft states."); 316 return (DDI_FAILURE); 317 } 318 319 softsp = ddi_get_soft_state(ds1287_state, instance); 320 DPRINTF("ds1287_attach: instance=%d softsp=0x%p\n", instance, 321 (void *)softsp); 322 323 softsp->dip = dip; 324 325 if (ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP, 326 "interrupt-priorities", (caddr_t)&ds1287_interrupt_priority, 327 sizeof (int)) != DDI_PROP_SUCCESS) { 328 cmn_err(CE_WARN, "ds1287_attach: Failed to create \"" 329 "interrupt-priorities\" property."); 330 goto error; 331 } 332 333 /* add the softint */ 334 ds1287_lo_iblock = (ddi_iblock_cookie_t)(uintptr_t) 335 ipltospl(ds1287_softint_priority); 336 337 if (ddi_add_softintr(dip, DDI_SOFTINT_FIXED, &ds1287_softintr_id, 338 &ds1287_lo_iblock, NULL, ds1287_softintr, (caddr_t)softsp) != 339 DDI_SUCCESS) { 340 cmn_err(CE_WARN, "ds1287_attach: Failed to add low interrupt."); 341 goto error1; 342 } 343 344 /* add the hi interrupt */ 345 if (ddi_add_intr(dip, 0, NULL, (ddi_idevice_cookie_t *) 346 &ds1287_hi_iblock, ds1287_intr, NULL) != DDI_SUCCESS) { 347 cmn_err(CE_WARN, "ds1287_attach: Failed to add high " 348 "interrupt."); 349 goto error2; 350 } 351 352 /* 353 * Combination of instance number and clone number 0 is used for 354 * creating the minor node. 355 */ 356 if (ddi_create_minor_node(dip, "power_button", S_IFCHR, 357 (instance << 8) + 0, "ddi_power_button", 0) == DDI_FAILURE) { 358 cmn_err(CE_WARN, "ds1287_attach: Failed to create minor node"); 359 goto error3; 360 } 361 362 ddi_report_dev(dip); 363 364 return (DDI_SUCCESS); 365 366 error3: 367 ddi_remove_intr(dip, 0, NULL); 368 error2: 369 ddi_remove_softintr(ds1287_softintr_id); 370 error1: 371 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "interrupt-priorities"); 372 error: 373 ddi_soft_state_free(ds1287_state, instance); 374 return (DDI_FAILURE); 375 } 376 377 /*ARGSUSED*/ 378 static int 379 ds1287_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 380 { 381 DPRINTF("ds1287_detach\n"); 382 switch (cmd) { 383 case DDI_DETACH: 384 /* 385 * Since it needs to always handle the power button, fail 386 * to detach. 387 */ 388 return (DDI_FAILURE); 389 case DDI_SUSPEND: 390 return (DDI_SUCCESS); 391 default: 392 return (DDI_FAILURE); 393 } 394 } 395 396 /*ARGSUSED1*/ 397 static int 398 ds1287_open(dev_t *devp, int flags, int otyp, cred_t *credp) 399 { 400 struct ds1287 *softsp; 401 int clone; 402 403 if (otyp != OTYP_CHR) 404 return (EINVAL); 405 406 if ((softsp = ddi_get_soft_state(ds1287_state, instance)) == 407 NULL) 408 return (ENXIO); 409 410 mutex_enter(&softsp->ds1287_mutex); 411 for (clone = 1; clone < DS1287_MAX_CLONE; clone++) 412 if (!softsp->clones[clone]) 413 break; 414 415 if (clone == DS1287_MAX_CLONE) { 416 cmn_err(CE_WARN, "ds1287_open: No more allocation left " 417 "to clone a minor."); 418 mutex_exit(&softsp->ds1287_mutex); 419 return (ENXIO); 420 } 421 422 *devp = makedevice(getmajor(*devp), (instance << 8) + clone); 423 softsp->clones[clone] = 1; 424 mutex_exit(&softsp->ds1287_mutex); 425 426 return (0); 427 } 428 429 /*ARGSUSED*/ 430 static int 431 ds1287_close(dev_t dev, int flags, int otyp, cred_t *credp) 432 { 433 struct ds1287 *softsp; 434 int clone; 435 436 if (otyp != OTYP_CHR) 437 return (EINVAL); 438 439 if ((softsp = ddi_get_soft_state(ds1287_state, instance)) == 440 NULL) 441 return (ENXIO); 442 443 clone = DS1287_MINOR_TO_CLONE(getminor(dev)); 444 mutex_enter(&softsp->ds1287_mutex); 445 if (softsp->monitor_on == clone) 446 softsp->monitor_on = 0; 447 softsp->clones[clone] = 0; 448 mutex_exit(&softsp->ds1287_mutex); 449 450 return (0); 451 } 452 453 /*ARGSUSED4*/ 454 static int 455 ds1287_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, 456 cred_t *credp, int *rvalp) 457 { 458 struct ds1287 *softsp; 459 int clone; 460 461 if ((softsp = ddi_get_soft_state(ds1287_state, instance)) == 462 NULL) 463 return (ENXIO); 464 465 clone = DS1287_MINOR_TO_CLONE(getminor(dev)); 466 switch (cmd) { 467 case PB_BEGIN_MONITOR: 468 DPRINTF("ds1287_ioctl: PB_BEGIN_MONITOR is called.\n"); 469 mutex_enter(&softsp->ds1287_mutex); 470 if (softsp->monitor_on) { 471 mutex_exit(&softsp->ds1287_mutex); 472 return (EBUSY); 473 } 474 softsp->monitor_on = clone; 475 mutex_exit(&softsp->ds1287_mutex); 476 return (0); 477 478 case PB_END_MONITOR: 479 DPRINTF("ds1287_ioctl: PB_END_MONITOR is called.\n"); 480 mutex_enter(&softsp->ds1287_mutex); 481 482 /* 483 * If PB_END_MONITOR is called without first 484 * calling PB_BEGIN_MONITOR, an error will be 485 * returned. 486 */ 487 if (!softsp->monitor_on) { 488 mutex_exit(&softsp->ds1287_mutex); 489 return (ENXIO); 490 } 491 492 /* 493 * This clone is not monitoring the button. 494 */ 495 if (softsp->monitor_on != clone) { 496 mutex_exit(&softsp->ds1287_mutex); 497 return (EINVAL); 498 } 499 softsp->monitor_on = 0; 500 mutex_exit(&softsp->ds1287_mutex); 501 return (0); 502 503 case PB_GET_EVENTS: 504 DPRINTF("ds1287_ioctl: PB_GET_EVENTS is called.\n"); 505 mutex_enter(&softsp->ds1287_mutex); 506 if (ddi_copyout((void *)&softsp->events, (void *)arg, 507 sizeof (int), mode) != 0) { 508 mutex_exit(&softsp->ds1287_mutex); 509 return (EFAULT); 510 } 511 512 /* 513 * This ioctl returned the events detected since last 514 * call. Note that any application can get the events 515 * and clear the event register. 516 */ 517 softsp->events = 0; 518 mutex_exit(&softsp->ds1287_mutex); 519 return (0); 520 521 /* 522 * This ioctl is used by the test suite. 523 */ 524 case PB_CREATE_BUTTON_EVENT: 525 DPRINTF("ds1287_ioctl: PB_CREATE_BUTTON_EVENT is called.\n"); 526 (void) ds1287_intr(NULL); 527 return (0); 528 529 default: 530 return (ENOTTY); 531 } 532 } 533 534 /*ARGSUSED*/ 535 static int 536 ds1287_chpoll(dev_t dev, short events, int anyyet, 537 short *reventsp, struct pollhead **phpp) 538 { 539 struct ds1287 *softsp; 540 541 if ((softsp = ddi_get_soft_state(ds1287_state, instance)) == NULL) 542 return (ENXIO); 543 544 mutex_enter(&softsp->ds1287_mutex); 545 *reventsp = 0; 546 if (softsp->events) 547 *reventsp = POLLRDNORM|POLLIN; 548 else { 549 if (!anyyet) 550 *phpp = &softsp->pollhd; 551 } 552 mutex_exit(&softsp->ds1287_mutex); 553 554 return (0); 555 } 556 557 static void 558 ds1287_log_message(void) 559 { 560 struct ds1287 *softsp; 561 562 if ((softsp = ddi_get_soft_state(ds1287_state, instance)) == NULL) { 563 cmn_err(CE_WARN, "ds1287: Failed to get internal state!"); 564 return; 565 } 566 567 mutex_enter(&softsp->ds1287_mutex); 568 softsp->shutdown_pending = 0; 569 cmn_err(CE_WARN, "ds1287: Failed to shut down the system!"); 570 mutex_exit(&softsp->ds1287_mutex); 571 } 572 573 /* 574 * To facilitate a power button abort, ds1287_intr() now posts 575 * a softint (calling ds1287_softintr()) for all power button presses and 576 * counts the number of button presses. An abort is issued if the desired 577 * number of button presses within the given time interval. 578 * 579 * Two variables are used to synchronize between the high level intr; 580 * the softint handler and timeout handler 581 * 582 * power_button_cancel - Indicates that an abort happened and the number 583 * of outstanding timeouts that have to be cancelled 584 * 585 * power_button_pressed - Indicates the number of button presses outstanding 586 * which have not been serviced 587 */ 588 /*ARGSUSED*/ 589 static uint_t 590 ds1287_intr(caddr_t ignore) 591 { 592 hrtime_t tstamp; 593 static hrtime_t o_tstamp = 0; 594 static hrtime_t power_button_tstamp = 0; 595 static int power_button_cnt; 596 uint8_t apcr1; 597 598 /* 599 * Stop the Fail-safe timer that starts running 600 * after power button is pressed. If it is not 601 * stopped in 21 seconds, system powers off. 602 */ 603 mutex_enter(&ds1287_reg_mutex); 604 select_bank(2); 605 DS1287_ADDR_REG = APC_APCR1; 606 apcr1 = DS1287_DATA_REG; 607 apcr1 |= APC_FSTRC; 608 DS1287_DATA_REG = apcr1; 609 select_bank(1); 610 mutex_exit(&ds1287_reg_mutex); 611 612 tstamp = gethrtime(); 613 614 /* need to deal with power button debounce */ 615 if (o_tstamp && (tstamp - o_tstamp) < power_button_debounce) { 616 o_tstamp = tstamp; 617 return (DDI_INTR_CLAIMED); 618 } 619 o_tstamp = tstamp; 620 621 power_button_cnt++; 622 623 mutex_enter(&ds1287_reg_mutex); 624 power_button_pressed++; 625 mutex_exit(&ds1287_reg_mutex); 626 627 /* 628 * If power button abort is enabled and power button was pressed 629 * power_button_abort_presses times within power_button_abort_interval 630 * then call abort_sequence_enter(); 631 */ 632 if (power_button_abort_enable) { 633 if (power_button_abort_presses == 1 || 634 tstamp < (power_button_tstamp + 635 power_button_abort_interval)) { 636 if (power_button_cnt == power_button_abort_presses) { 637 mutex_enter(&ds1287_reg_mutex); 638 power_button_cancel += power_button_timeouts; 639 power_button_pressed = 0; 640 mutex_exit(&ds1287_reg_mutex); 641 power_button_cnt = 0; 642 abort_sequence_enter("Power Button Abort"); 643 return (DDI_INTR_CLAIMED); 644 } 645 } else { 646 power_button_cnt = 1; 647 power_button_tstamp = tstamp; 648 } 649 } 650 651 if (!power_button_enable) 652 return (DDI_INTR_CLAIMED); 653 654 /* post softint to issue timeout for power button action */ 655 ddi_trigger_softintr(ds1287_softintr_id); 656 657 return (DDI_INTR_CLAIMED); 658 } 659 660 /* 661 * Handle the softints.... 662 * 663 * If only one softint is posted for several button presses, record 664 * the number of additional presses just incase this was actually not quite 665 * an Abort sequence so that we can log this event later. 666 * 667 * Issue a timeout with a duration being a fraction larger than 668 * the specified Abort interval inorder to perform a power down if required. 669 */ 670 static uint_t 671 ds1287_softintr(caddr_t arg) 672 { 673 struct ds1287 *softsp = (struct ds1287 *)arg; 674 675 DPRINTF("ds1287_softintr\n"); 676 677 if (!power_button_abort_enable) 678 return (ds1287_issue_shutdown(arg)); 679 680 mutex_enter(&ds1287_reg_mutex); 681 if (!power_button_pressed) { 682 mutex_exit(&ds1287_reg_mutex); 683 return (DDI_INTR_CLAIMED); 684 } 685 686 /* 687 * Schedule a timeout to do the necessary 688 * work for shutdown, only one timeout for 689 * n presses if power button was pressed 690 * more than once before softint fired 691 */ 692 if (power_button_pressed > 1) 693 additional_presses += power_button_pressed - 1; 694 695 timeout_cancel = 0; 696 power_button_pressed = 0; 697 power_button_timeouts++; 698 mutex_exit(&ds1287_reg_mutex); 699 (void) timeout((void(*)(void *))ds1287_timeout, 700 softsp, NSEC_TO_TICK(power_button_abort_interval) + 701 ABORT_INCREMENT_DELAY); 702 703 return (DDI_INTR_CLAIMED); 704 } 705 706 /* 707 * Upon receiving a timeout the following is determined: 708 * 709 * If an Abort sequence was issued, then we cancel all outstanding timeouts 710 * and additional presses prior to the Abort sequence. 711 * 712 * If we had multiple timeouts issued and the abort sequence was not met, 713 * then we had more than one button press to power down the machine. We 714 * were probably trying to issue an abort. So log a message indicating this 715 * and cancel all outstanding timeouts. 716 * 717 * If we had just one timeout and the abort sequence was not met then 718 * we really did want to power down the machine, so call ds1287_issue_shutdown() 719 * to do the work and schedule a power down 720 */ 721 static void 722 ds1287_timeout(caddr_t arg) 723 { 724 static int first = 0; 725 726 DPRINTF("ds1287_timeout\n"); 727 728 /* 729 * Abort was generated cancel all outstanding power 730 * button timeouts 731 */ 732 mutex_enter(&ds1287_reg_mutex); 733 if (power_button_cancel) { 734 power_button_cancel--; 735 power_button_timeouts--; 736 if (!first) { 737 first++; 738 additional_presses = 0; 739 } 740 mutex_exit(&ds1287_reg_mutex); 741 return; 742 } 743 first = 0; 744 745 /* 746 * We get here if the timeout(s) have fired and they were 747 * not issued prior to an abort. 748 * 749 * If we had more than one press in the interval we were 750 * probably trying to issue an abort, but didnt press the 751 * required number within the interval. Hence cancel all 752 * timeouts and do not continue towards shutdown. 753 */ 754 if (!timeout_cancel) { 755 timeout_cancel = power_button_timeouts + 756 additional_presses; 757 758 power_button_timeouts--; 759 if (!power_button_timeouts) 760 additional_presses = 0; 761 762 if (timeout_cancel > 1) { 763 mutex_exit(&ds1287_reg_mutex); 764 cmn_err(CE_NOTE, "Power Button pressed " 765 "%d times, cancelling all requests", 766 timeout_cancel); 767 return; 768 } 769 mutex_exit(&ds1287_reg_mutex); 770 771 /* Go and do the work to request shutdown */ 772 (void) ds1287_issue_shutdown(arg); 773 return; 774 } 775 776 power_button_timeouts--; 777 if (!power_button_timeouts) 778 additional_presses = 0; 779 mutex_exit(&ds1287_reg_mutex); 780 } 781 782 static uint_t 783 ds1287_issue_shutdown(caddr_t arg) 784 { 785 struct ds1287 *softsp = (struct ds1287 *)arg; 786 787 DPRINTF("ds1287_issue_shutdown\n"); 788 789 mutex_enter(&softsp->ds1287_mutex); 790 softsp->events |= PB_BUTTON_PRESS; 791 if (softsp->monitor_on != 0) { 792 mutex_exit(&softsp->ds1287_mutex); 793 pollwakeup(&softsp->pollhd, POLLRDNORM); 794 pollwakeup(&softsp->pollhd, POLLIN); 795 return (DDI_INTR_CLAIMED); 796 } 797 798 if (!softsp->shutdown_pending) { 799 cmn_err(CE_WARN, "Power button is pressed, powering down " 800 "the system!"); 801 softsp->shutdown_pending = 1; 802 do_shutdown(); 803 804 /* 805 * Wait a while for "do_shutdown()" to shut down the system 806 * before logging an error message. 807 */ 808 (void) timeout((void(*)(void *))ds1287_log_message, NULL, 809 100 * hz); 810 } 811 mutex_exit(&softsp->ds1287_mutex); 812 813 return (DDI_INTR_CLAIMED); 814 } 815 816 /* 817 * Read the current time from the clock chip and convert to UNIX form. 818 * Assumes that the year in the clock chip is valid. 819 * Must be called with tod_lock held. 820 */ 821 static timestruc_t 822 todds_get(void) 823 { 824 timestruc_t ts; 825 todinfo_t tod; 826 struct rtc_t rtc; 827 828 ASSERT(MUTEX_HELD(&tod_lock)); 829 830 read_rtc(&rtc); 831 DPRINTF("todds_get: century=%d year=%d dom=%d hrs=%d\n", 832 rtc.rtc_century, rtc.rtc_year, rtc.rtc_dom, rtc.rtc_hrs); 833 834 /* 835 * tod_year is base 1900 so this code needs to adjust the true 836 * year retrieved from the rtc's century and year fields. 837 */ 838 tod.tod_year = rtc.rtc_year + (rtc.rtc_century * 100) - 1900; 839 tod.tod_month = rtc.rtc_mon; 840 tod.tod_day = rtc.rtc_dom; 841 tod.tod_dow = rtc.rtc_dow; 842 tod.tod_hour = rtc.rtc_hrs; 843 tod.tod_min = rtc.rtc_min; 844 tod.tod_sec = rtc.rtc_sec; 845 846 ts.tv_sec = tod_to_utc(tod); 847 ts.tv_nsec = 0; 848 849 /* set the hw watchdog timer if it's been activated */ 850 if (watchdog_activated) { 851 int ret = 0; 852 ret = tod_ops.tod_set_watchdog_timer(watchdog_timeout_seconds); 853 if (ret == 0) 854 cmn_err(CE_WARN, "ds1287: failed to set hardware " 855 "watchdog timer."); 856 } 857 858 return (ts); 859 } 860 861 void 862 read_rtc(struct rtc_t *rtc) 863 { 864 uint8_t regb; 865 866 /* 867 * Some SuperIO tod devices don't seem to properly initialize 868 * the CADDR register to place the Century register at bank 1 869 * address 0x48. 870 */ 871 mutex_enter(&ds1287_reg_mutex); 872 873 select_bank(2); 874 DS1287_ADDR_REG = RTC_CADDR; 875 regb = DS1287_DATA_REG; 876 if (regb != 0xc8) { 877 if (!ds1287_caddr_warn) { 878 ds1287_caddr_warn = 1; 879 cmn_err(CE_WARN, "ds1287: century address register " 880 "incorrect (exp 0xc8, obs %x)", regb); 881 } 882 DS1287_DATA_REG = 0xc8; 883 } 884 885 select_bank(1); 886 /* 887 * Freeze clock update 888 */ 889 DS1287_ADDR_REG = RTC_B; 890 regb = DS1287_DATA_REG; 891 DS1287_DATA_REG = (regb | RTC_SET); 892 893 DS1287_ADDR_REG = RTC_SEC; 894 rtc->rtc_sec = DS1287_DATA_REG; 895 DS1287_ADDR_REG = RTC_ASEC; 896 rtc->rtc_asec = DS1287_DATA_REG; 897 DS1287_ADDR_REG = RTC_MIN; 898 rtc->rtc_min = DS1287_DATA_REG; 899 DS1287_ADDR_REG = RTC_AMIN; 900 rtc->rtc_amin = DS1287_DATA_REG; 901 DS1287_ADDR_REG = RTC_HRS; 902 rtc->rtc_hrs = DS1287_DATA_REG; 903 DS1287_ADDR_REG = RTC_AHRS; 904 rtc->rtc_ahrs = DS1287_DATA_REG; 905 DS1287_ADDR_REG = RTC_DOW; 906 rtc->rtc_dow = DS1287_DATA_REG; 907 DS1287_ADDR_REG = RTC_DOM; 908 rtc->rtc_dom = DS1287_DATA_REG; 909 DS1287_ADDR_REG = RTC_MON; 910 rtc->rtc_mon = DS1287_DATA_REG; 911 DS1287_ADDR_REG = RTC_YEAR; 912 rtc->rtc_year = DS1287_DATA_REG; 913 DS1287_ADDR_REG = RTC_CENTURY; 914 rtc->rtc_century = DS1287_DATA_REG; 915 916 /* Read date alarm */ 917 DS1287_ADDR_REG = RTC_ADOM; 918 rtc->rtc_adom = DS1287_DATA_REG; 919 DS1287_ADDR_REG = RTC_AMON; 920 rtc->rtc_amon = DS1287_DATA_REG; 921 922 /* Read wakeup data */ 923 select_bank(2); 924 DS1287_ADDR_REG = APC_WDWR; 925 rtc->apc_wdwr = DS1287_DATA_REG; 926 DS1287_ADDR_REG = APC_WDMR; 927 rtc->apc_wdmr = DS1287_DATA_REG; 928 DS1287_ADDR_REG = APC_WMR; 929 rtc->apc_wmr = DS1287_DATA_REG; 930 DS1287_ADDR_REG = APC_WYR; 931 rtc->apc_wyr = DS1287_DATA_REG; 932 DS1287_ADDR_REG = APC_WCR; 933 rtc->apc_wcr = DS1287_DATA_REG; 934 935 /* 936 * Unfreeze clock update 937 */ 938 DS1287_ADDR_REG = RTC_B; 939 DS1287_DATA_REG = regb; 940 941 mutex_exit(&ds1287_reg_mutex); 942 } 943 944 /* 945 * Write the specified time into the clock chip. 946 * Must be called with tod_lock held. 947 */ 948 static void 949 todds_set(timestruc_t ts) 950 { 951 struct rtc_t rtc; 952 todinfo_t tod = utc_to_tod(ts.tv_sec); 953 int year; 954 955 ASSERT(MUTEX_HELD(&tod_lock)); 956 957 /* tod_year is base 1900 so this code needs to adjust */ 958 year = 1900 + tod.tod_year; 959 rtc.rtc_year = year % 100; 960 rtc.rtc_century = year / 100; 961 rtc.rtc_mon = (uint8_t)tod.tod_month; 962 rtc.rtc_dom = (uint8_t)tod.tod_day; 963 rtc.rtc_dow = (uint8_t)tod.tod_dow; 964 rtc.rtc_hrs = (uint8_t)tod.tod_hour; 965 rtc.rtc_min = (uint8_t)tod.tod_min; 966 rtc.rtc_sec = (uint8_t)tod.tod_sec; 967 DPRINTF("todds_set: century=%d year=%d dom=%d hrs=%d\n", 968 rtc.rtc_century, rtc.rtc_year, rtc.rtc_dom, rtc.rtc_hrs); 969 970 write_rtc_time(&rtc); 971 } 972 973 void 974 write_rtc_time(struct rtc_t *rtc) 975 { 976 uint8_t regb; 977 978 /* 979 * Some SuperIO tod devices don't seem to properly initialize 980 * the CADDR register to place the Century register at bank 1 981 * address 0x48. 982 */ 983 mutex_enter(&ds1287_reg_mutex); 984 985 select_bank(2); 986 DS1287_ADDR_REG = RTC_CADDR; 987 regb = DS1287_DATA_REG; 988 if (regb != 0xc8) { 989 if (!ds1287_caddr_warn) { 990 ds1287_caddr_warn = 1; 991 cmn_err(CE_WARN, "ds1287: century address register " 992 "incorrect (exp 0xc8, obs %x)", regb); 993 } 994 DS1287_DATA_REG = 0xc8; 995 } 996 997 select_bank(1); 998 999 /* 1000 * Freeze 1001 */ 1002 DS1287_ADDR_REG = RTC_B; 1003 regb = DS1287_DATA_REG; 1004 1005 DS1287_DATA_REG = (regb | RTC_SET); 1006 1007 DS1287_ADDR_REG = RTC_SEC; 1008 DS1287_DATA_REG = rtc->rtc_sec; 1009 DS1287_ADDR_REG = RTC_MIN; 1010 DS1287_DATA_REG = rtc->rtc_min; 1011 DS1287_ADDR_REG = RTC_HRS; 1012 DS1287_DATA_REG = rtc->rtc_hrs; 1013 DS1287_ADDR_REG = RTC_DOW; 1014 DS1287_DATA_REG = rtc->rtc_dow; 1015 DS1287_ADDR_REG = RTC_DOM; 1016 DS1287_DATA_REG = rtc->rtc_dom; 1017 DS1287_ADDR_REG = RTC_MON; 1018 DS1287_DATA_REG = rtc->rtc_mon; 1019 DS1287_ADDR_REG = RTC_YEAR; 1020 DS1287_DATA_REG = rtc->rtc_year; 1021 DS1287_ADDR_REG = RTC_CENTURY; 1022 DS1287_DATA_REG = rtc->rtc_century; 1023 1024 /* 1025 * Unfreeze 1026 */ 1027 DS1287_ADDR_REG = RTC_B; 1028 DS1287_DATA_REG = regb; 1029 1030 mutex_exit(&ds1287_reg_mutex); 1031 } 1032 1033 void 1034 write_rtc_alarm(struct rtc_t *rtc) 1035 { 1036 mutex_enter(&ds1287_reg_mutex); 1037 1038 select_bank(1); 1039 DS1287_ADDR_REG = RTC_ASEC; 1040 DS1287_DATA_REG = rtc->rtc_asec; 1041 DS1287_ADDR_REG = RTC_AMIN; 1042 DS1287_DATA_REG = rtc->rtc_amin; 1043 DS1287_ADDR_REG = RTC_AHRS; 1044 DS1287_DATA_REG = rtc->rtc_ahrs; 1045 DS1287_ADDR_REG = RTC_ADOM; 1046 DS1287_DATA_REG = rtc->rtc_adom; 1047 DS1287_ADDR_REG = RTC_AMON; 1048 DS1287_DATA_REG = rtc->rtc_amon; 1049 1050 select_bank(2); 1051 DS1287_ADDR_REG = APC_WDWR; 1052 DS1287_DATA_REG = rtc->apc_wdwr; 1053 DS1287_ADDR_REG = APC_WDMR; 1054 DS1287_DATA_REG = rtc->apc_wdmr; 1055 DS1287_ADDR_REG = APC_WMR; 1056 DS1287_DATA_REG = rtc->apc_wmr; 1057 DS1287_ADDR_REG = APC_WYR; 1058 DS1287_DATA_REG = rtc->apc_wyr; 1059 DS1287_ADDR_REG = APC_WCR; 1060 DS1287_DATA_REG = rtc->apc_wcr; 1061 1062 mutex_exit(&ds1287_reg_mutex); 1063 } 1064 1065 /* 1066 * program the rtc registers for alarm to go off at the specified time 1067 */ 1068 static void 1069 todds_set_power_alarm(timestruc_t ts) 1070 { 1071 todinfo_t tod; 1072 uint8_t apcr2; 1073 struct rtc_t rtc; 1074 1075 ASSERT(MUTEX_HELD(&tod_lock)); 1076 tod = utc_to_tod(ts.tv_sec); 1077 mutex_enter(&ds1287_reg_mutex); 1078 1079 /* Clear Time Match Detect */ 1080 select_bank(2); 1081 DS1287_ADDR_REG = APC_APSR; 1082 apcr2 = DS1287_DATA_REG; 1083 1084 /* Disable Time Match Enable */ 1085 DS1287_ADDR_REG = APC_APCR2; 1086 apcr2 = DS1287_DATA_REG; 1087 DS1287_DATA_REG = (apcr2 & (~APC_TME)); 1088 1089 mutex_exit(&ds1287_reg_mutex); 1090 1091 rtc.rtc_asec = (uint8_t)tod.tod_sec; 1092 rtc.rtc_amin = (uint8_t)tod.tod_min; 1093 rtc.rtc_ahrs = (uint8_t)tod.tod_hour; 1094 rtc.rtc_adom = (uint8_t)tod.tod_day; 1095 rtc.rtc_amon = (uint8_t)tod.tod_month; 1096 1097 rtc.apc_wdwr = (uint8_t)tod.tod_dow; 1098 rtc.apc_wdmr = (uint8_t)tod.tod_day; 1099 rtc.apc_wmr = (uint8_t)tod.tod_month; 1100 rtc.apc_wyr = tod.tod_year % 100; 1101 rtc.apc_wcr = (tod.tod_year / 100) + 19; 1102 1103 write_rtc_alarm(&rtc); 1104 1105 mutex_enter(&ds1287_reg_mutex); 1106 /* Enable Time Match enable */ 1107 select_bank(2); 1108 DS1287_ADDR_REG = APC_APCR2; 1109 DS1287_DATA_REG = (apcr2 | APC_TME); 1110 1111 mutex_exit(&ds1287_reg_mutex); 1112 } 1113 1114 /* 1115 * clear alarm interrupt 1116 */ 1117 static void 1118 todds_clear_power_alarm(void) 1119 { 1120 uint8_t apcr2; 1121 1122 ASSERT(MUTEX_HELD(&tod_lock)); 1123 1124 mutex_enter(&ds1287_reg_mutex); 1125 1126 /* Clear Time Match Detect */ 1127 select_bank(2); 1128 DS1287_ADDR_REG = APC_APSR; 1129 apcr2 = DS1287_DATA_REG; 1130 1131 /* Disable Time Match Enable */ 1132 DS1287_ADDR_REG = APC_APCR2; 1133 apcr2 = DS1287_DATA_REG; 1134 DS1287_DATA_REG = (apcr2 & (~APC_TME)); 1135 1136 mutex_exit(&ds1287_reg_mutex); 1137 } 1138 1139 /* 1140 * Determine the cpu frequency by watching the TOD chip rollover twice. 1141 * Cpu clock rate is determined by computing the ticks added (in tick register) 1142 * during one second interval on TOD. 1143 */ 1144 uint64_t 1145 todds_get_cpufrequency(void) 1146 { 1147 uint64_t cpu_freq; 1148 1149 ASSERT(MUTEX_HELD(&tod_lock)); 1150 mutex_enter(&ds1287_reg_mutex); 1151 1152 select_bank(1); 1153 DS1287_ADDR_REG = RTC_SEC; 1154 cpu_freq = find_cpufrequency(v_rtc_data_reg); 1155 1156 mutex_exit(&ds1287_reg_mutex); 1157 return (cpu_freq); 1158 } 1159 1160 static void 1161 select_bank(int bank) 1162 { 1163 uint8_t rega; 1164 int banksel; 1165 1166 /* Select Bank 1 */ 1167 DS1287_ADDR_REG = RTC_A; 1168 rega = DS1287_DATA_REG; 1169 rega = rega & ~(RTC_DIV0 | RTC_DIV1 | RTC_DIV2); 1170 switch (bank) { 1171 case 0: 1172 banksel = RTC_DIV1; 1173 break; 1174 case 1: 1175 banksel = RTC_DIV0 | RTC_DIV1; 1176 break; 1177 case 2: 1178 banksel = RTC_DIV2; 1179 break; 1180 } 1181 rega |= banksel; 1182 DS1287_DATA_REG = rega; 1183 } 1184 1185 /*ARGSUSED*/ 1186 static uint_t 1187 todds_set_watchdog_timer(uint_t timeoutval) 1188 { 1189 ASSERT(MUTEX_HELD(&tod_lock)); 1190 return (0); 1191 } 1192 1193 static uint_t 1194 todds_clear_watchdog_timer(void) 1195 { 1196 ASSERT(MUTEX_HELD(&tod_lock)); 1197 return (0); 1198 } 1199