1 /* $NetBSD: sequoia.c,v 1.17 2022/10/15 21:53:21 andvar Exp $ */ 2 3 /* 4 * Copyright 1997 5 * Digital Equipment Corporation. All rights reserved. 6 * 7 * This software is furnished under license and may be used and 8 * copied only in accordance with the following terms and conditions. 9 * Subject to these conditions, you may download, copy, install, 10 * use, modify and distribute this software in source and/or binary 11 * form. No title or ownership is transferred hereby. 12 * 13 * 1) Any source code used, modified or distributed must reproduce 14 * and retain this copyright notice and list of conditions as 15 * they appear in the source file. 16 * 17 * 2) No right is granted to use any trade name, trademark, or logo of 18 * Digital Equipment Corporation. Neither the "Digital Equipment 19 * Corporation" name nor any trademark or logo of Digital Equipment 20 * Corporation may be used to endorse or promote products derived 21 * from this software without the prior written permission of 22 * Digital Equipment Corporation. 23 * 24 * 3) This software is provided "AS-IS" and any express or implied 25 * warranties, including but not limited to, any implied warranties 26 * of merchantability, fitness for a particular purpose, or 27 * non-infringement are disclaimed. In no event shall DIGITAL be 28 * liable for any damages whatsoever, and in particular, DIGITAL 29 * shall not be liable for special, indirect, consequential, or 30 * incidental damages or damages for lost profits, loss of 31 * revenue or loss of use, whether such damages arise in contract, 32 * negligence, tort, under statute, in equity, at law or otherwise, 33 * even if advised of the possibility of such damage. 34 */ 35 36 /* 37 ** 38 ** INCLUDE FILES 39 ** 40 */ 41 42 #include <sys/cdefs.h> 43 __KERNEL_RCSID(0, "$NetBSD: sequoia.c,v 1.17 2022/10/15 21:53:21 andvar Exp $"); 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/callout.h> 48 #include <sys/device.h> 49 #include <sys/syslog.h> 50 #include <sys/types.h> 51 #include <sys/bus.h> 52 #include <sys/time.h> 53 #include <sys/kernel.h> 54 55 #include <dev/isa/isareg.h> 56 #include <dev/ofisa/ofisavar.h> 57 #include <machine/isa_machdep.h> 58 #include <shark/shark/sequoia.h> 59 #include <shark/shark/shark_fiq.h> 60 #include <arm/cpufunc.h> 61 62 #include <dev/ofw/openfirm.h> 63 64 65 67 /* 68 ** 69 ** MACROS 70 ** 71 */ 72 73 /* define registers on sequoia used by pins */ 74 #define SEQUOIA_1GPIO PMC_GPCR_REG /* reg 0x007 gpio 0-3 */ 75 #define SEQUOIA_2GPIO SEQ2_OGPIOCR_REG /* reg 0x304 gpio 4.8 */ 76 77 /* define pins on sequoia that talk to smart card reader */ 78 #define SCR_DETECT_DIR GPIOCR2_M_GPIOBDIR0 79 #define SCR_DETECT GPIOCR2_M_GPIOBDATA0 80 81 82 #define SCR_POWER_DIR GPCR_M_GPIODIR0 83 #define SCR_POWER GPCR_M_GPIODATA0 84 85 #define SCR_RESET_DIR GPCR_M_GPIODIR1 86 #define SCR_RESET GPCR_M_GPIODATA1 87 88 #define SCR_CLOCK_DIR OGPIOCR_M_GPIODIR6 89 #define SCR_CLOCK OGPIOCR_M_GPIODATA6 90 91 #define SCR_DATA_IN_DIR GPCR_M_GPIODIR2 92 #define SCR_DATA_IN GPCR_M_GPIODATA2 93 94 #define SCR_DATA_OUT_DIR OGPIOCR_M_GPIODIR5 95 #define SCR_DATA_OUT OGPIOCR_M_GPIODATA5 96 97 #define SCR_BUGA_DIR OGPIOCR_M_GPIODIR4 98 #define SCR_BUGA OGPIOCR_M_GPIODATA4 99 100 #define SCR_BUGB_DIR OGPIOCR_M_GPIODIR7 101 #define SCR_BUGB OGPIOCR_M_GPIODATA7 102 103 104 105 /* define pins on sequoia that talk to leds */ 106 #define LED_BILED_YELLOW_BIT FOMPCR_M_PCON5 107 #define LED_BILED_GREEN_BIT FOMPCR_M_PCON6 108 109 #define LED_DEBUG_YELLOW_BIT FOMPCR_M_PCON7 110 #define LED_DEBUG_GREEN_BIT FOMPCR_M_PCON8 111 112 113 /* define biled colors */ 114 #define LED_BILED_NONE 0 115 #define LED_BILED_GREEN 1 116 #define LED_BILED_YELLOW 2 117 #define LED_BILED_RED 3 118 119 120 #define LED_TIMEOUT hz / 20 /* 20 times a second */ 121 #define LED_NET_ACTIVE (1000000/hz) * LED_TIMEOUT /* delay in us for net activity */ 122 123 124 125 126 /* 127 ** 128 ** DATA 129 ** 130 */ 131 static bus_space_handle_t sequoia_ioh; 132 133 static struct timeval ledLastActive; /* last time we get net activity */ 134 static int ledColor; /* present color of led */ 135 static int ledBlockCount; /* reference count of block calles */ 136 int sequoia_index_cache = -1; /* set to silly value so that we dont cache on init */ 137 138 static callout_t led_timo_ch; 139 140 static u_int sequoiaLock_savedints; 141 static bool sequoiaLock_held; 142 143 /* 144 ** 145 ** FUNCTIONAL PROTOTYPES 146 ** 147 */ 148 static void ledSetBiled(int color); 149 static void ledTimeout(void *arg); 150 151 /* 152 ** 153 ** FUNCTIONS 154 ** 155 */ 156 void sequoiaInit(void) 157 { 158 u_int16_t seqReg; 159 160 /* map the sequoia registers */ 161 if (bus_space_map(&isa_io_bs_tag, SEQUOIA_BASE, SEQUOIA_NPORTS, 0, &sequoia_ioh)) 162 { 163 panic("SequoiaInit: io mapping failed"); 164 } 165 166 sequoiaLock(); 167 168 /* 169 ** 170 ** setup the pins associated with the X server 171 ** 172 */ 173 /* seems power on sets them correctly */ 174 175 176 177 /* 178 ** setup the pins associated with the led 179 */ 180 sequoiaRead(SEQR_SEQPSR1_REG,&seqReg); 181 SET(seqReg,SEQPSR1_M_TAGDEN); /* enable pc[4:9] */ 182 sequoiaWrite(SEQR_SEQPSR1_REG,seqReg); 183 184 185 sequoiaRead(SEQR_SEQPSR3_REG,&seqReg); 186 CLR(seqReg,SEQPSR3_M_PC5PINEN); /* enable pc5, biled */ 187 CLR(seqReg,SEQPSR3_M_PC6PINEN); /* enable pc6, biled */ 188 CLR(seqReg,SEQPSR3_M_PC7PINEN); /* enable pc7, debug led yellow */ 189 CLR(seqReg,SEQPSR3_M_PC8PINEN); /* enable pc8, debug led green */ 190 sequoiaWrite(SEQR_SEQPSR3_REG,seqReg); 191 192 sequoiaRead (PMC_FOMPCR_REG, &seqReg); 193 CLR(seqReg,LED_BILED_YELLOW_BIT); 194 CLR(seqReg,LED_BILED_GREEN_BIT); 195 SET(seqReg,LED_DEBUG_YELLOW_BIT); 196 CLR(seqReg,LED_DEBUG_GREEN_BIT); 197 sequoiaWrite(PMC_FOMPCR_REG, seqReg); 198 199 200 /* 201 ** 202 ** setup the pins associated with the smart card reader * 203 ** 204 */ 205 /* sequoia 1 direction & data */ 206 207 sequoiaRead(SEQUOIA_1GPIO,&seqReg); 208 209 SET(seqReg,SCR_POWER_DIR); /* output */ 210 SET(seqReg,SCR_RESET_DIR); /* output */ 211 CLR(seqReg,SCR_DATA_IN_DIR); /* input */ 212 213 CLR(seqReg,SCR_POWER); /* 0V to card */ 214 SET(seqReg,SCR_RESET); /* 0V to card */ 215 216 sequoiaWrite(SEQUOIA_1GPIO,seqReg); 217 218 219 220 221 /* sequoia 2 pin enables */ 222 sequoiaRead(SEQ2_SEQ2PSR_REG,&seqReg); 223 224 SET(seqReg,SEQ2PSR_M_DPBUSEN); 225 CLR(seqReg,SEQ2PSR_M_GPIOPINEN); 226 227 sequoiaWrite(SEQ2_SEQ2PSR_REG,seqReg); 228 229 230 231 /* sequoia 2 direction & data */ 232 sequoiaRead(SEQUOIA_2GPIO,&seqReg); 233 234 SET(seqReg,SCR_BUGA_DIR); /* output */ 235 SET(seqReg,SCR_DATA_OUT_DIR); /* output */ 236 SET(seqReg,SCR_CLOCK_DIR); /* output */ 237 SET(seqReg,SCR_BUGB_DIR); /* output */ 238 239 CLR(seqReg,SCR_BUGA); /* 0 */ 240 CLR(seqReg,SCR_BUGB); /* 0 */ 241 CLR(seqReg,SCR_CLOCK); /* 0 */ 242 sequoiaWrite(SEQUOIA_2GPIO,seqReg); 243 244 /* setup the wak0 pin to be detect */ 245 sequoiaRead(SEQR_SEQPSR2_REG,&seqReg); 246 247 SET(seqReg,SEQPSR2_M_DIRTYPINEN); 248 SET(seqReg,SEQPSR2_M_GPIOB0PINEN); 249 250 sequoiaWrite(SEQR_SEQPSR2_REG,seqReg); 251 252 253 sequoiaRead(PMC_GPIOCR2_REG,&seqReg); 254 255 CLR(seqReg,SCR_DETECT_DIR); /* input */ 256 257 sequoiaWrite(PMC_GPIOCR2_REG,seqReg); 258 259 /* don't delay when setting PC bits. this is particularly important 260 for using PC[4] to clear the FIQ. */ 261 sequoiaRead(PMC_SCCR_REG, &seqReg); 262 sequoiaWrite(PMC_SCCR_REG, seqReg | SCCR_M_PCSTGDIS); 263 264 sequoiaUnlock(); 265 266 /* setup the biled info */ 267 ledColor = LED_BILED_GREEN; 268 ledLastActive.tv_usec = 0; 269 ledLastActive.tv_sec = 0; 270 ledBlockCount = 0; 271 callout_init(&led_timo_ch, 0); 272 callout_reset(&led_timo_ch, LED_TIMEOUT, ledTimeout, NULL); 273 } 274 275 void 276 sequoiaLock(void) 277 { 278 sequoiaLock_savedints = disable_interrupts(I32_bit | F32_bit); 279 KASSERT(!sequoiaLock_held); 280 sequoiaLock_held = true; 281 } 282 283 void 284 sequoiaUnlock(void) 285 { 286 KASSERT(sequoiaLock_held); 287 sequoiaLock_held = false; 288 restore_interrupts(sequoiaLock_savedints); 289 } 290 291 bool 292 sequoiaIsLocked(void) 293 { 294 return sequoiaLock_held; 295 } 296 297 /* X console functions */ 298 void consXTvOn(void) 299 { 300 u_int16_t savedPSR3; 301 u_int16_t savedFMPCR; 302 /* 303 ** Switch on TV output on the Sequoia, data indicates mode, 304 ** but we are currently hardwired to NTSC, so ignore it. 305 */ 306 307 sequoiaLock(); 308 309 sequoiaRead (SEQR_SEQPSR3_REG, &savedPSR3); 310 sequoiaWrite(SEQR_SEQPSR3_REG, (savedPSR3 | SEQPSR3_M_PC3PINEN)); 311 312 sequoiaRead (PMC_FOMPCR_REG, &savedFMPCR); 313 sequoiaWrite(PMC_FOMPCR_REG, (savedFMPCR | FOMPCR_M_PCON3)); 314 315 sequoiaUnlock(); 316 } 317 318 void consXTvOff(void) 319 { 320 u_int16_t savedPSR3; 321 u_int16_t savedFMPCR; 322 /* 323 ** Switch off TV output on the Seqoia 324 */ 325 326 sequoiaLock(); 327 328 sequoiaRead (SEQR_SEQPSR3_REG, &savedPSR3); 329 sequoiaWrite(SEQR_SEQPSR3_REG, (savedPSR3 & ~SEQPSR3_M_PC3PINEN)); 330 331 sequoiaRead (PMC_FOMPCR_REG, &savedFMPCR); 332 sequoiaWrite(PMC_FOMPCR_REG, (savedFMPCR & ~FOMPCR_M_PCON3)); 333 334 sequoiaUnlock(); 335 } 336 337 338 339 340 /* smart card routines */ 341 342 int scrGetDetect (void) 343 { 344 int r; 345 u_int16_t seqReg; 346 347 sequoiaLock(); 348 sequoiaRead(PMC_GPIOCR2_REG,&seqReg); 349 sequoiaUnlock(); 350 351 /* inverse logic, so invert */ 352 if (ISSET(seqReg,SCR_DETECT)) 353 { 354 r = 0; 355 } else 356 { 357 r = 1; 358 } 359 360 return r; 361 } 362 363 364 void scrSetPower (int value) 365 { 366 u_int16_t seqReg; 367 368 sequoiaLock(); 369 370 sequoiaRead(SEQUOIA_1GPIO,&seqReg); 371 372 if (value) 373 { 374 SET(seqReg,SCR_POWER); 375 } else 376 { 377 CLR(seqReg,SCR_POWER); 378 } 379 sequoiaWrite(SEQUOIA_1GPIO,seqReg); 380 381 sequoiaUnlock(); 382 } 383 384 void scrSetClock (int value) 385 { 386 u_int16_t seqReg; 387 388 sequoiaLock(); 389 390 sequoiaRead(SEQUOIA_2GPIO,&seqReg); 391 392 if (value) 393 { 394 SET(seqReg,SCR_CLOCK); 395 } else 396 { 397 CLR(seqReg,SCR_CLOCK); 398 } 399 sequoiaWrite(SEQUOIA_2GPIO,seqReg); 400 401 sequoiaUnlock(); 402 } 403 404 void scrSetReset (int value) 405 { 406 u_int16_t seqReg; 407 408 sequoiaLock(); 409 410 sequoiaRead(SEQUOIA_1GPIO,&seqReg); 411 412 if (value) 413 { 414 SET(seqReg,SCR_RESET); 415 } else 416 { 417 CLR(seqReg,SCR_RESET); 418 } 419 sequoiaWrite(SEQUOIA_1GPIO,seqReg); 420 421 sequoiaUnlock(); 422 } 423 424 425 void scrSetDataHighZ (void) 426 { 427 u_int16_t seqReg; 428 429 sequoiaLock(); 430 431 sequoiaRead(SEQUOIA_2GPIO,&seqReg); 432 433 /* set data to 5V, io pin is inverse logic */ 434 CLR(seqReg,SCR_DATA_OUT); 435 436 sequoiaWrite(SEQUOIA_2GPIO,seqReg); 437 438 sequoiaUnlock(); 439 } 440 441 void scrSetData (int value) 442 { 443 u_int16_t seqReg; 444 445 sequoiaLock(); 446 447 sequoiaRead(SEQUOIA_2GPIO,&seqReg); 448 /* inverse logic */ 449 if (value ) 450 { 451 CLR(seqReg,SCR_DATA_OUT); 452 } else 453 { 454 SET(seqReg,SCR_DATA_OUT); 455 } 456 sequoiaWrite(SEQUOIA_2GPIO,seqReg); 457 458 sequoiaUnlock(); 459 } 460 461 int scrGetData (void) 462 { 463 int r; 464 u_int16_t seqReg; 465 466 sequoiaLock(); 467 sequoiaRead(SEQUOIA_1GPIO,&seqReg); 468 sequoiaUnlock(); 469 470 if (ISSET(seqReg,SCR_DATA_IN)) 471 { 472 r = 1; 473 } else 474 { 475 r = 0; 476 } 477 return r; 478 } 479 480 481 482 483 484 485 486 487 void ledNetActive (void) 488 { 489 getmicrotime(&ledLastActive); 490 } 491 492 void ledNetBlock (void) 493 { 494 ledBlockCount++; 495 } 496 497 void ledNetUnblock (void) 498 { 499 ledBlockCount--; 500 } 501 502 void ledPanic (void) 503 { 504 /* we are in panic, timeout wont happen, so set led */ 505 ledSetBiled(LED_BILED_RED); 506 } 507 508 static void ledTimeout(void *arg) 509 { 510 int timeSpan; /* in usec */ 511 struct timeval now; 512 513 getmicrotime(&now); 514 if(now.tv_sec == ledLastActive.tv_sec) 515 { 516 timeSpan = now.tv_usec - ledLastActive.tv_usec; 517 } 518 519 else if (now.tv_sec - 10 < ledLastActive.tv_sec) /* stop rollover problems */ 520 { 521 timeSpan = (1000000 + now.tv_usec) - ledLastActive.tv_usec; 522 } 523 524 else 525 { 526 timeSpan = LED_NET_ACTIVE * 2; /* ie big number */ 527 } 528 529 530 531 /* check if we are blocked */ 532 if(ledBlockCount) 533 { 534 if(ledColor == LED_BILED_YELLOW) 535 { 536 ledSetBiled(LED_BILED_NONE); 537 } 538 else 539 { 540 ledSetBiled(LED_BILED_YELLOW); 541 } 542 } 543 544 545 /* check if we have network activity */ 546 else if (timeSpan < LED_NET_ACTIVE) 547 { 548 if(ledColor == LED_BILED_GREEN) 549 { 550 ledSetBiled(LED_BILED_NONE); 551 } 552 else 553 { 554 ledSetBiled(LED_BILED_GREEN); 555 } 556 } 557 558 /* normal operating mode */ 559 else 560 { 561 if(ledColor != LED_BILED_GREEN) 562 { 563 ledSetBiled(LED_BILED_GREEN); 564 } 565 } 566 567 /* resubmint the timeout */ 568 callout_reset(&led_timo_ch, LED_TIMEOUT, ledTimeout, NULL); 569 570 } 571 572 573 static void ledSetBiled(int color) 574 { 575 u_int16_t seqReg; 576 577 sequoiaLock(); 578 579 ledColor = color; 580 581 sequoiaRead (PMC_FOMPCR_REG, &seqReg); 582 switch(color) 583 { 584 case LED_BILED_NONE: 585 SET(seqReg,LED_BILED_YELLOW_BIT); 586 SET(seqReg,LED_BILED_GREEN_BIT); 587 break; 588 589 case LED_BILED_YELLOW: 590 CLR(seqReg,LED_BILED_YELLOW_BIT); 591 SET(seqReg,LED_BILED_GREEN_BIT); 592 break; 593 594 case LED_BILED_GREEN: 595 SET(seqReg,LED_BILED_YELLOW_BIT); 596 CLR(seqReg,LED_BILED_GREEN_BIT); 597 break; 598 599 case LED_BILED_RED: 600 CLR(seqReg,LED_BILED_YELLOW_BIT); 601 CLR(seqReg,LED_BILED_GREEN_BIT); 602 break; 603 604 default: 605 panic("invalid color %x",color); 606 break; 607 } 608 sequoiaWrite(PMC_FOMPCR_REG, seqReg); 609 610 sequoiaUnlock(); 611 } 612 613 614 int hwGetRev(void) 615 { 616 u_int16_t seqReg; 617 618 sequoiaLock(); 619 sequoiaRead(SR_POR_REG,&seqReg); 620 sequoiaUnlock(); 621 622 seqReg = seqReg >> POR_V_MISCCF0; 623 seqReg = seqReg & 0x7; 624 625 return seqReg; 626 } 627 628 629 630 631 632 /* routines to read/write to sequoia registers */ 633 void sequoiaWrite(int reg,u_int16_t seqReg) 634 { 635 636 KASSERT(sequoiaLock_held); 637 638 /* 639 On SHARK, the fiq comes from the pmi/smi. After receiving 640 a FIQ, the SMI must be cleared. The SMI gets cleared by 641 changing to sleep mode, thereby lowering PC[4]. */ 642 // need to do the right thing with the cache if this is going to work */ 643 if (reg == PMC_FOMPCR_REG) { 644 bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_INDEX_OFFSET,reg); 645 bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_DATA_OFFSET, 646 seqReg | (FOMPCR_M_PCON4)); 647 bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_INDEX_OFFSET, 648 PMC_SLPMPCR_REG); 649 bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_DATA_OFFSET, 650 seqReg & ~(SLPMPCR_M_PCSLP4)); 651 sequoia_index_cache = PMC_SLPMPCR_REG; 652 } else { 653 /* normal case: just do the write */ 654 if(sequoia_index_cache != reg) 655 { 656 sequoia_index_cache = reg; 657 bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_INDEX_OFFSET,reg); 658 } 659 bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_DATA_OFFSET,seqReg); 660 } 661 } 662 663 void sequoiaRead (int reg,u_int16_t * seqReg_ptr) 664 { 665 666 KASSERT(sequoiaLock_held); 667 668 if(sequoia_index_cache != reg) 669 { 670 sequoia_index_cache = reg; 671 bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_INDEX_OFFSET,reg); 672 } 673 *seqReg_ptr = bus_space_read_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_DATA_OFFSET); 674 } 675 676 void ledSetDebug(int command) 677 { 678 u_int16_t seqReg; 679 680 sequoiaLock(); 681 682 sequoiaRead (PMC_FOMPCR_REG, &seqReg); 683 684 685 switch (command) 686 { 687 case LED_DEBUG_STATE_0: 688 CLR(seqReg,LED_DEBUG_YELLOW_BIT); 689 CLR(seqReg,LED_DEBUG_GREEN_BIT); 690 break; 691 692 case LED_DEBUG_STATE_1: 693 SET(seqReg,LED_DEBUG_YELLOW_BIT); 694 CLR(seqReg,LED_DEBUG_GREEN_BIT); 695 break; 696 697 case LED_DEBUG_STATE_2: 698 CLR(seqReg,LED_DEBUG_YELLOW_BIT); 699 SET(seqReg,LED_DEBUG_GREEN_BIT); 700 break; 701 702 case LED_DEBUG_STATE_3: 703 SET(seqReg,LED_DEBUG_YELLOW_BIT); 704 SET(seqReg,LED_DEBUG_GREEN_BIT); 705 break; 706 707 case LED_DEBUG_YELLOW_ON: 708 SET(seqReg,LED_DEBUG_YELLOW_BIT); 709 break; 710 711 case LED_DEBUG_YELLOW_OFF: 712 CLR(seqReg,LED_DEBUG_YELLOW_BIT); 713 break; 714 715 case LED_DEBUG_GREEN_ON: 716 SET(seqReg,LED_DEBUG_GREEN_BIT); 717 break; 718 719 case LED_DEBUG_GREEN_OFF: 720 CLR(seqReg,LED_DEBUG_GREEN_BIT); 721 break; 722 723 default: 724 panic("ledSetDebug: invalid command %d",command); 725 break; 726 } 727 sequoiaWrite(PMC_FOMPCR_REG, seqReg); 728 729 sequoiaUnlock(); 730 } 731 732 733 int testPin=0; 734 void scrToggleTestPin (void) 735 { 736 u_int16_t seqReg; 737 738 sequoiaLock(); 739 740 sequoiaRead(SEQUOIA_2GPIO,&seqReg); 741 742 if (testPin) 743 { 744 testPin = 0; 745 CLR(seqReg,SCR_BUGA); 746 } 747 else 748 { 749 SET(seqReg,SCR_BUGA); 750 testPin = 1; 751 } 752 sequoiaWrite(SEQUOIA_2GPIO,seqReg); 753 754 sequoiaUnlock(); 755 } 756 757 static const struct device_compatible_entry compat_data[] = { 758 { .compat = "sequoia" }, 759 DEVICE_COMPAT_EOL 760 }; 761 762 static int 763 sequoia_cfprint(void *aux, const char *pnp) 764 { 765 struct ofbus_attach_args *oba = aux; 766 767 if (pnp != NULL) { 768 aprint_normal("%s at %s", oba->oba_ofname, pnp); 769 } 770 return UNCONF; 771 } 772 773 static int 774 sequoia_match(device_t parent, cfdata_t cf, void *aux) 775 { 776 struct ofbus_attach_args *oba = aux; 777 778 /* beat ofisa */ 779 return of_compatible_match(oba->oba_phandle, compat_data) ? 100 : 0; 780 } 781 782 static void 783 sequoia_attach(device_t parent, device_t self, void *aux) 784 { 785 const struct ofbus_attach_args *oba = aux; 786 struct ofbus_attach_args noba = *oba; 787 788 aprint_naive("\n"); 789 aprint_normal("\n"); 790 791 noba.oba_busname = "sequoia"; 792 793 /* attach the i2c bus connected to the DRAM banks slots */ 794 strlcpy(noba.oba_ofname, "dec,dnard-i2c", sizeof(noba.oba_ofname)); 795 config_found(self, &noba, sequoia_cfprint, 796 CFARGS(.iattr = "sequoia")); 797 798 /* attach the ofisa instance at the same OFW node */ 799 config_found(self, aux, ofisaprint, 800 CFARGS(.iattr = "ofisa_subclass")); 801 } 802 803 CFATTACH_DECL_NEW(sequoia, 0, 804 sequoia_match, sequoia_attach, NULL, NULL); 805