Received: by 2002:a25:8b12:0:0:0:0:0 with SMTP id i18csp1087019ybl; Wed, 14 Aug 2019 10:29:20 -0700 (PDT) X-Google-Smtp-Source: APXvYqxhlDUWH9tfosPEtqh+kRc13I3yod4P+iG2txOfdKEhNaCASrgMVhyJMHMu5i/Fql+SSViI X-Received: by 2002:a17:90b:911:: with SMTP id bo17mr781281pjb.40.1565803760575; Wed, 14 Aug 2019 10:29:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1565803760; cv=none; d=google.com; s=arc-20160816; b=VYD/ghuafDXBoAJqPGTHSLfsfQZ7bG/ohXCI+ccq9e22ipdBYEIRArcna8iwYPh4VF ox71Xq9VwuO+mTLXrWZ8XZJX/rJLKRBV9Wt8oGxsDWohPzmksFKo0xObngf+4Y3bUcmR 9H99r0jSOlxDgn2TsRdVAa87wPP7hMJQs82ZVQBQuSwZWhScuBT8QHvujP7o1PWXyiID fdFC2r3Vw2iFTb///P76/cqUwsnxxYzex05Wqc3Yk0n4iq/7+rDpVDomr+kG2IOnPSBP sD2Noiv/g7ZF/4iBVJm2sWY2uHHNRLo2cXNC6HWdrv0prE/ZvhtoZ+A15AGN9MjWqc2c 3CAg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=kBlw1aRyeS8T1IEP/WxvvWmsSwCx/y+/DdWQoalQq3U=; b=mFdnlFWitZeZxYg9QX+KnPFVkvIHNZeTefaqBtjUI7ZTdEcx4DyzQkNeQmUy43avhS VBpXoF6pBxptTLmRALHWuZO0xqIqfDIl7VpH8KfieRvjFEPRF08L/7hVrbFB5BlN5FZX +XFCwul1cbszwEjFZ0cFcJ91fSQjoiRFPvdY3IrWZbcEHph00tLVTd8YY11kU1AgVtFK SM/TdsrKv88MpM176dv3Qtz0MtQywrh7zesmkB3VaVtAmq+O3jsTrLzwi9mjoaP2v/K8 qUCXe+rvq+jan3C4ksca3ZCukP/MeK6CqZhk3529SWXczBLSGjGDbub9pJCQbeOyuspb OPHA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=cWYytbRe; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n6si180641pgs.333.2019.08.14.10.29.04; Wed, 14 Aug 2019 10:29:20 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=cWYytbRe; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729402AbfHNR1L (ORCPT + 99 others); Wed, 14 Aug 2019 13:27:11 -0400 Received: from mail.kernel.org ([198.145.29.99]:52622 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729036AbfHNRDx (ORCPT ); Wed, 14 Aug 2019 13:03:53 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 7E66321721; Wed, 14 Aug 2019 17:03:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1565802233; bh=7oC41y1/DvvtuaK/R0aXPzmQz9Z45akuQkvn+dDeXj4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cWYytbReroHPVcsn+MvFHhHwST7A/uYDaMO3cOfcf+bkYUlEYwi/S1EleqM9+I65N gt5DonQB0aG83BvRT9NMjU5ZsNqjIsiCt2lFbW6OBv6L+aaZFHg5wmRyejvIoU+70b 66+t8JVPmrNWb529ubu7s+UJVmSQTZdHmi7s9Xfg= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Marc Kleine-Budde , Joakim Zhang Subject: [PATCH 5.2 046/144] can: flexcan: fix stop mode acknowledgment Date: Wed, 14 Aug 2019 19:00:02 +0200 Message-Id: <20190814165801.752037420@linuxfoundation.org> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190814165759.466811854@linuxfoundation.org> References: <20190814165759.466811854@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Joakim Zhang commit 5f186c257fa4808bb7f14e643b9fba3e11f08a30 upstream. To enter stop mode, the CPU should manually assert a global Stop Mode request and check the acknowledgment asserted by FlexCAN. The CPU must only consider the FlexCAN in stop mode when both request and acknowledgment conditions are satisfied. Fixes: de3578c198c6 ("can: flexcan: add self wakeup support") Reported-by: Marc Kleine-Budde Signed-off-by: Joakim Zhang Cc: linux-stable # >= v5.0 Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/flexcan.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -400,9 +400,10 @@ static void flexcan_enable_wakeup_irq(st priv->write(reg_mcr, ®s->mcr); } -static inline void flexcan_enter_stop_mode(struct flexcan_priv *priv) +static inline int flexcan_enter_stop_mode(struct flexcan_priv *priv) { struct flexcan_regs __iomem *regs = priv->regs; + unsigned int ackval; u32 reg_mcr; reg_mcr = priv->read(®s->mcr); @@ -412,20 +413,37 @@ static inline void flexcan_enter_stop_mo /* enable stop request */ regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr, 1 << priv->stm.req_bit, 1 << priv->stm.req_bit); + + /* get stop acknowledgment */ + if (regmap_read_poll_timeout(priv->stm.gpr, priv->stm.ack_gpr, + ackval, ackval & (1 << priv->stm.ack_bit), + 0, FLEXCAN_TIMEOUT_US)) + return -ETIMEDOUT; + + return 0; } -static inline void flexcan_exit_stop_mode(struct flexcan_priv *priv) +static inline int flexcan_exit_stop_mode(struct flexcan_priv *priv) { struct flexcan_regs __iomem *regs = priv->regs; + unsigned int ackval; u32 reg_mcr; /* remove stop request */ regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr, 1 << priv->stm.req_bit, 0); + /* get stop acknowledgment */ + if (regmap_read_poll_timeout(priv->stm.gpr, priv->stm.ack_gpr, + ackval, !(ackval & (1 << priv->stm.ack_bit)), + 0, FLEXCAN_TIMEOUT_US)) + return -ETIMEDOUT; + reg_mcr = priv->read(®s->mcr); reg_mcr &= ~FLEXCAN_MCR_SLF_WAK; priv->write(reg_mcr, ®s->mcr); + + return 0; } static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv) @@ -1612,7 +1630,9 @@ static int __maybe_unused flexcan_suspen */ if (device_may_wakeup(device)) { enable_irq_wake(dev->irq); - flexcan_enter_stop_mode(priv); + err = flexcan_enter_stop_mode(priv); + if (err) + return err; } else { err = flexcan_chip_disable(priv); if (err) @@ -1662,10 +1682,13 @@ static int __maybe_unused flexcan_noirq_ { struct net_device *dev = dev_get_drvdata(device); struct flexcan_priv *priv = netdev_priv(dev); + int err; if (netif_running(dev) && device_may_wakeup(device)) { flexcan_enable_wakeup_irq(priv, false); - flexcan_exit_stop_mode(priv); + err = flexcan_exit_stop_mode(priv); + if (err) + return err; } return 0;