Skip to content

Commit

Permalink
i2c-designware: Tx abort cleanups
Browse files Browse the repository at this point in the history
* ABRT_MASTER_DIS: Fix a typo.

* i2c_dw_handle_tx_abort: Return an appropriate error number
  depending on abort_source.

* i2c_dw_xfer: Add a missing abort_source initialization.

Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi@necel.com>
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
  • Loading branch information
Shinya Kuribayashi authored and Ben Dooks committed Dec 9, 2009
1 parent 597fe31 commit ce6eb57
Showing 1 changed file with 40 additions and 7 deletions.
47 changes: 40 additions & 7 deletions drivers/i2c/busses/i2c-designware.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,27 @@
#define ABRT_SBYTE_ACKDET 7
#define ABRT_SBYTE_NORSTRT 9
#define ABRT_10B_RD_NORSTRT 10
#define ARB_MASTER_DIS 11
#define ABRT_MASTER_DIS 11
#define ARB_LOST 12

#define DW_IC_TX_ABRT_7B_ADDR_NOACK (1UL << ABRT_7B_ADDR_NOACK)
#define DW_IC_TX_ABRT_10ADDR1_NOACK (1UL << ABRT_10ADDR1_NOACK)
#define DW_IC_TX_ABRT_10ADDR2_NOACK (1UL << ABRT_10ADDR2_NOACK)
#define DW_IC_TX_ABRT_TXDATA_NOACK (1UL << ABRT_TXDATA_NOACK)
#define DW_IC_TX_ABRT_GCALL_NOACK (1UL << ABRT_GCALL_NOACK)
#define DW_IC_TX_ABRT_GCALL_READ (1UL << ABRT_GCALL_READ)
#define DW_IC_TX_ABRT_SBYTE_ACKDET (1UL << ABRT_SBYTE_ACKDET)
#define DW_IC_TX_ABRT_SBYTE_NORSTRT (1UL << ABRT_SBYTE_NORSTRT)
#define DW_IC_TX_ABRT_10B_RD_NORSTRT (1UL << ABRT_10B_RD_NORSTRT)
#define DW_IC_TX_ABRT_MASTER_DIS (1UL << ABRT_MASTER_DIS)
#define DW_IC_TX_ARB_LOST (1UL << ARB_LOST)

#define DW_IC_TX_ABRT_NOACK (DW_IC_TX_ABRT_7B_ADDR_NOACK | \
DW_IC_TX_ABRT_10ADDR1_NOACK | \
DW_IC_TX_ABRT_10ADDR2_NOACK | \
DW_IC_TX_ABRT_TXDATA_NOACK | \
DW_IC_TX_ABRT_GCALL_NOACK)

static char *abort_sources[] = {
[ABRT_7B_ADDR_NOACK] =
"slave address not acknowledged (7bit mode)",
Expand Down Expand Up @@ -472,6 +490,24 @@ i2c_dw_read(struct dw_i2c_dev *dev)
}
}

static int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev)
{
unsigned long abort_source = dev->abort_source;
int i;

for_each_bit(i, &abort_source, ARRAY_SIZE(abort_sources))
dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]);

if (abort_source & DW_IC_TX_ARB_LOST)
return -EAGAIN;
else if (abort_source & DW_IC_TX_ABRT_NOACK)
return -EREMOTEIO;
else if (abort_source & DW_IC_TX_ABRT_GCALL_READ)
return -EINVAL; /* wrong msgs[] data */
else
return -EIO;
}

/*
* Prepare controller for a transaction and call i2c_dw_xfer_msg
*/
Expand All @@ -493,6 +529,7 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
dev->msg_read_idx = 0;
dev->msg_err = 0;
dev->status = STATUS_IDLE;
dev->abort_source = 0;

ret = i2c_dw_wait_bus_not_busy(dev);
if (ret < 0)
Expand Down Expand Up @@ -526,12 +563,8 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)

/* We have an error */
if (dev->cmd_err == DW_IC_ERR_TX_ABRT) {
unsigned long abort_source = dev->abort_source;
int i;

for_each_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) {
dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]);
}
ret = i2c_dw_handle_tx_abort(dev);
goto done;
}
ret = -EIO;

Expand Down

0 comments on commit ce6eb57

Please sign in to comment.