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