diff options
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-msm-v2.c | 68 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-piix4.c | 2 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-tiny-usb.c | 25 |
3 files changed, 56 insertions, 39 deletions
diff --git a/drivers/i2c/busses/i2c-msm-v2.c b/drivers/i2c/busses/i2c-msm-v2.c index 7f98d9f527b9..f4ed71f9c1a7 100644 --- a/drivers/i2c/busses/i2c-msm-v2.c +++ b/drivers/i2c/busses/i2c-msm-v2.c @@ -1310,7 +1310,8 @@ static int i2c_msm_dma_xfer_process(struct i2c_msm_ctrl *ctrl) ret = i2c_msm_xfer_wait_for_completion(ctrl, &ctrl->xfer.complete); if (!ret && ctrl->xfer.rx_cnt) - i2c_msm_xfer_wait_for_completion(ctrl, &ctrl->xfer.rx_complete); + ret = i2c_msm_xfer_wait_for_completion(ctrl, + &ctrl->xfer.rx_complete); dma_xfer_end: /* free scatter-gather lists */ @@ -1716,9 +1717,7 @@ static irqreturn_t i2c_msm_qup_isr(int irq, void *devid) void __iomem *base = ctrl->rsrcs.base; struct i2c_msm_xfer *xfer = &ctrl->xfer; struct i2c_msm_xfer_mode_blk *blk = &ctrl->xfer.blk; - u32 i2c_status = 0; u32 err_flags = 0; - u32 qup_op = 0; u32 clr_flds = 0; bool log_event = false; bool signal_complete = false; @@ -1731,24 +1730,24 @@ static irqreturn_t i2c_msm_qup_isr(int irq, void *devid) return IRQ_HANDLED; } - i2c_status = readl_relaxed(base + QUP_I2C_STATUS); - err_flags = readl_relaxed(base + QUP_ERROR_FLAGS); - qup_op = readl_relaxed(base + QUP_OPERATIONAL); + ctrl->i2c_sts_reg = readl_relaxed(base + QUP_I2C_STATUS); + err_flags = readl_relaxed(base + QUP_ERROR_FLAGS); + ctrl->qup_op_reg = readl_relaxed(base + QUP_OPERATIONAL); - if (i2c_status & QUP_MSTR_STTS_ERR_MASK) { + if (ctrl->i2c_sts_reg & QUP_MSTR_STTS_ERR_MASK) { signal_complete = true; log_event = true; /* * If there is more than 1 error here, last one sticks. * The order of the error set here matters. */ - if (i2c_status & QUP_ARB_LOST) + if (ctrl->i2c_sts_reg & QUP_ARB_LOST) ctrl->xfer.err = I2C_MSM_ERR_ARB_LOST; - if (i2c_status & QUP_BUS_ERROR) + if (ctrl->i2c_sts_reg & QUP_BUS_ERROR) ctrl->xfer.err = I2C_MSM_ERR_BUS_ERR; - if (i2c_status & QUP_PACKET_NACKED) + if (ctrl->i2c_sts_reg & QUP_PACKET_NACKED) ctrl->xfer.err = I2C_MSM_ERR_NACK; } @@ -1761,7 +1760,7 @@ static irqreturn_t i2c_msm_qup_isr(int irq, void *devid) i2c_msm_dbg_qup_reg_dump(ctrl); /* clear interrupts fields */ - clr_flds = i2c_status & QUP_MSTR_STTS_ERR_MASK; + clr_flds = ctrl->i2c_sts_reg & QUP_MSTR_STTS_ERR_MASK; if (clr_flds) { writel_relaxed(clr_flds, base + QUP_I2C_STATUS); need_wmb = true; @@ -1773,7 +1772,9 @@ static irqreturn_t i2c_msm_qup_isr(int irq, void *devid) need_wmb = true; } - clr_flds = qup_op & (QUP_OUTPUT_SERVICE_FLAG | QUP_INPUT_SERVICE_FLAG); + clr_flds = ctrl->qup_op_reg & + (QUP_OUTPUT_SERVICE_FLAG | + QUP_INPUT_SERVICE_FLAG); if (clr_flds) { writel_relaxed(clr_flds, base + QUP_OPERATIONAL); need_wmb = true; @@ -1814,25 +1815,25 @@ static irqreturn_t i2c_msm_qup_isr(int irq, void *devid) /* handle data completion */ if (xfer->mode_id == I2C_MSM_XFER_MODE_BLOCK) { /* block ready for writing */ - if (qup_op & QUP_OUTPUT_SERVICE_FLAG) { + if (ctrl->qup_op_reg & QUP_OUTPUT_SERVICE_FLAG) { log_event = true; - if (qup_op & QUP_OUT_BLOCK_WRITE_REQ) + if (ctrl->qup_op_reg & QUP_OUT_BLOCK_WRITE_REQ) complete(&blk->wait_tx_blk); - if ((qup_op & blk->complete_mask) + if ((ctrl->qup_op_reg & blk->complete_mask) == blk->complete_mask) { log_event = true; signal_complete = true; } } /* block ready for reading */ - if (qup_op & QUP_INPUT_SERVICE_FLAG) { + if (ctrl->qup_op_reg & QUP_INPUT_SERVICE_FLAG) { log_event = true; complete(&blk->wait_rx_blk); } } else { /* for FIFO/DMA Mode*/ - if (qup_op & QUP_MAX_INPUT_DONE_FLAG) { + if (ctrl->qup_op_reg & QUP_MAX_INPUT_DONE_FLAG) { log_event = true; /* * If last transaction is an input then the entire @@ -1850,7 +1851,7 @@ static irqreturn_t i2c_msm_qup_isr(int irq, void *devid) * here QUP_OUTPUT_SERVICE_FLAG and assumes that * QUP_MAX_OUTPUT_DONE_FLAG. */ - if (qup_op & (QUP_OUTPUT_SERVICE_FLAG | + if (ctrl->qup_op_reg & (QUP_OUTPUT_SERVICE_FLAG | QUP_MAX_OUTPUT_DONE_FLAG)) { log_event = true; /* @@ -1863,13 +1864,11 @@ static irqreturn_t i2c_msm_qup_isr(int irq, void *devid) } isr_end: - if (ctrl->xfer.err || (ctrl->dbgfs.dbg_lvl >= MSM_DBG)) - i2c_msm_dbg_dump_diag(ctrl, true, i2c_status, qup_op); - if (log_event || (ctrl->dbgfs.dbg_lvl >= MSM_DBG)) i2c_msm_prof_evnt_add(ctrl, MSM_PROF, I2C_MSM_IRQ_END, - i2c_status, qup_op, err_flags); + ctrl->i2c_sts_reg, ctrl->qup_op_reg, + err_flags); if (signal_complete) complete(&ctrl->xfer.complete); @@ -2078,8 +2077,12 @@ static int i2c_msm_xfer_wait_for_completion(struct i2c_msm_ctrl *ctrl, xfer->timeout, time_left, 0); } else { /* return an error if one detected by ISR */ - if (xfer->err) + if (ctrl->xfer.err || + (ctrl->dbgfs.dbg_lvl >= MSM_DBG)) { + i2c_msm_dbg_dump_diag(ctrl, true, + ctrl->i2c_sts_reg, ctrl->qup_op_reg); ret = -(xfer->err); + } i2c_msm_prof_evnt_add(ctrl, MSM_DBG, I2C_MSM_COMPLT_OK, xfer->timeout, time_left, 0); } @@ -2229,19 +2232,8 @@ static int i2c_msm_pm_clk_enable(struct i2c_msm_ctrl *ctrl) static int i2c_msm_pm_xfer_start(struct i2c_msm_ctrl *ctrl) { int ret; - struct i2c_msm_xfer *xfer = &ctrl->xfer; mutex_lock(&ctrl->xfer.mtx); - /* if system is suspended just bail out */ - if (ctrl->pwr_state == I2C_MSM_PM_SYS_SUSPENDED) { - struct i2c_msg *msgs = xfer->msgs + xfer->cur_buf.msg_idx; - dev_err(ctrl->dev, - "slave:0x%x is calling xfer when system is suspended\n", - msgs->addr); - mutex_unlock(&ctrl->xfer.mtx); - return -EIO; - } - i2c_msm_pm_pinctrl_state(ctrl, true); pm_runtime_get_sync(ctrl->dev); /* @@ -2327,6 +2319,14 @@ i2c_msm_frmwrk_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) return PTR_ERR(msgs); } + /* if system is suspended just bail out */ + if (ctrl->pwr_state == I2C_MSM_PM_SYS_SUSPENDED) { + dev_err(ctrl->dev, + "slave:0x%x is calling xfer when system is suspended\n", + msgs->addr); + return -EIO; + } + ret = i2c_msm_pm_xfer_start(ctrl); if (ret) return ret; diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 630bce68bf38..b61db9db3ca5 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -54,7 +54,7 @@ #define SMBSLVDAT (0xC + piix4_smba) /* count for request_region */ -#define SMBIOSIZE 8 +#define SMBIOSIZE 9 /* PCI Address Constants */ #define SMBBA 0x090 diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c index 0ed77eeff31e..a2e3dd715380 100644 --- a/drivers/i2c/busses/i2c-tiny-usb.c +++ b/drivers/i2c/busses/i2c-tiny-usb.c @@ -178,22 +178,39 @@ static int usb_read(struct i2c_adapter *adapter, int cmd, int value, int index, void *data, int len) { struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data; + void *dmadata = kmalloc(len, GFP_KERNEL); + int ret; + + if (!dmadata) + return -ENOMEM; /* do control transfer */ - return usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0), + ret = usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0), cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | - USB_DIR_IN, value, index, data, len, 2000); + USB_DIR_IN, value, index, dmadata, len, 2000); + + memcpy(data, dmadata, len); + kfree(dmadata); + return ret; } static int usb_write(struct i2c_adapter *adapter, int cmd, int value, int index, void *data, int len) { struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data; + void *dmadata = kmemdup(data, len, GFP_KERNEL); + int ret; + + if (!dmadata) + return -ENOMEM; /* do control transfer */ - return usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0), + ret = usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0), cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - value, index, data, len, 2000); + value, index, dmadata, len, 2000); + + kfree(dmadata); + return ret; } static void i2c_tiny_usb_free(struct i2c_tiny_usb *dev) |