From: Tyrone Ting <redacted>
This patchset includes the following fixes:
- Add dt-bindings description for NPCM845.
- Bug fix for timeout calculation.
- Better handling of spurious interrupts.
- Fix for event type in slave mode.
- Removal of own slave addresses [2:10].
- Support for next gen BMC (NPCM845).
The NPCM I2C driver is tested on NPCM750 and NPCM845 evaluation boards.
Addressed comments from:
- Krzysztof Kozlowski : https://lkml.org/lkml/2022/2/21/129
- Wolfram Sang : https://lore.kernel.org/lkml/Yh536s%2F7bm6Xt6o3@ninjato/
- Rob Herring : https://lkml.org/lkml/2022/2/20/425
- Rob Herring : https://lkml.org/lkml/2022/2/22/945
- Krzysztof Kozlowski : https://www.spinics.net/lists/linux-i2c/
msg55903.html
- Jonathan Neuschäfer : https://lkml.org/lkml/2022/2/21/500
- Krzysztof Kozlowski : https://lkml.org/lkml/2022/2/20/49
Changes since version 2:
- Keep old code as fallback, if getting nuvoton,sys-mgr property fails.
- Fix the error reported by running 'make DT_CHECKER_FLAGS=-m
dt_binding_check'.
- Make nuvoton,sys-mgr required for nuvoton,npcm845-i2c.
- Correct the patch's subject about changing the way of getting GCR
regmap and add the description about keeping old code as fallback
if getting nuvoton,sys-mgr property fails.
- Correct the patch title and description about removing the unused
variable clk_regmap.
- Use the data field directly instead of the macros since macros are
not constants anymore in this patch.
Changes since version 1:
- Add nuvoton,sys-mgr property in NPCM devicetree.
- Describe the commit message in imperative mood.
- Modify the description in i2c binding document to cover NPCM series.
- Add new property in i2c binding document.
- Create a new patch for client address calculation.
- Create a new patch for updating gcr property name.
- Create a new patch for removing unused clock node.
- Explain EOB in the commit description.
- Create a new patch for correcting NPCM register access width.
- Remove some comment since the corresponding logic no longer exists.
- Remove fixes tag while the patch adds an additional feature.
- Use devicetree data field to support NPCM845.
Tali Perry (7):
i2c: npcm: Fix client address calculation
i2c: npcm: Change the way of getting GCR regmap
i2c: npcm: Remove unused variable clk_regmap
i2c: npcm: Fix timeout calculation
i2c: npcm: Add tx complete counter
i2c: npcm: Handle spurious interrupts
i2c: npcm: Remove own slave addresses 2:10
Tyrone Ting (4):
arm: dts: add new property for NPCM i2c module
dt-bindings: i2c: npcm: support NPCM845
i2c: npcm: Correct register access width
i2c: npcm: Support NPCM845
.../bindings/i2c/nuvoton,npcm7xx-i2c.yaml | 26 +-
arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi | 16 +
drivers/i2c/busses/Kconfig | 8 +-
drivers/i2c/busses/Makefile | 2 +-
drivers/i2c/busses/i2c-npcm7xx.c | 291 +++++++++++-------
5 files changed, 221 insertions(+), 122 deletions(-)
--
2.17.1
@@ -7,17 +7,18 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#title:nuvoton NPCM7XX I2C Controller Device Tree Bindingsdescription:|-The NPCM750x includes sixteen I2C bus controllers. All Controllers support-both master and slave mode. Each controller can switch between master and slave-at run time (i.e. IPMB mode). Each controller has two 16 byte HW FIFO for TX and-RX.+I2C bus controllers of the NPCM series support both master and+slave mode. Each controller can switch between master and slave at run time+(i.e. IPMB mode). HW FIFO for TX and RX are supported.maintainers:-Tali Perry <tali.perry1@gmail.com>properties:compatible:-const:nuvoton,npcm750-i2c+enum:+-nuvoton,npcm750-i2c+-nuvoton,npcm845-i2creg:maxItems:1
@@ -36,6 +37,10 @@ properties:default:100000enum:[100000,400000,1000000]+nuvoton,sys-mgr:+$ref:"/schemas/types.yaml#/definitions/phandle"+description:The phandle of system manager register node.+required:-compatible-reg
From: Tali Perry <tali.perry1@gmail.com>
Fix i2c client address by left-shifting 1 bit before
applying it to the data register.
Fixes: 56a1485b102e ("i2c: npcm7xx: Add Nuvoton NPCM I2C controller driver")
Signed-off-by: Tali Perry <tali.perry1@gmail.com>
Signed-off-by: Tyrone Ting <redacted>
---
drivers/i2c/busses/i2c-npcm7xx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Tali Perry <tali.perry1@gmail.com>
Change the way of getting NPCM system manager reigster (GCR)
and still maintain the old mechanism as a fallback if getting
nuvoton,sys-mgr fails while working with the legacy devicetree
file.
Fixes: 56a1485b102e ("i2c: npcm7xx: Add Nuvoton NPCM I2C controller driver")
Signed-off-by: Tali Perry <tali.perry1@gmail.com>
Signed-off-by: Tyrone Ting <redacted>
---
drivers/i2c/busses/i2c-npcm7xx.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
From: Tali Perry <tali.perry1@gmail.com>
Use adap.timeout for timeout calculation instead of hard-coded
value of 35ms.
Fixes: 56a1485b102e ("i2c: npcm7xx: Add Nuvoton NPCM I2C controller driver")
Signed-off-by: Tali Perry <tali.perry1@gmail.com>
Signed-off-by: Tyrone Ting <redacted>
Reported-by: kernel test robot <redacted>
---
drivers/i2c/busses/i2c-npcm7xx.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
From: Tali Perry <tali.perry1@gmail.com>
tx_complete counter is used to indicate successful transaction
count.
Similar counters for failed tx were previously added.
Fixes: 56a1485b102e ("i2c: npcm7xx: Add Nuvoton NPCM I2C controller driver")
Signed-off-by: Tali Perry <tali.perry1@gmail.com>
Signed-off-by: Tyrone Ting <redacted>
---
drivers/i2c/busses/i2c-npcm7xx.c | 4 ++++
1 file changed, 4 insertions(+)
@@ -684,6 +685,8 @@ static void npcm_i2c_callback(struct npcm_i2c *bus,switch(op_status){caseI2C_MASTER_DONE_IND:bus->cmd_err=bus->msgs_num;+if(bus->tx_complete_cnt<ULLONG_MAX)+bus->tx_complete_cnt++;fallthrough;caseI2C_BLOCK_BYTES_ERR_IND:/* Master tx finished and all transmit bytes were sent */
From: Tyrone Ting <redacted>
Use ioread8 instead of ioread32 to access the SMBnCTL3 register since
the register is only 8-bit wide.
Fixes: 56a1485b102e ("i2c: npcm7xx: Add Nuvoton NPCM I2C controller driver")
Signed-off-by: Tyrone Ting <redacted>
Signed-off-by: Tali Perry <tali.perry1@gmail.com>
Reviewed-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
---
drivers/i2c/busses/i2c-npcm7xx.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
From: Tali Perry <tali.perry1@gmail.com>
In order to better handle spurious interrupts:
1. Disable incoming interrupts in master only mode.
2. Clear end of busy (EOB) after every interrupt.
3. Return correct status during interrupt.
Fixes: 56a1485b102e ("i2c: npcm7xx: Add Nuvoton NPCM I2C controller driver")
Signed-off-by: Tali Perry <tali.perry1@gmail.com>
Signed-off-by: Tyrone Ting <redacted>
---
drivers/i2c/busses/i2c-npcm7xx.c | 92 ++++++++++++++++++++++----------
1 file changed, 63 insertions(+), 29 deletions(-)
@@ -564,6 +564,15 @@ static inline void npcm_i2c_nack(struct npcm_i2c *bus)iowrite8(val,bus->reg+NPCM_I2CCTL1);}+staticinlinevoidnpcm_i2c_clear_master_status(structnpcm_i2c*bus)+{+u8val;++/* Clear NEGACK, STASTR and BER bits */+val=NPCM_I2CST_BER|NPCM_I2CST_NEGACK|NPCM_I2CST_STASTR;+iowrite8(val,bus->reg+NPCM_I2CST);+}+#if IS_ENABLED(CONFIG_I2C_SLAVE)staticvoidnpcm_i2c_slave_int_enable(structnpcm_i2c*bus,boolenable){
@@ -643,8 +652,8 @@ static void npcm_i2c_reset(struct npcm_i2c *bus)iowrite8(NPCM_I2CCST_BB,bus->reg+NPCM_I2CCST);iowrite8(0xFF,bus->reg+NPCM_I2CST);-/* Clear EOB bit */-iowrite8(NPCM_I2CCST3_EO_BUSY,bus->reg+NPCM_I2CCST3);+/* Clear and disable EOB */+npcm_i2c_eob_int(bus,false);/* Clear all fifo bits: */iowrite8(NPCM_I2CFIF_CTS_CLR_FIFO,bus->reg+NPCM_I2CFIF_CTS);
@@ -656,6 +665,9 @@ static void npcm_i2c_reset(struct npcm_i2c *bus)}#endif+/* clear status bits for spurious interrupts */+npcm_i2c_clear_master_status(bus);+bus->state=I2C_IDLE;}
@@ -818,15 +830,6 @@ static void npcm_i2c_read_fifo(struct npcm_i2c *bus, u8 bytes_in_fifo)}}-staticinlinevoidnpcm_i2c_clear_master_status(structnpcm_i2c*bus)-{-u8val;--/* Clear NEGACK, STASTR and BER bits */-val=NPCM_I2CST_BER|NPCM_I2CST_NEGACK|NPCM_I2CST_STASTR;-iowrite8(val,bus->reg+NPCM_I2CST);-}-staticvoidnpcm_i2c_master_abort(structnpcm_i2c*bus){/* Only current master is allowed to issue a stop condition */
@@ -1470,6 +1482,9 @@ static void npcm_i2c_irq_handle_nack(struct npcm_i2c *bus)npcm_i2c_eob_int(bus,false);npcm_i2c_master_stop(bus);+/* Clear SDA Status bit (by reading dummy byte) */+npcm_i2c_rd_byte(bus);+/**ThebusisreleasedfromstallonlyaftertheSWclears*NEGACKbit.ThenaStopconditionissent.
@@ -1477,6 +1492,8 @@ static void npcm_i2c_irq_handle_nack(struct npcm_i2c *bus)npcm_i2c_clear_master_status(bus);readx_poll_timeout_atomic(ioread8,bus->reg+NPCM_I2CCST,val,!(val&NPCM_I2CCST_BUSY),10,200);+/* verify no status bits are still set after bus is released */+npcm_i2c_clear_master_status(bus);}bus->state=I2C_IDLE;
@@ -1675,10 +1692,10 @@ static int npcm_i2c_recovery_tgclk(struct i2c_adapter *_adap)intiter=27;if((npcm_i2c_get_SDA(_adap)==1)&&(npcm_i2c_get_SCL(_adap)==1)){-dev_dbg(bus->dev,"bus%d recovery skipped, bus not stuck",-bus->num);+dev_dbg(bus->dev,"bus%d-0x%x recovery skipped, bus not stuck",+bus->num,bus->dest_addr);npcm_i2c_reset(bus);-returnstatus;+return0;}npcm_i2c_int_enable(bus,false);
@@ -1940,10 +1958,18 @@ static int npcm_i2c_init_module(struct npcm_i2c *bus, enum i2c_mode mode,val=(val|NPCM_I2CCTL1_NMINTE)&~NPCM_I2CCTL1_RWS;iowrite8(val,bus->reg+NPCM_I2CCTL1);-npcm_i2c_int_enable(bus,true);-npcm_i2c_reset(bus);+/* check HW is OK: SDA and SCL should be high at this point. */+if((npcm_i2c_get_SDA(&bus->adap)==0)||+(npcm_i2c_get_SCL(&bus->adap)==0)){+dev_err(bus->dev,"I2C%d init fail: lines are low",bus->num);+dev_err(bus->dev,"SDA=%d SCL=%d",npcm_i2c_get_SDA(&bus->adap),+npcm_i2c_get_SCL(&bus->adap));+return-ENXIO;+}++npcm_i2c_int_enable(bus,true);return0;}
@@ -1991,10 +2017,14 @@ static irqreturn_t npcm_i2c_bus_irq(int irq, void *dev_id)#if IS_ENABLED(CONFIG_I2C_SLAVE)if(bus->slave){bus->master_or_slave=I2C_SLAVE;-returnnpcm_i2c_int_slave_handler(bus);+if(npcm_i2c_int_slave_handler(bus))+returnIRQ_HANDLED;}#endif-returnIRQ_NONE;+/* clear status bits for spurious interrupts */+npcm_i2c_clear_master_status(bus);++returnIRQ_HANDLED;}staticboolnpcm_i2c_master_start_xmit(structnpcm_i2c*bus,
@@ -2160,26 +2189,31 @@ static int npcm_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,}}}-ret=bus->cmd_err;/* if there was BER, check if need to recover the bus: */if(bus->cmd_err==-EAGAIN)-ret=i2c_recover_bus(adap);+bus->cmd_err=i2c_recover_bus(adap);/**Afteranytypeoferror,checkifLASTbitisstillset,*duetoaHWissue.*Itcannotbeclearedwithoutresettingthemodule.*/-if(bus->cmd_err&&-(NPCM_I2CRXF_CTL_LAST_PEC&ioread8(bus->reg+NPCM_I2CRXF_CTL)))+elseif(bus->cmd_err&&+(NPCM_I2CRXF_CTL_LAST_PEC&ioread8(bus->reg+NPCM_I2CRXF_CTL)))npcm_i2c_reset(bus);+/* after any xfer, successful or not, stall and EOB must be disabled */+npcm_i2c_stall_after_start(bus,false);+npcm_i2c_eob_int(bus,false);+#if IS_ENABLED(CONFIG_I2C_SLAVE)/* reenable slave if it was enabled */if(bus->slave)iowrite8((bus->slave->addr&0x7F)|NPCM_I2CADDR_SAEN,bus->reg+NPCM_I2CADDR1);+#else+npcm_i2c_int_enable(bus,false);#endifreturnbus->cmd_err;}
@@ -441,7 +461,7 @@ static inline bool npcm_i2c_tx_fifo_empty(struct npcm_i2c *bus)tx_fifo_sts=ioread8(bus->reg+NPCM_I2CTXF_STS);/* check if TX FIFO is not empty */-if((tx_fifo_sts&NPCM_I2CTXF_STS_TX_BYTES)==0)+if((tx_fifo_sts&bus->data->txf_sts_tx_bytes)==0)returnfalse;/* check if TX FIFO status bit is set: */
@@ -454,7 +474,7 @@ static inline bool npcm_i2c_rx_fifo_full(struct npcm_i2c *bus)rx_fifo_sts=ioread8(bus->reg+NPCM_I2CRXF_STS);/* check if RX FIFO is not empty: */-if((rx_fifo_sts&NPCM_I2CRXF_STS_RX_BYTES)==0)+if((rx_fifo_sts&bus->data->rxf_sts_rx_bytes)==0)returnfalse;/* check if rx fifo full status is set: */
@@ -786,11 +806,11 @@ static void npcm_i2c_set_fifo(struct npcm_i2c *bus, int nread, int nwrite)/* configure RX FIFO */if(nread>0){-rxf_ctl=min_t(int,nread,I2C_HW_FIFO_SIZE);+rxf_ctl=min_t(int,nread,bus->data->fifo_size);/* set LAST bit. if LAST is set next FIFO packet is nacked */-if(nread<=I2C_HW_FIFO_SIZE)-rxf_ctl|=NPCM_I2CRXF_CTL_LAST_PEC;+if(nread<=bus->data->fifo_size)+rxf_ctl|=bus->data->rxf_ctl_last_pec;/**ifweareabouttoreadthefirstbyteinblkrdmode,
@@ -808,9 +828,9 @@ static void npcm_i2c_set_fifo(struct npcm_i2c *bus, int nread, int nwrite)/* configure TX FIFO */if(nwrite>0){-if(nwrite>I2C_HW_FIFO_SIZE)+if(nwrite>bus->data->fifo_size)/* data to send is more then FIFO size. */-iowrite8(I2C_HW_FIFO_SIZE,bus->reg+NPCM_I2CTXF_CTL);+iowrite8(bus->data->fifo_size,bus->reg+NPCM_I2CTXF_CTL);elseiowrite8(nwrite,bus->reg+NPCM_I2CTXF_CTL);
@@ -918,8 +938,8 @@ static int npcm_i2c_slave_get_wr_buf(struct npcm_i2c *bus)intret=bus->slv_wr_ind;/* fill a cyclic buffer */-for(i=0;i<I2C_HW_FIFO_SIZE;i++){-if(bus->slv_wr_size>=I2C_HW_FIFO_SIZE)+for(i=0;i<bus->data->fifo_size;i++){+if(bus->slv_wr_size>=bus->data->fifo_size)break;if(bus->state==I2C_SLAVE_MATCH){i2c_slave_event(bus->slave,I2C_SLAVE_READ_REQUESTED,&value);
@@ -927,11 +947,11 @@ static int npcm_i2c_slave_get_wr_buf(struct npcm_i2c *bus)}else{i2c_slave_event(bus->slave,I2C_SLAVE_READ_PROCESSED,&value);}-ind=(bus->slv_wr_ind+bus->slv_wr_size)%I2C_HW_FIFO_SIZE;+ind=(bus->slv_wr_ind+bus->slv_wr_size)&(bus->data->fifo_size-1);bus->slv_wr_buf[ind]=value;bus->slv_wr_size++;}-returnI2C_HW_FIFO_SIZE-ret;+returnbus->data->fifo_size-ret;}staticvoidnpcm_i2c_slave_send_rd_buf(structnpcm_i2c*bus)
@@ -999,12 +1019,12 @@ static void npcm_i2c_slave_wr_buf_sync(struct npcm_i2c *bus){intleft_in_fifo;-left_in_fifo=FIELD_GET(NPCM_I2CTXF_STS_TX_BYTES,-ioread8(bus->reg+NPCM_I2CTXF_STS));+left_in_fifo=(bus->data->txf_sts_tx_bytes&+ioread8(bus->reg+NPCM_I2CTXF_STS));/* fifo already full: */-if(left_in_fifo>=I2C_HW_FIFO_SIZE||-bus->slv_wr_size>=I2C_HW_FIFO_SIZE)+if(left_in_fifo>=bus->data->fifo_size||+bus->slv_wr_size>=bus->data->fifo_size)return;/* update the wr fifo index back to the untransmitted bytes: */
@@ -1319,8 +1339,8 @@ static void npcm_i2c_master_fifo_read(struct npcm_i2c *bus)*read==FIFOSize+C(whereC<FIFOSize)thenfirstreadCbytes*andinthenextintwereadrestofthedata.*/-if(rcount<(2*I2C_HW_FIFO_SIZE)&&rcount>I2C_HW_FIFO_SIZE)-fifo_bytes=rcount-I2C_HW_FIFO_SIZE;+if(rcount<(2*bus->data->fifo_size)&&rcount>bus->data->fifo_size)+fifo_bytes=rcount-bus->data->fifo_size;if(rcount<=fifo_bytes){/* last bytes are about to be read - end of tx */
@@ -2200,7 +2220,7 @@ static int npcm_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,*Itcannotbeclearedwithoutresettingthemodule.*/elseif(bus->cmd_err&&-(NPCM_I2CRXF_CTL_LAST_PEC&ioread8(bus->reg+NPCM_I2CRXF_CTL)))+(bus->data->rxf_ctl_last_pec&ioread8(bus->reg+NPCM_I2CRXF_CTL)))npcm_i2c_reset(bus);/* after any xfer, successful or not, stall and EOB must be disabled */
@@ -2281,6 +2310,13 @@ static int npcm_i2c_probe_bus(struct platform_device *pdev)bus->dev=&pdev->dev;+match=of_match_device(npcm_i2c_bus_of_table,dev);+if(!match){+dev_err(dev,"OF data missing\n");+return-EINVAL;+}+bus->data=match->data;+bus->num=of_alias_get_id(pdev->dev.of_node,"i2c");/* core clk must be acquired to calculate module timing settings */i2c_clk=devm_clk_get(&pdev->dev,NULL);
@@ -2294,7 +2330,7 @@ static int npcm_i2c_probe_bus(struct platform_device *pdev)if(IS_ERR(gcr_regmap))returnPTR_ERR(gcr_regmap);-regmap_write(gcr_regmap,NPCM_I2CSEGCTL,NPCM_I2CSEGCTL_INIT_VAL);+regmap_write(gcr_regmap,NPCM_I2CSEGCTL,bus->data->segctl_init_val);bus->reg=devm_platform_ioremap_resource(pdev,0);if(IS_ERR(bus->reg))
@@ -2355,12 +2391,6 @@ static int npcm_i2c_remove_bus(struct platform_device *pdev)return0;}-staticconststructof_device_idnpcm_i2c_bus_of_table[]={-{.compatible="nuvoton,npcm750-i2c",},-{}-};-MODULE_DEVICE_TABLE(of,npcm_i2c_bus_of_table);-staticstructplatform_drivernpcm_i2c_bus_driver={.probe=npcm_i2c_probe_bus,.remove=npcm_i2c_remove_bus,
From: Tali Perry <tali.perry1@gmail.com>
NPCM can support up to 10 own slave addresses.
In practice, only one address is actually being used.
In order to access addresses 2 and above, need to switch
register banks. The switch needs spinlock.
To avoid using spinlock for this useless feature
removed support of SA >= 2.
Also fix returned slave event enum.
Remove some comment since the bank selection is not
required. The bank selection is not required since
the supported slave addresses are reduced.
Fixes: 56a1485b102e ("i2c: npcm7xx: Add Nuvoton NPCM I2C controller driver")
Signed-off-by: Tali Perry <tali.perry1@gmail.com>
Signed-off-by: Tyrone Ting <redacted>
---
drivers/i2c/busses/i2c-npcm7xx.c | 46 ++++++++++++++++----------------
1 file changed, 23 insertions(+), 23 deletions(-)
@@ -614,16 +611,18 @@ static int npcm_i2c_slave_enable(struct npcm_i2c *bus, enum i2c_addr addr_type,iowrite8(i2cctl3,bus->reg+NPCM_I2CCTL3);return0;}+if(addr_type>I2C_SLAVE_ADDR2&&addr_type<=I2C_SLAVE_ADDR10){+dev_err(bus->dev,+"try to enable more then 2 SA not supported\n");+}if(addr_type>=I2C_ARP_ADDR)return-EFAULT;/* select bank 0 for address 3 to 10 */-if(addr_type>I2C_SLAVE_ADDR2)-npcm_i2c_select_bank(bus,I2C_BANK_0);+/* Set and enable the address */iowrite8(sa_reg,bus->reg+npcm_i2caddr[addr_type]);npcm_i2c_slave_int_enable(bus,enable);-if(addr_type>I2C_SLAVE_ADDR2)-npcm_i2c_select_bank(bus,I2C_BANK_1);+return0;}#endif
@@ -846,15 +845,13 @@ static u8 npcm_i2c_get_slave_addr(struct npcm_i2c *bus, enum i2c_addr addr_type){u8slave_add;-/* select bank 0 for address 3 to 10 */-if(addr_type>I2C_SLAVE_ADDR2)-npcm_i2c_select_bank(bus,I2C_BANK_0);+if(addr_type>I2C_SLAVE_ADDR2&&addr_type<=I2C_SLAVE_ADDR10){+dev_err(bus->dev,+"get slave: try to use more then 2 slave addresses not supported\n");+}slave_add=ioread8(bus->reg+npcm_i2caddr[(int)addr_type]);-if(addr_type>I2C_SLAVE_ADDR2)-npcm_i2c_select_bank(bus,I2C_BANK_1);-returnslave_add;}
@@ -864,12 +861,12 @@ static int npcm_i2c_remove_slave_addr(struct npcm_i2c *bus, u8 slave_add)/* Set the enable bit */slave_add|=0x80;-npcm_i2c_select_bank(bus,I2C_BANK_0);-for(i=I2C_SLAVE_ADDR1;i<I2C_NUM_OWN_ADDR;i++){++for(i=I2C_SLAVE_ADDR1;i<I2C_NUM_OWN_ADDR_SUPPORTED;i++){if(ioread8(bus->reg+npcm_i2caddr[i])==slave_add)iowrite8(0,bus->reg+npcm_i2caddr[i]);}-npcm_i2c_select_bank(bus,I2C_BANK_1);+return0;}
@@ -924,11 +921,15 @@ static int npcm_i2c_slave_get_wr_buf(struct npcm_i2c *bus)for(i=0;i<I2C_HW_FIFO_SIZE;i++){if(bus->slv_wr_size>=I2C_HW_FIFO_SIZE)break;-i2c_slave_event(bus->slave,I2C_SLAVE_READ_REQUESTED,&value);+if(bus->state==I2C_SLAVE_MATCH){+i2c_slave_event(bus->slave,I2C_SLAVE_READ_REQUESTED,&value);+bus->state=I2C_OPER_STARTED;+}else{+i2c_slave_event(bus->slave,I2C_SLAVE_READ_PROCESSED,&value);+}ind=(bus->slv_wr_ind+bus->slv_wr_size)%I2C_HW_FIFO_SIZE;bus->slv_wr_buf[ind]=value;bus->slv_wr_size++;-i2c_slave_event(bus->slave,I2C_SLAVE_READ_PROCESSED,&value);}returnI2C_HW_FIFO_SIZE-ret;}
@@ -976,7 +977,6 @@ static void npcm_i2c_slave_xmit(struct npcm_i2c *bus, u16 nwrite,if(nwrite==0)return;-bus->state=I2C_OPER_STARTED;bus->operation=I2C_WRITE_OPER;/* get the next buffer */
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Date: 2022-03-03 10:27:22
On Thu, Mar 03, 2022 at 04:31:30PM +0800, Tyrone Ting wrote:
From: Tyrone Ting <redacted>
This patchset includes the following fixes:
- Add dt-bindings description for NPCM845.
- Bug fix for timeout calculation.
- Better handling of spurious interrupts.
- Fix for event type in slave mode.
- Removal of own slave addresses [2:10].
- Support for next gen BMC (NPCM845).
The NPCM I2C driver is tested on NPCM750 and NPCM845 evaluation boards.
Overall my impression that the code was never tested for this driver and
somehow appears in the upstream and hence this series.
Anyway, I'm going to review the changes here.
--
With Best Regards,
Andy Shevchenko
1. Why this is not using i2c_8bit_addr_from_msg() helper?
2. This is duplication of what npcm_i2c_master_start_xmit() does.
Taking 2 into account, what is this exactly fixing?
Sounds like a red herring.
--
With Best Regards,
Andy Shevchenko
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Date: 2022-03-03 10:38:02
On Thu, Mar 03, 2022 at 04:31:39PM +0800, Tyrone Ting wrote:
From: Tali Perry <tali.perry1@gmail.com>
In order to better handle spurious interrupts:
1. Disable incoming interrupts in master only mode.
2. Clear end of busy (EOB) after every interrupt.
3. Return correct status during interrupt.
This is bad commit message, it doesn't explain "why" you are doing these.
...
quoted hunk
+ /*+ * if irq is not one of the above, make sure EOB is disabled and all+ * status bits are cleared.
This does not explain why you hide the spurious interrupt.
@@ -7,17 +7,18 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#title:nuvoton NPCM7XX I2C Controller Device Tree Bindingsdescription:|-The NPCM750x includes sixteen I2C bus controllers. All Controllers support-both master and slave mode. Each controller can switch between master and slave-at run time (i.e. IPMB mode). Each controller has two 16 byte HW FIFO for TX and-RX.+I2C bus controllers of the NPCM series support both master and+slave mode. Each controller can switch between master and slave at run time+(i.e. IPMB mode). HW FIFO for TX and RX are supported.maintainers:-Tali Perry <tali.perry1@gmail.com>properties:compatible:-const:nuvoton,npcm750-i2c+enum:+-nuvoton,npcm750-i2c+-nuvoton,npcm845-i2creg:maxItems:1
@@ -36,6 +37,10 @@ properties:default:100000enum:[100000,400000,1000000]+nuvoton,sys-mgr:+$ref:"/schemas/types.yaml#/definitions/phandle"+description:The phandle of system manager register node.+required:-compatible-reg
From: Krzysztof Kozlowski <hidden> Date: 2022-03-03 10:38:40
On 03/03/2022 09:31, Tyrone Ting wrote:
From: Tali Perry <tali.perry1@gmail.com>
Change the way of getting NPCM system manager reigster (GCR)
and still maintain the old mechanism as a fallback if getting
nuvoton,sys-mgr fails while working with the legacy devicetree
file.
Fixes: 56a1485b102e ("i2c: npcm7xx: Add Nuvoton NPCM I2C controller driver")
Signed-off-by: Tali Perry <tali.perry1@gmail.com>
Signed-off-by: Tyrone Ting <redacted>
---
drivers/i2c/busses/i2c-npcm7xx.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
Acked-by: Krzysztof Kozlowski <redacted>
Best regards,
Krzysztof
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Date: 2022-03-03 10:44:54
On Thu, Mar 03, 2022 at 04:31:41PM +0800, Tyrone Ting wrote:
From: Tyrone Ting <redacted>
Add NPCM8XX I2C support.
The NPCM8XX uses a similar i2c module as NPCM7XX.
The internal HW FIFO is larger in NPCM8XX.
Signed-off-by: Tyrone Ting <redacted>
Signed-off-by: Tali Perry <tali.perry1@gmail.com>
Besides too many parentheses, this is an interesting change. So, in different
versions of IP the field is on different bits? Perhaps it means that you need
something like internal ops structure for all these, where you will have been
using the statically defined masks?
...
quoted hunk
+ match = of_match_device(npcm_i2c_bus_of_table, dev);+ if (!match) {+ dev_err(dev, "OF data missing\n");+ return -EINVAL;+ }+ bus->data = match->data;
From: Tali Perry <tali.perry1@gmail.com> Date: 2022-03-03 12:36:19
On Thu, Mar 3, 2022 at 12:45 PM Andy Shevchenko [off-list ref] wrote:
quoted
On Thu, Mar 03, 2022 at 04:31:41PM +0800, Tyrone Ting wrote:
quoted
From: Tyrone Ting <redacted>
Add NPCM8XX I2C support.
The NPCM8XX uses a similar i2c module as NPCM7XX.
The internal HW FIFO is larger in NPCM8XX.
Signed-off-by: Tyrone Ting <redacted>
Signed-off-by: Tali Perry <tali.perry1@gmail.com>
Besides too many parentheses, this is an interesting change. So, in different
versions of IP the field is on different bits? Perhaps it means that you need
something like internal ops structure for all these, where you will have been
using the statically defined masks?
Those are two very similar modules. The first generation had a 16 bytes HW FIFO
and the second generation has 32 bytes.
In V1 of this patchset the masks were defined under
CONFIG but we were asked to change the approach:
the entire discussion can be found here:
https://www.spinics.net/lists/linux-i2c/msg55566.html
Did we understand the request change right?
quoted
...
quoted
+ match = of_match_device(npcm_i2c_bus_of_table, dev);+ if (!match) {+ dev_err(dev, "OF data missing\n");+ return -EINVAL;+ }+ bus->data = match->data;
From: Tali Perry <tali.perry1@gmail.com> Date: 2022-03-03 12:48:35
On Thu, Mar 3, 2022 at 12:37 PM Andy Shevchenko [off-list ref] wrote:
quoted
On Thu, Mar 03, 2022 at 04:31:39PM +0800, Tyrone Ting wrote:
quoted
From: Tali Perry <tali.perry1@gmail.com>
In order to better handle spurious interrupts:
1. Disable incoming interrupts in master only mode.
2. Clear end of busy (EOB) after every interrupt.
3. Return correct status during interrupt.
This is bad commit message, it doesn't explain "why" you are doing these.
...
BMC users connect a huge tree of i2c devices and muxes.
This tree suffers from spikes, noise and double clocks.
All these may cause spurious interrupts to the BMC.
If the driver gets an IRQ which was not expected and was not handled
by the IRQ handler,
there is nothing left to do but to clear the interrupt and move on.
If the transaction failed, driver has a recovery function.
After that, user may retry to send the message.
Indeed the commit message doesn't explain all this.
We will fix and add to the next patchset.
quoted
quoted
+ /*+ * if irq is not one of the above, make sure EOB is disabled and all+ * status bits are cleared.
This does not explain why you hide the spurious interrupt.
No, this is bad commit message, since you have bitwise masks and there is
nothing to fix from functional point of view. So, why is this a fix?
The next gen of this device is a 64 bit cpu.
The module is and was 8 bit.
The ioread32 that seemed to work smoothly on a 32 bit machine
was causing a panic on a 64 bit machine.
since the module is 8 bit we changed to ioread8.
This is working both for the 32 and 64 CPUs with no issue.
quoted
Signed-off-by: Tyrone Ting <redacted>
Signed-off-by: Tali Perry <tali.perry1@gmail.com>
From: Tali Perry <tali.perry1@gmail.com> Date: 2022-03-03 13:04:18
On Thu, Mar 3, 2022 at 12:27 PM Andy Shevchenko
[off-list ref] wrote:
On Thu, Mar 03, 2022 at 04:31:30PM +0800, Tyrone Ting wrote:
quoted
From: Tyrone Ting <redacted>
This patchset includes the following fixes:
- Add dt-bindings description for NPCM845.
- Bug fix for timeout calculation.
- Better handling of spurious interrupts.
- Fix for event type in slave mode.
- Removal of own slave addresses [2:10].
- Support for next gen BMC (NPCM845).
The NPCM I2C driver is tested on NPCM750 and NPCM845 evaluation boards.
Overall my impression that the code was never tested for this driver and
somehow appears in the upstream and hence this series.
Anyway, I'm going to review the changes here.
--
Actually it was and is being used by multiple users in lots of BMCs.
We haven't submitted patches for this driver for a while
and accumulated them all on Nuvoton Github repo, but now we wanted to
clear the table.
All your comments will be addressed and fixed for the next patchset.
As always, we really appreciate your review and taking the time to go
through all these changes.
Besides too many parentheses, this is an interesting change. So, in different
versions of IP the field is on different bits? Perhaps it means that you need
something like internal ops structure for all these, where you will have been
using the statically defined masks?
Those are two very similar modules. The first generation had a 16 bytes HW FIFO
and the second generation has 32 bytes.
In V1 of this patchset the masks were defined under
CONFIG but we were asked to change the approach:
the entire discussion can be found here:
https://www.spinics.net/lists/linux-i2c/msg55566.html
Did we understand the request change right?
Not really. If you have not simply "one (MSB) bit more" for FIFO size, then
I proposed to create a specific operations structure and use callbacks (see
drivers/dma/dw/ case for iDMA 32-bit vs. DesignWare).
But hold on and read set of questions below.
Previously it was a fixed field with the NPCM_I2CTXF_STS_TX_BYTES mask applied,
right? From above I have got that FIFO is growing twice. Is it correct?
Does the LSB stay at the same offset? What is the meaning of the MSB in 32 byte
case? If it's reserved then why not to always use 32 byte approach?
--
With Best Regards,
Andy Shevchenko
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Date: 2022-03-03 14:14:33
On Thu, Mar 03, 2022 at 02:48:20PM +0200, Tali Perry wrote:
quoted
On Thu, Mar 3, 2022 at 12:37 PM Andy Shevchenko [off-list ref] wrote:
quoted
On Thu, Mar 03, 2022 at 04:31:39PM +0800, Tyrone Ting wrote:
quoted
From: Tali Perry <tali.perry1@gmail.com>
In order to better handle spurious interrupts:
1. Disable incoming interrupts in master only mode.
2. Clear end of busy (EOB) after every interrupt.
3. Return correct status during interrupt.
This is bad commit message, it doesn't explain "why" you are doing these.
...
BMC users connect a huge tree of i2c devices and muxes.
This tree suffers from spikes, noise and double clocks.
All these may cause spurious interrupts to the BMC.
If the driver gets an IRQ which was not expected and was not handled
by the IRQ handler,
there is nothing left to do but to clear the interrupt and move on.
Yes, the problem is what "move on" means in your case.
If you get a spurious interrupts there are possibilities what's wrong:
1) HW bug(s)
2) FW bug(s)
3) Missed IRQ mask in the driver
4) Improper IRQ mask in the driver
The below approach seems incorrect to me.
If the transaction failed, driver has a recovery function.
After that, user may retry to send the message.
Indeed the commit message doesn't explain all this.
We will fix and add to the next patchset.
quoted
quoted
quoted
+ /*+ * if irq is not one of the above, make sure EOB is disabled and all+ * status bits are cleared.
This does not explain why you hide the spurious interrupt.
No, this is bad commit message, since you have bitwise masks and there is
nothing to fix from functional point of view. So, why is this a fix?
The next gen of this device is a 64 bit cpu.
The module is and was 8 bit.
The ioread32 that seemed to work smoothly on a 32 bit machine
was causing a panic on a 64 bit machine.
since the module is 8 bit we changed to ioread8.
This is working both for the 32 and 64 CPUs with no issue.
Then the commit message is completely wrong here.
And provide necessary (no need to have noisy commit messages)
bits of the oops to show what's going on
--
With Best Regards,
Andy Shevchenko
@@ -7,17 +7,18 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#title:nuvoton NPCM7XX I2C Controller Device Tree Bindingsdescription:|-The NPCM750x includes sixteen I2C bus controllers. All Controllers support-both master and slave mode. Each controller can switch between master and slave-at run time (i.e. IPMB mode). Each controller has two 16 byte HW FIFO for TX and-RX.+I2C bus controllers of the NPCM series support both master and+slave mode. Each controller can switch between master and slave at run time+(i.e. IPMB mode). HW FIFO for TX and RX are supported.maintainers:-Tali Perry <tali.perry1@gmail.com>properties:compatible:-const:nuvoton,npcm750-i2c+enum:+-nuvoton,npcm750-i2c+-nuvoton,npcm845-i2creg:maxItems:1
@@ -36,6 +37,10 @@ properties:default:100000enum:[100000,400000,1000000]+nuvoton,sys-mgr:+$ref:"/schemas/types.yaml#/definitions/phandle"+description:The phandle of system manager register node.+required:-compatible-reg
Hi Krzysztof:
Thank you for your review.
Krzysztof Kozlowski [off-list ref] 於 2022年3月3日 週四 下午6:38寫道:
On 03/03/2022 09:31, Tyrone Ting wrote:
quoted
From: Tali Perry <tali.perry1@gmail.com>
Change the way of getting NPCM system manager reigster (GCR)
and still maintain the old mechanism as a fallback if getting
nuvoton,sys-mgr fails while working with the legacy devicetree
file.
Fixes: 56a1485b102e ("i2c: npcm7xx: Add Nuvoton NPCM I2C controller driver")
Signed-off-by: Tali Perry <tali.perry1@gmail.com>
Signed-off-by: Tyrone Ting <redacted>
---
drivers/i2c/busses/i2c-npcm7xx.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
Acked-by: Krzysztof Kozlowski <redacted>
Best regards,
Krzysztof
1. Why this is not using i2c_8bit_addr_from_msg() helper?
2. This is duplication of what npcm_i2c_master_start_xmit() does.
Taking 2 into account, what is this exactly fixing?
Sounds like a red herring.
--
With Best Regards,
Andy Shevchenko
No, this is bad commit message, since you have bitwise masks and there is
nothing to fix from functional point of view. So, why is this a fix?
The next gen of this device is a 64 bit cpu.
The module is and was 8 bit.
The ioread32 that seemed to work smoothly on a 32 bit machine
was causing a panic on a 64 bit machine.
since the module is 8 bit we changed to ioread8.
This is working both for the 32 and 64 CPUs with no issue.
Then the commit message is completely wrong here.
I disagree: The commit message is perhaps incomplete, but not wrong.
The SMBnCTL3 register was specified as 8 bits wide in the datasheets of
multiple chip generations, as far as I can tell, but the driver wrongly
made a 32-bit access, which just happened not to blow up.
So, indeed, "since the register is only 8-bit wide" seems to be a
correct claim.
And provide necessary (no need to have noisy commit messages)
bits of the oops to show what's going on
I guess it's blowing up now because SMBnCTL3 isn't 32-bit aligned
(being at offset 0x0e in the controller).
Jonathan
From: Wolfram Sang <wsa@kernel.org> Date: 2022-03-18 20:29:03
On Thu, Mar 03, 2022 at 04:31:31PM +0800, Tyrone Ting wrote:
From: Tyrone Ting <redacted>
Add nuvoton,sys-mgr property for controlling NPCM gcr register.
Signed-off-by: Tyrone Ting <redacted>
Signed-off-by: Tali Perry <tali.perry1@gmail.com>
There are some comments about this series, so I am expecting a v4
somewhen. However, I already want to state that I usually don't take DTS
patches. So, I guess the path forward is that Rob needs to ack the patch
which is now patch 2. Once he does this and I apply it, you can take this
DTS patch via arm-soc. Sounds good?
Hi Wolfram:
Thank you for your reminder and suggestion.
There are still some discussions for the patch V4 and it might take
some time though.
Yes, the dts patch could be submitted via arm-soc.
I really appreciate your comments.
Wolfram Sang [off-list ref] 於 2022年3月19日 週六 上午4:29寫道:
On Thu, Mar 03, 2022 at 04:31:31PM +0800, Tyrone Ting wrote:
quoted
From: Tyrone Ting <redacted>
Add nuvoton,sys-mgr property for controlling NPCM gcr register.
Signed-off-by: Tyrone Ting <redacted>
Signed-off-by: Tali Perry <tali.perry1@gmail.com>
There are some comments about this series, so I am expecting a v4
somewhen. However, I already want to state that I usually don't take DTS
patches. So, I guess the path forward is that Rob needs to ack the patch
which is now patch 2. Once he does this and I apply it, you can take this
DTS patch via arm-soc. Sounds good?
No, this is bad commit message, since you have bitwise masks and there is
nothing to fix from functional point of view. So, why is this a fix?
The next gen of this device is a 64 bit cpu.
The module is and was 8 bit.
The ioread32 that seemed to work smoothly on a 32 bit machine
was causing a panic on a 64 bit machine.
since the module is 8 bit we changed to ioread8.
This is working both for the 32 and 64 CPUs with no issue.
Then the commit message is completely wrong here.
I disagree: The commit message is perhaps incomplete, but not wrong.
The SMBnCTL3 register was specified as 8 bits wide in the datasheets of
multiple chip generations, as far as I can tell, but the driver wrongly
made a 32-bit access, which just happened not to blow up.
So, indeed, "since the register is only 8-bit wide" seems to be a
correct claim.
quoted
And provide necessary (no need to have noisy commit messages)
bits of the oops to show what's going on
I guess it's blowing up now because SMBnCTL3 isn't 32-bit aligned
(being at offset 0x0e in the controller).
Hi Andy,
After this clarification can you please acknowledge this specific patch?
If you think there is a better way to describe this, can you propose one?
No, this is bad commit message, since you have bitwise masks and there is
nothing to fix from functional point of view. So, why is this a fix?
The next gen of this device is a 64 bit cpu.
The module is and was 8 bit.
The ioread32 that seemed to work smoothly on a 32 bit machine
was causing a panic on a 64 bit machine.
since the module is 8 bit we changed to ioread8.
This is working both for the 32 and 64 CPUs with no issue.
Then the commit message is completely wrong here.
I disagree: The commit message is perhaps incomplete, but not wrong.
The SMBnCTL3 register was specified as 8 bits wide in the datasheets of
multiple chip generations, as far as I can tell, but the driver wrongly
made a 32-bit access, which just happened not to blow up.
So, indeed, "since the register is only 8-bit wide" seems to be a
correct claim.
quoted
And provide necessary (no need to have noisy commit messages)
bits of the oops to show what's going on
I guess it's blowing up now because SMBnCTL3 isn't 32-bit aligned
(being at offset 0x0e in the controller).
Hi Andy,
After this clarification can you please acknowledge this specific patch?
If you think there is a better way to describe this, can you propose one?
To be honest, I think it's probably best to include all the necessary
explanations in the next version of this patch, i.e.:
- That the register was always defined as 8-bit in the datasheets,
and so the 32-bit access was always incorrect, but simply didn't
cause a visible error
- How the 32-bit access caused an error now, perhaps with a trimmed
Oops log as Andy suggested
Jonathan
From: Avi Fishman <avifishman70@gmail.com> Date: 2022-04-04 21:27:14
On Thu, Mar 3, 2022 at 4:14 PM Andy Shevchenko
[off-list ref] wrote:
On Thu, Mar 03, 2022 at 02:48:20PM +0200, Tali Perry wrote:
quoted
quoted
On Thu, Mar 3, 2022 at 12:37 PM Andy Shevchenko [off-list ref] wrote:
quoted
On Thu, Mar 03, 2022 at 04:31:39PM +0800, Tyrone Ting wrote:
quoted
From: Tali Perry <tali.perry1@gmail.com>
In order to better handle spurious interrupts:
1. Disable incoming interrupts in master only mode.
2. Clear end of busy (EOB) after every interrupt.
3. Return correct status during interrupt.
This is bad commit message, it doesn't explain "why" you are doing these.
...
quoted
BMC users connect a huge tree of i2c devices and muxes.
This tree suffers from spikes, noise and double clocks.
All these may cause spurious interrupts to the BMC.
If the driver gets an IRQ which was not expected and was not handled
by the IRQ handler,
there is nothing left to do but to clear the interrupt and move on.
Yes, the problem is what "move on" means in your case.
If you get a spurious interrupts there are possibilities what's wrong:
1) HW bug(s)
2) FW bug(s)
3) Missed IRQ mask in the driver
4) Improper IRQ mask in the driver
The below approach seems incorrect to me.
Andy, What about this explanation:
On rare cases the i2c gets a spurious interrupt which means that we
enter an interrupt but in
the interrupt handler we don't find any status bit that points to the
reason we got this interrupt.
This may be a rare case of HW issue that is still under investigation.
In order to overcome this we are doing the following:
1. Disable incoming interrupts in master mode only when slave mode is
not enabled.
2. Clear end of busy (EOB) after every interrupt.
3. Clear other status bits (just in case since we found them cleared)
4. Return correct status during the interrupt that will finish the transaction.
On next xmit transaction if the bus is still busy the master will
issue a recovery process before issuing the new transaction.
quoted
If the transaction failed, driver has a recovery function.
After that, user may retry to send the message.
Indeed the commit message doesn't explain all this.
We will fix and add to the next patchset.
quoted
quoted
quoted
+ /*+ * if irq is not one of the above, make sure EOB is disabled and all+ * status bits are cleared.
This does not explain why you hide the spurious interrupt.
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Date: 2022-04-05 07:15:45
On Mon, Apr 04, 2022 at 08:03:44PM +0300, Avi Fishman wrote:
On Thu, Mar 3, 2022 at 4:14 PM Andy Shevchenko
[off-list ref] wrote:
quoted
On Thu, Mar 03, 2022 at 02:48:20PM +0200, Tali Perry wrote:
quoted
quoted
On Thu, Mar 3, 2022 at 12:37 PM Andy Shevchenko [off-list ref] wrote:
quoted
On Thu, Mar 03, 2022 at 04:31:39PM +0800, Tyrone Ting wrote:
quoted
From: Tali Perry <tali.perry1@gmail.com>
In order to better handle spurious interrupts:
1. Disable incoming interrupts in master only mode.
2. Clear end of busy (EOB) after every interrupt.
3. Return correct status during interrupt.
This is bad commit message, it doesn't explain "why" you are doing these.
...
quoted
BMC users connect a huge tree of i2c devices and muxes.
This tree suffers from spikes, noise and double clocks.
All these may cause spurious interrupts to the BMC.
(1)
quoted
quoted
If the driver gets an IRQ which was not expected and was not handled
by the IRQ handler,
there is nothing left to do but to clear the interrupt and move on.
Yes, the problem is what "move on" means in your case.
If you get a spurious interrupts there are possibilities what's wrong:
1) HW bug(s)
2) FW bug(s)
3) Missed IRQ mask in the driver
4) Improper IRQ mask in the driver
The below approach seems incorrect to me.
Andy, What about this explanation:
On rare cases the i2c gets a spurious interrupt which means that we
enter an interrupt but in
the interrupt handler we don't find any status bit that points to the
reason we got this interrupt.
This may be a rare case of HW issue that is still under investigation.
In order to overcome this we are doing the following:
1. Disable incoming interrupts in master mode only when slave mode is
not enabled.
2. Clear end of busy (EOB) after every interrupt.
3. Clear other status bits (just in case since we found them cleared)
4. Return correct status during the interrupt that will finish the transaction.
On next xmit transaction if the bus is still busy the master will
issue a recovery process before issuing the new transaction.
This sounds better, thanks.
One thing to clarify, the (1) states that the HW "issue" is known and becomes a
PCB level one, i.e. noisy environment that has not been properly shielded.
So, if it is known, please put the reason in the commit message.
Also would be good to see numbers of "rare". Is it 0.1%?
quoted
quoted
If the transaction failed, driver has a recovery function.
After that, user may retry to send the message.
Indeed the commit message doesn't explain all this.
We will fix and add to the next patchset.
quoted
quoted
quoted
+ /*+ * if irq is not one of the above, make sure EOB is disabled and all+ * status bits are cleared.
This does not explain why you hide the spurious interrupt.
From: Avi Fishman <avifishman70@gmail.com> Date: 2022-04-10 07:33:35
On Tue, Apr 5, 2022 at 10:13 AM Andy Shevchenko
[off-list ref] wrote:
On Mon, Apr 04, 2022 at 08:03:44PM +0300, Avi Fishman wrote:
quoted
On Thu, Mar 3, 2022 at 4:14 PM Andy Shevchenko
[off-list ref] wrote:
quoted
On Thu, Mar 03, 2022 at 02:48:20PM +0200, Tali Perry wrote:
quoted
quoted
On Thu, Mar 3, 2022 at 12:37 PM Andy Shevchenko [off-list ref] wrote:
quoted
On Thu, Mar 03, 2022 at 04:31:39PM +0800, Tyrone Ting wrote:
quoted
From: Tali Perry <tali.perry1@gmail.com>
In order to better handle spurious interrupts:
1. Disable incoming interrupts in master only mode.
2. Clear end of busy (EOB) after every interrupt.
3. Return correct status during interrupt.
This is bad commit message, it doesn't explain "why" you are doing these.
...
quoted
BMC users connect a huge tree of i2c devices and muxes.
This tree suffers from spikes, noise and double clocks.
All these may cause spurious interrupts to the BMC.
(1)
quoted
quoted
quoted
If the driver gets an IRQ which was not expected and was not handled
by the IRQ handler,
there is nothing left to do but to clear the interrupt and move on.
Yes, the problem is what "move on" means in your case.
If you get a spurious interrupts there are possibilities what's wrong:
1) HW bug(s)
2) FW bug(s)
3) Missed IRQ mask in the driver
4) Improper IRQ mask in the driver
The below approach seems incorrect to me.
Andy, What about this explanation:
On rare cases the i2c gets a spurious interrupt which means that we
enter an interrupt but in
the interrupt handler we don't find any status bit that points to the
reason we got this interrupt.
This may be a rare case of HW issue that is still under investigation
About 1 to 100,000 transactions
quoted
In order to overcome this we are doing the following:
1. Disable incoming interrupts in master mode only when slave mode is
not enabled.
2. Clear end of busy (EOB) after every interrupt.
3. Clear other status bits (just in case since we found them cleared)
4. Return correct status during the interrupt that will finish the transaction.
On next xmit transaction if the bus is still busy the master will
issue a recovery process before issuing the new transaction.
This sounds better, thanks.
One thing to clarify, the (1) states that the HW "issue" is known and becomes a
PCB level one, i.e. noisy environment that has not been properly shielded.
So, if it is known, please put the reason in the commit message.
The HW issue is not known yet, we see it on few platforms and in other
platforms we don't, so the first assumption was this.
So eventually we don't want to claim this without proving it.
Also would be good to see numbers of "rare". Is it 0.1%?
I added above the known statistics.
quoted
quoted
quoted
If the transaction failed, driver has a recovery function.
After that, user may retry to send the message.
Indeed the commit message doesn't explain all this.
We will fix and add to the next patchset.
quoted
quoted
quoted
+ /*+ * if irq is not one of the above, make sure EOB is disabled and all+ * status bits are cleared.
This does not explain why you hide the spurious interrupt.