diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-14 22:25:37 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-14 22:25:37 +0300 |
commit | 32250e4a5fa0b618044afa59fba01093a4bcb14a (patch) | |
tree | 678461393befc77b25e8d68cb637529927d3c284 /drivers/i2c/busses/i2c-img-scb.c | |
parent | 5339f9d4c2ceccab00b28d65bd5c2b2cd6a3de05 (diff) | |
parent | c698d639f72b55686ec3518d2bc8dc5f2eca9354 (diff) | |
download | linux-32250e4a5fa0b618044afa59fba01093a4bcb14a.tar.xz |
Merge branch 'i2c/for-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c updates from Wolfram Sang:
"Quite some driver updates:
- piix4 can now handle multiplexed adapters
- brcmstb, xlr, eg20t, designware drivers support more SoCs
- emev2 gained i2c slave support
- img-scb and rcar got bigger refactoring to remove issues
- lots of common driver updates
i2c core changes:
- new quirk flag when an adapter does not support clock stretching,
so clients can be configured to avoid that if possible
- added a helper function to retrieve timing parameters from firmware
(with rcar being the first user)
- "multi-master" DT binding added so drivers can adapt to this
setting (like disabling PM to keep arbitration working)
- RuntimePM for the logical adapter device is now always enabled by
the core to ensure propagation from childs to the parent (the HW
device)
- new macro builtin_i2c_driver to reduce boilerplate"
* 'i2c/for-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (70 commits)
i2c: create builtin_i2c_driver to avoid registration boilerplate
i2c: imx: fix i2c resource leak with dma transfer
dt-bindings: i2c: eeprom: add another EEPROM device
dt-bindings: move I2C eeprom descriptions to the proper file
i2c: designware: Do not require clock when SSCN and FFCN are provided
DT: i2c: trivial-devices: Add Epson RX8010 and MPL3115
i2c: s3c2410: remove superfluous runtime PM calls
i2c: always enable RuntimePM for the adapter device
i2c: designware: retry transfer on transient failure
i2c: ibm_iic: rename i2c_timings struct due to clash with generic version
i2c: designware: Add support for AMD Seattle I2C
i2c: imx: Remove unneeded comments
i2c: st: use to_platform_device()
i2c: designware: use to_pci_dev()
i2c: brcmstb: Adding support for CM and DSL SoCs
i2c: mediatek: fix i2c multi transfer issue in high speed mode
i2c: imx: improve code readability
i2c: imx: Improve message log when DMA is not used
i2c: imx: add runtime pm support to improve the performance
i2c: imx: init bus recovery info before adding i2c adapter
...
Diffstat (limited to 'drivers/i2c/busses/i2c-img-scb.c')
-rw-r--r-- | drivers/i2c/busses/i2c-img-scb.c | 92 |
1 files changed, 67 insertions, 25 deletions
diff --git a/drivers/i2c/busses/i2c-img-scb.c b/drivers/i2c/busses/i2c-img-scb.c index 3795fe130ef2..379ef9c31664 100644 --- a/drivers/i2c/busses/i2c-img-scb.c +++ b/drivers/i2c/busses/i2c-img-scb.c @@ -151,10 +151,11 @@ #define INT_FIFO_EMPTYING BIT(12) #define INT_TRANSACTION_DONE BIT(15) #define INT_SLAVE_EVENT BIT(16) +#define INT_MASTER_HALTED BIT(17) #define INT_TIMING BIT(18) +#define INT_STOP_DETECTED BIT(19) #define INT_FIFO_FULL_FILLING (INT_FIFO_FULL | INT_FIFO_FILLING) -#define INT_FIFO_EMPTY_EMPTYING (INT_FIFO_EMPTY | INT_FIFO_EMPTYING) /* Level interrupts need clearing after handling instead of before */ #define INT_LEVEL 0x01e00 @@ -177,7 +178,8 @@ INT_FIFO_FULL | \ INT_FIFO_FILLING | \ INT_FIFO_EMPTY | \ - INT_FIFO_EMPTYING) + INT_MASTER_HALTED | \ + INT_STOP_DETECTED) #define INT_ENABLE_MASK_WAITSTOP (INT_SLAVE_EVENT | \ INT_ADDR_ACK_ERR | \ @@ -511,7 +513,17 @@ static void img_i2c_soft_reset(struct img_i2c *i2c) SCB_CONTROL_CLK_ENABLE | SCB_CONTROL_SOFT_RESET); } -/* enable or release transaction halt for control of repeated starts */ +/* + * Enable or release transaction halt for control of repeated starts. + * In version 3.3 of the IP when transaction halt is set, an interrupt + * will be generated after each byte of a transfer instead of after + * every transfer but before the stop bit. + * Due to this behaviour we have to be careful that every time we + * release the transaction halt we have to re-enable it straight away + * so that we only process a single byte, not doing so will result in + * all remaining bytes been processed and a stop bit being issued, + * which will prevent us having a repeated start. + */ static void img_i2c_transaction_halt(struct img_i2c *i2c, bool t_halt) { u32 val; @@ -580,7 +592,6 @@ static void img_i2c_read(struct img_i2c *i2c) img_i2c_writel(i2c, SCB_READ_ADDR_REG, i2c->msg.addr); img_i2c_writel(i2c, SCB_READ_COUNT_REG, i2c->msg.len); - img_i2c_transaction_halt(i2c, false); mod_timer(&i2c->check_timer, jiffies + msecs_to_jiffies(1)); } @@ -594,7 +605,6 @@ static void img_i2c_write(struct img_i2c *i2c) img_i2c_writel(i2c, SCB_WRITE_ADDR_REG, i2c->msg.addr); img_i2c_writel(i2c, SCB_WRITE_COUNT_REG, i2c->msg.len); - img_i2c_transaction_halt(i2c, false); mod_timer(&i2c->check_timer, jiffies + msecs_to_jiffies(1)); img_i2c_write_fifo(i2c); @@ -750,7 +760,9 @@ static unsigned int img_i2c_atomic(struct img_i2c *i2c, next_cmd = CMD_RET_ACK; break; case CMD_RET_ACK: - if (i2c->line_status & LINESTAT_ACK_DET) { + if (i2c->line_status & LINESTAT_ACK_DET || + (i2c->line_status & LINESTAT_NACK_DET && + i2c->msg.flags & I2C_M_IGNORE_NAK)) { if (i2c->msg.len == 0) { next_cmd = CMD_GEN_STOP; } else if (i2c->msg.flags & I2C_M_RD) { @@ -858,34 +870,42 @@ static unsigned int img_i2c_auto(struct img_i2c *i2c, /* Enable transaction halt on start bit */ if (!i2c->last_msg && line_status & LINESTAT_START_BIT_DET) { - img_i2c_transaction_halt(i2c, true); + img_i2c_transaction_halt(i2c, !i2c->last_msg); /* we're no longer interested in the slave event */ i2c->int_enable &= ~INT_SLAVE_EVENT; } mod_timer(&i2c->check_timer, jiffies + msecs_to_jiffies(1)); + if (int_status & INT_STOP_DETECTED) { + /* Drain remaining data in FIFO and complete transaction */ + if (i2c->msg.flags & I2C_M_RD) + img_i2c_read_fifo(i2c); + return ISR_COMPLETE(0); + } + if (i2c->msg.flags & I2C_M_RD) { - if (int_status & INT_FIFO_FULL_FILLING) { + if (int_status & (INT_FIFO_FULL_FILLING | INT_MASTER_HALTED)) { img_i2c_read_fifo(i2c); if (i2c->msg.len == 0) return ISR_WAITSTOP; } } else { - if (int_status & INT_FIFO_EMPTY_EMPTYING) { - /* - * The write fifo empty indicates that we're in the - * last byte so it's safe to start a new write - * transaction without losing any bytes from the - * previous one. - * see 2.3.7 Repeated Start Transactions. - */ + if (int_status & (INT_FIFO_EMPTY | INT_MASTER_HALTED)) { if ((int_status & INT_FIFO_EMPTY) && i2c->msg.len == 0) return ISR_WAITSTOP; img_i2c_write_fifo(i2c); } } + if (int_status & INT_MASTER_HALTED) { + /* + * Release and then enable transaction halt, to + * allow only a single byte to proceed. + */ + img_i2c_transaction_halt(i2c, false); + img_i2c_transaction_halt(i2c, !i2c->last_msg); + } return 0; } @@ -1017,20 +1037,23 @@ static int img_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, return -EIO; for (i = 0; i < num; i++) { - if (likely(msgs[i].len)) - continue; /* * 0 byte reads are not possible because the slave could try * and pull the data line low, preventing a stop bit. */ - if (unlikely(msgs[i].flags & I2C_M_RD)) + if (!msgs[i].len && msgs[i].flags & I2C_M_RD) return -EIO; /* * 0 byte writes are possible and used for probing, but we * cannot do them in automatic mode, so use atomic mode * instead. + * + * Also, the I2C_M_IGNORE_NAK mode can only be implemented + * in atomic mode. */ - atomic = true; + if (!msgs[i].len || + (msgs[i].flags & I2C_M_IGNORE_NAK)) + atomic = true; } ret = clk_prepare_enable(i2c->scb_clk); @@ -1069,12 +1092,31 @@ static int img_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, img_i2c_writel(i2c, SCB_INT_CLEAR_REG, ~0); img_i2c_writel(i2c, SCB_CLEAR_REG, ~0); - if (atomic) + if (atomic) { img_i2c_atomic_start(i2c); - else if (msg->flags & I2C_M_RD) - img_i2c_read(i2c); - else - img_i2c_write(i2c); + } else { + /* + * Enable transaction halt if not the last message in + * the queue so that we can control repeated starts. + */ + img_i2c_transaction_halt(i2c, !i2c->last_msg); + + if (msg->flags & I2C_M_RD) + img_i2c_read(i2c); + else + img_i2c_write(i2c); + + /* + * Release and then enable transaction halt, to + * allow only a single byte to proceed. + * This doesn't have an effect on the initial transfer + * but will allow the following transfers to start + * processing if the previous transfer was marked as + * complete while the i2c block was halted. + */ + img_i2c_transaction_halt(i2c, false); + img_i2c_transaction_halt(i2c, !i2c->last_msg); + } spin_unlock_irqrestore(&i2c->lock, flags); time_left = wait_for_completion_timeout(&i2c->msg_complete, |