Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ce6eb574 authored by Shinya Kuribayashi's avatar Shinya Kuribayashi Committed by Ben Dooks
Browse files

i2c-designware: Tx abort cleanups



* 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: default avatarShinya Kuribayashi <shinya.kuribayashi@necel.com>
Signed-off-by: default avatarBen Dooks <ben-linux@fluff.org>
parent 597fe310
Loading
Loading
Loading
Loading
+40 −7
Original line number Original line Diff line number Diff line
@@ -123,9 +123,27 @@
#define ABRT_SBYTE_ACKDET	7
#define ABRT_SBYTE_ACKDET	7
#define ABRT_SBYTE_NORSTRT	9
#define ABRT_SBYTE_NORSTRT	9
#define ABRT_10B_RD_NORSTRT	10
#define ABRT_10B_RD_NORSTRT	10
#define ARB_MASTER_DIS		11
#define ABRT_MASTER_DIS		11
#define ARB_LOST		12
#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[] = {
static char *abort_sources[] = {
	[ABRT_7B_ADDR_NOACK]	=
	[ABRT_7B_ADDR_NOACK]	=
		"slave address not acknowledged (7bit mode)",
		"slave address not acknowledged (7bit mode)",
@@ -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
 * Prepare controller for a transaction and call i2c_dw_xfer_msg
 */
 */
@@ -493,6 +529,7 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
	dev->msg_read_idx = 0;
	dev->msg_read_idx = 0;
	dev->msg_err = 0;
	dev->msg_err = 0;
	dev->status = STATUS_IDLE;
	dev->status = STATUS_IDLE;
	dev->abort_source = 0;


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


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

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