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

Commit 6d9939f6 authored by Felipe Balbi's avatar Felipe Balbi Committed by Wolfram Sang
Browse files

i2c: omap: split out [XR]DR and [XR]RDY



While they do pretty much the same thing, there
are a few peculiarities. Specially WRT erratas,
it's best to split those out and re-factor the
read/write loop to another function which both
cases call.

This last part will be done on another patch.

While at that, also avoid an unncessary register
read since dev->fifo_len will always contain the
correct amount of data to be transferred.

Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
Signed-off-by: default avatarShubhrajyoti D <shubhrajyoti@ti.com>
Signed-off-by: default avatarWolfram Sang <w.sang@pengutronix.de>
parent 540a4790
Loading
Loading
Loading
Loading
+92 −34
Original line number Diff line number Diff line
@@ -801,36 +801,62 @@ omap_i2c_isr(int this_irq, void *dev_id)
			return IRQ_HANDLED;
		}

		if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) {
		if (stat & OMAP_I2C_STAT_RDR) {
			u8 num_bytes = 1;

			if (dev->fifo_size)
				num_bytes = dev->buf_len;

			while (num_bytes--) {
				if (!dev->buf_len) {
					dev_err(dev->dev,
							"RDR IRQ while no data"
							" requested\n");
					break;
				}

				w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
				*dev->buf++ = w;
				dev->buf_len--;

				/*
				 * Data reg in 2430, omap3 and
				 * omap4 is 8 bit wide
				 */
				if (dev->flags &
						OMAP_I2C_FLAG_16BIT_DATA_REG) {
					if (dev->buf_len) {
						*dev->buf++ = w >> 8;
						dev->buf_len--;
					}
				}
			}

			if (dev->errata & I2C_OMAP_ERRATA_I207)
				i2c_omap_errata_i207(dev, stat);

			if (dev->fifo_size) {
				if (stat & OMAP_I2C_STAT_RRDY)
					num_bytes = dev->fifo_size;
				else    /* read RXSTAT on RDR interrupt */
					num_bytes = (omap_i2c_read_reg(dev,
							OMAP_I2C_BUFSTAT_REG)
							>> 8) & 0x3F;
			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR);
			continue;
		}

		if (stat & OMAP_I2C_STAT_RRDY) {
			u8 num_bytes = 1;

			if (dev->fifo_size)
				num_bytes = dev->fifo_size;

			while (num_bytes--) {
				if (!dev->buf_len) {
					if (stat & OMAP_I2C_STAT_RRDY)
					dev_err(dev->dev,
							"RRDY IRQ while no data"
							" requested\n");
					if (stat & OMAP_I2C_STAT_RDR)
						dev_err(dev->dev,
							"RDR IRQ while no data"
								" requested\n");
					break;
				}

				w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
				*dev->buf++ = w;
				dev->buf_len--;

				/*
				 * Data reg in 2430, omap3 and
				 * omap4 is 8 bit wide
@@ -843,36 +869,68 @@ omap_i2c_isr(int this_irq, void *dev_id)
					}
				}
			}
			omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY |
						OMAP_I2C_STAT_RDR));

			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RRDY);
			continue;
		}

		if (stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)) {
		if (stat & OMAP_I2C_STAT_XDR) {
			u8 num_bytes = 1;
			if (dev->fifo_size) {
				if (stat & OMAP_I2C_STAT_XRDY)
					num_bytes = dev->fifo_size;
				else    /* read TXSTAT on XDR interrupt */
					num_bytes = omap_i2c_read_reg(dev,
							OMAP_I2C_BUFSTAT_REG)
							& 0x3F;
			}

			if (dev->fifo_size)
				num_bytes = dev->buf_len;

			while (num_bytes--) {
				if (!dev->buf_len) {
					if (stat & OMAP_I2C_STAT_XRDY)
					dev_err(dev->dev,
							"XRDY IRQ while no "
							"XDR IRQ while no "
							"data to send\n");
					if (stat & OMAP_I2C_STAT_XDR)
					break;
				}

				w = *dev->buf++;
				dev->buf_len--;

				/*
				 * Data reg in 2430, omap3 and
				 * omap4 is 8 bit wide
				 */
				if (dev->flags &
						OMAP_I2C_FLAG_16BIT_DATA_REG) {
					if (dev->buf_len) {
						w |= *dev->buf++ << 8;
						dev->buf_len--;
					}
				}

				if ((dev->errata & I2C_OMAP_ERRATA_I462) &&
				    errata_omap3_i462(dev, &stat, &err))
					goto complete;

				omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
			}

			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XDR);
			continue;
		}

		if (stat & OMAP_I2C_STAT_XRDY) {
			u8 num_bytes = 1;

			if (dev->fifo_size)
				num_bytes = dev->fifo_size;

			while (num_bytes--) {
				if (!dev->buf_len) {
					dev_err(dev->dev,
							"XDR IRQ while no "
							"XRDY IRQ while no "
							"data to send\n");
					break;
				}

				w = *dev->buf++;
				dev->buf_len--;

				/*
				 * Data reg in 2430, omap3 and
				 * omap4 is 8 bit wide
@@ -891,8 +949,8 @@ omap_i2c_isr(int this_irq, void *dev_id)

				omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
			}
			omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
						OMAP_I2C_STAT_XDR));

			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XRDY);
			continue;
		}