在 2023/2/18 0:54, Strahinja Jankovic 写道:
Hi,

I tried running Avocado tests for cubieboard with following command:

ARMBIAN_ARTIFACTS_CACHED=yes  AVOCADO_ALLOW_LARGE_STORAGE=yes avocado
--show=app,console run    -t machine:cubieboard
tests/avocado/boot_linux_console.py

Without this patch all tests pass:
RESULTS    : PASS 3 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0
| CANCEL 0
JOB TIME   : 53.15 s

However, if I apply this patch, all tests fail. This is part of the
log that captures the failure:

axp20x-i2c 1-0034: AXP20x variant AXP209 found
console: random: crng init done
console: irq 43: nobody cared (try booting with the "irqpoll" option)
console: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.10.16-sunxi #21.02.2
console: Hardware name: Allwinner sun4i/sun5i Families
console: [<c010ca1d>] (unwind_backtrace) from [<c010951d>]
(show_stack+0x11/0x14)
console: [<c010951d>] (show_stack) from [<c096eb27>] (dump_stack+0x77/0x84)
console: [<c096eb27>] (dump_stack) from [<c0969147>]
(__report_bad_irq+0x37/0x94)
console: [<c0969147>] (__report_bad_irq) from [<c016618b>]
(note_interrupt+0xfb/0x1f4)
console: [<c016618b>] (note_interrupt) from [<c0163aeb>]
(handle_irq_event_percpu+0x4f/0x54)
console: [<c0163aeb>] (handle_irq_event_percpu) from [<c0163b29>]
(handle_irq_event+0x39/0x50)
console: [<c0163b29>] (handle_irq_event) from [<c0166d93>]
(handle_fasteoi_irq+0x67/0xbc)
console: [<c0166d93>] (handle_fasteoi_irq) from [<c0162eed>]
(generic_handle_irq+0x29/0x34)
console: [<c0162eed>] (generic_handle_irq) from [<c01633a7>]
(__handle_domain_irq+0x43/0x84)
console: [<c01633a7>] (__handle_domain_irq) from [<c05937d7>]
(sun4i_handle_irq+0x3b/0x4c)
console: [<c05937d7>] (sun4i_handle_irq) from [<c0100b65>] (__irq_svc+0x65/0x94)
console: Exception stack(0xc1517950 to 0xc1517998)
console: 7940:                                     c1701ca0 60000153
000000e4 00000001
console: 7960: c1701c40 00000002 60000153 c1517a1c c1701ca0 00000000
c0f03d00 fffede04
console: 7980: 00000000 c15179a0 c075ebb7 c09785d4 00000173 ffffffff
console: [<c0100b65>] (__irq_svc) from [<c09785d4>]
(_raw_spin_unlock_irqrestore+0x1c/0x20)
console: [<c09785d4>] (_raw_spin_unlock_irqrestore) from [<c075ebb7>]
(mv64xxx_i2c_xfer+0x5b/0x13c)
console: [<c075ebb7>] (mv64xxx_i2c_xfer) from [<c075951d>]
(__i2c_transfer+0x145/0x4c0)
console: [<c075951d>] (__i2c_transfer) from [<c07598f3>]
(i2c_transfer+0x5b/0xbc)
console: [<c07598f3>] (i2c_transfer) from [<c06674e9>]
(regmap_i2c_read+0x49/0x68)
console: [<c06674e9>] (regmap_i2c_read) from [<c0664241>]
(_regmap_raw_read+0x99/0x1d8)
console: [<c0664241>] (_regmap_raw_read) from [<c06643a9>]
(_regmap_bus_read+0x29/0x40)
console: [<c06643a9>] (_regmap_bus_read) from [<c066358d>]
(_regmap_read+0x3d/0xe8)
console: [<c066358d>] (_regmap_read) from [<c0663989>]
(_regmap_update_bits+0x75/0xb0)
console: [<c0663989>] (_regmap_update_bits) from [<c0664745>]
(regmap_update_bits_base+0x39/0x50)
console: [<c0664745>] (regmap_update_bits_base) from [<c06683ef>]
(regmap_irq_update_bits+0x2f/0x34)
console: [<c06683ef>] (regmap_irq_update_bits) from [<c0668df7>]
(regmap_add_irq_chip_fwnode+0x56f/0x72c)
console: [<c0668df7>] (regmap_add_irq_chip_fwnode) from [<c0668fe3>]
(regmap_add_irq_chip+0x2f/0x34)
console: [<c0668fe3>] (regmap_add_irq_chip) from [<c066e53b>]
(axp20x_device_probe+0x3f/0x368)
console: [<c066e53b>] (axp20x_device_probe) from [<c0758b93>]
(i2c_device_probe+0x1d3/0x1e4)
console: [<c0758b93>] (i2c_device_probe) from [<c064fe3b>]
(really_probe+0xb7/0x378)
console: [<c064fe3b>] (really_probe) from [<c06502c1>]
(driver_probe_device+0xa9/0x16c)
console: [<c06502c1>] (driver_probe_device) from [<c064e93d>]
(bus_for_each_drv+0x4d/0x78)
console: [<c064e93d>] (bus_for_each_drv) from [<c064fd17>]
(__device_attach+0x8f/0xf0)
console: [<c064fd17>] (__device_attach) from [<c064f29b>]
(bus_probe_device+0x5b/0x60)
console: [<c064f29b>] (bus_probe_device) from [<c064c6b7>]
(device_add+0x2e7/0x564)
console: [<c064c6b7>] (device_add) from [<c0759b1f>]
(i2c_new_client_device+0xdf/0x1bc)
console: [<c0759b1f>] (i2c_new_client_device) from [<c075c541>]
(of_i2c_register_device+0x71/0x90)
console: [<c075c541>] (of_i2c_register_device) from [<c075c771>]
(of_i2c_register_devices+0x59/0xc4)
console: [<c075c771>] (of_i2c_register_devices) from [<c075a2a9>]
(i2c_register_adapter+0x195/0x53c)
console: [<c075a2a9>] (i2c_register_adapter) from [<c075ee31>]
(mv64xxx_i2c_probe+0x199/0x440)
console: [<c075ee31>] (mv64xxx_i2c_probe) from [<c0651a7b>]
(platform_drv_probe+0x33/0x68)
console: [<c0651a7b>] (platform_drv_probe) from [<c064fe3b>]
(really_probe+0xb7/0x378)
console: [<c064fe3b>] (really_probe) from [<c06502c1>]
(driver_probe_device+0xa9/0x16c)
console: [<c06502c1>] (driver_probe_device) from [<c0650501>]
(device_driver_attach+0x3d/0x40)
console: [<c0650501>] (device_driver_attach) from [<c0650561>]
(__driver_attach+0x5d/0xe0)
console: [<c0650561>] (__driver_attach) from [<c064e8b1>]
(bus_for_each_dev+0x41/0x68)
console: [<c064e8b1>] (bus_for_each_dev) from [<c064f453>]
(bus_add_driver+0xe7/0x154)
console: [<c064f453>] (bus_add_driver) from [<c0650c8d>]
(driver_register+0x39/0xa0)
console: [<c0650c8d>] (driver_register) from [<c0101c99>]
(do_one_initcall+0x39/0x1b0)
console: [<c0101c99>] (do_one_initcall) from [<c0e00ee9>]
(kernel_init_freeable+0x1c1/0x20c)
console: [<c0e00ee9>] (kernel_init_freeable) from [<c0973ba9>]
(kernel_init+0xd/0xe0)
console: [<c0973ba9>] (kernel_init) from [<c0100159>] (ret_from_fork+0x11/0x38)
console: Exception stack(0xc1517fb0 to 0xc1517ff8)
console: 7fa0:                                     00000000 00000000
00000000 00000000
console: 7fc0: 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000
console: 7fe0: 00000000 00000000 00000000 00000000 00000013 00000000
console: handlers:
console: [<(ptrval)>] mv64xxx_i2c_intr
console: Disabling IRQ #43

