static int msm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { DECLARE_COMPLETION_ONSTACK(complete); struct msm_i2c_dev *dev = i2c_get_adapdata(adap); int ret; int rem = num; uint16_t addr; long timeout; unsigned long flags; while (rem) { addr = msgs->addr << 1; if (msgs->flags & I2C_M_RD) addr |= 1; spin_lock_irqsave(&dev->lock, flags); dev->msg = msgs; dev->pos = 0; dev->err = 0; dev->flush_cnt = 0; dev->cnt = msgs->len; dev->complete = &complete; spin_unlock_irqrestore(&dev->lock, flags); ret = msm_i2c_poll_notbusy(dev); if (ret) { dev_err(dev->dev, "Error waiting for notbusy\n"); goto out_err; } if (rem == 1 && msgs->len == 0) addr |= I2C_WRITE_DATA_LAST_BYTE; /* Wait for WR buffer not full */ ret = msm_i2c_poll_writeready(dev); if (ret) { dev_err(dev->dev, "Error waiting for write ready before addr\n"); goto out_err; } /* special case for doing 1 byte read. * There should be no scheduling between I2C controller becoming * ready to read and writing LAST-BYTE to I2C controller * This will avoid potential of I2C controller starting to latch * another extra byte. */ if ((msgs->len == 1) && (msgs->flags & I2C_M_RD)) { uint32_t retries = 0; spin_lock_irqsave(&dev->lock, flags); writel(I2C_WRITE_DATA_ADDR_BYTE | addr, dev->base + I2C_WRITE_DATA); /* Poll for I2C controller going into RX_DATA mode to * ensure controller goes into receive mode. * Just checking write_buffer_full may not work since * there is delay between the write-buffer becoming * empty and the slave sending ACK to ensure I2C * controller goes in receive mode to receive data. */ while (retries != 2000) { uint32_t status = readl(dev->base + I2C_STATUS); if (status & I2C_STATUS_RX_DATA_STATE) break; retries++; } if (retries >= 2000) { spin_unlock_irqrestore(&dev->lock, flags); dev_err(dev->dev, "Error doing one byte read\n"); goto out_err; } writel(I2C_WRITE_DATA_LAST_BYTE, dev->base + I2C_WRITE_DATA); spin_unlock_irqrestore(&dev->lock, flags); } else { writel(I2C_WRITE_DATA_ADDR_BYTE | addr, dev->base + I2C_WRITE_DATA); } /* Polling and waiting for write_buffer_empty is not necessary. * Even worse, if we do, it can result in invalid status and * error if interrupt(s) occur while polling. */ /* * Now that we've setup the xfer, the ISR will transfer the data * and wake us up with dev->err set if there was an error */ /* * Added by M4MO Camera module timeout error */ #if defined(CONFIG_SAMSUNG_M4MO) timeout = wait_for_completion_timeout(&complete, 200 * HZ); #else timeout = wait_for_completion_timeout(&complete, HZ); #endif if (!timeout) { dev_err(dev->dev, "Transaction timed out\n"); writel(I2C_WRITE_DATA_LAST_BYTE, dev->base + I2C_WRITE_DATA); msleep(100); /* FLUSH */ readl(dev->base + I2C_READ_DATA); readl(dev->base + I2C_STATUS); ret = -ETIMEDOUT; goto out_err; } if (dev->err) { dev_err(dev->dev, "Error during data xfer (%d)\n", dev->err); ret = dev->err; goto out_err; } msgs++; rem--; } ret = num; out_err: spin_lock_irqsave(&dev->lock, flags); dev->complete = NULL; dev->msg = NULL; dev->pos = 0; dev->err = 0; dev->flush_cnt = 0; dev->cnt = 0; spin_unlock_irqrestore(&dev->lock, flags); return ret; }
static int msm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { DECLARE_COMPLETION_ONSTACK(complete); struct msm_i2c_dev *dev = i2c_get_adapdata(adap); int ret; int rem = num; uint16_t addr; long timeout; unsigned long flags; int check_busy = 1; mutex_lock(&dev->mlock); if (dev->suspended) { mutex_unlock(&dev->mlock); return -EIO; } /* Don't allow power collapse until we release remote spinlock */ pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, "msm_i2c", dev->pdata->pm_lat); msm_i2c_rmutex_lock(dev); if (adap == &dev->adap_pri) writel(0, dev->base + I2C_INTERFACE_SELECT); else writel(I2C_INTERFACE_SELECT_INTF_SELECT, dev->base + I2C_INTERFACE_SELECT); enable_irq(dev->irq); while (rem) { addr = msgs->addr << 1; if (msgs->flags & I2C_M_RD) addr |= 1; spin_lock_irqsave(&dev->lock, flags); dev->msg = msgs; dev->rem = rem; dev->pos = 0; dev->err = 0; dev->flush_cnt = 0; dev->cnt = msgs->len; dev->complete = &complete; spin_unlock_irqrestore(&dev->lock, flags); if (check_busy) { ret = msm_i2c_poll_notbusy(dev); if (ret) ret = msm_i2c_recover_bus_busy(dev, adap); if (ret) { dev_err(dev->dev, "Error waiting for notbusy\n"); goto out_err; } check_busy = 0; } if (rem == 1 && msgs->len == 0) addr |= I2C_WRITE_DATA_LAST_BYTE; /* Wait for WR buffer not full */ ret = msm_i2c_poll_writeready(dev); if (ret) { ret = msm_i2c_recover_bus_busy(dev, adap); if (ret) { dev_err(dev->dev, "Error waiting for write ready before addr\n"); goto out_err; } } /* special case for doing 1 byte read. * There should be no scheduling between I2C controller becoming * ready to read and writing LAST-BYTE to I2C controller * This will avoid potential of I2C controller starting to latch * another extra byte. */ if ((msgs->len == 1) && (msgs->flags & I2C_M_RD)) { uint32_t retries = 0; spin_lock_irqsave(&dev->lock, flags); writel(I2C_WRITE_DATA_ADDR_BYTE | addr, dev->base + I2C_WRITE_DATA); /* Poll for I2C controller going into RX_DATA mode to * ensure controller goes into receive mode. * Just checking write_buffer_full may not work since * there is delay between the write-buffer becoming * empty and the slave sending ACK to ensure I2C * controller goes in receive mode to receive data. */ while (retries != 2000) { uint32_t status = readl(dev->base + I2C_STATUS); if ((status & I2C_STATUS_RX_DATA_STATE) == I2C_STATUS_RX_DATA_STATE) break; retries++; } if (retries >= 2000) { dev->rd_acked = 0; spin_unlock_irqrestore(&dev->lock, flags); /* 1-byte-reads from slow devices in interrupt * context */ goto wait_for_int; } dev->rd_acked = 1; writel(I2C_WRITE_DATA_LAST_BYTE, dev->base + I2C_WRITE_DATA); spin_unlock_irqrestore(&dev->lock, flags); } else { writel(I2C_WRITE_DATA_ADDR_BYTE | addr, dev->base + I2C_WRITE_DATA); } /* Polling and waiting for write_buffer_empty is not necessary. * Even worse, if we do, it can result in invalid status and * error if interrupt(s) occur while polling. */ /* * Now that we've setup the xfer, the ISR will transfer the data * and wake us up with dev->err set if there was an error */ wait_for_int: timeout = wait_for_completion_timeout(&complete, HZ); if (!timeout) { dev_err(dev->dev, "Transaction timed out\n"); writel(I2C_WRITE_DATA_LAST_BYTE, dev->base + I2C_WRITE_DATA); msleep(100); /* FLUSH */ readl(dev->base + I2C_READ_DATA); readl(dev->base + I2C_STATUS); ret = -ETIMEDOUT; goto out_err; } if (dev->err) { dev_err(dev->dev, "Error during data xfer (%d)\n", dev->err); ret = dev->err; goto out_err; } if (msgs->flags & I2C_M_RD) check_busy = 1; msgs++; rem--; } ret = num; out_err: spin_lock_irqsave(&dev->lock, flags); dev->complete = NULL; dev->msg = NULL; dev->rem = 0; dev->pos = 0; dev->err = 0; dev->flush_cnt = 0; dev->cnt = 0; spin_unlock_irqrestore(&dev->lock, flags); disable_irq(dev->irq); msm_i2c_rmutex_unlock(dev); pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, "msm_i2c", PM_QOS_DEFAULT_VALUE); mutex_unlock(&dev->mlock); return ret; }
static int msm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { DECLARE_COMPLETION_ONSTACK(complete); struct msm_i2c_dev *dev = i2c_get_adapdata(adap); int ret; long timeout; unsigned long flags; /* * If there is an i2c_xfer after driver has been suspended, * grab wakelock to abort suspend. */ if (dev->is_suspended) wake_lock(&dev->wakelock); clk_enable(dev->clk); enable_irq(dev->irq); ret = msm_i2c_poll_notbusy(dev, 1); if (ret) { dev_err(dev->dev, "Still busy in starting xfer(%02X)\n", msgs->addr); if (!dev->skip_recover) { ret = msm_i2c_recover_bus_busy(dev); if (ret) goto err; } } spin_lock_irqsave(&dev->lock, flags); if (dev->flush_cnt) { dev_warn(dev->dev, "%d unrequested bytes read\n", dev->flush_cnt); } dev->msg = msgs; dev->rem = num; dev->pos = -1; dev->ret = num; dev->need_flush = false; dev->flush_cnt = 0; dev->cnt = msgs->len; dev->complete = &complete; msm_i2c_interrupt_locked(dev); spin_unlock_irqrestore(&dev->lock, flags); /* * Now that we've setup the xfer, the ISR will transfer the data * and wake us up with dev->err set if there was an error */ timeout = wait_for_completion_timeout(&complete, HZ); if (msm_i2c_poll_notbusy(dev, 0)) /* Read may not have stopped in time */ dev_err(dev->dev, "Still busy after xfer completion (%02X)\n", msgs->addr); spin_lock_irqsave(&dev->lock, flags); if (dev->flush_cnt) { dev_warn(dev->dev, "%d unrequested bytes read\n", dev->flush_cnt); } ret = dev->ret; dev->complete = NULL; dev->msg = NULL; dev->rem = 0; dev->pos = 0; dev->ret = 0; dev->flush_cnt = 0; dev->cnt = 0; spin_unlock_irqrestore(&dev->lock, flags); if (!timeout) { dev_err(dev->dev, "Transaction timed out\n"); ret = -ETIMEDOUT; } if (ret < 0) { dev_err(dev->dev, "Error during data xfer (%d) (%02X)\n", ret, msgs->addr); if (!dev->skip_recover) msm_i2c_recover_bus_busy(dev); } err: disable_irq(dev->irq); clk_disable(dev->clk); if (dev->is_suspended) wake_unlock(&dev->wakelock); return ret; }
int msm_i2c_xfer(struct i2c_msg msgs[], int num) { int ret, ret_wait; clk_enable(dev.pdata->clk_nr); unmask_interrupt(dev.pdata->irq_nr); ret = msm_i2c_poll_notbusy(1); if (ret) { ret = msm_i2c_recover_bus_busy(); if (ret) goto err; } enter_critical_section(); if (dev.flush_cnt) { I2C_DBG(DEBUGLEVEL, "%d unrequested bytes read\n", dev.flush_cnt); } dev.msg = msgs; dev.rem = num; dev.pos = -1; dev.ret = num; dev.need_flush = false; dev.flush_cnt = 0; dev.cnt = msgs->len; msm_i2c_interrupt_locked(); exit_critical_section(); /* * Now that we've setup the xfer, the ISR will transfer the data * and wake us up with dev.err set if there was an error */ ret_wait = msm_i2c_poll_notbusy(0); /* Read may not have stopped in time */ enter_critical_section(); if (dev.flush_cnt) { I2C_DBG(DEBUGLEVEL, "%d unrequested bytes read\n", dev.flush_cnt); } ret = dev.ret; dev.msg = NULL; dev.rem = 0; dev.pos = 0; dev.ret = 0; dev.flush_cnt = 0; dev.cnt = 0; exit_critical_section(); if (ret_wait) { I2C_DBG(DEBUGLEVEL, "Still busy after xfer completion\n"); ret_wait = msm_i2c_recover_bus_busy(); if (ret_wait) goto err; } if (timeout == ERR_TIMED_OUT) { I2C_DBG(DEBUGLEVEL, "Transaction timed out\n"); ret = ERR_TIMED_OUT; } if (ret < 0) { I2C_ERR("Error during data xfer (%d)\n", ret); msm_i2c_recover_bus_busy(); } /* if (timeout == ERR_TIMED_OUT) { I2C_DBG(DEBUGLEVEL, "Transaction timed out\n"); ret = 2; msm_i2c_recover_bus_busy(); } if (timeout == ERR_TIMED_OUT) { I2C_DBG(DEBUGLEVEL, "Transaction timed out\n"); ret = ERR_TIMED_OUT; } if (ret < 0) { I2C_ERR("Error during data xfer (%d)\n", ret); msm_i2c_recover_bus_busy(); } */ err: mask_interrupt(dev.pdata->irq_nr); clk_disable(dev.pdata->clk_nr); return ret; }