Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ffd51f46 authored by Helge Deller's avatar Helge Deller Committed by Dmitry Torokhov
Browse files

Input: HIL - cleanup coding style



Signed-off-by: default avatarHelge Deller <deller@gmx.de>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 3acaf540
Loading
Loading
Loading
Loading
+43 −34
Original line number Diff line number Diff line
@@ -95,9 +95,11 @@ static void hil_kbd_process_record(struct hil_kbd *kbd)
	p = data[idx - 1];

	if ((p & ~HIL_CMDCT_POL) ==
	    (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) goto report;
	    (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL))
		goto report;
	if ((p & ~HIL_CMDCT_RPL) ==
	    (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) goto report;
	    (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL))
		goto report;

	/* Not a poll response.  See if we are loading config records. */
	switch (p & HIL_PKT_DATA_MASK) {
@@ -107,27 +109,32 @@ static void hil_kbd_process_record(struct hil_kbd *kbd)
		for (; i < HIL_KBD_MAX_LENGTH; i++)
			kbd->idd[i] = 0;
		break;

	case HIL_CMD_RSC:
		for (i = 0; i < idx; i++)
			kbd->rsc[i] = kbd->data[i] & HIL_PKT_DATA_MASK;
		for (; i < HIL_KBD_MAX_LENGTH; i++)
			kbd->rsc[i] = 0;
		break;

	case HIL_CMD_EXD:
		for (i = 0; i < idx; i++)
			kbd->exd[i] = kbd->data[i] & HIL_PKT_DATA_MASK;
		for (; i < HIL_KBD_MAX_LENGTH; i++)
			kbd->exd[i] = 0;
		break;

	case HIL_CMD_RNM:
		for (i = 0; i < idx; i++)
			kbd->rnm[i] = kbd->data[i] & HIL_PKT_DATA_MASK;
		for (; i < HIL_KBD_MAX_LENGTH + 1; i++)
			kbd->rnm[i] = '\0';
		break;

	default:
		/* These occur when device isn't present */
		if (p == (HIL_ERR_INT | HIL_PKT_CMD)) break; 
		if (p == (HIL_ERR_INT | HIL_PKT_CMD))
			break;
		/* Anything else we'd like to know about. */
		printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p);
		break;
