Received: by 2002:a05:6a10:9e8c:0:0:0:0 with SMTP id y12csp1080057pxx; Fri, 30 Oct 2020 01:08:07 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzbDl6fNuyxT9XZ1V4ZZ6DvDzHPe6mVUx3nijfaRDe+iW+xb6COsqnO08zpMUL+YDuR/NHY X-Received: by 2002:a17:906:52c6:: with SMTP id w6mr1179731ejn.199.1604045287448; Fri, 30 Oct 2020 01:08:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1604045287; cv=none; d=google.com; s=arc-20160816; b=gfvAVWKgTe0AaPNeg0ViUDg3yMiEFd8zmBSKJNtWErwGOVfHoQmNosdJc+yRhOOAoz Shlf5XrnyNcgohA/WjKoOCdOWewqEFLmiurNuUpZQLrW7560Uuzm2RQnotjv66FBc4RP DgJk4+YF8erVjITwr7UffvbR7ZnlzWyhj3QqALbVDkfg1GEtEV2m/RdvqxF8OmUuVPp0 HalcSg0wOffPP2U/OqHIXU8gtk9co3ZASzHGOSX7Yyu4JUstq/V7EtS/LPrgTMcGSpXT FvnqGLwkK5hb7U0ThBFBTn+U5L4Iri8t2pVVc3rn7iNNWDM+F0AGA3ZCLabqYZuECL6T dIPg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:message-id:date:subject:cc:to:from :dkim-signature; bh=ECF5VlgUT7MZAjqCXV2X/LFjRoTX9Mtp2Qy4jq7s1LQ=; b=qv+amDHmlcKaXKcveIYkvsbkN4GQtLDExIXtOeNILTuV2Idac7DG5QTbYTlqBnVYC7 KpzkdVoWk66d0mPXSb1W3ObDPVbioNTsffKB8pjApIWmyHAGtksT2TzzIK+tSEKxOUcs 80L1PpZA6P+gwmOngHPdrEm6611dHEVvmMDt5Yi1qvk99z9qaIsCpLTATS/71kbbAcqF rvzQlLfkenuVfGS53uMC1XbDk6MSdhY3dNcnuPUanenQAxJfhSCMpEBvJqb0vnC2JbfW QANdAu7Po6TuZ4dvsjnd7Sg4yTrgMwIrqs1mXj6bVCc0dDcqm8dhAoOoh0PFYJhBdKA3 xnrw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@vivotek.com header.s=dkim header.b=NhVda22k; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id bs4si3851336edb.290.2020.10.30.01.07.45; Fri, 30 Oct 2020 01:08:07 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@vivotek.com header.s=dkim header.b=NhVda22k; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725995AbgJ3IFQ (ORCPT + 99 others); Fri, 30 Oct 2020 04:05:16 -0400 Received: from mail.vivotek.com ([60.248.39.150]:48994 "EHLO mail.vivotek.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726082AbgJ3IFK (ORCPT ); Fri, 30 Oct 2020 04:05:10 -0400 Received: from pps.filterd (vivotekpps.vivotek.com [127.0.0.1]) by vivotekpps.vivotek.com (8.16.0.42/8.16.0.42) with SMTP id 09U80MIm015010; Fri, 30 Oct 2020 16:04:56 +0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vivotek.com; h=from : to : cc : subject : date : message-id : mime-version : content-type; s=dkim; bh=ECF5VlgUT7MZAjqCXV2X/LFjRoTX9Mtp2Qy4jq7s1LQ=; b=NhVda22k2X3jNVi6kCfPI9OJ1drN1d++14RrbjCBvtM4NASCJVBH/wrVNoIYlMJ1i7PA wIk2hYjXwBJgIB+90nQCz8C2DQ3aYJjFPQYYxwx5XE2suFwQAGRzzotxmkh36TubgrOm 0TBOOR3cPbfO6GRzb4qcev3pk8Q5b2RZtB8= Received: from cas01.vivotek.tw ([192.168.0.58]) by vivotekpps.vivotek.com with ESMTP id 34c6q166qp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Fri, 30 Oct 2020 16:04:56 +0800 Received: from localhost.localdomain (192.168.17.134) by CAS01.vivotek.tw (192.168.0.58) with Microsoft SMTP Server (TLS) id 14.3.487.0; Fri, 30 Oct 2020 16:04:55 +0800 From: Michael Wu To: Jarkko Nikula , Andy Shevchenko , Mika Westerberg , Wolfram Sang , , CC: Morgan Chang , Michael Wu Subject: [PATCH 0/2] Designware I2C slave confusing IC_INTR_STOP_DET handle Date: Fri, 30 Oct 2020 16:04:18 +0800 Message-ID: <20201030080420.28016-1-michael.wu@vatics.com> X-Mailer: git-send-email 2.17.1 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [192.168.17.134] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.312,18.0.737 definitions=2020-10-29_12:2020-10-29,2020-10-29 signatures=0 X-Proofpoint-Spam-Reason: safe Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When an I2C slave works, sometimes both IC_INTR_RX_FULL and IC_INTR_STOP_DET may be rising during an IRQ handle, especially when system is busy or too late to handle interrupts. If IC_INTR_RX_FULL is rising and the system doesn't handle immediately, IC_INTR_STOP_DET may be rising and the system has to handle these two events. For this there may be two problems: 1. IC_INTR_STOP_DET is rising after i2c_dw_read_clear_intrbits_slave() done: It seems invalidated because I2C_SLAVE_WRITE_REQUESTED is reported after the 1st I2C_SLAVE_WRITE_RECEIVED. $ i2cset -f -y 2 0x42 0x00 0x41; dmesg -c [0][clear_intrbits]0x1 STATUS SLAVE_ACTIVITY=0x1 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4 [1][irq_handler ]0x1 STATUS SLAVE_ACTIVITY=0x1 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4 I2C_SLAVE_WRITE_RECEIVED [0][clear_intrbits]0x1 STATUS SLAVE_ACTIVITY=0x1 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4 [1][irq_handler ]0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x714 : INTR_STAT=0x204 I2C_SLAVE_WRITE_REQUESTED I2C_SLAVE_WRITE_RECEIVED [0][clear_intrbits]0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x710 : INTR_STAT=0x200 [1][irq_handler ]0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x510 : INTR_STAT=0x0 I2C_SLAVE_STOP [2][clear_intrbits]0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x510 : INTR_STAT=0x0 t1: ISR with the 1st IC_INTR_RX_FULL. t2: Clear listed IC_INTR bits by i2c_dw_read_clear_intrbits_slave(). t3: Enter i2c_dw_irq_handler_slave() and then report I2C_SLAVE_WRITE_RECEIVED due to 'if (stat & DW_IC_INTR_RX_FULL)' matched. t4: ISR with the 2nd IC_INTR_RX_FULL. t5: Clear listed IC_INTR bits by i2c_dw_read_clear_intrbits_slave() while IC_INTR_STOP_DET has not risen yet. t6: IC_INTR_STOP_DET is rising after entering i2c_dw_irq_handler_slave(). The driver reports I2C_SLAVE_WRITE_REQUESTED first due to 'if ((stat & DW_IC_INTR_RX_FULL) && (stat & DW_IC_INTR_STOP_DET))' matched and then reports I2C_SLAVE_WRITE_RECEIVED. t7: Reports I2C_SLAVE_STOP due to IC_INTR_STOP_DET not be cleared yet. 2. Both IC_INTR_STOP_DET and IC_INTR_RX_FULL are rising before i2c_dw_read_clear_intrbits_slave(): I2C_SLAVE_STOP never be reported because IC_INTR_STOP_DET was cleared by i2c_dw_read_clear_intrbits_slave(). $ i2cset -f -y 2 0x42 0x00 0x41; dmesg -c [0][clear_intrbits]0x1 STATUS SLAVE_ACTIVITY=0x1 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4 [1][irq_handler ]0x1 STATUS SLAVE_ACTIVITY=0x1 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4 I2C_SLAVE_WRITE_RECEIVED [0][clear_intrbits]0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x714 : INTR_STAT=0x204 [1][irq_handler ]0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4 I2C_SLAVE_WRITE_RECEIVED t1: ISR with the 1st IC_INTR_RX_FULL. t2: Clear listed IC_INTR bits by i2c_dw_read_clear_intrbits_slave(). t3: Enter i2c_dw_irq_handler_slave() and then report I2C_SLAVE_WRITE_RECEIVED due to 'if (stat & DW_IC_INTR_RX_FULL)' matched. t4: ISR with both IC_INTR_STOP_DET and the 2nd IC_INTR_RX_FULL. t5: Clear listed IC_INTR bits by i2c_dw_read_clear_intrbits_slave(). The current IC_INTR_STOP_DET was cleared by this i2c_dw_read_clear_intrbits_slave(). t6: Enter i2c_dw_irq_handler_slave() and then report i2c_slave_event(WRITE_RECEIVED) due to 'if (stat & DW_IC_INTR_RX_FULL)' matched. t7: I2C_SLAVE_STOP never be reported because IC_INTR_STOP_DET was cleared in t5. In order to resolve these problems, i2c_dw_read_clear_intrbits_slave() should be called only once in an ISR and take the returned stat to handle those occurred events. The ISR handling has to be adjusted to conform event reporting described in Documentation/i2c/slave-interface.rst. Michael Wu (2): i2c: designware: call i2c_dw_read_clear_intrbits_slave() once i2c: designware: slave should do WRITE_REQUESTED before WRITE_RECEIVED drivers/i2c/busses/i2c-designware-slave.c | 52 +++++++++-------------- 1 file changed, 19 insertions(+), 33 deletions(-) -- 2.17.1