1 /* 2 * HP i8042-based System Device Controller driver. 3 * 4 * Copyright (c) 2001 Brian S. Julin 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions, and the following disclaimer, 12 * without modification. 13 * 2. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * Alternatively, this software may be distributed under the terms of the 17 * GNU General Public License ("GPL"). 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * 29 * References: 30 * System Device Controller Microprocessor Firmware Theory of Operation 31 * for Part Number 1820-4784 Revision B. Dwg No. A-1820-4784-2 32 * Helge Deller's original hilkbd.c port for PA-RISC. 33 * 34 * 35 * Driver theory of operation: 36 * 37 * hp_sdc_put does all writing to the SDC. ISR can run on a different 38 * CPU than hp_sdc_put, but only one CPU runs hp_sdc_put at a time 39 * (it cannot really benefit from SMP anyway.) A tasket fit this perfectly. 40 * 41 * All data coming back from the SDC is sent via interrupt and can be read 42 * fully in the ISR, so there are no latency/throughput problems there. 43 * The problem is with output, due to the slow clock speed of the SDC 44 * compared to the CPU. This should not be too horrible most of the time, 45 * but if used with HIL devices that support the multibyte transfer command, 46 * keeping outbound throughput flowing at the 6500KBps that the HIL is 47 * capable of is more than can be done at HZ=100. 48 * 49 * Busy polling for IBF clear wastes CPU cycles and bus cycles. hp_sdc.ibf 50 * is set to 0 when the IBF flag in the status register has cleared. ISR 51 * may do this, and may also access the parts of queued transactions related 52 * to reading data back from the SDC, but otherwise will not touch the 53 * hp_sdc state. Whenever a register is written hp_sdc.ibf is set to 1. 54 * 55 * The i8042 write index and the values in the 4-byte input buffer 56 * starting at 0x70 are kept track of in hp_sdc.wi, and .r7[], respectively, 57 * to minimize the amount of IO needed to the SDC. However these values 58 * do not need to be locked since they are only ever accessed by hp_sdc_put. 59 * 60 * A timer task schedules the tasklet once per second just to make 61 * sure it doesn't freeze up and to allow for bad reads to time out. 62 */ 63 64 #include <linux/hp_sdc.h> 65 #include <linux/errno.h> 66 #include <linux/init.h> 67 #include <linux/module.h> 68 #include <linux/ioport.h> 69 #include <linux/time.h> 70 #include <linux/slab.h> 71 #include <linux/hil.h> 72 #include <asm/io.h> 73 #include <asm/system.h> 74 75 /* Machine-specific abstraction */ 76 77 #if defined(__hppa__) 78 # include <asm/parisc-device.h> 79 # define sdc_readb(p) gsc_readb(p) 80 # define sdc_writeb(v,p) gsc_writeb((v),(p)) 81 #elif defined(__mc68000__) 82 # include <asm/uaccess.h> 83 # define sdc_readb(p) in_8(p) 84 # define sdc_writeb(v,p) out_8((p),(v)) 85 #else 86 # error "HIL is not supported on this platform" 87 #endif 88 89 #define PREFIX "HP SDC: " 90 91 MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>"); 92 MODULE_DESCRIPTION("HP i8042-based SDC Driver"); 93 MODULE_LICENSE("Dual BSD/GPL"); 94 95 EXPORT_SYMBOL(hp_sdc_request_timer_irq); 96 EXPORT_SYMBOL(hp_sdc_request_hil_irq); 97 EXPORT_SYMBOL(hp_sdc_request_cooked_irq); 98 99 EXPORT_SYMBOL(hp_sdc_release_timer_irq); 100 EXPORT_SYMBOL(hp_sdc_release_hil_irq); 101 EXPORT_SYMBOL(hp_sdc_release_cooked_irq); 102 103 EXPORT_SYMBOL(__hp_sdc_enqueue_transaction); 104 EXPORT_SYMBOL(hp_sdc_enqueue_transaction); 105 EXPORT_SYMBOL(hp_sdc_dequeue_transaction); 106 107 static hp_i8042_sdc hp_sdc; /* All driver state is kept in here. */ 108 109 /*************** primitives for use in any context *********************/ 110 static inline uint8_t hp_sdc_status_in8(void) 111 { 112 uint8_t status; 113 unsigned long flags; 114 115 write_lock_irqsave(&hp_sdc.ibf_lock, flags); 116 status = sdc_readb(hp_sdc.status_io); 117 if (!(status & HP_SDC_STATUS_IBF)) 118 hp_sdc.ibf = 0; 119 write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); 120 121 return status; 122 } 123 124 static inline uint8_t hp_sdc_data_in8(void) 125 { 126 return sdc_readb(hp_sdc.data_io); 127 } 128 129 static inline void hp_sdc_status_out8(uint8_t val) 130 { 131 unsigned long flags; 132 133 write_lock_irqsave(&hp_sdc.ibf_lock, flags); 134 hp_sdc.ibf = 1; 135 if ((val & 0xf0) == 0xe0) 136 hp_sdc.wi = 0xff; 137 sdc_writeb(val, hp_sdc.status_io); 138 write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); 139 } 140 141 static inline void hp_sdc_data_out8(uint8_t val) 142 { 143 unsigned long flags; 144 145 write_lock_irqsave(&hp_sdc.ibf_lock, flags); 146 hp_sdc.ibf = 1; 147 sdc_writeb(val, hp_sdc.data_io); 148 write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); 149 } 150 151 /* Care must be taken to only invoke hp_sdc_spin_ibf when 152 * absolutely needed, or in rarely invoked subroutines. 153 * Not only does it waste CPU cycles, it also wastes bus cycles. 154 */ 155 static inline void hp_sdc_spin_ibf(void) 156 { 157 unsigned long flags; 158 rwlock_t *lock; 159 160 lock = &hp_sdc.ibf_lock; 161 162 read_lock_irqsave(lock, flags); 163 if (!hp_sdc.ibf) { 164 read_unlock_irqrestore(lock, flags); 165 return; 166 } 167 read_unlock(lock); 168 write_lock(lock); 169 while (sdc_readb(hp_sdc.status_io) & HP_SDC_STATUS_IBF) 170 { } 171 hp_sdc.ibf = 0; 172 write_unlock_irqrestore(lock, flags); 173 } 174 175 176 /************************ Interrupt context functions ************************/ 177 static void hp_sdc_take(int irq, void *dev_id, uint8_t status, uint8_t data) 178 { 179 hp_sdc_transaction *curr; 180 181 read_lock(&hp_sdc.rtq_lock); 182 if (hp_sdc.rcurr < 0) { 183 read_unlock(&hp_sdc.rtq_lock); 184 return; 185 } 186 curr = hp_sdc.tq[hp_sdc.rcurr]; 187 read_unlock(&hp_sdc.rtq_lock); 188 189 curr->seq[curr->idx++] = status; 190 curr->seq[curr->idx++] = data; 191 hp_sdc.rqty -= 2; 192 do_gettimeofday(&hp_sdc.rtv); 193 194 if (hp_sdc.rqty <= 0) { 195 /* All data has been gathered. */ 196 if (curr->seq[curr->actidx] & HP_SDC_ACT_SEMAPHORE) 197 if (curr->act.semaphore) 198 up(curr->act.semaphore); 199 200 if (curr->seq[curr->actidx] & HP_SDC_ACT_CALLBACK) 201 if (curr->act.irqhook) 202 curr->act.irqhook(irq, dev_id, status, data); 203 204 curr->actidx = curr->idx; 205 curr->idx++; 206 /* Return control of this transaction */ 207 write_lock(&hp_sdc.rtq_lock); 208 hp_sdc.rcurr = -1; 209 hp_sdc.rqty = 0; 210 write_unlock(&hp_sdc.rtq_lock); 211 tasklet_schedule(&hp_sdc.task); 212 } 213 } 214 215 static irqreturn_t hp_sdc_isr(int irq, void *dev_id) 216 { 217 uint8_t status, data; 218 219 status = hp_sdc_status_in8(); 220 /* Read data unconditionally to advance i8042. */ 221 data = hp_sdc_data_in8(); 222 223 /* For now we are ignoring these until we get the SDC to behave. */ 224 if (((status & 0xf1) == 0x51) && data == 0x82) 225 return IRQ_HANDLED; 226 227 switch (status & HP_SDC_STATUS_IRQMASK) { 228 case 0: /* This case is not documented. */ 229 break; 230 231 case HP_SDC_STATUS_USERTIMER: 232 case HP_SDC_STATUS_PERIODIC: 233 case HP_SDC_STATUS_TIMER: 234 read_lock(&hp_sdc.hook_lock); 235 if (hp_sdc.timer != NULL) 236 hp_sdc.timer(irq, dev_id, status, data); 237 read_unlock(&hp_sdc.hook_lock); 238 break; 239 240 case HP_SDC_STATUS_REG: 241 hp_sdc_take(irq, dev_id, status, data); 242 break; 243 244 case HP_SDC_STATUS_HILCMD: 245 case HP_SDC_STATUS_HILDATA: 246 read_lock(&hp_sdc.hook_lock); 247 if (hp_sdc.hil != NULL) 248 hp_sdc.hil(irq, dev_id, status, data); 249 read_unlock(&hp_sdc.hook_lock); 250 break; 251 252 case HP_SDC_STATUS_PUP: 253 read_lock(&hp_sdc.hook_lock); 254 if (hp_sdc.pup != NULL) 255 hp_sdc.pup(irq, dev_id, status, data); 256 else 257 printk(KERN_INFO PREFIX "HP SDC reports successful PUP.\n"); 258 read_unlock(&hp_sdc.hook_lock); 259 break; 260 261 default: 262 read_lock(&hp_sdc.hook_lock); 263 if (hp_sdc.cooked != NULL) 264 hp_sdc.cooked(irq, dev_id, status, data); 265 read_unlock(&hp_sdc.hook_lock); 266 break; 267 } 268 269 return IRQ_HANDLED; 270 } 271 272 273 static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id) 274 { 275 int status; 276 277 status = hp_sdc_status_in8(); 278 printk(KERN_WARNING PREFIX "NMI !\n"); 279 280 #if 0 281 if (status & HP_SDC_NMISTATUS_FHS) { 282 read_lock(&hp_sdc.hook_lock); 283 if (hp_sdc.timer != NULL) 284 hp_sdc.timer(irq, dev_id, status, 0); 285 read_unlock(&hp_sdc.hook_lock); 286 } else { 287 /* TODO: pass this on to the HIL handler, or do SAK here? */ 288 printk(KERN_WARNING PREFIX "HIL NMI\n"); 289 } 290 #endif 291 292 return IRQ_HANDLED; 293 } 294 295 296 /***************** Kernel (tasklet) context functions ****************/ 297 298 unsigned long hp_sdc_put(void); 299 300 static void hp_sdc_tasklet(unsigned long foo) 301 { 302 write_lock_irq(&hp_sdc.rtq_lock); 303 304 if (hp_sdc.rcurr >= 0) { 305 struct timeval tv; 306 307 do_gettimeofday(&tv); 308 if (tv.tv_sec > hp_sdc.rtv.tv_sec) 309 tv.tv_usec += USEC_PER_SEC; 310 311 if (tv.tv_usec - hp_sdc.rtv.tv_usec > HP_SDC_MAX_REG_DELAY) { 312 hp_sdc_transaction *curr; 313 uint8_t tmp; 314 315 curr = hp_sdc.tq[hp_sdc.rcurr]; 316 /* If this turns out to be a normal failure mode 317 * we'll need to figure out a way to communicate 318 * it back to the application. and be less verbose. 319 */ 320 printk(KERN_WARNING PREFIX "read timeout (%ius)!\n", 321 tv.tv_usec - hp_sdc.rtv.tv_usec); 322 curr->idx += hp_sdc.rqty; 323 hp_sdc.rqty = 0; 324 tmp = curr->seq[curr->actidx]; 325 curr->seq[curr->actidx] |= HP_SDC_ACT_DEAD; 326 if (tmp & HP_SDC_ACT_SEMAPHORE) 327 if (curr->act.semaphore) 328 up(curr->act.semaphore); 329 330 if (tmp & HP_SDC_ACT_CALLBACK) { 331 /* Note this means that irqhooks may be called 332 * in tasklet/bh context. 333 */ 334 if (curr->act.irqhook) 335 curr->act.irqhook(0, NULL, 0, 0); 336 } 337 338 curr->actidx = curr->idx; 339 curr->idx++; 340 hp_sdc.rcurr = -1; 341 } 342 } 343 write_unlock_irq(&hp_sdc.rtq_lock); 344 hp_sdc_put(); 345 } 346 347 unsigned long hp_sdc_put(void) 348 { 349 hp_sdc_transaction *curr; 350 uint8_t act; 351 int idx, curridx; 352 353 int limit = 0; 354 355 write_lock(&hp_sdc.lock); 356 357 /* If i8042 buffers are full, we cannot do anything that 358 requires output, so we skip to the administrativa. */ 359 if (hp_sdc.ibf) { 360 hp_sdc_status_in8(); 361 if (hp_sdc.ibf) 362 goto finish; 363 } 364 365 anew: 366 /* See if we are in the middle of a sequence. */ 367 if (hp_sdc.wcurr < 0) 368 hp_sdc.wcurr = 0; 369 read_lock_irq(&hp_sdc.rtq_lock); 370 if (hp_sdc.rcurr == hp_sdc.wcurr) 371 hp_sdc.wcurr++; 372 read_unlock_irq(&hp_sdc.rtq_lock); 373 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) 374 hp_sdc.wcurr = 0; 375 curridx = hp_sdc.wcurr; 376 377 if (hp_sdc.tq[curridx] != NULL) 378 goto start; 379 380 while (++curridx != hp_sdc.wcurr) { 381 if (curridx >= HP_SDC_QUEUE_LEN) { 382 curridx = -1; /* Wrap to top */ 383 continue; 384 } 385 read_lock_irq(&hp_sdc.rtq_lock); 386 if (hp_sdc.rcurr == curridx) { 387 read_unlock_irq(&hp_sdc.rtq_lock); 388 continue; 389 } 390 read_unlock_irq(&hp_sdc.rtq_lock); 391 if (hp_sdc.tq[curridx] != NULL) 392 break; /* Found one. */ 393 } 394 if (curridx == hp_sdc.wcurr) { /* There's nothing queued to do. */ 395 curridx = -1; 396 } 397 hp_sdc.wcurr = curridx; 398 399 start: 400 401 /* Check to see if the interrupt mask needs to be set. */ 402 if (hp_sdc.set_im) { 403 hp_sdc_status_out8(hp_sdc.im | HP_SDC_CMD_SET_IM); 404 hp_sdc.set_im = 0; 405 goto finish; 406 } 407 408 if (hp_sdc.wcurr == -1) 409 goto done; 410 411 curr = hp_sdc.tq[curridx]; 412 idx = curr->actidx; 413 414 if (curr->actidx >= curr->endidx) { 415 hp_sdc.tq[curridx] = NULL; 416 /* Interleave outbound data between the transactions. */ 417 hp_sdc.wcurr++; 418 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) 419 hp_sdc.wcurr = 0; 420 goto finish; 421 } 422 423 act = curr->seq[idx]; 424 idx++; 425 426 if (curr->idx >= curr->endidx) { 427 if (act & HP_SDC_ACT_DEALLOC) 428 kfree(curr); 429 hp_sdc.tq[curridx] = NULL; 430 /* Interleave outbound data between the transactions. */ 431 hp_sdc.wcurr++; 432 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) 433 hp_sdc.wcurr = 0; 434 goto finish; 435 } 436 437 while (act & HP_SDC_ACT_PRECMD) { 438 if (curr->idx != idx) { 439 idx++; 440 act &= ~HP_SDC_ACT_PRECMD; 441 break; 442 } 443 hp_sdc_status_out8(curr->seq[idx]); 444 curr->idx++; 445 /* act finished? */ 446 if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_PRECMD) 447 goto actdone; 448 /* skip quantity field if data-out sequence follows. */ 449 if (act & HP_SDC_ACT_DATAOUT) 450 curr->idx++; 451 goto finish; 452 } 453 if (act & HP_SDC_ACT_DATAOUT) { 454 int qty; 455 456 qty = curr->seq[idx]; 457 idx++; 458 if (curr->idx - idx < qty) { 459 hp_sdc_data_out8(curr->seq[curr->idx]); 460 curr->idx++; 461 /* act finished? */ 462 if (curr->idx - idx >= qty && 463 (act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAOUT) 464 goto actdone; 465 goto finish; 466 } 467 idx += qty; 468 act &= ~HP_SDC_ACT_DATAOUT; 469 } else 470 while (act & HP_SDC_ACT_DATAREG) { 471 int mask; 472 uint8_t w7[4]; 473 474 mask = curr->seq[idx]; 475 if (idx != curr->idx) { 476 idx++; 477 idx += !!(mask & 1); 478 idx += !!(mask & 2); 479 idx += !!(mask & 4); 480 idx += !!(mask & 8); 481 act &= ~HP_SDC_ACT_DATAREG; 482 break; 483 } 484 485 w7[0] = (mask & 1) ? curr->seq[++idx] : hp_sdc.r7[0]; 486 w7[1] = (mask & 2) ? curr->seq[++idx] : hp_sdc.r7[1]; 487 w7[2] = (mask & 4) ? curr->seq[++idx] : hp_sdc.r7[2]; 488 w7[3] = (mask & 8) ? curr->seq[++idx] : hp_sdc.r7[3]; 489 490 if (hp_sdc.wi > 0x73 || hp_sdc.wi < 0x70 || 491 w7[hp_sdc.wi - 0x70] == hp_sdc.r7[hp_sdc.wi - 0x70]) { 492 int i = 0; 493 494 /* Need to point the write index register */ 495 while (i < 4 && w7[i] == hp_sdc.r7[i]) 496 i++; 497 498 if (i < 4) { 499 hp_sdc_status_out8(HP_SDC_CMD_SET_D0 + i); 500 hp_sdc.wi = 0x70 + i; 501 goto finish; 502 } 503 504 idx++; 505 if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAREG) 506 goto actdone; 507 508 curr->idx = idx; 509 act &= ~HP_SDC_ACT_DATAREG; 510 break; 511 } 512 513 hp_sdc_data_out8(w7[hp_sdc.wi - 0x70]); 514 hp_sdc.r7[hp_sdc.wi - 0x70] = w7[hp_sdc.wi - 0x70]; 515 hp_sdc.wi++; /* write index register autoincrements */ 516 { 517 int i = 0; 518 519 while ((i < 4) && w7[i] == hp_sdc.r7[i]) 520 i++; 521 if (i >= 4) { 522 curr->idx = idx + 1; 523 if ((act & HP_SDC_ACT_DURING) == 524 HP_SDC_ACT_DATAREG) 525 goto actdone; 526 } 527 } 528 goto finish; 529 } 530 /* We don't go any further in the command if there is a pending read, 531 because we don't want interleaved results. */ 532 read_lock_irq(&hp_sdc.rtq_lock); 533 if (hp_sdc.rcurr >= 0) { 534 read_unlock_irq(&hp_sdc.rtq_lock); 535 goto finish; 536 } 537 read_unlock_irq(&hp_sdc.rtq_lock); 538 539 540 if (act & HP_SDC_ACT_POSTCMD) { 541 uint8_t postcmd; 542 543 /* curr->idx should == idx at this point. */ 544 postcmd = curr->seq[idx]; 545 curr->idx++; 546 if (act & HP_SDC_ACT_DATAIN) { 547 548 /* Start a new read */ 549 hp_sdc.rqty = curr->seq[curr->idx]; 550 do_gettimeofday(&hp_sdc.rtv); 551 curr->idx++; 552 /* Still need to lock here in case of spurious irq. */ 553 write_lock_irq(&hp_sdc.rtq_lock); 554 hp_sdc.rcurr = curridx; 555 write_unlock_irq(&hp_sdc.rtq_lock); 556 hp_sdc_status_out8(postcmd); 557 goto finish; 558 } 559 hp_sdc_status_out8(postcmd); 560 goto actdone; 561 } 562 563 actdone: 564 if (act & HP_SDC_ACT_SEMAPHORE) 565 up(curr->act.semaphore); 566 else if (act & HP_SDC_ACT_CALLBACK) 567 curr->act.irqhook(0,NULL,0,0); 568 569 if (curr->idx >= curr->endidx) { /* This transaction is over. */ 570 if (act & HP_SDC_ACT_DEALLOC) 571 kfree(curr); 572 hp_sdc.tq[curridx] = NULL; 573 } else { 574 curr->actidx = idx + 1; 575 curr->idx = idx + 2; 576 } 577 /* Interleave outbound data between the transactions. */ 578 hp_sdc.wcurr++; 579 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) 580 hp_sdc.wcurr = 0; 581 582 finish: 583 /* If by some quirk IBF has cleared and our ISR has run to 584 see that that has happened, do it all again. */ 585 if (!hp_sdc.ibf && limit++ < 20) 586 goto anew; 587 588 done: 589 if (hp_sdc.wcurr >= 0) 590 tasklet_schedule(&hp_sdc.task); 591 write_unlock(&hp_sdc.lock); 592 593 return 0; 594 } 595 596 /******* Functions called in either user or kernel context ****/ 597 int __hp_sdc_enqueue_transaction(hp_sdc_transaction *this) 598 { 599 int i; 600 601 if (this == NULL) { 602 BUG(); 603 return -EINVAL; 604 } 605 606 /* Can't have same transaction on queue twice */ 607 for (i = 0; i < HP_SDC_QUEUE_LEN; i++) 608 if (hp_sdc.tq[i] == this) 609 goto fail; 610 611 this->actidx = 0; 612 this->idx = 1; 613 614 /* Search for empty slot */ 615 for (i = 0; i < HP_SDC_QUEUE_LEN; i++) 616 if (hp_sdc.tq[i] == NULL) { 617 hp_sdc.tq[i] = this; 618 tasklet_schedule(&hp_sdc.task); 619 return 0; 620 } 621 622 printk(KERN_WARNING PREFIX "No free slot to add transaction.\n"); 623 return -EBUSY; 624 625 fail: 626 printk(KERN_WARNING PREFIX "Transaction add failed: transaction already queued?\n"); 627 return -EINVAL; 628 } 629 630 int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) { 631 unsigned long flags; 632 int ret; 633 634 write_lock_irqsave(&hp_sdc.lock, flags); 635 ret = __hp_sdc_enqueue_transaction(this); 636 write_unlock_irqrestore(&hp_sdc.lock,flags); 637 638 return ret; 639 } 640 641 int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) 642 { 643 unsigned long flags; 644 int i; 645 646 write_lock_irqsave(&hp_sdc.lock, flags); 647 648 /* TODO: don't remove it if it's not done. */ 649 650 for (i = 0; i < HP_SDC_QUEUE_LEN; i++) 651 if (hp_sdc.tq[i] == this) 652 hp_sdc.tq[i] = NULL; 653 654 write_unlock_irqrestore(&hp_sdc.lock, flags); 655 return 0; 656 } 657 658 659 660 /********************** User context functions **************************/ 661 int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback) 662 { 663 if (callback == NULL || hp_sdc.dev == NULL) 664 return -EINVAL; 665 666 write_lock_irq(&hp_sdc.hook_lock); 667 if (hp_sdc.timer != NULL) { 668 write_unlock_irq(&hp_sdc.hook_lock); 669 return -EBUSY; 670 } 671 672 hp_sdc.timer = callback; 673 /* Enable interrupts from the timers */ 674 hp_sdc.im &= ~HP_SDC_IM_FH; 675 hp_sdc.im &= ~HP_SDC_IM_PT; 676 hp_sdc.im &= ~HP_SDC_IM_TIMERS; 677 hp_sdc.set_im = 1; 678 write_unlock_irq(&hp_sdc.hook_lock); 679 680 tasklet_schedule(&hp_sdc.task); 681 682 return 0; 683 } 684 685 int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback) 686 { 687 if (callback == NULL || hp_sdc.dev == NULL) 688 return -EINVAL; 689 690 write_lock_irq(&hp_sdc.hook_lock); 691 if (hp_sdc.hil != NULL) { 692 write_unlock_irq(&hp_sdc.hook_lock); 693 return -EBUSY; 694 } 695 696 hp_sdc.hil = callback; 697 hp_sdc.im &= ~(HP_SDC_IM_HIL | HP_SDC_IM_RESET); 698 hp_sdc.set_im = 1; 699 write_unlock_irq(&hp_sdc.hook_lock); 700 701 tasklet_schedule(&hp_sdc.task); 702 703 return 0; 704 } 705 706 int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback) 707 { 708 if (callback == NULL || hp_sdc.dev == NULL) 709 return -EINVAL; 710 711 write_lock_irq(&hp_sdc.hook_lock); 712 if (hp_sdc.cooked != NULL) { 713 write_unlock_irq(&hp_sdc.hook_lock); 714 return -EBUSY; 715 } 716 717 /* Enable interrupts from the HIL MLC */ 718 hp_sdc.cooked = callback; 719 hp_sdc.im &= ~(HP_SDC_IM_HIL | HP_SDC_IM_RESET); 720 hp_sdc.set_im = 1; 721 write_unlock_irq(&hp_sdc.hook_lock); 722 723 tasklet_schedule(&hp_sdc.task); 724 725 return 0; 726 } 727 728 int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback) 729 { 730 write_lock_irq(&hp_sdc.hook_lock); 731 if ((callback != hp_sdc.timer) || 732 (hp_sdc.timer == NULL)) { 733 write_unlock_irq(&hp_sdc.hook_lock); 734 return -EINVAL; 735 } 736 737 /* Disable interrupts from the timers */ 738 hp_sdc.timer = NULL; 739 hp_sdc.im |= HP_SDC_IM_TIMERS; 740 hp_sdc.im |= HP_SDC_IM_FH; 741 hp_sdc.im |= HP_SDC_IM_PT; 742 hp_sdc.set_im = 1; 743 write_unlock_irq(&hp_sdc.hook_lock); 744 tasklet_schedule(&hp_sdc.task); 745 746 return 0; 747 } 748 749 int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback) 750 { 751 write_lock_irq(&hp_sdc.hook_lock); 752 if ((callback != hp_sdc.hil) || 753 (hp_sdc.hil == NULL)) { 754 write_unlock_irq(&hp_sdc.hook_lock); 755 return -EINVAL; 756 } 757 758 hp_sdc.hil = NULL; 759 /* Disable interrupts from HIL only if there is no cooked driver. */ 760 if(hp_sdc.cooked == NULL) { 761 hp_sdc.im |= (HP_SDC_IM_HIL | HP_SDC_IM_RESET); 762 hp_sdc.set_im = 1; 763 } 764 write_unlock_irq(&hp_sdc.hook_lock); 765 tasklet_schedule(&hp_sdc.task); 766 767 return 0; 768 } 769 770 int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) 771 { 772 write_lock_irq(&hp_sdc.hook_lock); 773 if ((callback != hp_sdc.cooked) || 774 (hp_sdc.cooked == NULL)) { 775 write_unlock_irq(&hp_sdc.hook_lock); 776 return -EINVAL; 777 } 778 779 hp_sdc.cooked = NULL; 780 /* Disable interrupts from HIL only if there is no raw HIL driver. */ 781 if(hp_sdc.hil == NULL) { 782 hp_sdc.im |= (HP_SDC_IM_HIL | HP_SDC_IM_RESET); 783 hp_sdc.set_im = 1; 784 } 785 write_unlock_irq(&hp_sdc.hook_lock); 786 tasklet_schedule(&hp_sdc.task); 787 788 return 0; 789 } 790 791 /************************* Keepalive timer task *********************/ 792 793 void hp_sdc_kicker (unsigned long data) 794 { 795 tasklet_schedule(&hp_sdc.task); 796 /* Re-insert the periodic task. */ 797 mod_timer(&hp_sdc.kicker, jiffies + HZ); 798 } 799 800 /************************** Module Initialization ***************************/ 801 802 #if defined(__hppa__) 803 804 static const struct parisc_device_id hp_sdc_tbl[] = { 805 { 806 .hw_type = HPHW_FIO, 807 .hversion_rev = HVERSION_REV_ANY_ID, 808 .hversion = HVERSION_ANY_ID, 809 .sversion = 0x73, 810 }, 811 { 0, } 812 }; 813 814 MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl); 815 816 static int __init hp_sdc_init_hppa(struct parisc_device *d); 817 818 static struct parisc_driver hp_sdc_driver = { 819 .name = "hp_sdc", 820 .id_table = hp_sdc_tbl, 821 .probe = hp_sdc_init_hppa, 822 }; 823 824 #endif /* __hppa__ */ 825 826 static int __init hp_sdc_init(void) 827 { 828 char *errstr; 829 hp_sdc_transaction t_sync; 830 uint8_t ts_sync[6]; 831 struct semaphore s_sync; 832 833 rwlock_init(&hp_sdc.lock); 834 rwlock_init(&hp_sdc.ibf_lock); 835 rwlock_init(&hp_sdc.rtq_lock); 836 rwlock_init(&hp_sdc.hook_lock); 837 838 hp_sdc.timer = NULL; 839 hp_sdc.hil = NULL; 840 hp_sdc.pup = NULL; 841 hp_sdc.cooked = NULL; 842 hp_sdc.im = HP_SDC_IM_MASK; /* Mask maskable irqs */ 843 hp_sdc.set_im = 1; 844 hp_sdc.wi = 0xff; 845 hp_sdc.r7[0] = 0xff; 846 hp_sdc.r7[1] = 0xff; 847 hp_sdc.r7[2] = 0xff; 848 hp_sdc.r7[3] = 0xff; 849 hp_sdc.ibf = 1; 850 851 memset(&hp_sdc.tq, 0, sizeof(hp_sdc.tq)); 852 853 hp_sdc.wcurr = -1; 854 hp_sdc.rcurr = -1; 855 hp_sdc.rqty = 0; 856 857 hp_sdc.dev_err = -ENODEV; 858 859 errstr = "IO not found for"; 860 if (!hp_sdc.base_io) 861 goto err0; 862 863 errstr = "IRQ not found for"; 864 if (!hp_sdc.irq) 865 goto err0; 866 867 hp_sdc.dev_err = -EBUSY; 868 869 #if defined(__hppa__) 870 errstr = "IO not available for"; 871 if (request_region(hp_sdc.data_io, 2, hp_sdc_driver.name)) 872 goto err0; 873 #endif 874 875 errstr = "IRQ not available for"; 876 if (request_irq(hp_sdc.irq, &hp_sdc_isr, IRQF_SHARED|IRQF_SAMPLE_RANDOM, 877 "HP SDC", &hp_sdc)) 878 goto err1; 879 880 errstr = "NMI not available for"; 881 if (request_irq(hp_sdc.nmi, &hp_sdc_nmisr, IRQF_SHARED, 882 "HP SDC NMI", &hp_sdc)) 883 goto err2; 884 885 printk(KERN_INFO PREFIX "HP SDC at 0x%p, IRQ %d (NMI IRQ %d)\n", 886 (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi); 887 888 hp_sdc_status_in8(); 889 hp_sdc_data_in8(); 890 891 tasklet_init(&hp_sdc.task, hp_sdc_tasklet, 0); 892 893 /* Sync the output buffer registers, thus scheduling hp_sdc_tasklet. */ 894 t_sync.actidx = 0; 895 t_sync.idx = 1; 896 t_sync.endidx = 6; 897 t_sync.seq = ts_sync; 898 ts_sync[0] = HP_SDC_ACT_DATAREG | HP_SDC_ACT_SEMAPHORE; 899 ts_sync[1] = 0x0f; 900 ts_sync[2] = ts_sync[3] = ts_sync[4] = ts_sync[5] = 0; 901 t_sync.act.semaphore = &s_sync; 902 init_MUTEX_LOCKED(&s_sync); 903 hp_sdc_enqueue_transaction(&t_sync); 904 down(&s_sync); /* Wait for t_sync to complete */ 905 906 /* Create the keepalive task */ 907 init_timer(&hp_sdc.kicker); 908 hp_sdc.kicker.expires = jiffies + HZ; 909 hp_sdc.kicker.function = &hp_sdc_kicker; 910 add_timer(&hp_sdc.kicker); 911 912 hp_sdc.dev_err = 0; 913 return 0; 914 err2: 915 free_irq(hp_sdc.irq, &hp_sdc); 916 err1: 917 release_region(hp_sdc.data_io, 2); 918 err0: 919 printk(KERN_WARNING PREFIX ": %s SDC IO=0x%p IRQ=0x%x NMI=0x%x\n", 920 errstr, (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi); 921 hp_sdc.dev = NULL; 922 923 return hp_sdc.dev_err; 924 } 925 926 #if defined(__hppa__) 927 928 static int __init hp_sdc_init_hppa(struct parisc_device *d) 929 { 930 if (!d) 931 return 1; 932 if (hp_sdc.dev != NULL) 933 return 1; /* We only expect one SDC */ 934 935 hp_sdc.dev = d; 936 hp_sdc.irq = d->irq; 937 hp_sdc.nmi = d->aux_irq; 938 hp_sdc.base_io = d->hpa.start; 939 hp_sdc.data_io = d->hpa.start + 0x800; 940 hp_sdc.status_io = d->hpa.start + 0x801; 941 942 return hp_sdc_init(); 943 } 944 945 #endif /* __hppa__ */ 946 947 #if !defined(__mc68000__) /* Link error on m68k! */ 948 static void __exit hp_sdc_exit(void) 949 #else 950 static void hp_sdc_exit(void) 951 #endif 952 { 953 write_lock_irq(&hp_sdc.lock); 954 955 /* Turn off all maskable "sub-function" irq's. */ 956 hp_sdc_spin_ibf(); 957 sdc_writeb(HP_SDC_CMD_SET_IM | HP_SDC_IM_MASK, hp_sdc.status_io); 958 959 /* Wait until we know this has been processed by the i8042 */ 960 hp_sdc_spin_ibf(); 961 962 free_irq(hp_sdc.nmi, &hp_sdc); 963 free_irq(hp_sdc.irq, &hp_sdc); 964 write_unlock_irq(&hp_sdc.lock); 965 966 del_timer(&hp_sdc.kicker); 967 968 tasklet_kill(&hp_sdc.task); 969 970 #if defined(__hppa__) 971 if (unregister_parisc_driver(&hp_sdc_driver)) 972 printk(KERN_WARNING PREFIX "Error unregistering HP SDC"); 973 #endif 974 } 975 976 static int __init hp_sdc_register(void) 977 { 978 hp_sdc_transaction tq_init; 979 uint8_t tq_init_seq[5]; 980 struct semaphore tq_init_sem; 981 #if defined(__mc68000__) 982 mm_segment_t fs; 983 unsigned char i; 984 #endif 985 986 hp_sdc.dev = NULL; 987 hp_sdc.dev_err = 0; 988 #if defined(__hppa__) 989 if (register_parisc_driver(&hp_sdc_driver)) { 990 printk(KERN_WARNING PREFIX "Error registering SDC with system bus tree.\n"); 991 return -ENODEV; 992 } 993 #elif defined(__mc68000__) 994 if (!MACH_IS_HP300) 995 return -ENODEV; 996 997 hp_sdc.irq = 1; 998 hp_sdc.nmi = 7; 999 hp_sdc.base_io = (unsigned long) 0xf0428000; 1000 hp_sdc.data_io = (unsigned long) hp_sdc.base_io + 1; 1001 hp_sdc.status_io = (unsigned long) hp_sdc.base_io + 3; 1002 fs = get_fs(); 1003 set_fs(KERNEL_DS); 1004 if (!get_user(i, (unsigned char *)hp_sdc.data_io)) 1005 hp_sdc.dev = (void *)1; 1006 set_fs(fs); 1007 hp_sdc.dev_err = hp_sdc_init(); 1008 #endif 1009 if (hp_sdc.dev == NULL) { 1010 printk(KERN_WARNING PREFIX "No SDC found.\n"); 1011 return hp_sdc.dev_err; 1012 } 1013 1014 init_MUTEX_LOCKED(&tq_init_sem); 1015 1016 tq_init.actidx = 0; 1017 tq_init.idx = 1; 1018 tq_init.endidx = 5; 1019 tq_init.seq = tq_init_seq; 1020 tq_init.act.semaphore = &tq_init_sem; 1021 1022 tq_init_seq[0] = 1023 HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE; 1024 tq_init_seq[1] = HP_SDC_CMD_READ_KCC; 1025 tq_init_seq[2] = 1; 1026 tq_init_seq[3] = 0; 1027 tq_init_seq[4] = 0; 1028 1029 hp_sdc_enqueue_transaction(&tq_init); 1030 1031 down(&tq_init_sem); 1032 up(&tq_init_sem); 1033 1034 if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) { 1035 printk(KERN_WARNING PREFIX "Error reading config byte.\n"); 1036 hp_sdc_exit(); 1037 return -ENODEV; 1038 } 1039 hp_sdc.r11 = tq_init_seq[4]; 1040 if (hp_sdc.r11 & HP_SDC_CFG_NEW) { 1041 const char *str; 1042 printk(KERN_INFO PREFIX "New style SDC\n"); 1043 tq_init_seq[1] = HP_SDC_CMD_READ_XTD; 1044 tq_init.actidx = 0; 1045 tq_init.idx = 1; 1046 down(&tq_init_sem); 1047 hp_sdc_enqueue_transaction(&tq_init); 1048 down(&tq_init_sem); 1049 up(&tq_init_sem); 1050 if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) { 1051 printk(KERN_WARNING PREFIX "Error reading extended config byte.\n"); 1052 return -ENODEV; 1053 } 1054 hp_sdc.r7e = tq_init_seq[4]; 1055 HP_SDC_XTD_REV_STRINGS(hp_sdc.r7e & HP_SDC_XTD_REV, str) 1056 printk(KERN_INFO PREFIX "Revision: %s\n", str); 1057 if (hp_sdc.r7e & HP_SDC_XTD_BEEPER) 1058 printk(KERN_INFO PREFIX "TI SN76494 beeper present\n"); 1059 if (hp_sdc.r7e & HP_SDC_XTD_BBRTC) 1060 printk(KERN_INFO PREFIX "OKI MSM-58321 BBRTC present\n"); 1061 printk(KERN_INFO PREFIX "Spunking the self test register to force PUP " 1062 "on next firmware reset.\n"); 1063 tq_init_seq[0] = HP_SDC_ACT_PRECMD | 1064 HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE; 1065 tq_init_seq[1] = HP_SDC_CMD_SET_STR; 1066 tq_init_seq[2] = 1; 1067 tq_init_seq[3] = 0; 1068 tq_init.actidx = 0; 1069 tq_init.idx = 1; 1070 tq_init.endidx = 4; 1071 down(&tq_init_sem); 1072 hp_sdc_enqueue_transaction(&tq_init); 1073 down(&tq_init_sem); 1074 up(&tq_init_sem); 1075 } else 1076 printk(KERN_INFO PREFIX "Old style SDC (1820-%s).\n", 1077 (hp_sdc.r11 & HP_SDC_CFG_REV) ? "3300" : "2564/3087"); 1078 1079 return 0; 1080 } 1081 1082 module_init(hp_sdc_register); 1083 module_exit(hp_sdc_exit); 1084 1085 /* Timing notes: These measurements taken on my 64MHz 7100-LC (715/64) 1086 * cycles cycles-adj time 1087 * between two consecutive mfctl(16)'s: 4 n/a 63ns 1088 * hp_sdc_spin_ibf when idle: 119 115 1.7us 1089 * gsc_writeb status register: 83 79 1.2us 1090 * IBF to clear after sending SET_IM: 6204 6006 93us 1091 * IBF to clear after sending LOAD_RT: 4467 4352 68us 1092 * IBF to clear after sending two LOAD_RTs: 18974 18859 295us 1093 * READ_T1, read status/data, IRQ, call handler: 35564 n/a 556us 1094 * cmd to ~IBF READ_T1 2nd time right after: 5158403 n/a 81ms 1095 * between IRQ received and ~IBF for above: 2578877 n/a 40ms 1096 * 1097 * Performance stats after a run of this module configuring HIL and 1098 * receiving a few mouse events: 1099 * 1100 * status in8 282508 cycles 7128 calls 1101 * status out8 8404 cycles 341 calls 1102 * data out8 1734 cycles 78 calls 1103 * isr 174324 cycles 617 calls (includes take) 1104 * take 1241 cycles 2 calls 1105 * put 1411504 cycles 6937 calls 1106 * task 1655209 cycles 6937 calls (includes put) 1107 * 1108 */ 1109