Exemplo n.º 1
0
static irqreturn_t i2c_vr_handler(int this_irq, void *dev_id,
				  struct pt_regs *pt_regs)
{
	struct vr_i2c *i2cs = dev_id;
	u32 isr[I2C_VR_ADAP_NR];
	int i;

	isr[0] = readl(&i2cs[0].regs->isr);
	isr[1] = readl(&i2cs[1].regs->isr);

	if (!(isr[0] & I2C_ISR_IRQ) && !(isr[1] & I2C_ISR_IRQ)) {
		/*
		 * This isn't our interrupt.  It must be for another device
		 * sharing this IRQ.
		 */
		return IRQ_NONE;
	}

	for (i = 0; i < I2C_VR_ADAP_NR; i++) {
		struct vr_i2c *i2c = &i2cs[i];
		struct i2c_vr_regs __iomem *regs = i2c->regs;

		if (!(isr[i] & I2C_ISR_IRQ))
			continue;

		if (i2c_debug > 2) {
			dev_dbg(&i2c->adap.dev,
				"%s: ISR=%08x, ICR=%08x, IBMR=%02x\n",
				__func__, isr[i], readl(&regs->icr),
				readl(&regs->ibmr));
			decode_ISR(isr[i]);
			decode_ICR(readl(&regs->icr));
		}

		if (i2c->irqlogidx < ARRAY_SIZE(i2c->isrlog))
			i2c->isrlog[i2c->irqlogidx++] = isr[i];

		show_state(i2c);

		/*
		* Always clear all pending IRQs.
		*/
		writel(isr[i] & I2C_ISR_IRQ, &regs->isr);

		if (i2c->msg) {
			if (isr[i] & ISR_ITE)
				i2c_vr_irq_txempty(i2c, isr[i]);
			if (isr[i] & ISR_IRF)
				i2c_vr_irq_rxfull(i2c, isr[i]);
		} else {
			i2c_vr_scream_blue_murder(i2c, "spurious irq");
		}
	}

	return IRQ_HANDLED;
}
Exemplo n.º 2
0
static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id)
{
	struct pxa_i2c *i2c = dev_id;
	u32 isr = readl(_ISR(i2c));

	if (i2c_debug > 2 && 0) {
		dev_dbg(&i2c->adap.dev, "%s: ISR=%08x, ICR=%08x, IBMR=%02x\n",
			__func__, isr, readl(_ICR(i2c)), readl(_IBMR(i2c)));
		decode_ISR(isr);
	}

	if (i2c->irqlogidx < ARRAY_SIZE(i2c->isrlog))
		i2c->isrlog[i2c->irqlogidx++] = isr;

	show_state(i2c);

	/*
	 * Always clear all pending IRQs.
	 */
	writel(isr & (ISR_SSD|ISR_ALD|ISR_ITE|ISR_IRF|ISR_SAD|ISR_BED), _ISR(i2c));

	if (isr & ISR_SAD)
		i2c_pxa_slave_start(i2c, isr);
	if (isr & ISR_SSD)
		i2c_pxa_slave_stop(i2c);

	if (i2c_pxa_is_slavemode(i2c)) {
		if (isr & ISR_ITE)
			i2c_pxa_slave_txempty(i2c, isr);
		if (isr & ISR_IRF)
			i2c_pxa_slave_rxfull(i2c, isr);
	} else if (i2c->msg) {
		if (isr & ISR_ITE)
			i2c_pxa_irq_txempty(i2c, isr);
		if (isr & ISR_IRF)
			i2c_pxa_irq_rxfull(i2c, isr);
	} else {
		i2c_pxa_scream_blue_murder(i2c, "spurious irq");
	}

	return IRQ_HANDLED;
}