diff options
-rw-r--r-- | drivers/i2c/busses/i2c-designware.c | 39 |
1 files changed, 14 insertions, 25 deletions
diff --git a/drivers/i2c/busses/i2c-designware.c b/drivers/i2c/busses/i2c-designware.c index bfb42f0f87a6..5fce1a07e6c1 100644 --- a/drivers/i2c/busses/i2c-designware.c +++ b/drivers/i2c/busses/i2c-designware.c | |||
@@ -149,7 +149,6 @@ static char *abort_sources[] = { | |||
149 | * @dev: driver model device node | 149 | * @dev: driver model device node |
150 | * @base: IO registers pointer | 150 | * @base: IO registers pointer |
151 | * @cmd_complete: tx completion indicator | 151 | * @cmd_complete: tx completion indicator |
152 | * @pump_msg: continue in progress transfers | ||
153 | * @lock: protect this struct and IO registers | 152 | * @lock: protect this struct and IO registers |
154 | * @clk: input reference clock | 153 | * @clk: input reference clock |
155 | * @cmd_err: run time hadware error code | 154 | * @cmd_err: run time hadware error code |
@@ -175,7 +174,6 @@ struct dw_i2c_dev { | |||
175 | struct device *dev; | 174 | struct device *dev; |
176 | void __iomem *base; | 175 | void __iomem *base; |
177 | struct completion cmd_complete; | 176 | struct completion cmd_complete; |
178 | struct tasklet_struct pump_msg; | ||
179 | struct mutex lock; | 177 | struct mutex lock; |
180 | struct clk *clk; | 178 | struct clk *clk; |
181 | int cmd_err; | 179 | int cmd_err; |
@@ -325,7 +323,7 @@ static int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev) | |||
325 | /* | 323 | /* |
326 | * Initiate low level master read/write transaction. | 324 | * Initiate low level master read/write transaction. |
327 | * This function is called from i2c_dw_xfer when starting a transfer. | 325 | * This function is called from i2c_dw_xfer when starting a transfer. |
328 | * This function is also called from dw_i2c_pump_msg to continue a transfer | 326 | * This function is also called from i2c_dw_isr to continue a transfer |
329 | * that is longer than the size of the TX FIFO. | 327 | * that is longer than the size of the TX FIFO. |
330 | */ | 328 | */ |
331 | static void | 329 | static void |
@@ -489,10 +487,7 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) | |||
489 | 487 | ||
490 | /* no error */ | 488 | /* no error */ |
491 | if (likely(!dev->cmd_err)) { | 489 | if (likely(!dev->cmd_err)) { |
492 | /* read rx fifo, and disable the adapter */ | 490 | /* Disable the adapter */ |
493 | do { | ||
494 | i2c_dw_read(dev); | ||
495 | } while (dev->status & STATUS_READ_IN_PROGRESS); | ||
496 | writel(0, dev->base + DW_IC_ENABLE); | 491 | writel(0, dev->base + DW_IC_ENABLE); |
497 | ret = num; | 492 | ret = num; |
498 | goto done; | 493 | goto done; |
@@ -520,20 +515,6 @@ static u32 i2c_dw_func(struct i2c_adapter *adap) | |||
520 | return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR; | 515 | return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR; |
521 | } | 516 | } |
522 | 517 | ||
523 | static void dw_i2c_pump_msg(unsigned long data) | ||
524 | { | ||
525 | struct dw_i2c_dev *dev = (struct dw_i2c_dev *) data; | ||
526 | u32 intr_mask; | ||
527 | |||
528 | i2c_dw_read(dev); | ||
529 | i2c_dw_xfer_msg(dev); | ||
530 | |||
531 | intr_mask = DW_IC_INTR_STOP_DET | DW_IC_INTR_TX_ABRT; | ||
532 | if (dev->status & STATUS_WRITE_IN_PROGRESS) | ||
533 | intr_mask |= DW_IC_INTR_TX_EMPTY; | ||
534 | writel(intr_mask, dev->base + DW_IC_INTR_MASK); | ||
535 | } | ||
536 | |||
537 | static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev) | 518 | static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev) |
538 | { | 519 | { |
539 | u32 stat; | 520 | u32 stat; |
@@ -604,10 +585,19 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) | |||
604 | if (stat & DW_IC_INTR_TX_ABRT) { | 585 | if (stat & DW_IC_INTR_TX_ABRT) { |
605 | dev->cmd_err |= DW_IC_ERR_TX_ABRT; | 586 | dev->cmd_err |= DW_IC_ERR_TX_ABRT; |
606 | dev->status = STATUS_IDLE; | 587 | dev->status = STATUS_IDLE; |
607 | } else if (stat & DW_IC_INTR_TX_EMPTY) | 588 | } |
608 | tasklet_schedule(&dev->pump_msg); | 589 | |
590 | if (stat & DW_IC_INTR_TX_EMPTY) { | ||
591 | i2c_dw_read(dev); | ||
592 | i2c_dw_xfer_msg(dev); | ||
593 | } | ||
594 | |||
595 | /* | ||
596 | * No need to modify or disable the interrupt mask here. | ||
597 | * i2c_dw_xfer_msg() will take care of it according to | ||
598 | * the current transmit status. | ||
599 | */ | ||
609 | 600 | ||
610 | writel(0, dev->base + DW_IC_INTR_MASK); /* disable interrupts */ | ||
611 | if (stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) | 601 | if (stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) |
612 | complete(&dev->cmd_complete); | 602 | complete(&dev->cmd_complete); |
613 | 603 | ||
@@ -653,7 +643,6 @@ static int __devinit dw_i2c_probe(struct platform_device *pdev) | |||
653 | } | 643 | } |
654 | 644 | ||
655 | init_completion(&dev->cmd_complete); | 645 | init_completion(&dev->cmd_complete); |
656 | tasklet_init(&dev->pump_msg, dw_i2c_pump_msg, (unsigned long) dev); | ||
657 | mutex_init(&dev->lock); | 646 | mutex_init(&dev->lock); |
658 | dev->dev = get_device(&pdev->dev); | 647 | dev->dev = get_device(&pdev->dev); |
659 | dev->irq = irq; | 648 | dev->irq = irq; |