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