root/drivers/input/serio/hp_sdc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hp_sdc_status_in8
  2. hp_sdc_data_in8
  3. hp_sdc_status_out8
  4. hp_sdc_data_out8
  5. hp_sdc_spin_ibf
  6. hp_sdc_take
  7. hp_sdc_isr
  8. hp_sdc_nmisr
  9. hp_sdc_tasklet
  10. hp_sdc_put
  11. __hp_sdc_enqueue_transaction
  12. hp_sdc_enqueue_transaction
  13. hp_sdc_dequeue_transaction
  14. hp_sdc_request_timer_irq
  15. hp_sdc_request_hil_irq
  16. hp_sdc_request_cooked_irq
  17. hp_sdc_release_timer_irq
  18. hp_sdc_release_hil_irq
  19. hp_sdc_release_cooked_irq
  20. hp_sdc_kicker
  21. hp_sdc_init
  22. request_module_delayed
  23. hp_sdc_init_hppa
  24. hp_sdc_exit
  25. hp_sdc_register

   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 
  91 MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
  92 MODULE_DESCRIPTION("HP i8042-based SDC Driver");
  93 MODULE_LICENSE("Dual BSD/GPL");
  94 
  95 EXPORT_SYMBOL(hp_sdc_request_timer_irq);
  96 EXPORT_SYMBOL(hp_sdc_request_hil_irq);
  97 EXPORT_SYMBOL(hp_sdc_request_cooked_irq);
  98 
  99 EXPORT_SYMBOL(hp_sdc_release_timer_irq);
 100 EXPORT_SYMBOL(hp_sdc_release_hil_irq);
 101 EXPORT_SYMBOL(hp_sdc_release_cooked_irq);
 102 
 103 EXPORT_SYMBOL(__hp_sdc_enqueue_transaction);
 104 EXPORT_SYMBOL(hp_sdc_enqueue_transaction);
 105 EXPORT_SYMBOL(hp_sdc_dequeue_transaction);
 106 
 107 static bool hp_sdc_disabled;
 108 module_param_named(no_hpsdc, hp_sdc_disabled, bool, 0);
 109 MODULE_PARM_DESC(no_hpsdc, "Do not enable HP SDC driver.");
 110 
 111 static hp_i8042_sdc     hp_sdc; /* All driver state is kept in here. */
 112 
 113 /*************** primitives for use in any context *********************/
 114 static 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 
 128 static inline uint8_t hp_sdc_data_in8(void)
 129 {
 130         return sdc_readb(hp_sdc.data_io);
 131 }
 132 
 133 static 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 
 145 static 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  */
 159 static 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 ************************/
 181 static 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 
 219 static 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 
 277 static 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 
 302 unsigned long hp_sdc_put(void);
 303 
 304 static 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 
 348 unsigned 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 ****/
 598 int __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 
 631 int 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 
 642 int 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 **************************/
 662 int 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 
 686 int 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 
 707 int 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 
 729 int 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 
 750 int 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 
 771 int 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 
 794 static 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 
 805 static 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 
 815 MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl);
 816 
 817 static int __init hp_sdc_init_hppa(struct parisc_device *d);
 818 static struct delayed_work moduleloader_work;
 819 
 820 static 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 
 828 static 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 
 929 static void request_module_delayed(struct work_struct *work)
 930 {
 931         request_module("hp_sdc_mlc");
 932 }
 933 
 934 static 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 
 964 static 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 
 994 static 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 (!probe_kernel_read(&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 
1101 module_init(hp_sdc_register);
1102 module_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  */

/* [<][>][^][v][top][bottom][index][help] */