diff options
Diffstat (limited to 'meta-phosphor/common/recipes-kernel/linux/linux-obmc/linux-dev-4.10-v2-3-6-drivers-i2c-Add-transfer-implementation-for-FSI-algorithm.patch')
-rw-r--r-- | meta-phosphor/common/recipes-kernel/linux/linux-obmc/linux-dev-4.10-v2-3-6-drivers-i2c-Add-transfer-implementation-for-FSI-algorithm.patch | 243 |
1 files changed, 0 insertions, 243 deletions
diff --git a/meta-phosphor/common/recipes-kernel/linux/linux-obmc/linux-dev-4.10-v2-3-6-drivers-i2c-Add-transfer-implementation-for-FSI-algorithm.patch b/meta-phosphor/common/recipes-kernel/linux/linux-obmc/linux-dev-4.10-v2-3-6-drivers-i2c-Add-transfer-implementation-for-FSI-algorithm.patch deleted file mode 100644 index 50410ffc8..000000000 --- a/meta-phosphor/common/recipes-kernel/linux/linux-obmc/linux-dev-4.10-v2-3-6-drivers-i2c-Add-transfer-implementation-for-FSI-algorithm.patch +++ /dev/null @@ -1,243 +0,0 @@ -From patchwork Wed May 10 15:52:39 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [linux, dev-4.10, v2, - 3/6] drivers: i2c: Add transfer implementation for FSI algorithm -From: eajames@linux.vnet.ibm.com -X-Patchwork-Id: 760702 -Message-Id: <1494431562-25101-4-git-send-email-eajames@linux.vnet.ibm.com> -To: openbmc@lists.ozlabs.org -Cc: "Edward A. James" <eajames@us.ibm.com>, cbostic@linux.vnet.ibm.com -Date: Wed, 10 May 2017 10:52:39 -0500 - -From: "Edward A. James" <eajames@us.ibm.com> - -Execute I2C transfers from the FSI-attached I2C master. Use polling -instead of interrupts as we have no hardware IRQ over FSI. - -Signed-off-by: Edward A. James <eajames@us.ibm.com> ---- - drivers/i2c/busses/i2c-fsi.c | 193 ++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 191 insertions(+), 2 deletions(-) - -diff --git a/drivers/i2c/busses/i2c-fsi.c b/drivers/i2c/busses/i2c-fsi.c -index cdebc99..f690b16 100644 ---- a/drivers/i2c/busses/i2c-fsi.c -+++ b/drivers/i2c/busses/i2c-fsi.c -@@ -143,6 +143,7 @@ struct fsi_i2c_port { - struct i2c_adapter adapter; - struct fsi_i2c_master *master; - u16 port; -+ u16 xfrd; - }; - - static DEFINE_IDA(fsi_i2c_ida); -@@ -229,17 +230,205 @@ static int fsi_i2c_set_port(struct fsi_i2c_port *port) - return rc; - } - -+static int fsi_i2c_start(struct fsi_i2c_port *port, struct i2c_msg *msg, -+ bool stop) -+{ -+ int rc; -+ struct fsi_i2c_master *i2c = port->master; -+ u32 cmd = I2C_CMD_WITH_START | I2C_CMD_WITH_ADDR; -+ -+ port->xfrd = 0; -+ -+ if (msg->flags & I2C_M_RD) -+ cmd |= I2C_CMD_READ; -+ -+ if (stop || msg->flags & I2C_M_STOP) -+ cmd |= I2C_CMD_WITH_STOP; -+ -+ cmd = SETFIELD(I2C_CMD_ADDR, cmd, msg->addr >> 1); -+ cmd = SETFIELD(I2C_CMD_LEN, cmd, msg->len); -+ -+ rc = fsi_i2c_write_reg(i2c->fsi, I2C_FSI_CMD, &cmd); -+ -+ return rc; -+} -+ -+static int fsi_i2c_write_fifo(struct fsi_i2c_port *port, struct i2c_msg *msg, -+ u8 fifo_count) -+{ -+ int write; -+ int rc = 0; -+ struct fsi_i2c_master *i2c = port->master; -+ int bytes_to_write = i2c->fifo_size - fifo_count; -+ int bytes_remaining = msg->len - port->xfrd; -+ -+ if (bytes_to_write > bytes_remaining) -+ bytes_to_write = bytes_remaining; -+ -+ while (bytes_to_write > 0) { -+ write = bytes_to_write; -+ /* fsi limited to max 4 byte aligned ops */ -+ if (bytes_to_write > 4) -+ write = 4; -+ else if (write == 3) -+ write = 2; -+ -+ rc = fsi_device_write(i2c->fsi, I2C_FSI_FIFO, -+ &msg->buf[port->xfrd], write); -+ if (rc) -+ return rc; -+ -+ port->xfrd += write; -+ bytes_to_write -= write; -+ } -+ -+ return rc; -+} -+ -+static int fsi_i2c_read_fifo(struct fsi_i2c_port *port, struct i2c_msg *msg, -+ u8 fifo_count) -+{ -+ int read; -+ int rc = 0; -+ struct fsi_i2c_master *i2c = port->master; -+ int xfr_remaining = msg->len - port->xfrd; -+ u32 dummy; -+ -+ while (fifo_count) { -+ read = fifo_count; -+ /* fsi limited to max 4 byte aligned ops */ -+ if (fifo_count > 4) -+ read = 4; -+ else if (read == 3) -+ read = 2; -+ -+ if (xfr_remaining) { -+ if (xfr_remaining < read) -+ read = xfr_remaining; -+ -+ rc = fsi_device_read(i2c->fsi, I2C_FSI_FIFO, -+ &msg->buf[port->xfrd], read); -+ if (rc) -+ return rc; -+ -+ port->xfrd += read; -+ xfr_remaining -= read; -+ } else { -+ /* no more buffer but data in fifo, need to clear it */ -+ rc = fsi_device_read(i2c->fsi, I2C_FSI_FIFO, &dummy, -+ read); -+ if (rc) -+ return rc; -+ } -+ -+ fifo_count -= read; -+ } -+ -+ return rc; -+} -+ -+static int fsi_i2c_handle_status(struct fsi_i2c_port *port, -+ struct i2c_msg *msg, u32 status) -+{ -+ int rc; -+ u8 fifo_count; -+ struct fsi_i2c_master *i2c = port->master; -+ u32 dummy = 0; -+ -+ if (status & I2C_STAT_ERR) { -+ rc = fsi_i2c_write_reg(i2c->fsi, I2C_FSI_RESET_ERR, &dummy); -+ if (rc) -+ return rc; -+ -+ if (status & I2C_STAT_NACK) -+ return -EFAULT; -+ -+ return -EIO; -+ } -+ -+ if (status & I2C_STAT_DAT_REQ) { -+ fifo_count = GETFIELD(I2C_STAT_FIFO_COUNT, status); -+ -+ if (msg->flags & I2C_M_RD) -+ rc = fsi_i2c_read_fifo(port, msg, fifo_count); -+ else -+ rc = fsi_i2c_write_fifo(port, msg, fifo_count); -+ -+ return rc; -+ } -+ -+ if (status & I2C_STAT_CMD_COMP) { -+ if (port->xfrd < msg->len) -+ rc = -ENODATA; -+ else -+ rc = msg->len; -+ } -+ -+ return rc; -+} -+ -+static int fsi_i2c_wait(struct fsi_i2c_port *port, struct i2c_msg *msg, -+ unsigned long timeout) -+{ -+ const unsigned long local_timeout = 2; /* jiffies */ -+ u32 status = 0; -+ int rc; -+ -+ do { -+ rc = fsi_i2c_read_reg(port->master->fsi, I2C_FSI_STAT, -+ &status); -+ if (rc) -+ return rc; -+ -+ if (status & I2C_STAT_ANY_RESP) { -+ rc = fsi_i2c_handle_status(port, msg, status); -+ if (rc < 0) -+ return rc; -+ -+ /* cmd complete and all data xfrd */ -+ if (rc == msg->len) -+ return 0; -+ -+ /* need to xfr more data, but maybe don't need wait */ -+ continue; -+ } -+ -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ schedule_timeout(local_timeout); -+ timeout = (timeout < local_timeout) ? 0 : -+ timeout - local_timeout; -+ } while (timeout); -+ -+ return -ETIME; -+} -+ - static int fsi_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, - int num) - { -- int rc; -+ int i, rc; -+ unsigned long start_time; - struct fsi_i2c_port *port = adap->algo_data; -+ struct i2c_msg *msg; - - rc = fsi_i2c_set_port(port); - if (rc) - return rc; - -- return -ENOSYS; -+ for (i = 0; i < num; ++i) { -+ msg = msgs + i; -+ start_time = jiffies; -+ -+ rc = fsi_i2c_start(port, msg, i == num - 1); -+ if (rc) -+ return rc; -+ -+ rc = fsi_i2c_wait(port, msg, -+ adap->timeout - (jiffies - start_time)); -+ if (rc) -+ return rc; -+ } -+ -+ return 0; - } - - static u32 fsi_i2c_functionality(struct i2c_adapter *adap) |