Example #1
0
/*
 * clear the hold on the bus, and take of anything else
 * that has been configured
 */
static void i2c_pxa_set_slave(struct pxa_i2c *i2c, int errcode)
{
	show_state(i2c);

	if (errcode < 0) {
		udelay(100);   /* simple delay */
	} else {
		/* we need to wait for the stop condition to end */

		/* if we where in stop, then clear... */
		if (readl(_ICR(i2c)) & ICR_STOP) {
			udelay(100);
			writel(readl(_ICR(i2c)) & ~ICR_STOP, _ICR(i2c));
		}

		if (!i2c_pxa_wait_slave(i2c)) {
			dev_err(&i2c->adap.dev, "%s: wait timedout\n",
				__func__);
			return;
		}
	}

	writel(readl(_ICR(i2c)) & ~(ICR_STOP|ICR_ACKNAK|ICR_MA), _ICR(i2c));
	writel(readl(_ICR(i2c)) & ~ICR_SCLE, _ICR(i2c));

	if (i2c_debug) {
		dev_dbg(&i2c->adap.dev, "ICR now %08x, ISR %08x\n", readl(_ICR(i2c)), readl(_ISR(i2c)));
		decode_ICR(readl(_ICR(i2c)));
	}
}
Example #2
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;
}