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