From patchwork Wed Jul 20 22:25:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Wang X-Patchwork-Id: 12924570 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C0C5EC433EF for ; Wed, 20 Jul 2022 23:07:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:MIME-Version: References:In-Reply-To:Message-ID:Date:Subject:CC:To:From:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=JiYeLDTjPl1YCY6DR3DRu1qSRQC2eHaAqNUKJHwRW/U=; b=a0vUukmQG5H+5523tQ64raqAFw PaTAFo5qbeabFvVA9aSRffvRAjuw1ojSZl2i1HJhvUt42q6e1Ol0Gwyhie5KIy8nmo0RtsdFnmxuH XoQmHwaNG6No76qO4k/nPzn9NzEbv+Gz11HPCrOnkNmR/OcvTFMvNIyK9HNh28vja4JynzcqyyTKi GLr8p9r6Iw3cEEPGir3vzBhd8rRvkOjN9VCay392aDCK0nFH7+m4gy9QTNdy1R7stBCEG2J0ErENe K61eadMm1ezuTSUdhgcxS1RyTGfJUtgf9HPxMykBPyUNqwrjnoRkESox0M6bpS40oOua3iZwWxeQo PcB38wKw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oEImV-00Cx7a-Hg; Wed, 20 Jul 2022 23:07:03 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oEImM-00Cx0c-BU for linux-mediatek@lists.infradead.org; Wed, 20 Jul 2022 23:06:55 +0000 X-UUID: 673ead30fa8a46af8754c917e926ec60-20220720 X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.8,REQID:1083e6da-96b3-451a-bcbd-e15ad4f26a87,OB:0,LO B:0,IP:0,URL:5,TC:0,Content:-5,EDM:0,RT:0,SF:0,FILE:0,RULE:Release_Ham,ACT ION:release,TS:0 X-CID-META: VersionHash:0f94e32,CLOUDID:c2c5d464-0b3f-4b2c-b3a6-ed5c044366a0,C OID:IGNORED,Recheck:0,SF:nil,TC:nil,Content:0,EDM:-3,IP:nil,URL:1,File:nil ,QS:nil,BEC:nil,COL:0 X-UUID: 673ead30fa8a46af8754c917e926ec60-20220720 Received: from mtkmbs11n1.mediatek.inc [(172.21.101.185)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 386405270; Wed, 20 Jul 2022 16:06:47 -0700 Received: from mtkmbs11n1.mediatek.inc (172.21.101.185) by mtkmbs10n2.mediatek.inc (172.21.101.183) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.792.3; Thu, 21 Jul 2022 06:25:42 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkmbs11n1.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.792.3 via Frontend Transport; Thu, 21 Jul 2022 06:25:41 +0800 From: To: , CC: , , , , , , , , , , , , , , , , , , , , , , , Subject: [PATCH v2 3/4] mt76: mt7921u: fix race issue between reset and suspend/resume Date: Thu, 21 Jul 2022 06:25:39 +0800 Message-ID: <983945d762b95c0259cc8d7702e5e25fffcc0ef0.1658355599.git.sean.wang@kernel.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <5f835553ee8b76e4a4ed83f9562eaa0b1a24c1e6.1658355599.git.sean.wang@kernel.org> References: <5f835553ee8b76e4a4ed83f9562eaa0b1a24c1e6.1658355599.git.sean.wang@kernel.org> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220720_160654_418600_94126B89 X-CRM114-Status: GOOD ( 16.20 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Sean Wang It is unexpected that the reset work is running simultaneously with the suspend or resume context and it is possible that reset work is still running even after mt7921 is suspended if we don't fix the race issue. Thus, the suspend procedure should be waiting until the reset is completed at the beginning and ignore the subsequent the reset requests. In case there is an error that happens during either suspend or resume handler, we will schedule a reset task to recover the error before returning the error code to ensure we can immediately fix the error there. Fixes: df3e4143ba8a ("mt76: mt7921u: add suspend/resume support") Co-developed-by: YN Chen Signed-off-by: YN Chen Signed-off-by: Sean Wang --- v2: use flush_work instead of cancel_work_sync --- .../net/wireless/mediatek/mt76/mt7921/usb.c | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c index dd3b8884e162..613d5cefffc7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c @@ -300,11 +300,15 @@ static void mt7921u_disconnect(struct usb_interface *usb_intf) static int mt7921u_suspend(struct usb_interface *intf, pm_message_t state) { struct mt7921_dev *dev = usb_get_intfdata(intf); + struct mt76_connac_pm *pm = &dev->pm; int err; + pm->suspended = true; + flush_work(&dev->reset_work); + err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true); if (err) - return err; + goto failed; mt76u_stop_rx(&dev->mt76); mt76u_stop_tx(&dev->mt76); @@ -312,11 +316,20 @@ static int mt7921u_suspend(struct usb_interface *intf, pm_message_t state) set_bit(MT76_STATE_SUSPEND, &dev->mphy.state); return 0; + +failed: + pm->suspended = false; + + if (err < 0) + mt7921_reset(&dev->mt76); + + return err; } static int mt7921u_resume(struct usb_interface *intf) { struct mt7921_dev *dev = usb_get_intfdata(intf); + struct mt76_connac_pm *pm = &dev->pm; bool reinit = true; int err, i; @@ -338,16 +351,23 @@ static int mt7921u_resume(struct usb_interface *intf) if (reinit || mt7921_dma_need_reinit(dev)) { err = mt7921u_dma_init(dev, true); if (err) - return err; + goto failed; } clear_bit(MT76_STATE_SUSPEND, &dev->mphy.state); err = mt76u_resume_rx(&dev->mt76); if (err < 0) - return err; + goto failed; + + err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false); +failed: + pm->suspended = false; + + if (err < 0) + mt7921_reset(&dev->mt76); - return mt76_connac_mcu_set_hif_suspend(&dev->mt76, false); + return err; } #endif /* CONFIG_PM */