diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-mxs.c')
-rw-r--r-- | drivers/i2c/busses/i2c-mxs.c | 45 |
1 files changed, 16 insertions, 29 deletions
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 8bb795e7d7b2..e3235ff8e551 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -68,19 +68,10 @@ static u8 *i2c_buf_virt; static void hw_i2c_dmachan_reset(struct mxs_i2c_dev *dev) { - mxs_dma_disable(dev->dma_chan); mxs_dma_reset(dev->dma_chan); mxs_dma_ack_irq(dev->dma_chan); } -static mxs_i2c_reset(struct mxs_i2c_dev *mxs_i2c) -{ - hw_i2c_dmachan_reset(mxs_i2c); - mxs_dma_enable_irq(mxs_i2c->dma_chan, 1); - mxs_reset_block((void __iomem *)mxs_i2c->regbase, 0); - __raw_writel(0x0000FF00, mxs_i2c->regbase + HW_I2C_CTRL1_SET); -} - static int hw_i2c_dma_init(struct platform_device *pdev) { struct mxs_i2c_dev *mxs_i2c = platform_get_drvdata(pdev); @@ -168,7 +159,7 @@ static void hw_i2c_dma_setup_read(u8 addr, void *buff, int len, int flags) desc[0]->cmd.cmd.bits.pio_words = 1; desc[0]->cmd.cmd.bits.wait4end = 1; desc[0]->cmd.cmd.bits.dec_sem = 1; - desc[0]->cmd.cmd.bits.irq = 0; + desc[0]->cmd.cmd.bits.irq = 1; desc[0]->cmd.cmd.bits.chain = 1; desc[0]->cmd.cmd.bits.command = DMA_READ; desc[0]->cmd.address = i2c_buf_phys; @@ -328,7 +319,6 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, msecs_to_jiffies(1000) ); if (err <= 0) { - mxs_i2c_reset(dev); dev_dbg(dev->dev, "controller is timed out\n"); return -ETIMEDOUT; } @@ -375,19 +365,9 @@ static irqreturn_t mxs_i2c_dma_isr(int this_irq, void *dev_id) mxs_dma_ack_irq(mxs_i2c->dma_chan); mxs_dma_cooked(mxs_i2c->dma_chan, &list); - complete(&mxs_i2c->cmd_complete); - return IRQ_HANDLED; } -static void mxs_i2c_task(struct work_struct *work) -{ - struct mxs_i2c_dev *mxs_i2c = container_of(work, - struct mxs_i2c_dev, work); - mxs_i2c_reset(mxs_i2c); - complete(&mxs_i2c->cmd_complete); -} - #define I2C_IRQ_MASK 0x000000FF static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) { @@ -402,8 +382,20 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) if (stat & BM_I2C_CTRL1_NO_SLAVE_ACK_IRQ) { mxs_i2c->cmd_err = -EREMOTEIO; - /* it takes long time to reset i2c */ - schedule_work(&mxs_i2c->work); + + /* + * Stop DMA + * Clear NAK + */ + __raw_writel(BM_I2C_CTRL1_CLR_GOT_A_NAK, + mxs_i2c->regbase + HW_I2C_CTRL1_SET); + hw_i2c_dmachan_reset(mxs_i2c); + mxs_reset_block((void __iomem *)mxs_i2c->regbase, 1); + /* Will catch all error (IRQ mask) */ + __raw_writel(0x0000FF00, mxs_i2c->regbase + HW_I2C_CTRL1_SET); + + complete(&mxs_i2c->cmd_complete); + goto done; } @@ -415,10 +407,7 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) complete(&mxs_i2c->cmd_complete); goto done; } - - if ((stat & done_mask) == done_mask && - (mxs_i2c->flags & MXS_I2C_PIOQUEUE_MODE)) - + if ((stat & done_mask) == done_mask) complete(&mxs_i2c->cmd_complete); done: @@ -535,8 +524,6 @@ static int mxs_i2c_probe(struct platform_device *pdev) } - INIT_WORK(&mxs_i2c->work, mxs_i2c_task); - return 0; no_i2c_adapter: |