Linux Audio

Check our new training course

Yocto / OpenEmbedded training

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