@@ -139,16 +146,19 @@ static void hil_kbd_process_record(struct hil_kbd *kbd)
	switch (kbd->data[0] & HIL_POL_CHARTYPE_MASK) {
	case HIL_POL_CHARTYPE_NONE:
		break;

	case HIL_POL_CHARTYPE_ASCII:
		while (cnt < idx - 1)
			input_report_key(dev, kbd->data[cnt++] & 0x7f, 1);
		break;

	case HIL_POL_CHARTYPE_RSVD1:
	case HIL_POL_CHARTYPE_RSVD2:
	case HIL_POL_CHARTYPE_BINARY:
		while (cnt < idx - 1)
			input_report_key(dev, kbd->data[cnt++], 1);
		break;

	case HIL_POL_CHARTYPE_SET1:
		while (cnt < idx - 1) {
			unsigned int key;
@@ -161,6 +171,7 @@ static void hil_kbd_process_record(struct hil_kbd *kbd)
				input_report_key(dev, key, !up);
		}
		break;

	case HIL_POL_CHARTYPE_SET2:
		while (cnt < idx - 1) {
			unsigned int key;
@@ -173,6 +184,7 @@ static void hil_kbd_process_record(struct hil_kbd *kbd)
				input_report_key(dev, key, !up);
		}
		break;

	case HIL_POL_CHARTYPE_SET3:
		while (cnt < idx - 1) {
			unsigned int key;
@@ -191,7 +203,8 @@ static void hil_kbd_process_record(struct hil_kbd *kbd)
	up(&kbd->sem);
}

static void hil_kbd_process_err(struct hil_kbd *kbd) {
static void hil_kbd_process_err(struct hil_kbd *kbd)
{
	printk(KERN_WARNING PREFIX "errored HIL packet\n");
	kbd->idx4 = 0;
	up(&kbd->sem);
@@ -205,28 +218,28 @@ static irqreturn_t hil_kbd_interrupt(struct serio *serio,
	int idx;

	kbd = serio_get_drvdata(serio);
	if (kbd == NULL) {
		BUG();
		return IRQ_HANDLED;
	}
	BUG_ON(kbd == NULL);

	if (kbd->idx4 >= (HIL_KBD_MAX_LENGTH * sizeof(hil_packet))) {
		hil_kbd_process_err(kbd);
		return IRQ_HANDLED;
	}
	idx = kbd->idx4/4;
	if (!(kbd->idx4 % 4)) kbd->data[idx] = 0;
	if (!(kbd->idx4 % 4))
		kbd->data[idx] = 0;
	packet = kbd->data[idx];
	packet |= ((hil_packet)data) << ((3 - (kbd->idx4 % 4)) * 8);
	kbd->data[idx] = packet;

	/* Records of N 4-byte hil_packets must terminate with a command. */
	if ((++(kbd->idx4)) % 4) return IRQ_HANDLED;
	if ((++(kbd->idx4)) % 4)
		return IRQ_HANDLED;
	if ((packet & 0xffff0000) != HIL_ERR_INT) {
		hil_kbd_process_err(kbd);
		return IRQ_HANDLED;
	}
	if (packet & HIL_PKT_CMD) hil_kbd_process_record(kbd);
	if (packet & HIL_PKT_CMD)
		hil_kbd_process_record(kbd);
	return IRQ_HANDLED;
}

@@ -235,10 +248,7 @@ static void hil_kbd_disconnect(struct serio *serio)
	struct hil_kbd *kbd;

	kbd = serio_get_drvdata(serio);
	if (kbd == NULL) {
		BUG();
		return;
	}
	BUG_ON(kbd == NULL);

	serio_close(serio);
	input_unregister_device(kbd->dev);
@@ -267,34 +277,34 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
	serio_set_drvdata(serio, kbd);
	kbd->serio = serio;

	init_MUTEX_LOCKED(&(kbd->sem));
	init_MUTEX_LOCKED(&kbd->sem);

	/* Get device info.  MLC driver supplies devid/status/etc. */
	serio->write(serio, 0);
	serio->write(serio, 0);
	serio->write(serio, HIL_PKT_CMD >> 8);
	serio->write(serio, HIL_CMD_IDD);
	down(&(kbd->sem));
	down(&kbd->sem);

	serio->write(serio, 0);
	serio->write(serio, 0);
	serio->write(serio, HIL_PKT_CMD >> 8);
	serio->write(serio, HIL_CMD_RSC);
	down(&(kbd->sem));
	down(&kbd->sem);

	serio->write(serio, 0);
	serio->write(serio, 0);
	serio->write(serio, HIL_PKT_CMD >> 8);
	serio->write(serio, HIL_CMD_RNM);
	down(&(kbd->sem));
	down(&kbd->sem);

	serio->write(serio, 0);
	serio->write(serio, 0);
	serio->write(serio, HIL_PKT_CMD >> 8);
	serio->write(serio, HIL_CMD_EXD);
	down(&(kbd->sem));
	down(&kbd->sem);

	up(&(kbd->sem));
	up(&kbd->sem);

	did = kbd->idd[0];
	idd = kbd->idd + 1;
@@ -315,7 +325,6 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
		goto bail2;
	}


	kbd->dev->evbit[0]	= BIT(EV_KEY) | BIT(EV_REP);
	kbd->dev->ledbit[0]	= BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
	kbd->dev->keycodemax	= HIL_KEYCODES_SET1_TBLSIZE;
@@ -344,8 +353,8 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
	serio->write(serio, 0);
	serio->write(serio, HIL_PKT_CMD >> 8);
	serio->write(serio, HIL_CMD_EK1); /* Enable Keyswitch Autorepeat 1 */
	down(&(kbd->sem));
	up(&(kbd->sem));
	down(&kbd->sem);
	up(&kbd->sem);

	return 0;
 bail2:
+49 −44
Original line number Diff line number Diff line
@@ -89,9 +89,11 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
	p = data[idx - 1];

	if ((p & ~HIL_CMDCT_POL) ==
	    (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) goto report;
	    (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL))
		goto report;
	if ((p & ~HIL_CMDCT_RPL) ==
	    (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) goto report;
	    (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL))
		goto report;

	/* Not a poll response.  See if we are loading config records. */
	switch (p & HIL_PKT_DATA_MASK) {
@@ -101,27 +103,32 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
		for (; i < HIL_PTR_MAX_LENGTH; i++)
			ptr->idd[i] = 0;
		break;

	case HIL_CMD_RSC:
		for (i = 0; i < idx; i++)
			ptr->rsc[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
		for (; i < HIL_PTR_MAX_LENGTH; i++)
			ptr->rsc[i] = 0;
		break;

	case HIL_CMD_EXD:
		for (i = 0; i < idx; i++)
			ptr->exd[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
		for (; i < HIL_PTR_MAX_LENGTH; i++)
			ptr->exd[i] = 0;
		break;

	case HIL_CMD_RNM:
		for (i = 0; i < idx; i++)
			ptr->rnm[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
		for (; i < HIL_PTR_MAX_LENGTH + 1; i++)
			ptr->rnm[i] = '\0';
			ptr->rnm[i] = 0;
		break;

	default:
		/* These occur when device isn't present */
		if (p == (HIL_ERR_INT | HIL_PKT_CMD)) break; 
		if (p == (HIL_ERR_INT | HIL_PKT_CMD))
			break;
		/* Anything else we'd like to know about. */
		printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p);
		break;
@@ -130,7 +137,8 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)

 report:
	if ((p & HIL_CMDCT_POL) != idx - 1) {
		printk(KERN_WARNING PREFIX "Malformed poll packet %x (idx = %i)\n", p, idx);
		printk(KERN_WARNING PREFIX
			"Malformed poll packet %x (idx = %i)\n", p, idx);
		goto out;
	}

@@ -157,7 +165,8 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
			input_report_abs(dev, ABS_X + i, val);
		} else {
			val = (int) (((int8_t)lo) | ((int8_t)hi<<8));
			if (i%3) val *= -1;
			if (i%3)
				val *= -1;
			input_report_rel(dev, REL_X + i, val);
		}
	}
@@ -168,10 +177,11 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
		btn = ptr->data[cnt++];
		up = btn & 1;
		btn &= 0xfe;
		if (btn == 0x8e) {
		if (btn == 0x8e)
			continue; /* TODO: proximity == touch? */
		}
		else if ((btn > 0x8c) || (btn < 0x80)) continue;
		else
			if ((btn > 0x8c) || (btn < 0x80))
				continue;
		btn = (btn - 0x80) >> 1;
		btn = ptr->btnmap[btn];
		input_report_key(dev, btn, !up);
@@ -182,11 +192,11 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
	up(&ptr->sem);
}

static void hil_ptr_process_err(struct hil_ptr *ptr) {
static void hil_ptr_process_err(struct hil_ptr *ptr)
{
	printk(KERN_WARNING PREFIX "errored HIL packet\n");
	ptr->idx4 = 0;
	up(&ptr->sem);
	return;
}

static irqreturn_t hil_ptr_interrupt(struct serio *serio,
@@ -197,29 +207,29 @@ static irqreturn_t hil_ptr_interrupt(struct serio *serio,
	int idx;

	ptr = serio_get_drvdata(serio);
	if (ptr == NULL) {
		BUG();
		return IRQ_HANDLED;
	}
	BUG_ON(ptr == NULL);

	if (ptr->idx4 >= (HIL_PTR_MAX_LENGTH * sizeof(hil_packet))) {
		hil_ptr_process_err(ptr);
		return IRQ_HANDLED;
	}
	idx = ptr->idx4/4;
	if (!(ptr->idx4 % 4)) ptr->data[idx] = 0;
	if (!(ptr->idx4 % 4))
		ptr->data[idx] = 0;
	packet = ptr->data[idx];
	packet |= ((hil_packet)data) << ((3 - (ptr->idx4 % 4)) * 8);
	ptr->data[idx] = packet;

	/* Records of N 4-byte hil_packets must terminate with a command. */
	if ((++(ptr->idx4)) % 4) return IRQ_HANDLED;
	if ((++(ptr->idx4)) % 4)
		return IRQ_HANDLED;
	if ((packet & 0xffff0000) != HIL_ERR_INT) {
		hil_ptr_process_err(ptr);
		return IRQ_HANDLED;
	}
	if (packet & HIL_PKT_CMD)
		hil_ptr_process_record(ptr);

	return IRQ_HANDLED;
}

@@ -228,10 +238,7 @@ static void hil_ptr_disconnect(struct serio *serio)
	struct hil_ptr *ptr;

	ptr = serio_get_drvdata(serio);
	if (ptr == NULL) {
		BUG();
		return;
	}
	BUG_ON(ptr == NULL);

	serio_close(serio);
	input_unregister_device(ptr->dev);
@@ -241,7 +248,7 @@ static void hil_ptr_disconnect(struct serio *serio)
static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
{
	struct hil_ptr	 *ptr;
	char		 *txt;
	const char	 *txt;
	unsigned int	 i, naxsets, btntype;
	uint8_t		 did, *idd;

@@ -260,34 +267,34 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
	serio_set_drvdata(serio, ptr);
	ptr->serio = serio;

	init_MUTEX_LOCKED(&(ptr->sem));
	init_MUTEX_LOCKED(&ptr->sem);

	/* Get device info.  MLC driver supplies devid/status/etc. */
	serio->write(serio, 0);
	serio->write(serio, 0);
	serio->write(serio, HIL_PKT_CMD >> 8);
	serio->write(serio, HIL_CMD_IDD);
	down(&(ptr->sem));
	down(&ptr->sem);

	serio->write(serio, 0);
	serio->write(serio, 0);
	serio->write(serio, HIL_PKT_CMD >> 8);
	serio->write(serio, HIL_CMD_RSC);
	down(&(ptr->sem));
	down(&ptr->sem);

	serio->write(serio, 0);
	serio->write(serio, 0);
	serio->write(serio, HIL_PKT_CMD >> 8);
	serio->write(serio, HIL_CMD_RNM);
	down(&(ptr->sem));
	down(&ptr->sem);

	serio->write(serio, 0);
	serio->write(serio, 0);
	serio->write(serio, HIL_PKT_CMD >> 8);
	serio->write(serio, HIL_CMD_EXD);
	down(&(ptr->sem));
	down(&ptr->sem);

	up(&(ptr->sem));
	up(&ptr->sem);

	did = ptr->idd[0];
	idd = ptr->idd + 1;
@@ -301,12 +308,12 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
		ptr->dev->evbit[0] = BIT(EV_ABS);
		txt = "absolute";
	}
	if (!ptr->dev->evbit[0]) {
	if (!ptr->dev->evbit[0])
		goto bail2;
	}

	ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
	if (ptr->nbtn) ptr->dev->evbit[0] |= BIT(EV_KEY);
	if (ptr->nbtn)
		ptr->dev->evbit[0] |= BIT(EV_KEY);

	naxsets = HIL_IDD_NUM_AXSETS(*idd);
	ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd);
@@ -341,12 +348,10 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
	}

	if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
		for (i = 0; i < ptr->naxes; i++) {
		for (i = 0; i < ptr->naxes; i++)
			set_bit(REL_X + i, ptr->dev->relbit);
		}
		for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) {
		for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++)
			set_bit(REL_X + i, ptr->dev->relbit);
		}
	} else {
		for (i = 0; i < ptr->naxes; i++) {
			set_bit(ABS_X + i, ptr->dev->absbit);
+272 −215

File changed.

Preview size limit exceeded, changes collapsed.

+222 −173
Original line number Diff line number Diff line
@@ -106,33 +106,39 @@ EXPORT_SYMBOL(hp_sdc_dequeue_transaction);
static hp_i8042_sdc	hp_sdc;	/* All driver state is kept in here. */

/*************** primitives for use in any context *********************/
static inline uint8_t hp_sdc_status_in8 (void) {
static inline uint8_t hp_sdc_status_in8(void)
{
	uint8_t status;
	unsigned long flags;

	write_lock_irqsave(&hp_sdc.ibf_lock, flags);
	status = sdc_readb(hp_sdc.status_io);
	if (!(status & HP_SDC_STATUS_IBF)) hp_sdc.ibf = 0;
	if (!(status & HP_SDC_STATUS_IBF))
		hp_sdc.ibf = 0;
	write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);

	return status;
}

static inline uint8_t hp_sdc_data_in8 (void) {
static inline uint8_t hp_sdc_data_in8(void)
{
	return sdc_readb(hp_sdc.data_io);
}

static inline void hp_sdc_status_out8 (uint8_t val) {
static inline void hp_sdc_status_out8(uint8_t val)
{
	unsigned long flags;

	write_lock_irqsave(&hp_sdc.ibf_lock, flags);
	hp_sdc.ibf = 1;
	if ((val & 0xf0) == 0xe0) hp_sdc.wi = 0xff;
	if ((val & 0xf0) == 0xe0)
		hp_sdc.wi = 0xff;
	sdc_writeb(val, hp_sdc.status_io);
	write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);
}

static inline void hp_sdc_data_out8 (uint8_t val) {
static inline void hp_sdc_data_out8(uint8_t val)
{
	unsigned long flags;

	write_lock_irqsave(&hp_sdc.ibf_lock, flags);
@@ -145,7 +151,8 @@ static inline void hp_sdc_data_out8 (uint8_t val) {
 *	absolutely needed, or in rarely invoked subroutines.
 *	Not only does it waste CPU cycles, it also wastes bus cycles.
 */
static inline void hp_sdc_spin_ibf(void) {
static inline void hp_sdc_spin_ibf(void)
{
	unsigned long flags;
	rwlock_t *lock;

@@ -158,14 +165,16 @@ static inline void hp_sdc_spin_ibf(void) {
	}
	read_unlock(lock);
	write_lock(lock);
	while (sdc_readb(hp_sdc.status_io) & HP_SDC_STATUS_IBF) {};
	while (sdc_readb(hp_sdc.status_io) & HP_SDC_STATUS_IBF)
		{ }
	hp_sdc.ibf = 0;
	write_unlock_irqrestore(lock, flags);
}


/************************ Interrupt context functions ************************/
static void hp_sdc_take (int irq, void *dev_id, uint8_t status, uint8_t data) {
static void hp_sdc_take(int irq, void *dev_id, uint8_t status, uint8_t data)
{
	hp_sdc_transaction *curr;

	read_lock(&hp_sdc.rtq_lock);
@@ -183,13 +192,14 @@ static void hp_sdc_take (int irq, void *dev_id, uint8_t status, uint8_t data) {

	if (hp_sdc.rqty <= 0) {
		/* All data has been gathered. */
		if(curr->seq[curr->actidx] & HP_SDC_ACT_SEMAPHORE) {
			if (curr->act.semaphore) up(curr->act.semaphore);
		}
		if(curr->seq[curr->actidx] & HP_SDC_ACT_CALLBACK) {
		if (curr->seq[curr->actidx] & HP_SDC_ACT_SEMAPHORE)
			if (curr->act.semaphore)
				up(curr->act.semaphore);

		if (curr->seq[curr->actidx] & HP_SDC_ACT_CALLBACK)
			if (curr->act.irqhook)
				curr->act.irqhook(irq, dev_id, status, data);
		}

		curr->actidx = curr->idx;
		curr->idx++;
		/* Return control of this transaction */
@@ -201,7 +211,8 @@ static void hp_sdc_take (int irq, void *dev_id, uint8_t status, uint8_t data) {
	}
}

static irqreturn_t hp_sdc_isr(int irq, void *dev_id) {
static irqreturn_t hp_sdc_isr(int irq, void *dev_id)
{
	uint8_t status, data;

	status = hp_sdc_status_in8();
@@ -209,13 +220,13 @@ static irqreturn_t hp_sdc_isr(int irq, void *dev_id) {
	data =   hp_sdc_data_in8();

	/* For now we are ignoring these until we get the SDC to behave. */
	if (((status & 0xf1) == 0x51) && data == 0x82) {
	if (((status & 0xf1) == 0x51) && data == 0x82)
		return IRQ_HANDLED;
	}

	switch (status & HP_SDC_STATUS_IRQMASK) {
	case 0: /* This case is not documented. */
		break;

	case HP_SDC_STATUS_USERTIMER:
	case HP_SDC_STATUS_PERIODIC:
	case HP_SDC_STATUS_TIMER:
@@ -224,9 +235,11 @@ static irqreturn_t hp_sdc_isr(int irq, void *dev_id) {
			hp_sdc.timer(irq, dev_id, status, data);
		read_unlock(&hp_sdc.hook_lock);
		break;

	case HP_SDC_STATUS_REG:
		hp_sdc_take(irq, dev_id, status, data);
		break;

	case HP_SDC_STATUS_HILCMD:
	case HP_SDC_STATUS_HILDATA:
		read_lock(&hp_sdc.hook_lock);
@@ -234,13 +247,16 @@ static irqreturn_t hp_sdc_isr(int irq, void *dev_id) {
			hp_sdc.hil(irq, dev_id, status, data);
		read_unlock(&hp_sdc.hook_lock);
		break;

	case HP_SDC_STATUS_PUP:
		read_lock(&hp_sdc.hook_lock);
		if (hp_sdc.pup != NULL)
			hp_sdc.pup(irq, dev_id, status, data);
		else printk(KERN_INFO PREFIX "HP SDC reports successful PUP.\n");
		else
			printk(KERN_INFO PREFIX "HP SDC reports successful PUP.\n");
		read_unlock(&hp_sdc.hook_lock);
		break;

	default:
		read_lock(&hp_sdc.hook_lock);
		if (hp_sdc.cooked != NULL)
@@ -248,11 +264,13 @@ static irqreturn_t hp_sdc_isr(int irq, void *dev_id) {
		read_unlock(&hp_sdc.hook_lock);
		break;
	}

	return IRQ_HANDLED;
}


static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id) {
static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id)
{
	int status;

	status = hp_sdc_status_in8();
@@ -264,12 +282,12 @@ static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id) {
		if (hp_sdc.timer != NULL)
			hp_sdc.timer(irq, dev_id, status, 0);
		read_unlock(&hp_sdc.hook_lock);
	}
	else {
	} else {
		/* TODO: pass this on to the HIL handler, or do SAK here? */
		printk(KERN_WARNING PREFIX "HIL NMI\n");
	}
#endif

	return IRQ_HANDLED;
}

@@ -278,13 +296,17 @@ static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id) {

unsigned long hp_sdc_put(void);

static void hp_sdc_tasklet(unsigned long foo) {

static void hp_sdc_tasklet(unsigned long foo)
{
	write_lock_irq(&hp_sdc.rtq_lock);

	if (hp_sdc.rcurr >= 0) {
		struct timeval tv;

		do_gettimeofday(&tv);
		if (tv.tv_sec > hp_sdc.rtv.tv_sec) tv.tv_usec += 1000000;
		if (tv.tv_sec > hp_sdc.rtv.tv_sec)
			tv.tv_usec += USEC_PER_SEC;

		if (tv.tv_usec - hp_sdc.rtv.tv_usec > HP_SDC_MAX_REG_DELAY) {
			hp_sdc_transaction *curr;
			uint8_t tmp;
@@ -300,10 +322,10 @@ static void hp_sdc_tasklet(unsigned long foo) {
			hp_sdc.rqty = 0;
			tmp = curr->seq[curr->actidx];
			curr->seq[curr->actidx] |= HP_SDC_ACT_DEAD;
			if(tmp & HP_SDC_ACT_SEMAPHORE) {
			if (tmp & HP_SDC_ACT_SEMAPHORE)
				if (curr->act.semaphore)
					up(curr->act.semaphore);
			}

			if (tmp & HP_SDC_ACT_CALLBACK) {
				/* Note this means that irqhooks may be called
				 * in tasklet/bh context.
@@ -311,6 +333,7 @@ static void hp_sdc_tasklet(unsigned long foo) {
				if (curr->act.irqhook)
					curr->act.irqhook(0, NULL, 0, 0);
			}

			curr->actidx = curr->idx;
			curr->idx++;
			hp_sdc.rcurr = -1;
@@ -320,7 +343,8 @@ static void hp_sdc_tasklet(unsigned long foo) {
	hp_sdc_put();
}

unsigned long hp_sdc_put(void) {
unsigned long hp_sdc_put(void)
{
	hp_sdc_transaction *curr;
	uint8_t act;
	int idx, curridx;
@@ -333,19 +357,24 @@ unsigned long hp_sdc_put(void) {
	   requires output, so we skip to the administrativa. */
	if (hp_sdc.ibf) {
		hp_sdc_status_in8();
		if (hp_sdc.ibf) goto finish;
		if (hp_sdc.ibf)
			goto finish;
	}

 anew:
	/* See if we are in the middle of a sequence. */
	if (hp_sdc.wcurr < 0) hp_sdc.wcurr = 0;
	if (hp_sdc.wcurr < 0)
		hp_sdc.wcurr = 0;
	read_lock_irq(&hp_sdc.rtq_lock);
	if (hp_sdc.rcurr == hp_sdc.wcurr) hp_sdc.wcurr++;
	if (hp_sdc.rcurr == hp_sdc.wcurr)
		hp_sdc.wcurr++;
	read_unlock_irq(&hp_sdc.rtq_lock);
	if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0;
	if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
		hp_sdc.wcurr = 0;
	curridx = hp_sdc.wcurr;

	if (hp_sdc.tq[curridx] != NULL) goto start;
	if (hp_sdc.tq[curridx] != NULL)
		goto start;

	while (++curridx != hp_sdc.wcurr) {
		if (curridx >= HP_SDC_QUEUE_LEN) {
@@ -358,7 +387,8 @@ unsigned long hp_sdc_put(void) {
			continue;
		}
		read_unlock_irq(&hp_sdc.rtq_lock);
		if (hp_sdc.tq[curridx] != NULL) break; /* Found one. */
		if (hp_sdc.tq[curridx] != NULL)
			break; /* Found one. */
	}
	if (curridx == hp_sdc.wcurr) { /* There's nothing queued to do. */
		curridx = -1;
@@ -374,7 +404,8 @@ unsigned long hp_sdc_put(void) {
		goto finish;
	}

	if (hp_sdc.wcurr == -1) goto done;
	if (hp_sdc.wcurr == -1)
		goto done;

	curr = hp_sdc.tq[curridx];
	idx = curr->actidx;
@@ -383,7 +414,8 @@ unsigned long hp_sdc_put(void) {
		hp_sdc.tq[curridx] = NULL;
		/* Interleave outbound data between the transactions. */
		hp_sdc.wcurr++;
		if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0;
		if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
			hp_sdc.wcurr = 0;
		goto finish;
	}

@@ -391,11 +423,13 @@ unsigned long hp_sdc_put(void) {
	idx++;

	if (curr->idx >= curr->endidx) {
		if (act & HP_SDC_ACT_DEALLOC) kfree(curr);
		if (act & HP_SDC_ACT_DEALLOC)
			kfree(curr);
		hp_sdc.tq[curridx] = NULL;
		/* Interleave outbound data between the transactions. */
		hp_sdc.wcurr++;
		if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0;
		if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
			hp_sdc.wcurr = 0;
		goto finish;
	}

@@ -411,7 +445,8 @@ unsigned long hp_sdc_put(void) {
		if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_PRECMD)
			goto actdone;
		/* skip quantity field if data-out sequence follows. */
		if (act & HP_SDC_ACT_DATAOUT) curr->idx++;
		if (act & HP_SDC_ACT_DATAOUT)
			curr->idx++;
		goto finish;
	}
	if (act & HP_SDC_ACT_DATAOUT) {
@@ -423,15 +458,15 @@ unsigned long hp_sdc_put(void) {
			hp_sdc_data_out8(curr->seq[curr->idx]);
			curr->idx++;
			/* act finished? */
			if ((curr->idx - idx >= qty) && 
			    ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAOUT))
			if (curr->idx - idx >= qty &&
			    (act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAOUT)
				goto actdone;
			goto finish;
		}
		idx += qty;
		act &= ~HP_SDC_ACT_DATAOUT;
	}
	else while (act & HP_SDC_ACT_DATAREG) {
	} else
	    while (act & HP_SDC_ACT_DATAREG) {
		int mask;
		uint8_t w7[4];

@@ -456,15 +491,19 @@ unsigned long hp_sdc_put(void) {
			int i = 0;

			/* Need to point the write index register */
			while ((i < 4) && w7[i] == hp_sdc.r7[i]) i++;
			while (i < 4 && w7[i] == hp_sdc.r7[i])
				i++;

			if (i < 4) {
				hp_sdc_status_out8(HP_SDC_CMD_SET_D0 + i);
				hp_sdc.wi = 0x70 + i;
				goto finish;
			}

			idx++;
			if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAREG)
				goto actdone;

			curr->idx = idx;
			act &= ~HP_SDC_ACT_DATAREG;
			break;
@@ -476,7 +515,8 @@ unsigned long hp_sdc_put(void) {
		{
			int i = 0;

			while ((i < 4) && w7[i] == hp_sdc.r7[i]) i++;
			while ((i < 4) && w7[i] == hp_sdc.r7[i])
				i++;
			if (i >= 4) {
				curr->idx = idx + 1;
				if ((act & HP_SDC_ACT_DURING) ==
@@ -520,63 +560,68 @@ unsigned long hp_sdc_put(void) {
	}

 actdone:
	if (act & HP_SDC_ACT_SEMAPHORE) {
	if (act & HP_SDC_ACT_SEMAPHORE)
		up(curr->act.semaphore);
	}
	else if (act & HP_SDC_ACT_CALLBACK) {
	else if (act & HP_SDC_ACT_CALLBACK)
		curr->act.irqhook(0,NULL,0,0);
	}

	if (curr->idx >= curr->endidx) { /* This transaction is over. */
		if (act & HP_SDC_ACT_DEALLOC) kfree(curr);
		if (act & HP_SDC_ACT_DEALLOC)
			kfree(curr);
		hp_sdc.tq[curridx] = NULL;
	}
	else {
	} else {
		curr->actidx = idx + 1;
		curr->idx = idx + 2;
	}
	/* Interleave outbound data between the transactions. */
	hp_sdc.wcurr++;
	if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0;
	if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN)
		hp_sdc.wcurr = 0;

 finish:
	/* If by some quirk IBF has cleared and our ISR has run to
	   see that that has happened, do it all again. */
	if (!hp_sdc.ibf && limit++ < 20) goto anew;
	if (!hp_sdc.ibf && limit++ < 20)
		goto anew;

 done:
	if (hp_sdc.wcurr >= 0) tasklet_schedule(&hp_sdc.task);
	if (hp_sdc.wcurr >= 0)
		tasklet_schedule(&hp_sdc.task);
	write_unlock(&hp_sdc.lock);

	return 0;
}

/******* Functions called in either user or kernel context ****/
int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) {
int hp_sdc_enqueue_transaction(hp_sdc_transaction *this)
{
	unsigned long flags;
	int i;

	if (this == NULL) {
		tasklet_schedule(&hp_sdc.task);
		return -EINVAL;
	};
	}

	write_lock_irqsave(&hp_sdc.lock, flags);

	/* Can't have same transaction on queue twice */
	for (i = 0; i < HP_SDC_QUEUE_LEN; i++)
		if (hp_sdc.tq[i] == this) goto fail;
		if (hp_sdc.tq[i] == this)
			goto fail;

	this->actidx = 0;
	this->idx = 1;

	/* Search for empty slot */
	for (i=0; i < HP_SDC_QUEUE_LEN; i++) {
	for (i = 0; i < HP_SDC_QUEUE_LEN; i++)
		if (hp_sdc.tq[i] == NULL) {
			hp_sdc.tq[i] = this;
			write_unlock_irqrestore(&hp_sdc.lock, flags);
			tasklet_schedule(&hp_sdc.task);
			return 0;
		}
	}

	write_unlock_irqrestore(&hp_sdc.lock, flags);
	printk(KERN_WARNING PREFIX "No free slot to add transaction.\n");
	return -EBUSY;
@@ -587,7 +632,8 @@ int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) {
	return -EINVAL;
}

int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) {
int hp_sdc_dequeue_transaction(hp_sdc_transaction *this)
{
	unsigned long flags;
	int i;

@@ -596,7 +642,8 @@ int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) {
	/* TODO: don't remove it if it's not done. */

	for (i = 0; i < HP_SDC_QUEUE_LEN; i++)
		if (hp_sdc.tq[i] == this) hp_sdc.tq[i] = NULL;
		if (hp_sdc.tq[i] == this)
			hp_sdc.tq[i] = NULL;

	write_unlock_irqrestore(&hp_sdc.lock, flags);
	return 0;
@@ -605,11 +652,11 @@ int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) {


/********************** User context functions **************************/
int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback) {

	if (callback == NULL || hp_sdc.dev == NULL) {
int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback)
{
	if (callback == NULL || hp_sdc.dev == NULL)
		return -EINVAL;
	}

	write_lock_irq(&hp_sdc.hook_lock);
	if (hp_sdc.timer != NULL) {
		write_unlock_irq(&hp_sdc.hook_lock);
@@ -629,11 +676,11 @@ int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback) {
	return 0;
}

int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback) {

	if (callback == NULL || hp_sdc.dev == NULL) {
int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback)
{
	if (callback == NULL || hp_sdc.dev == NULL)
		return -EINVAL;
	}

	write_lock_irq(&hp_sdc.hook_lock);
	if (hp_sdc.hil != NULL) {
		write_unlock_irq(&hp_sdc.hook_lock);
@@ -650,11 +697,11 @@ int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback) {
	return 0;
}

int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback) {

	if (callback == NULL || hp_sdc.dev == NULL) {
int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback)
{
	if (callback == NULL || hp_sdc.dev == NULL)
		return -EINVAL;
	}

	write_lock_irq(&hp_sdc.hook_lock);
	if (hp_sdc.cooked != NULL) {
		write_unlock_irq(&hp_sdc.hook_lock);
@@ -672,9 +719,8 @@ int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback) {
	return 0;
}

int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback) {


int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback)
{
	write_lock_irq(&hp_sdc.hook_lock);
	if ((callback != hp_sdc.timer) ||
	    (hp_sdc.timer == NULL)) {
@@ -694,8 +740,8 @@ int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback) {
	return 0;
}

int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback) {

int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback)
{
	write_lock_irq(&hp_sdc.hook_lock);
	if ((callback != hp_sdc.hil) ||
	    (hp_sdc.hil == NULL)) {
@@ -715,8 +761,8 @@ int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback) {
	return 0;
}

int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) {

int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback)
{
	write_lock_irq(&hp_sdc.hook_lock);
	if ((callback != hp_sdc.cooked) ||
	    (hp_sdc.cooked == NULL)) {
@@ -738,7 +784,8 @@ int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) {

/************************* Keepalive timer task *********************/

void hp_sdc_kicker (unsigned long data) {
void hp_sdc_kicker (unsigned long data)
{
	tasklet_schedule(&hp_sdc.task);
	/* Re-insert the periodic task. */
	mod_timer(&hp_sdc.kicker, jiffies + HZ);
@@ -772,7 +819,6 @@ static struct parisc_driver hp_sdc_driver = {

static int __init hp_sdc_init(void)
{
	int i;
	char *errstr;
	hp_sdc_transaction t_sync;
	uint8_t ts_sync[6];
@@ -796,7 +842,8 @@ static int __init hp_sdc_init(void)
	hp_sdc.r7[3]		= 0xff;
	hp_sdc.ibf		= 1;

	for (i = 0; i < HP_SDC_QUEUE_LEN; i++) hp_sdc.tq[i] = NULL;
	memset(&hp_sdc.tq, 0, sizeof(hp_sdc.tq));

	hp_sdc.wcurr		= -1;
        hp_sdc.rcurr		= -1;
	hp_sdc.rqty		= 0;
@@ -804,25 +851,30 @@ static int __init hp_sdc_init(void)
	hp_sdc.dev_err = -ENODEV;

	errstr = "IO not found for";
	if (!hp_sdc.base_io) goto err0;
	if (!hp_sdc.base_io)
		goto err0;

	errstr = "IRQ not found for";
	if (!hp_sdc.irq) goto err0;
	if (!hp_sdc.irq)
		goto err0;

	hp_sdc.dev_err = -EBUSY;

#if defined(__hppa__)
	errstr = "IO not available for";
        if (request_region(hp_sdc.data_io, 2, hp_sdc_driver.name)) goto err0;
        if (request_region(hp_sdc.data_io, 2, hp_sdc_driver.name))
		goto err0;
#endif

	errstr = "IRQ not available for";
	if (request_irq(hp_sdc.irq, &hp_sdc_isr, IRQF_SHARED|IRQF_SAMPLE_RANDOM,
		"HP SDC", &hp_sdc)) goto err1;
			"HP SDC", &hp_sdc))
		goto err1;

	errstr = "NMI not available for";
	if (request_irq(hp_sdc.nmi, &hp_sdc_nmisr, IRQF_SHARED,
		"HP SDC NMI", &hp_sdc)) goto err2;
			"HP SDC NMI", &hp_sdc))
		goto err2;

	printk(KERN_INFO PREFIX "HP SDC at 0x%p, IRQ %d (NMI IRQ %d)\n",
	       (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi);
@@ -861,6 +913,7 @@ static int __init hp_sdc_init(void)
	printk(KERN_WARNING PREFIX ": %s SDC IO=0x%p IRQ=0x%x NMI=0x%x\n",
		errstr, (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi);
	hp_sdc.dev = NULL;

	return hp_sdc.dev_err;
}

@@ -868,8 +921,10 @@ static int __init hp_sdc_init(void)

static int __init hp_sdc_init_hppa(struct parisc_device *d)
{
	if (!d) return 1;
	if (hp_sdc.dev != NULL) return 1;	/* We only expect one SDC */
	if (!d)
		return 1;
	if (hp_sdc.dev != NULL)
		return 1;	/* We only expect one SDC */

	hp_sdc.dev		= d;
	hp_sdc.irq		= d->irq;
@@ -906,8 +961,6 @@ static void hp_sdc_exit(void)

	tasklet_kill(&hp_sdc.task);

/*        release_region(hp_sdc.data_io, 2); */

#if defined(__hppa__)
	if (unregister_parisc_driver(&hp_sdc_driver))
		printk(KERN_WARNING PREFIX "Error unregistering HP SDC");
@@ -979,7 +1032,7 @@ static int __init hp_sdc_register(void)
	}
	hp_sdc.r11 = tq_init_seq[4];
	if (hp_sdc.r11 & HP_SDC_CFG_NEW) {
		char *str;
		const char *str;
		printk(KERN_INFO PREFIX "New style SDC\n");
		tq_init_seq[1] = HP_SDC_CMD_READ_XTD;
		tq_init.actidx		= 0;
@@ -995,12 +1048,10 @@ static int __init hp_sdc_register(void)
		hp_sdc.r7e = tq_init_seq[4];
		HP_SDC_XTD_REV_STRINGS(hp_sdc.r7e & HP_SDC_XTD_REV, str)
		printk(KERN_INFO PREFIX "Revision: %s\n", str);
		if (hp_sdc.r7e & HP_SDC_XTD_BEEPER) {
		if (hp_sdc.r7e & HP_SDC_XTD_BEEPER)
			printk(KERN_INFO PREFIX "TI SN76494 beeper present\n");
		}
		if (hp_sdc.r7e & HP_SDC_XTD_BBRTC) {
		if (hp_sdc.r7e & HP_SDC_XTD_BBRTC)
			printk(KERN_INFO PREFIX "OKI MSM-58321 BBRTC present\n");
		}
		printk(KERN_INFO PREFIX "Spunking the self test register to force PUP "
		       "on next firmware reset.\n");
		tq_init_seq[0] = HP_SDC_ACT_PRECMD |
@@ -1015,11 +1066,9 @@ static int __init hp_sdc_register(void)
		hp_sdc_enqueue_transaction(&tq_init);
		down(&tq_init_sem);
		up(&tq_init_sem);
	}
	else {
	} else
		printk(KERN_INFO PREFIX "Old style SDC (1820-%s).\n",
		       (hp_sdc.r11 & HP_SDC_CFG_REV) ? "3300" : "2564/3087");
	}

        return 0;
}
+117 −110

File changed.

Preview size limit exceeded, changes collapsed.