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