[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20191127055334.1476-3-qiangqing.zhang@nxp.com>
Date: Wed, 27 Nov 2019 05:56:47 +0000
From: Joakim Zhang <qiangqing.zhang@....com>
To: "mkl@...gutronix.de" <mkl@...gutronix.de>,
"sean@...nix.com" <sean@...nix.com>,
"linux-can@...r.kernel.org" <linux-can@...r.kernel.org>
CC: dl-linux-imx <linux-imx@....com>,
"netdev@...r.kernel.org" <netdev@...r.kernel.org>,
Joakim Zhang <qiangqing.zhang@....com>
Subject: [PATCH V2 2/4] can: flexcan: try to exit stop mode during probe stage
CAN controller could be stucked in stop mode once it enters stop mode
when suspend, and then it fails to exit stop mode when resume. Only code
reset can get CAN out of stop mode, so add stop mode remove request
during probe stage for other methods(soft reset from chip level,
unbind/bind driver, etc) to let CAN active again. MCR[LPMACK] will be
checked when enable CAN in register_flexcandev().
Suggested-by: Sean Nyekjaer <sean@...nix.com>
Signed-off-by: Joakim Zhang <qiangqing.zhang@....com>
------
ChangeLog:
V1->V2: new add.
---
drivers/net/can/flexcan.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 2297663cacb2..5d5ed28d3005 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -449,6 +449,13 @@ static inline int flexcan_exit_stop_mode(struct flexcan_priv *priv)
return 0;
}
+static void flexcan_try_exit_stop_mode(struct flexcan_priv *priv)
+{
+ /* remove stop request */
+ regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr,
+ 1 << priv->stm.req_bit, 0);
+}
+
static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv)
{
struct flexcan_regs __iomem *regs = priv->regs;
@@ -1649,6 +1656,21 @@ static int flexcan_probe(struct platform_device *pdev)
priv->devtype_data = devtype_data;
priv->reg_xceiver = reg_xceiver;
+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE) {
+ err = flexcan_setup_stop_mode(pdev);
+ if (err)
+ dev_dbg(&pdev->dev, "failed to setup stop-mode\n");
+
+ /* CAN controller could be stucked in stop mode once it enters
+ * stop mode when suspend, and then it fails to exit stop
+ * mode when resume. Only code reset can get CAN out of stop
+ * mode, so add stop mode remove request here for other methods
+ * (soft reset, bind, etc) to let CAN active again. MCR[LPMACK]
+ * will be checked when enable CAN in register_flexcandev().
+ */
+ flexcan_try_exit_stop_mode(priv);
+ }
+
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
@@ -1661,12 +1683,6 @@ static int flexcan_probe(struct platform_device *pdev)
devm_can_led_init(dev);
- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE) {
- err = flexcan_setup_stop_mode(pdev);
- if (err)
- dev_dbg(&pdev->dev, "failed to setup stop-mode\n");
- }
-
return 0;
failed_register:
--
2.17.1
Powered by blists - more mailing lists