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