Linux Audio

Check our new training course

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