RESULTS    : PASS 0 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 3
| CANCEL 0
JOB TIME   : 94.23 s


I also tried looking into the A10/A20/H3 specification, and I could
not find information about this register being W1C when TWI is used in
master mode. Can you share where that information is stated?

I can see in Linux kernel that "allwinner,sun6i-a31-i2c" compatible
devices have the "irq_clear_inverted" boolean set to true, but I also
looked at A31 spec and I could not find the W1C information for master
mode.

Hi:

I had checked the datasheet and linux source code. Not all of the sunxi SoC
has W1C feature. Only the devices compatible with 'allwinner-sun6i-a31-i2c'
has irq_clear_inverted feature.


```c
if(of_device_is_compatible(np, "allwinner,sun6i-a31-i2c"))
drv_data->irq_clear_inverted= true;
```

cubieboard is based A10 SoC, the irq flag is cleared when write 0, so this
patch make it failed. I will try fix it and send new patch later.


Also, can you share how you ran QEMU so I can try to reproduce the
hang that you encountered?

I am portting allwinner r40 device and you can read it from my github repo:
https://github.com/qianfan-Zhao/qemu/tree/allwinner-r40
R40 is compatible with sun6i-a31-i2c and you can find the W1C flag on it's
datasheet.

(DRAMC is not impl on my github repo, so the u-boot code can't work)


Best regards,
Strahinja


On Fri, Feb 17, 2023 at 10:42 AM <qianfangui...@163.com> wrote:
From: qianfan Zhao <qianfangui...@163.com>

TWI_CNTR_INT_FLAG is W1C(write 1 to clear and write 0 has non-effect)
register, we should lower interrupt when the guest write this bit.

The linux kernel will hang in irq handler(mv64xxx_i2c_intr) if no
device connected on the i2c bus, next is the trace log:

[    7.004130] axp20x-i2c 0-0034: AXP20x variant AXP221 found
allwinner_i2c_rw write   CNTR[0x0c]: e4 { A_ACK M_STA BUS_EN INT_EN  }
allwinner_i2c_rw  read   CNTR[0x0c]: cc { A_ACK INT_FLAG BUS_EN INT_EN }
allwinner_i2c_rw  read   STAT[0x10]: 08 { STAT_M_STA_TX }
allwinner_i2c_rw write   DATA[0x08]: 68
allwinner_i2c_rw write   CNTR[0x0c]: c4 { A_ACK BUS_EN INT_EN  }
allwinner_i2c_rw write   CNTR[0x0c]: cc { A_ACK INT_FLAG BUS_EN INT_EN }
allwinner_i2c_rw  read   CNTR[0x0c]: cc { A_ACK INT_FLAG BUS_EN INT_EN }
allwinner_i2c_rw  read   STAT[0x10]: 20 { STAT_M_ADDR_WR_NACK }
allwinner_i2c_rw write   CNTR[0x0c]: 54 { A_ACK M_STP BUS_EN  }
allwinner_i2c_rw write   CNTR[0x0c]: 4c { A_ACK INT_FLAG BUS_EN  }
allwinner_i2c_rw  read   CNTR[0x0c]: 4c { A_ACK INT_FLAG BUS_EN  }
allwinner_i2c_rw  read   STAT[0x10]: f8 { STAT_IDLE }
allwinner_i2c_rw write   CNTR[0x0c]: 54 { A_ACK M_STP BUS_EN  }
allwinner_i2c_rw write   CNTR[0x0c]: 4c { A_ACK INT_FLAG BUS_EN  }
allwinner_i2c_rw  read   CNTR[0x0c]: 4c { A_ACK INT_FLAG BUS_EN  }
allwinner_i2c_rw  read   STAT[0x10]: f8 { STAT_IDLE }

Fix it.

Signed-off-by: qianfan Zhao <qianfangui...@163.com>
---
  hw/i2c/allwinner-i2c.c | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/i2c/allwinner-i2c.c b/hw/i2c/allwinner-i2c.c
index 36b387520f..86a77d4a59 100644
--- a/hw/i2c/allwinner-i2c.c
+++ b/hw/i2c/allwinner-i2c.c
@@ -443,8 +443,9 @@ static void allwinner_i2c_write(void *opaque, hwaddr offset,
                  s->stat = STAT_FROM_STA(STAT_IDLE);
                  s->cntr &= ~TWI_CNTR_M_STP;
              }
-            if ((s->cntr & TWI_CNTR_INT_FLAG) == 0) {
-                /* Interrupt flag cleared */
+            if (s->cntr & TWI_CNTR_INT_FLAG) {
+                /* Write 1 to clear this flag */
+                s->cntr &= ~TWI_CNTR_INT_FLAG;
                  qemu_irq_lower(s->irq);
              }
              if ((s->cntr & TWI_CNTR_A_ACK) == 0) {
--
2.25.1



Reply via email to