2  * HP i8042-based System Device Controller driver.
 
   4  * Copyright (c) 2001 Brian S. Julin
 
   7  * Redistribution and use in source and binary forms, with or without
 
   8  * modification, are permitted provided that the following conditions
 
  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.
 
  16  * Alternatively, this software may be distributed under the terms of the
 
  17  * GNU General Public License ("GPL").
 
  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
 
  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.
 
  35  * Driver theory of operation:
 
  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.
 
  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.
 
  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.
 
  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.
 
  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.
 
  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/slab.h>
 
  71 #include <linux/hil.h>
 
  73 #include <asm/system.h>
 
  75 /* Machine-specific abstraction */
 
  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 <asm/uaccess.h>
 
  83 # define sdc_readb(p)           in_8(p)
 
  84 # define sdc_writeb(v,p)        out_8((p),(v))
 
  86 # error "HIL is not supported on this platform"
 
  89 #define PREFIX "HP SDC: "
 
  91 MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
 
  92 MODULE_DESCRIPTION("HP i8042-based SDC Driver");
 
  93 MODULE_LICENSE("Dual BSD/GPL");
 
  95 EXPORT_SYMBOL(hp_sdc_request_timer_irq);
 
  96 EXPORT_SYMBOL(hp_sdc_request_hil_irq);
 
  97 EXPORT_SYMBOL(hp_sdc_request_cooked_irq);
 
  99 EXPORT_SYMBOL(hp_sdc_release_timer_irq);
 
 100 EXPORT_SYMBOL(hp_sdc_release_hil_irq);
 
 101 EXPORT_SYMBOL(hp_sdc_release_cooked_irq);
 
 103 EXPORT_SYMBOL(__hp_sdc_enqueue_transaction);
 
 104 EXPORT_SYMBOL(hp_sdc_enqueue_transaction);
 
 105 EXPORT_SYMBOL(hp_sdc_dequeue_transaction);
 
 107 static hp_i8042_sdc     hp_sdc; /* All driver state is kept in here. */
 
 109 /*************** primitives for use in any context *********************/
 
 110 static inline uint8_t hp_sdc_status_in8(void)
 
 115         write_lock_irqsave(&hp_sdc.ibf_lock, flags);
 
 116         status = sdc_readb(hp_sdc.status_io);
 
 117         if (!(status & HP_SDC_STATUS_IBF))
 
 119         write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);
 
 124 static inline uint8_t hp_sdc_data_in8(void)
 
 126         return sdc_readb(hp_sdc.data_io);
 
 129 static inline void hp_sdc_status_out8(uint8_t val)
 
 133         write_lock_irqsave(&hp_sdc.ibf_lock, flags);
 
 135         if ((val & 0xf0) == 0xe0)
 
 137         sdc_writeb(val, hp_sdc.status_io);
 
 138         write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);
 
 141 static inline void hp_sdc_data_out8(uint8_t val)
 
 145         write_lock_irqsave(&hp_sdc.ibf_lock, flags);
 
 147         sdc_writeb(val, hp_sdc.data_io);
 
 148         write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);
 
 151 /*      Care must be taken to only invoke hp_sdc_spin_ibf when
 
 152  *      absolutely needed, or in rarely invoked subroutines.
 
 153  *      Not only does it waste CPU cycles, it also wastes bus cycles.
 
 155 static inline void hp_sdc_spin_ibf(void)
 
 160         lock = &hp_sdc.ibf_lock;
 
 162         read_lock_irqsave(lock, flags);
 
 164                 read_unlock_irqrestore(lock, flags);
 
 169         while (sdc_readb(hp_sdc.status_io) & HP_SDC_STATUS_IBF)
 
 172         write_unlock_irqrestore(lock, flags);
 
 176 /************************ Interrupt context functions ************************/
 
 177 static void hp_sdc_take(int irq, void *dev_id, uint8_t status, uint8_t data)
 
 179         hp_sdc_transaction *curr;
 
 181         read_lock(&hp_sdc.rtq_lock);
 
 182         if (hp_sdc.rcurr < 0) {
 
 183                 read_unlock(&hp_sdc.rtq_lock);
 
 186         curr = hp_sdc.tq[hp_sdc.rcurr];
 
 187         read_unlock(&hp_sdc.rtq_lock);
 
 189         curr->seq[curr->idx++] = status;
 
 190         curr->seq[curr->idx++] = data;
 
 192         do_gettimeofday(&hp_sdc.rtv);
 
 194         if (hp_sdc.rqty <= 0) {
 
 195                 /* All data has been gathered. */
 
 196                 if (curr->seq[curr->actidx] & HP_SDC_ACT_SEMAPHORE)
 
 197                         if (curr->act.semaphore)
 
 198                                 up(curr->act.semaphore);
 
 200                 if (curr->seq[curr->actidx] & HP_SDC_ACT_CALLBACK)
 
 201                         if (curr->act.irqhook)
 
 202                                 curr->act.irqhook(irq, dev_id, status, data);
 
 204                 curr->actidx = curr->idx;
 
 206                 /* Return control of this transaction */
 
 207                 write_lock(&hp_sdc.rtq_lock);
 
 210                 write_unlock(&hp_sdc.rtq_lock);
 
 211                 tasklet_schedule(&hp_sdc.task);
 
 215 static irqreturn_t hp_sdc_isr(int irq, void *dev_id)
 
 217         uint8_t status, data;
 
 219         status = hp_sdc_status_in8();
 
 220         /* Read data unconditionally to advance i8042. */
 
 221         data =   hp_sdc_data_in8();
 
 223         /* For now we are ignoring these until we get the SDC to behave. */
 
 224         if (((status & 0xf1) == 0x51) && data == 0x82)
 
 227         switch (status & HP_SDC_STATUS_IRQMASK) {
 
 228         case 0: /* This case is not documented. */
 
 231         case HP_SDC_STATUS_USERTIMER:
 
 232         case HP_SDC_STATUS_PERIODIC:
 
 233         case HP_SDC_STATUS_TIMER:
 
 234                 read_lock(&hp_sdc.hook_lock);
 
 235                 if (hp_sdc.timer != NULL)
 
 236                         hp_sdc.timer(irq, dev_id, status, data);
 
 237                 read_unlock(&hp_sdc.hook_lock);
 
 240         case HP_SDC_STATUS_REG:
 
 241                 hp_sdc_take(irq, dev_id, status, data);
 
 244         case HP_SDC_STATUS_HILCMD:
 
 245         case HP_SDC_STATUS_HILDATA:
 
 246                 read_lock(&hp_sdc.hook_lock);
 
 247                 if (hp_sdc.hil != NULL)
 
 248                         hp_sdc.hil(irq, dev_id, status, data);
 
 249                 read_unlock(&hp_sdc.hook_lock);
 
 252         case HP_SDC_STATUS_PUP:
 
 253                 read_lock(&hp_sdc.hook_lock);
 
 254                 if (hp_sdc.pup != NULL)
 
 255                         hp_sdc.pup(irq, dev_id, status, data);
 
 257                         printk(KERN_INFO PREFIX "HP SDC reports successful PUP.\n");
 
 258                 read_unlock(&hp_sdc.hook_lock);
 
 262                 read_lock(&hp_sdc.hook_lock);
 
 263                 if (hp_sdc.cooked != NULL)
 
 264                         hp_sdc.cooked(irq, dev_id, status, data);
 
 265                 read_unlock(&hp_sdc.hook_lock);
 
 273 static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id)
 
 277         status = hp_sdc_status_in8();
 
 278         printk(KERN_WARNING PREFIX "NMI !\n");
 
 281         if (status & HP_SDC_NMISTATUS_FHS) {
 
 282                 read_lock(&hp_sdc.hook_lock);
 
 283                 if (hp_sdc.timer != NULL)
 
 284                         hp_sdc.timer(irq, dev_id, status, 0);
 
 285                 read_unlock(&hp_sdc.hook_lock);
 
 287                 /* TODO: pass this on to the HIL handler, or do SAK here? */
 
 288                 printk(KERN_WARNING PREFIX "HIL NMI\n");
 
 296 /***************** Kernel (tasklet) context functions ****************/
 
 298 unsigned long hp_sdc_put(void);
 
 300 static void hp_sdc_tasklet(unsigned long foo)
 
 302         write_lock_irq(&hp_sdc.rtq_lock);
 
 304         if (hp_sdc.rcurr >= 0) {
 
 307                 do_gettimeofday(&tv);
 
 308                 if (tv.tv_sec > hp_sdc.rtv.tv_sec)
 
 309                         tv.tv_usec += USEC_PER_SEC;
 
 311                 if (tv.tv_usec - hp_sdc.rtv.tv_usec > HP_SDC_MAX_REG_DELAY) {
 
 312                         hp_sdc_transaction *curr;
 
 315                         curr = hp_sdc.tq[hp_sdc.rcurr];
 
 316                         /* If this turns out to be a normal failure mode
 
 317                          * we'll need to figure out a way to communicate
 
 318                          * it back to the application. and be less verbose.
 
 320                         printk(KERN_WARNING PREFIX "read timeout (%ius)!\n",
 
 321                                tv.tv_usec - hp_sdc.rtv.tv_usec);
 
 322                         curr->idx += hp_sdc.rqty;
 
 324                         tmp = curr->seq[curr->actidx];
 
 325                         curr->seq[curr->actidx] |= HP_SDC_ACT_DEAD;
 
 326                         if (tmp & HP_SDC_ACT_SEMAPHORE)
 
 327                                 if (curr->act.semaphore)
 
 328                                         up(curr->act.semaphore);
 
 330                         if (tmp & HP_SDC_ACT_CALLBACK) {
 
 331                                 /* Note this means that irqhooks may be called
 
 332                                  * in tasklet/bh context.
 
 334                                 if (curr->act.irqhook)
 
 335                                         curr->act.irqhook(0, NULL, 0, 0);
 
 338                         curr->actidx = curr->idx;
 
 343         write_unlock_irq(&hp_sdc.rtq_lock);
 
 347 unsigned long hp_sdc_put(void)
 
 349         hp_sdc_transaction *curr;
 
 355         write_lock(&hp_sdc.lock);
 
 357         /* If i8042 buffers are full, we cannot do anything that
 
 358            requires output, so we skip to the administrativa. */
 
 366         /* See if we are in the middle of a sequence. */
 
 367         if (hp_sdc.wcurr < 0)
 
 369         read_lock_irq(&hp_sdc.rtq_lock);
 
 370         if (hp_sdc.rcurr == hp_sdc.wcurr)
 
 372         read_unlock_irq(&hp_sdc.rtq_lock);
 
 373         if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
 
 375         curridx = hp_sdc.wcurr;
 
 377         if (hp_sdc.tq[curridx] != NULL)
 
 380         while (++curridx != hp_sdc.wcurr) {
 
 381                 if (curridx >= HP_SDC_QUEUE_LEN) {
 
 382                         curridx = -1; /* Wrap to top */
 
 385                 read_lock_irq(&hp_sdc.rtq_lock);
 
 386                 if (hp_sdc.rcurr == curridx) {
 
 387                         read_unlock_irq(&hp_sdc.rtq_lock);
 
 390                 read_unlock_irq(&hp_sdc.rtq_lock);
 
 391                 if (hp_sdc.tq[curridx] != NULL)
 
 392                         break; /* Found one. */
 
 394         if (curridx == hp_sdc.wcurr) { /* There's nothing queued to do. */
 
 397         hp_sdc.wcurr = curridx;
 
 401         /* Check to see if the interrupt mask needs to be set. */
 
 403                 hp_sdc_status_out8(hp_sdc.im | HP_SDC_CMD_SET_IM);
 
 408         if (hp_sdc.wcurr == -1)
 
 411         curr = hp_sdc.tq[curridx];
 
 414         if (curr->actidx >= curr->endidx) {
 
 415                 hp_sdc.tq[curridx] = NULL;
 
 416                 /* Interleave outbound data between the transactions. */
 
 418                 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
 
 423         act = curr->seq[idx];
 
 426         if (curr->idx >= curr->endidx) {
 
 427                 if (act & HP_SDC_ACT_DEALLOC)
 
 429                 hp_sdc.tq[curridx] = NULL;
 
 430                 /* Interleave outbound data between the transactions. */
 
 432                 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
 
 437         while (act & HP_SDC_ACT_PRECMD) {
 
 438                 if (curr->idx != idx) {
 
 440                         act &= ~HP_SDC_ACT_PRECMD;
 
 443                 hp_sdc_status_out8(curr->seq[idx]);
 
 446                 if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_PRECMD)
 
 448                 /* skip quantity field if data-out sequence follows. */
 
 449                 if (act & HP_SDC_ACT_DATAOUT)
 
 453         if (act & HP_SDC_ACT_DATAOUT) {
 
 456                 qty = curr->seq[idx];
 
 458                 if (curr->idx - idx < qty) {
 
 459                         hp_sdc_data_out8(curr->seq[curr->idx]);
 
 462                         if (curr->idx - idx >= qty &&
 
 463                             (act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAOUT)
 
 468                 act &= ~HP_SDC_ACT_DATAOUT;
 
 470             while (act & HP_SDC_ACT_DATAREG) {
 
 474                 mask = curr->seq[idx];
 
 475                 if (idx != curr->idx) {
 
 481                         act &= ~HP_SDC_ACT_DATAREG;
 
 485                 w7[0] = (mask & 1) ? curr->seq[++idx] : hp_sdc.r7[0];
 
 486                 w7[1] = (mask & 2) ? curr->seq[++idx] : hp_sdc.r7[1];
 
 487                 w7[2] = (mask & 4) ? curr->seq[++idx] : hp_sdc.r7[2];
 
 488                 w7[3] = (mask & 8) ? curr->seq[++idx] : hp_sdc.r7[3];
 
 490                 if (hp_sdc.wi > 0x73 || hp_sdc.wi < 0x70 ||
 
 491                     w7[hp_sdc.wi - 0x70] == hp_sdc.r7[hp_sdc.wi - 0x70]) {
 
 494                         /* Need to point the write index register */
 
 495                         while (i < 4 && w7[i] == hp_sdc.r7[i])
 
 499                                 hp_sdc_status_out8(HP_SDC_CMD_SET_D0 + i);
 
 500                                 hp_sdc.wi = 0x70 + i;
 
 505                         if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAREG)
 
 509                         act &= ~HP_SDC_ACT_DATAREG;
 
 513                 hp_sdc_data_out8(w7[hp_sdc.wi - 0x70]);
 
 514                 hp_sdc.r7[hp_sdc.wi - 0x70] = w7[hp_sdc.wi - 0x70];
 
 515                 hp_sdc.wi++; /* write index register autoincrements */
 
 519                         while ((i < 4) && w7[i] == hp_sdc.r7[i])
 
 523                                 if ((act & HP_SDC_ACT_DURING) ==
 
 530         /* We don't go any further in the command if there is a pending read,
 
 531            because we don't want interleaved results. */
 
 532         read_lock_irq(&hp_sdc.rtq_lock);
 
 533         if (hp_sdc.rcurr >= 0) {
 
 534                 read_unlock_irq(&hp_sdc.rtq_lock);
 
 537         read_unlock_irq(&hp_sdc.rtq_lock);
 
 540         if (act & HP_SDC_ACT_POSTCMD) {
 
 543                 /* curr->idx should == idx at this point. */
 
 544                 postcmd = curr->seq[idx];
 
 546                 if (act & HP_SDC_ACT_DATAIN) {
 
 548                         /* Start a new read */
 
 549                         hp_sdc.rqty = curr->seq[curr->idx];
 
 550                         do_gettimeofday(&hp_sdc.rtv);
 
 552                         /* Still need to lock here in case of spurious irq. */
 
 553                         write_lock_irq(&hp_sdc.rtq_lock);
 
 554                         hp_sdc.rcurr = curridx;
 
 555                         write_unlock_irq(&hp_sdc.rtq_lock);
 
 556                         hp_sdc_status_out8(postcmd);
 
 559                 hp_sdc_status_out8(postcmd);
 
 564         if (act & HP_SDC_ACT_SEMAPHORE)
 
 565                 up(curr->act.semaphore);
 
 566         else if (act & HP_SDC_ACT_CALLBACK)
 
 567                 curr->act.irqhook(0,NULL,0,0);
 
 569         if (curr->idx >= curr->endidx) { /* This transaction is over. */
 
 570                 if (act & HP_SDC_ACT_DEALLOC)
 
 572                 hp_sdc.tq[curridx] = NULL;
 
 574                 curr->actidx = idx + 1;
 
 577         /* Interleave outbound data between the transactions. */
 
 579         if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
 
 583         /* If by some quirk IBF has cleared and our ISR has run to
 
 584            see that that has happened, do it all again. */
 
 585         if (!hp_sdc.ibf && limit++ < 20)
 
 589         if (hp_sdc.wcurr >= 0)
 
 590                 tasklet_schedule(&hp_sdc.task);
 
 591         write_unlock(&hp_sdc.lock);
 
 596 /******* Functions called in either user or kernel context ****/
 
 597 int __hp_sdc_enqueue_transaction(hp_sdc_transaction *this)
 
 606         /* Can't have same transaction on queue twice */
 
 607         for (i = 0; i < HP_SDC_QUEUE_LEN; i++)
 
 608                 if (hp_sdc.tq[i] == this)
 
 614         /* Search for empty slot */
 
 615         for (i = 0; i < HP_SDC_QUEUE_LEN; i++)
 
 616                 if (hp_sdc.tq[i] == NULL) {
 
 618                         tasklet_schedule(&hp_sdc.task);
 
 622         printk(KERN_WARNING PREFIX "No free slot to add transaction.\n");
 
 626         printk(KERN_WARNING PREFIX "Transaction add failed: transaction already queued?\n");
 
 630 int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) {
 
 634         write_lock_irqsave(&hp_sdc.lock, flags);
 
 635         ret = __hp_sdc_enqueue_transaction(this);
 
 636         write_unlock_irqrestore(&hp_sdc.lock,flags);
 
 641 int hp_sdc_dequeue_transaction(hp_sdc_transaction *this)
 
 646         write_lock_irqsave(&hp_sdc.lock, flags);
 
 648         /* TODO: don't remove it if it's not done. */
 
 650         for (i = 0; i < HP_SDC_QUEUE_LEN; i++)
 
 651                 if (hp_sdc.tq[i] == this)
 
 654         write_unlock_irqrestore(&hp_sdc.lock, flags);
 
 660 /********************** User context functions **************************/
 
 661 int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback)
 
 663         if (callback == NULL || hp_sdc.dev == NULL)
 
 666         write_lock_irq(&hp_sdc.hook_lock);
 
 667         if (hp_sdc.timer != NULL) {
 
 668                 write_unlock_irq(&hp_sdc.hook_lock);
 
 672         hp_sdc.timer = callback;
 
 673         /* Enable interrupts from the timers */
 
 674         hp_sdc.im &= ~HP_SDC_IM_FH;
 
 675         hp_sdc.im &= ~HP_SDC_IM_PT;
 
 676         hp_sdc.im &= ~HP_SDC_IM_TIMERS;
 
 678         write_unlock_irq(&hp_sdc.hook_lock);
 
 680         tasklet_schedule(&hp_sdc.task);
 
 685 int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback)
 
 687         if (callback == NULL || hp_sdc.dev == NULL)
 
 690         write_lock_irq(&hp_sdc.hook_lock);
 
 691         if (hp_sdc.hil != NULL) {
 
 692                 write_unlock_irq(&hp_sdc.hook_lock);
 
 696         hp_sdc.hil = callback;
 
 697         hp_sdc.im &= ~(HP_SDC_IM_HIL | HP_SDC_IM_RESET);
 
 699         write_unlock_irq(&hp_sdc.hook_lock);
 
 701         tasklet_schedule(&hp_sdc.task);
 
 706 int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback)
 
 708         if (callback == NULL || hp_sdc.dev == NULL)
 
 711         write_lock_irq(&hp_sdc.hook_lock);
 
 712         if (hp_sdc.cooked != NULL) {
 
 713                 write_unlock_irq(&hp_sdc.hook_lock);
 
 717         /* Enable interrupts from the HIL MLC */
 
 718         hp_sdc.cooked = callback;
 
 719         hp_sdc.im &= ~(HP_SDC_IM_HIL | HP_SDC_IM_RESET);
 
 721         write_unlock_irq(&hp_sdc.hook_lock);
 
 723         tasklet_schedule(&hp_sdc.task);
 
 728 int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback)
 
 730         write_lock_irq(&hp_sdc.hook_lock);
 
 731         if ((callback != hp_sdc.timer) ||
 
 732             (hp_sdc.timer == NULL)) {
 
 733                 write_unlock_irq(&hp_sdc.hook_lock);
 
 737         /* Disable interrupts from the timers */
 
 739         hp_sdc.im |= HP_SDC_IM_TIMERS;
 
 740         hp_sdc.im |= HP_SDC_IM_FH;
 
 741         hp_sdc.im |= HP_SDC_IM_PT;
 
 743         write_unlock_irq(&hp_sdc.hook_lock);
 
 744         tasklet_schedule(&hp_sdc.task);
 
 749 int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback)
 
 751         write_lock_irq(&hp_sdc.hook_lock);
 
 752         if ((callback != hp_sdc.hil) ||
 
 753             (hp_sdc.hil == NULL)) {
 
 754                 write_unlock_irq(&hp_sdc.hook_lock);
 
 759         /* Disable interrupts from HIL only if there is no cooked driver. */
 
 760         if(hp_sdc.cooked == NULL) {
 
 761                 hp_sdc.im |= (HP_SDC_IM_HIL | HP_SDC_IM_RESET);
 
 764         write_unlock_irq(&hp_sdc.hook_lock);
 
 765         tasklet_schedule(&hp_sdc.task);
 
 770 int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback)
 
 772         write_lock_irq(&hp_sdc.hook_lock);
 
 773         if ((callback != hp_sdc.cooked) ||
 
 774             (hp_sdc.cooked == NULL)) {
 
 775                 write_unlock_irq(&hp_sdc.hook_lock);
 
 779         hp_sdc.cooked = NULL;
 
 780         /* Disable interrupts from HIL only if there is no raw HIL driver. */
 
 781         if(hp_sdc.hil == NULL) {
 
 782                 hp_sdc.im |= (HP_SDC_IM_HIL | HP_SDC_IM_RESET);
 
 785         write_unlock_irq(&hp_sdc.hook_lock);
 
 786         tasklet_schedule(&hp_sdc.task);
 
 791 /************************* Keepalive timer task *********************/
 
 793 void hp_sdc_kicker (unsigned long data)
 
 795         tasklet_schedule(&hp_sdc.task);
 
 796         /* Re-insert the periodic task. */
 
 797         mod_timer(&hp_sdc.kicker, jiffies + HZ);
 
 800 /************************** Module Initialization ***************************/
 
 802 #if defined(__hppa__)
 
 804 static const struct parisc_device_id hp_sdc_tbl[] = {
 
 807                 .hversion_rev = HVERSION_REV_ANY_ID,
 
 808                 .hversion =     HVERSION_ANY_ID,
 
 814 MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl);
 
 816 static int __init hp_sdc_init_hppa(struct parisc_device *d);
 
 818 static struct parisc_driver hp_sdc_driver = {
 
 820         .id_table =     hp_sdc_tbl,
 
 821         .probe =        hp_sdc_init_hppa,
 
 824 #endif /* __hppa__ */
 
 826 static int __init hp_sdc_init(void)
 
 829         hp_sdc_transaction t_sync;
 
 831         struct semaphore s_sync;
 
 833         rwlock_init(&hp_sdc.lock);
 
 834         rwlock_init(&hp_sdc.ibf_lock);
 
 835         rwlock_init(&hp_sdc.rtq_lock);
 
 836         rwlock_init(&hp_sdc.hook_lock);
 
 841         hp_sdc.cooked           = NULL;
 
 842         hp_sdc.im               = HP_SDC_IM_MASK;  /* Mask maskable irqs */
 
 851         memset(&hp_sdc.tq, 0, sizeof(hp_sdc.tq));
 
 857         hp_sdc.dev_err = -ENODEV;
 
 859         errstr = "IO not found for";
 
 863         errstr = "IRQ not found for";
 
 867         hp_sdc.dev_err = -EBUSY;
 
 869 #if defined(__hppa__)
 
 870         errstr = "IO not available for";
 
 871         if (request_region(hp_sdc.data_io, 2, hp_sdc_driver.name))
 
 875         errstr = "IRQ not available for";
 
 876         if (request_irq(hp_sdc.irq, &hp_sdc_isr, IRQF_SHARED|IRQF_SAMPLE_RANDOM,
 
 880         errstr = "NMI not available for";
 
 881         if (request_irq(hp_sdc.nmi, &hp_sdc_nmisr, IRQF_SHARED,
 
 882                         "HP SDC NMI", &hp_sdc))
 
 885         printk(KERN_INFO PREFIX "HP SDC at 0x%p, IRQ %d (NMI IRQ %d)\n",
 
 886                (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi);
 
 891         tasklet_init(&hp_sdc.task, hp_sdc_tasklet, 0);
 
 893         /* Sync the output buffer registers, thus scheduling hp_sdc_tasklet. */
 
 897         t_sync.seq      = ts_sync;
 
 898         ts_sync[0]      = HP_SDC_ACT_DATAREG | HP_SDC_ACT_SEMAPHORE;
 
 900         ts_sync[2] = ts_sync[3] = ts_sync[4] = ts_sync[5] = 0;
 
 901         t_sync.act.semaphore = &s_sync;
 
 902         init_MUTEX_LOCKED(&s_sync);
 
 903         hp_sdc_enqueue_transaction(&t_sync);
 
 904         down(&s_sync); /* Wait for t_sync to complete */
 
 906         /* Create the keepalive task */
 
 907         init_timer(&hp_sdc.kicker);
 
 908         hp_sdc.kicker.expires = jiffies + HZ;
 
 909         hp_sdc.kicker.function = &hp_sdc_kicker;
 
 910         add_timer(&hp_sdc.kicker);
 
 915         free_irq(hp_sdc.irq, &hp_sdc);
 
 917         release_region(hp_sdc.data_io, 2);
 
 919         printk(KERN_WARNING PREFIX ": %s SDC IO=0x%p IRQ=0x%x NMI=0x%x\n",
 
 920                 errstr, (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi);
 
 923         return hp_sdc.dev_err;
 
 926 #if defined(__hppa__)
 
 928 static int __init hp_sdc_init_hppa(struct parisc_device *d)
 
 932         if (hp_sdc.dev != NULL)
 
 933                 return 1;       /* We only expect one SDC */
 
 937         hp_sdc.nmi              = d->aux_irq;
 
 938         hp_sdc.base_io          = d->hpa.start;
 
 939         hp_sdc.data_io          = d->hpa.start + 0x800;
 
 940         hp_sdc.status_io        = d->hpa.start + 0x801;
 
 942         return hp_sdc_init();
 
 945 #endif /* __hppa__ */
 
 947 static void hp_sdc_exit(void)
 
 949         write_lock_irq(&hp_sdc.lock);
 
 951         /* Turn off all maskable "sub-function" irq's. */
 
 953         sdc_writeb(HP_SDC_CMD_SET_IM | HP_SDC_IM_MASK, hp_sdc.status_io);
 
 955         /* Wait until we know this has been processed by the i8042 */
 
 958         free_irq(hp_sdc.nmi, &hp_sdc);
 
 959         free_irq(hp_sdc.irq, &hp_sdc);
 
 960         write_unlock_irq(&hp_sdc.lock);
 
 962         del_timer(&hp_sdc.kicker);
 
 964         tasklet_kill(&hp_sdc.task);
 
 966 #if defined(__hppa__)
 
 967         if (unregister_parisc_driver(&hp_sdc_driver))
 
 968                 printk(KERN_WARNING PREFIX "Error unregistering HP SDC");
 
 972 static int __init hp_sdc_register(void)
 
 974         hp_sdc_transaction tq_init;
 
 975         uint8_t tq_init_seq[5];
 
 976         struct semaphore tq_init_sem;
 
 977 #if defined(__mc68000__)
 
 984 #if defined(__hppa__)
 
 985         if (register_parisc_driver(&hp_sdc_driver)) {
 
 986                 printk(KERN_WARNING PREFIX "Error registering SDC with system bus tree.\n");
 
 989 #elif defined(__mc68000__)
 
 995         hp_sdc.base_io   = (unsigned long) 0xf0428000;
 
 996         hp_sdc.data_io   = (unsigned long) hp_sdc.base_io + 1;
 
 997         hp_sdc.status_io = (unsigned long) hp_sdc.base_io + 3;
 
1000         if (!get_user(i, (unsigned char *)hp_sdc.data_io))
 
1001                 hp_sdc.dev = (void *)1;
 
1003         hp_sdc.dev_err   = hp_sdc_init();
 
1005         if (hp_sdc.dev == NULL) {
 
1006                 printk(KERN_WARNING PREFIX "No SDC found.\n");
 
1007                 return hp_sdc.dev_err;
 
1010         init_MUTEX_LOCKED(&tq_init_sem);
 
1015         tq_init.seq             = tq_init_seq;
 
1016         tq_init.act.semaphore   = &tq_init_sem;
 
1019                 HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE;
 
1020         tq_init_seq[1] = HP_SDC_CMD_READ_KCC;
 
1025         hp_sdc_enqueue_transaction(&tq_init);
 
1030         if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) {
 
1031                 printk(KERN_WARNING PREFIX "Error reading config byte.\n");
 
1035         hp_sdc.r11 = tq_init_seq[4];
 
1036         if (hp_sdc.r11 & HP_SDC_CFG_NEW) {
 
1038                 printk(KERN_INFO PREFIX "New style SDC\n");
 
1039                 tq_init_seq[1] = HP_SDC_CMD_READ_XTD;
 
1043                 hp_sdc_enqueue_transaction(&tq_init);
 
1046                 if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) {
 
1047                         printk(KERN_WARNING PREFIX "Error reading extended config byte.\n");
 
1050                 hp_sdc.r7e = tq_init_seq[4];
 
1051                 HP_SDC_XTD_REV_STRINGS(hp_sdc.r7e & HP_SDC_XTD_REV, str)
 
1052                 printk(KERN_INFO PREFIX "Revision: %s\n", str);
 
1053                 if (hp_sdc.r7e & HP_SDC_XTD_BEEPER)
 
1054                         printk(KERN_INFO PREFIX "TI SN76494 beeper present\n");
 
1055                 if (hp_sdc.r7e & HP_SDC_XTD_BBRTC)
 
1056                         printk(KERN_INFO PREFIX "OKI MSM-58321 BBRTC present\n");
 
1057                 printk(KERN_INFO PREFIX "Spunking the self test register to force PUP "
 
1058                        "on next firmware reset.\n");
 
1059                 tq_init_seq[0] = HP_SDC_ACT_PRECMD |
 
1060                         HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE;
 
1061                 tq_init_seq[1] = HP_SDC_CMD_SET_STR;
 
1068                 hp_sdc_enqueue_transaction(&tq_init);
 
1072                 printk(KERN_INFO PREFIX "Old style SDC (1820-%s).\n",
 
1073                        (hp_sdc.r11 & HP_SDC_CFG_REV) ? "3300" : "2564/3087");
 
1078 module_init(hp_sdc_register);
 
1079 module_exit(hp_sdc_exit);
 
1081 /* Timing notes:  These measurements taken on my 64MHz 7100-LC (715/64)
 
1082  *                                              cycles cycles-adj    time
 
1083  * between two consecutive mfctl(16)'s:              4        n/a    63ns
 
1084  * hp_sdc_spin_ibf when idle:                      119        115   1.7us
 
1085  * gsc_writeb status register:                      83         79   1.2us
 
1086  * IBF to clear after sending SET_IM:             6204       6006    93us
 
1087  * IBF to clear after sending LOAD_RT:            4467       4352    68us
 
1088  * IBF to clear after sending two LOAD_RTs:      18974      18859   295us
 
1089  * READ_T1, read status/data, IRQ, call handler: 35564        n/a   556us
 
1090  * cmd to ~IBF READ_T1 2nd time right after:   5158403        n/a    81ms
 
1091  * between IRQ received and ~IBF for above:    2578877        n/a    40ms
 
1093  * Performance stats after a run of this module configuring HIL and
 
1094  * receiving a few mouse events:
 
1096  * status in8  282508 cycles 7128 calls
 
1097  * status out8   8404 cycles  341 calls
 
1098  * data out8     1734 cycles   78 calls
 
1099  * isr         174324 cycles  617 calls (includes take)
 
1100  * take          1241 cycles    2 calls
 
1101  * put        1411504 cycles 6937 calls
 
1102  * task       1655209 cycles 6937 calls (includes put)