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