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/export.h> 67 #include <linux/init.h> 68 #include <linux/module.h> 69 #include <linux/ioport.h> 70 #include <linux/time.h> 71 #include <linux/semaphore.h> 72 #include <linux/slab.h> 73 #include <linux/hil.h> 74 #include <asm/io.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 <linux/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 bool 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 hp_sdc.rtime = ktime_get(); 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 ktime_t now = ktime_get(); 311 312 if (ktime_after(now, ktime_add_us(hp_sdc.rtime, 313 HP_SDC_MAX_REG_DELAY))) { 314 hp_sdc_transaction *curr; 315 uint8_t tmp; 316 317 curr = hp_sdc.tq[hp_sdc.rcurr]; 318 /* If this turns out to be a normal failure mode 319 * we'll need to figure out a way to communicate 320 * it back to the application. and be less verbose. 321 */ 322 printk(KERN_WARNING PREFIX "read timeout (%lldus)!\n", 323 ktime_us_delta(now, hp_sdc.rtime)); 324 curr->idx += hp_sdc.rqty; 325 hp_sdc.rqty = 0; 326 tmp = curr->seq[curr->actidx]; 327 curr->seq[curr->actidx] |= HP_SDC_ACT_DEAD; 328 if (tmp & HP_SDC_ACT_SEMAPHORE) 329 if (curr->act.semaphore) 330 up(curr->act.semaphore); 331 332 if (tmp & HP_SDC_ACT_CALLBACK) { 333 /* Note this means that irqhooks may be called 334 * in tasklet/bh context. 335 */ 336 if (curr->act.irqhook) 337 curr->act.irqhook(0, NULL, 0, 0); 338 } 339 340 curr->actidx = curr->idx; 341 curr->idx++; 342 hp_sdc.rcurr = -1; 343 } 344 } 345 write_unlock_irq(&hp_sdc.rtq_lock); 346 hp_sdc_put(); 347 } 348 349 unsigned long hp_sdc_put(void) 350 { 351 hp_sdc_transaction *curr; 352 uint8_t act; 353 int idx, curridx; 354 355 int limit = 0; 356 357 write_lock(&hp_sdc.lock); 358 359 /* If i8042 buffers are full, we cannot do anything that 360 requires output, so we skip to the administrativa. */ 361 if (hp_sdc.ibf) { 362 hp_sdc_status_in8(); 363 if (hp_sdc.ibf) 364 goto finish; 365 } 366 367 anew: 368 /* See if we are in the middle of a sequence. */ 369 if (hp_sdc.wcurr < 0) 370 hp_sdc.wcurr = 0; 371 read_lock_irq(&hp_sdc.rtq_lock); 372 if (hp_sdc.rcurr == hp_sdc.wcurr) 373 hp_sdc.wcurr++; 374 read_unlock_irq(&hp_sdc.rtq_lock); 375 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) 376 hp_sdc.wcurr = 0; 377 curridx = hp_sdc.wcurr; 378 379 if (hp_sdc.tq[curridx] != NULL) 380 goto start; 381 382 while (++curridx != hp_sdc.wcurr) { 383 if (curridx >= HP_SDC_QUEUE_LEN) { 384 curridx = -1; /* Wrap to top */ 385 continue; 386 } 387 read_lock_irq(&hp_sdc.rtq_lock); 388 if (hp_sdc.rcurr == curridx) { 389 read_unlock_irq(&hp_sdc.rtq_lock); 390 continue; 391 } 392 read_unlock_irq(&hp_sdc.rtq_lock); 393 if (hp_sdc.tq[curridx] != NULL) 394 break; /* Found one. */ 395 } 396 if (curridx == hp_sdc.wcurr) { /* There's nothing queued to do. */ 397 curridx = -1; 398 } 399 hp_sdc.wcurr = curridx; 400 401 start: 402 403 /* Check to see if the interrupt mask needs to be set. */ 404 if (hp_sdc.set_im) { 405 hp_sdc_status_out8(hp_sdc.im | HP_SDC_CMD_SET_IM); 406 hp_sdc.set_im = 0; 407 goto finish; 408 } 409 410 if (hp_sdc.wcurr == -1) 411 goto done; 412 413 curr = hp_sdc.tq[curridx]; 414 idx = curr->actidx; 415 416 if (curr->actidx >= curr->endidx) { 417 hp_sdc.tq[curridx] = NULL; 418 /* Interleave outbound data between the transactions. */ 419 hp_sdc.wcurr++; 420 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) 421 hp_sdc.wcurr = 0; 422 goto finish; 423 } 424 425 act = curr->seq[idx]; 426 idx++; 427 428 if (curr->idx >= curr->endidx) { 429 if (act & HP_SDC_ACT_DEALLOC) 430 kfree(curr); 431 hp_sdc.tq[curridx] = NULL; 432 /* Interleave outbound data between the transactions. */ 433 hp_sdc.wcurr++; 434 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) 435 hp_sdc.wcurr = 0; 436 goto finish; 437 } 438 439 while (act & HP_SDC_ACT_PRECMD) { 440 if (curr->idx != idx) { 441 idx++; 442 act &= ~HP_SDC_ACT_PRECMD; 443 break; 444 } 445 hp_sdc_status_out8(curr->seq[idx]); 446 curr->idx++; 447 /* act finished? */ 448 if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_PRECMD) 449 goto actdone; 450 /* skip quantity field if data-out sequence follows. */ 451 if (act & HP_SDC_ACT_DATAOUT) 452 curr->idx++; 453 goto finish; 454 } 455 if (act & HP_SDC_ACT_DATAOUT) { 456 int qty; 457 458 qty = curr->seq[idx]; 459 idx++; 460 if (curr->idx - idx < qty) { 461 hp_sdc_data_out8(curr->seq[curr->idx]); 462 curr->idx++; 463 /* act finished? */ 464 if (curr->idx - idx >= qty && 465 (act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAOUT) 466 goto actdone; 467 goto finish; 468 } 469 idx += qty; 470 act &= ~HP_SDC_ACT_DATAOUT; 471 } else 472 while (act & HP_SDC_ACT_DATAREG) { 473 int mask; 474 uint8_t w7[4]; 475 476 mask = curr->seq[idx]; 477 if (idx != curr->idx) { 478 idx++; 479 idx += !!(mask & 1); 480 idx += !!(mask & 2); 481 idx += !!(mask & 4); 482 idx += !!(mask & 8); 483 act &= ~HP_SDC_ACT_DATAREG; 484 break; 485 } 486 487 w7[0] = (mask & 1) ? curr->seq[++idx] : hp_sdc.r7[0]; 488 w7[1] = (mask & 2) ? curr->seq[++idx] : hp_sdc.r7[1]; 489 w7[2] = (mask & 4) ? curr->seq[++idx] : hp_sdc.r7[2]; 490 w7[3] = (mask & 8) ? curr->seq[++idx] : hp_sdc.r7[3]; 491 492 if (hp_sdc.wi > 0x73 || hp_sdc.wi < 0x70 || 493 w7[hp_sdc.wi - 0x70] == hp_sdc.r7[hp_sdc.wi - 0x70]) { 494 int i = 0; 495 496 /* Need to point the write index register */ 497 while (i < 4 && w7[i] == hp_sdc.r7[i]) 498 i++; 499 500 if (i < 4) { 501 hp_sdc_status_out8(HP_SDC_CMD_SET_D0 + i); 502 hp_sdc.wi = 0x70 + i; 503 goto finish; 504 } 505 506 idx++; 507 if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAREG) 508 goto actdone; 509 510 curr->idx = idx; 511 act &= ~HP_SDC_ACT_DATAREG; 512 break; 513 } 514 515 hp_sdc_data_out8(w7[hp_sdc.wi - 0x70]); 516 hp_sdc.r7[hp_sdc.wi - 0x70] = w7[hp_sdc.wi - 0x70]; 517 hp_sdc.wi++; /* write index register autoincrements */ 518 { 519 int i = 0; 520 521 while ((i < 4) && w7[i] == hp_sdc.r7[i]) 522 i++; 523 if (i >= 4) { 524 curr->idx = idx + 1; 525 if ((act & HP_SDC_ACT_DURING) == 526 HP_SDC_ACT_DATAREG) 527 goto actdone; 528 } 529 } 530 goto finish; 531 } 532 /* We don't go any further in the command if there is a pending read, 533 because we don't want interleaved results. */ 534 read_lock_irq(&hp_sdc.rtq_lock); 535 if (hp_sdc.rcurr >= 0) { 536 read_unlock_irq(&hp_sdc.rtq_lock); 537 goto finish; 538 } 539 read_unlock_irq(&hp_sdc.rtq_lock); 540 541 542 if (act & HP_SDC_ACT_POSTCMD) { 543 uint8_t postcmd; 544 545 /* curr->idx should == idx at this point. */ 546 postcmd = curr->seq[idx]; 547 curr->idx++; 548 if (act & HP_SDC_ACT_DATAIN) { 549 550 /* Start a new read */ 551 hp_sdc.rqty = curr->seq[curr->idx]; 552 hp_sdc.rtime = ktime_get(); 553 curr->idx++; 554 /* Still need to lock here in case of spurious irq. */ 555 write_lock_irq(&hp_sdc.rtq_lock); 556 hp_sdc.rcurr = curridx; 557 write_unlock_irq(&hp_sdc.rtq_lock); 558 hp_sdc_status_out8(postcmd); 559 goto finish; 560 } 561 hp_sdc_status_out8(postcmd); 562 goto actdone; 563 } 564 565 actdone: 566 if (act & HP_SDC_ACT_SEMAPHORE) 567 up(curr->act.semaphore); 568 else if (act & HP_SDC_ACT_CALLBACK) 569 curr->act.irqhook(0,NULL,0,0); 570 571 if (curr->idx >= curr->endidx) { /* This transaction is over. */ 572 if (act & HP_SDC_ACT_DEALLOC) 573 kfree(curr); 574 hp_sdc.tq[curridx] = NULL; 575 } else { 576 curr->actidx = idx + 1; 577 curr->idx = idx + 2; 578 } 579 /* Interleave outbound data between the transactions. */ 580 hp_sdc.wcurr++; 581 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) 582 hp_sdc.wcurr = 0; 583 584 finish: 585 /* If by some quirk IBF has cleared and our ISR has run to 586 see that that has happened, do it all again. */ 587 if (!hp_sdc.ibf && limit++ < 20) 588 goto anew; 589 590 done: 591 if (hp_sdc.wcurr >= 0) 592 tasklet_schedule(&hp_sdc.task); 593 write_unlock(&hp_sdc.lock); 594 595 return 0; 596 } 597 598 /******* Functions called in either user or kernel context ****/ 599 int __hp_sdc_enqueue_transaction(hp_sdc_transaction *this) 600 { 601 int i; 602 603 if (this == NULL) { 604 BUG(); 605 return -EINVAL; 606 } 607 608 /* Can't have same transaction on queue twice */ 609 for (i = 0; i < HP_SDC_QUEUE_LEN; i++) 610 if (hp_sdc.tq[i] == this) 611 goto fail; 612 613 this->actidx = 0; 614 this->idx = 1; 615 616 /* Search for empty slot */ 617 for (i = 0; i < HP_SDC_QUEUE_LEN; i++) 618 if (hp_sdc.tq[i] == NULL) { 619 hp_sdc.tq[i] = this; 620 tasklet_schedule(&hp_sdc.task); 621 return 0; 622 } 623 624 printk(KERN_WARNING PREFIX "No free slot to add transaction.\n"); 625 return -EBUSY; 626 627 fail: 628 printk(KERN_WARNING PREFIX "Transaction add failed: transaction already queued?\n"); 629 return -EINVAL; 630 } 631 632 int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) { 633 unsigned long flags; 634 int ret; 635 636 write_lock_irqsave(&hp_sdc.lock, flags); 637 ret = __hp_sdc_enqueue_transaction(this); 638 write_unlock_irqrestore(&hp_sdc.lock,flags); 639 640 return ret; 641 } 642 643 int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) 644 { 645 unsigned long flags; 646 int i; 647 648 write_lock_irqsave(&hp_sdc.lock, flags); 649 650 /* TODO: don't remove it if it's not done. */ 651 652 for (i = 0; i < HP_SDC_QUEUE_LEN; i++) 653 if (hp_sdc.tq[i] == this) 654 hp_sdc.tq[i] = NULL; 655 656 write_unlock_irqrestore(&hp_sdc.lock, flags); 657 return 0; 658 } 659 660 661 662 /********************** User context functions **************************/ 663 int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback) 664 { 665 if (callback == NULL || hp_sdc.dev == NULL) 666 return -EINVAL; 667 668 write_lock_irq(&hp_sdc.hook_lock); 669 if (hp_sdc.timer != NULL) { 670 write_unlock_irq(&hp_sdc.hook_lock); 671 return -EBUSY; 672 } 673 674 hp_sdc.timer = callback; 675 /* Enable interrupts from the timers */ 676 hp_sdc.im &= ~HP_SDC_IM_FH; 677 hp_sdc.im &= ~HP_SDC_IM_PT; 678 hp_sdc.im &= ~HP_SDC_IM_TIMERS; 679 hp_sdc.set_im = 1; 680 write_unlock_irq(&hp_sdc.hook_lock); 681 682 tasklet_schedule(&hp_sdc.task); 683 684 return 0; 685 } 686 687 int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback) 688 { 689 if (callback == NULL || hp_sdc.dev == NULL) 690 return -EINVAL; 691 692 write_lock_irq(&hp_sdc.hook_lock); 693 if (hp_sdc.hil != NULL) { 694 write_unlock_irq(&hp_sdc.hook_lock); 695 return -EBUSY; 696 } 697 698 hp_sdc.hil = callback; 699 hp_sdc.im &= ~(HP_SDC_IM_HIL | HP_SDC_IM_RESET); 700 hp_sdc.set_im = 1; 701 write_unlock_irq(&hp_sdc.hook_lock); 702 703 tasklet_schedule(&hp_sdc.task); 704 705 return 0; 706 } 707 708 int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback) 709 { 710 if (callback == NULL || hp_sdc.dev == NULL) 711 return -EINVAL; 712 713 write_lock_irq(&hp_sdc.hook_lock); 714 if (hp_sdc.cooked != NULL) { 715 write_unlock_irq(&hp_sdc.hook_lock); 716 return -EBUSY; 717 } 718 719 /* Enable interrupts from the HIL MLC */ 720 hp_sdc.cooked = callback; 721 hp_sdc.im &= ~(HP_SDC_IM_HIL | HP_SDC_IM_RESET); 722 hp_sdc.set_im = 1; 723 write_unlock_irq(&hp_sdc.hook_lock); 724 725 tasklet_schedule(&hp_sdc.task); 726 727 return 0; 728 } 729 730 int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback) 731 { 732 write_lock_irq(&hp_sdc.hook_lock); 733 if ((callback != hp_sdc.timer) || 734 (hp_sdc.timer == NULL)) { 735 write_unlock_irq(&hp_sdc.hook_lock); 736 return -EINVAL; 737 } 738 739 /* Disable interrupts from the timers */ 740 hp_sdc.timer = NULL; 741 hp_sdc.im |= HP_SDC_IM_TIMERS; 742 hp_sdc.im |= HP_SDC_IM_FH; 743 hp_sdc.im |= HP_SDC_IM_PT; 744 hp_sdc.set_im = 1; 745 write_unlock_irq(&hp_sdc.hook_lock); 746 tasklet_schedule(&hp_sdc.task); 747 748 return 0; 749 } 750 751 int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback) 752 { 753 write_lock_irq(&hp_sdc.hook_lock); 754 if ((callback != hp_sdc.hil) || 755 (hp_sdc.hil == NULL)) { 756 write_unlock_irq(&hp_sdc.hook_lock); 757 return -EINVAL; 758 } 759 760 hp_sdc.hil = NULL; 761 /* Disable interrupts from HIL only if there is no cooked driver. */ 762 if(hp_sdc.cooked == NULL) { 763 hp_sdc.im |= (HP_SDC_IM_HIL | HP_SDC_IM_RESET); 764 hp_sdc.set_im = 1; 765 } 766 write_unlock_irq(&hp_sdc.hook_lock); 767 tasklet_schedule(&hp_sdc.task); 768 769 return 0; 770 } 771 772 int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) 773 { 774 write_lock_irq(&hp_sdc.hook_lock); 775 if ((callback != hp_sdc.cooked) || 776 (hp_sdc.cooked == NULL)) { 777 write_unlock_irq(&hp_sdc.hook_lock); 778 return -EINVAL; 779 } 780 781 hp_sdc.cooked = NULL; 782 /* Disable interrupts from HIL only if there is no raw HIL driver. */ 783 if(hp_sdc.hil == NULL) { 784 hp_sdc.im |= (HP_SDC_IM_HIL | HP_SDC_IM_RESET); 785 hp_sdc.set_im = 1; 786 } 787 write_unlock_irq(&hp_sdc.hook_lock); 788 tasklet_schedule(&hp_sdc.task); 789 790 return 0; 791 } 792 793 /************************* Keepalive timer task *********************/ 794 795 static void hp_sdc_kicker(struct timer_list *unused) 796 { 797 tasklet_schedule(&hp_sdc.task); 798 /* Re-insert the periodic task. */ 799 mod_timer(&hp_sdc.kicker, jiffies + HZ); 800 } 801 802 /************************** Module Initialization ***************************/ 803 804 #if defined(__hppa__) 805 806 static const struct parisc_device_id hp_sdc_tbl[] __initconst = { 807 { 808 .hw_type = HPHW_FIO, 809 .hversion_rev = HVERSION_REV_ANY_ID, 810 .hversion = HVERSION_ANY_ID, 811 .sversion = 0x73, 812 }, 813 { 0, } 814 }; 815 816 MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl); 817 818 static int __init hp_sdc_init_hppa(struct parisc_device *d); 819 static struct delayed_work moduleloader_work; 820 821 static struct parisc_driver hp_sdc_driver __refdata = { 822 .name = "hp_sdc", 823 .id_table = hp_sdc_tbl, 824 .probe = hp_sdc_init_hppa, 825 }; 826 827 #endif /* __hppa__ */ 828 829 static int __init hp_sdc_init(void) 830 { 831 char *errstr; 832 hp_sdc_transaction t_sync; 833 uint8_t ts_sync[6]; 834 struct semaphore s_sync; 835 836 rwlock_init(&hp_sdc.lock); 837 rwlock_init(&hp_sdc.ibf_lock); 838 rwlock_init(&hp_sdc.rtq_lock); 839 rwlock_init(&hp_sdc.hook_lock); 840 841 hp_sdc.timer = NULL; 842 hp_sdc.hil = NULL; 843 hp_sdc.pup = NULL; 844 hp_sdc.cooked = NULL; 845 hp_sdc.im = HP_SDC_IM_MASK; /* Mask maskable irqs */ 846 hp_sdc.set_im = 1; 847 hp_sdc.wi = 0xff; 848 hp_sdc.r7[0] = 0xff; 849 hp_sdc.r7[1] = 0xff; 850 hp_sdc.r7[2] = 0xff; 851 hp_sdc.r7[3] = 0xff; 852 hp_sdc.ibf = 1; 853 854 memset(&hp_sdc.tq, 0, sizeof(hp_sdc.tq)); 855 856 hp_sdc.wcurr = -1; 857 hp_sdc.rcurr = -1; 858 hp_sdc.rqty = 0; 859 860 hp_sdc.dev_err = -ENODEV; 861 862 errstr = "IO not found for"; 863 if (!hp_sdc.base_io) 864 goto err0; 865 866 errstr = "IRQ not found for"; 867 if (!hp_sdc.irq) 868 goto err0; 869 870 hp_sdc.dev_err = -EBUSY; 871 872 #if defined(__hppa__) 873 errstr = "IO not available for"; 874 if (request_region(hp_sdc.data_io, 2, hp_sdc_driver.name)) 875 goto err0; 876 #endif 877 878 errstr = "IRQ not available for"; 879 if (request_irq(hp_sdc.irq, &hp_sdc_isr, IRQF_SHARED, 880 "HP SDC", &hp_sdc)) 881 goto err1; 882 883 errstr = "NMI not available for"; 884 if (request_irq(hp_sdc.nmi, &hp_sdc_nmisr, IRQF_SHARED, 885 "HP SDC NMI", &hp_sdc)) 886 goto err2; 887 888 pr_info(PREFIX "HP SDC at 0x%08lx, IRQ %d (NMI IRQ %d)\n", 889 hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi); 890 891 hp_sdc_status_in8(); 892 hp_sdc_data_in8(); 893 894 tasklet_init(&hp_sdc.task, hp_sdc_tasklet, 0); 895 896 /* Sync the output buffer registers, thus scheduling hp_sdc_tasklet. */ 897 t_sync.actidx = 0; 898 t_sync.idx = 1; 899 t_sync.endidx = 6; 900 t_sync.seq = ts_sync; 901 ts_sync[0] = HP_SDC_ACT_DATAREG | HP_SDC_ACT_SEMAPHORE; 902 ts_sync[1] = 0x0f; 903 ts_sync[2] = ts_sync[3] = ts_sync[4] = ts_sync[5] = 0; 904 t_sync.act.semaphore = &s_sync; 905 sema_init(&s_sync, 0); 906 hp_sdc_enqueue_transaction(&t_sync); 907 down(&s_sync); /* Wait for t_sync to complete */ 908 909 /* Create the keepalive task */ 910 timer_setup(&hp_sdc.kicker, hp_sdc_kicker, 0); 911 hp_sdc.kicker.expires = jiffies + HZ; 912 add_timer(&hp_sdc.kicker); 913 914 hp_sdc.dev_err = 0; 915 return 0; 916 err2: 917 free_irq(hp_sdc.irq, &hp_sdc); 918 err1: 919 release_region(hp_sdc.data_io, 2); 920 err0: 921 printk(KERN_WARNING PREFIX ": %s SDC IO=0x%p IRQ=0x%x NMI=0x%x\n", 922 errstr, (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi); 923 hp_sdc.dev = NULL; 924 925 return hp_sdc.dev_err; 926 } 927 928 #if defined(__hppa__) 929 930 static void request_module_delayed(struct work_struct *work) 931 { 932 request_module("hp_sdc_mlc"); 933 } 934 935 static int __init hp_sdc_init_hppa(struct parisc_device *d) 936 { 937 int ret; 938 939 if (!d) 940 return 1; 941 if (hp_sdc.dev != NULL) 942 return 1; /* We only expect one SDC */ 943 944 hp_sdc.dev = d; 945 hp_sdc.irq = d->irq; 946 hp_sdc.nmi = d->aux_irq; 947 hp_sdc.base_io = d->hpa.start; 948 hp_sdc.data_io = d->hpa.start + 0x800; 949 hp_sdc.status_io = d->hpa.start + 0x801; 950 951 INIT_DELAYED_WORK(&moduleloader_work, request_module_delayed); 952 953 ret = hp_sdc_init(); 954 /* after successful initialization give SDC some time to settle 955 * and then load the hp_sdc_mlc upper layer driver */ 956 if (!ret) 957 schedule_delayed_work(&moduleloader_work, 958 msecs_to_jiffies(2000)); 959 960 return ret; 961 } 962 963 #endif /* __hppa__ */ 964 965 static void hp_sdc_exit(void) 966 { 967 /* do nothing if we don't have a SDC */ 968 if (!hp_sdc.dev) 969 return; 970 971 write_lock_irq(&hp_sdc.lock); 972 973 /* Turn off all maskable "sub-function" irq's. */ 974 hp_sdc_spin_ibf(); 975 sdc_writeb(HP_SDC_CMD_SET_IM | HP_SDC_IM_MASK, hp_sdc.status_io); 976 977 /* Wait until we know this has been processed by the i8042 */ 978 hp_sdc_spin_ibf(); 979 980 free_irq(hp_sdc.nmi, &hp_sdc); 981 free_irq(hp_sdc.irq, &hp_sdc); 982 write_unlock_irq(&hp_sdc.lock); 983 984 timer_delete_sync(&hp_sdc.kicker); 985 986 tasklet_kill(&hp_sdc.task); 987 988 #if defined(__hppa__) 989 cancel_delayed_work_sync(&moduleloader_work); 990 if (unregister_parisc_driver(&hp_sdc_driver)) 991 printk(KERN_WARNING PREFIX "Error unregistering HP SDC"); 992 #endif 993 } 994 995 static int __init hp_sdc_register(void) 996 { 997 hp_sdc_transaction tq_init; 998 uint8_t tq_init_seq[5]; 999 struct semaphore tq_init_sem; 1000 #if defined(__mc68000__) 1001 unsigned char i; 1002 #endif 1003 1004 if (hp_sdc_disabled) { 1005 printk(KERN_WARNING PREFIX "HP SDC driver disabled by no_hpsdc=1.\n"); 1006 return -ENODEV; 1007 } 1008 1009 hp_sdc.dev = NULL; 1010 hp_sdc.dev_err = 0; 1011 #if defined(__hppa__) 1012 if (register_parisc_driver(&hp_sdc_driver)) { 1013 printk(KERN_WARNING PREFIX "Error registering SDC with system bus tree.\n"); 1014 return -ENODEV; 1015 } 1016 #elif defined(__mc68000__) 1017 if (!MACH_IS_HP300) 1018 return -ENODEV; 1019 1020 hp_sdc.irq = 1; 1021 hp_sdc.nmi = 7; 1022 hp_sdc.base_io = (unsigned long) 0xf0428000; 1023 hp_sdc.data_io = (unsigned long) hp_sdc.base_io + 1; 1024 hp_sdc.status_io = (unsigned long) hp_sdc.base_io + 3; 1025 if (!copy_from_kernel_nofault(&i, (unsigned char *)hp_sdc.data_io, 1)) 1026 hp_sdc.dev = (void *)1; 1027 hp_sdc.dev_err = hp_sdc_init(); 1028 #endif 1029 if (hp_sdc.dev == NULL) { 1030 printk(KERN_WARNING PREFIX "No SDC found.\n"); 1031 return hp_sdc.dev_err; 1032 } 1033 1034 sema_init(&tq_init_sem, 0); 1035 1036 tq_init.actidx = 0; 1037 tq_init.idx = 1; 1038 tq_init.endidx = 5; 1039 tq_init.seq = tq_init_seq; 1040 tq_init.act.semaphore = &tq_init_sem; 1041 1042 tq_init_seq[0] = 1043 HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE; 1044 tq_init_seq[1] = HP_SDC_CMD_READ_KCC; 1045 tq_init_seq[2] = 1; 1046 tq_init_seq[3] = 0; 1047 tq_init_seq[4] = 0; 1048 1049 hp_sdc_enqueue_transaction(&tq_init); 1050 1051 down(&tq_init_sem); 1052 up(&tq_init_sem); 1053 1054 if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) { 1055 printk(KERN_WARNING PREFIX "Error reading config byte.\n"); 1056 hp_sdc_exit(); 1057 return -ENODEV; 1058 } 1059 hp_sdc.r11 = tq_init_seq[4]; 1060 if (hp_sdc.r11 & HP_SDC_CFG_NEW) { 1061 const char *str; 1062 printk(KERN_INFO PREFIX "New style SDC\n"); 1063 tq_init_seq[1] = HP_SDC_CMD_READ_XTD; 1064 tq_init.actidx = 0; 1065 tq_init.idx = 1; 1066 down(&tq_init_sem); 1067 hp_sdc_enqueue_transaction(&tq_init); 1068 down(&tq_init_sem); 1069 up(&tq_init_sem); 1070 if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) { 1071 printk(KERN_WARNING PREFIX "Error reading extended config byte.\n"); 1072 return -ENODEV; 1073 } 1074 hp_sdc.r7e = tq_init_seq[4]; 1075 HP_SDC_XTD_REV_STRINGS(hp_sdc.r7e & HP_SDC_XTD_REV, str) 1076 printk(KERN_INFO PREFIX "Revision: %s\n", str); 1077 if (hp_sdc.r7e & HP_SDC_XTD_BEEPER) 1078 printk(KERN_INFO PREFIX "TI SN76494 beeper present\n"); 1079 if (hp_sdc.r7e & HP_SDC_XTD_BBRTC) 1080 printk(KERN_INFO PREFIX "OKI MSM-58321 BBRTC present\n"); 1081 printk(KERN_INFO PREFIX "Spunking the self test register to force PUP " 1082 "on next firmware reset.\n"); 1083 tq_init_seq[0] = HP_SDC_ACT_PRECMD | 1084 HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE; 1085 tq_init_seq[1] = HP_SDC_CMD_SET_STR; 1086 tq_init_seq[2] = 1; 1087 tq_init_seq[3] = 0; 1088 tq_init.actidx = 0; 1089 tq_init.idx = 1; 1090 tq_init.endidx = 4; 1091 down(&tq_init_sem); 1092 hp_sdc_enqueue_transaction(&tq_init); 1093 down(&tq_init_sem); 1094 up(&tq_init_sem); 1095 } else 1096 printk(KERN_INFO PREFIX "Old style SDC (1820-%s).\n", 1097 (hp_sdc.r11 & HP_SDC_CFG_REV) ? "3300" : "2564/3087"); 1098 1099 return 0; 1100 } 1101 1102 module_init(hp_sdc_register); 1103 module_exit(hp_sdc_exit); 1104 1105 /* Timing notes: These measurements taken on my 64MHz 7100-LC (715/64) 1106 * cycles cycles-adj time 1107 * between two consecutive mfctl(16)'s: 4 n/a 63ns 1108 * hp_sdc_spin_ibf when idle: 119 115 1.7us 1109 * gsc_writeb status register: 83 79 1.2us 1110 * IBF to clear after sending SET_IM: 6204 6006 93us 1111 * IBF to clear after sending LOAD_RT: 4467 4352 68us 1112 * IBF to clear after sending two LOAD_RTs: 18974 18859 295us 1113 * READ_T1, read status/data, IRQ, call handler: 35564 n/a 556us 1114 * cmd to ~IBF READ_T1 2nd time right after: 5158403 n/a 81ms 1115 * between IRQ received and ~IBF for above: 2578877 n/a 40ms 1116 * 1117 * Performance stats after a run of this module configuring HIL and 1118 * receiving a few mouse events: 1119 * 1120 * status in8 282508 cycles 7128 calls 1121 * status out8 8404 cycles 341 calls 1122 * data out8 1734 cycles 78 calls 1123 * isr 174324 cycles 617 calls (includes take) 1124 * take 1241 cycles 2 calls 1125 * put 1411504 cycles 6937 calls 1126 * task 1655209 cycles 6937 calls (includes put) 1127 * 1128 */ 1129