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