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