can: mcp251xfd: __mcp251xfd_chip_set_mode(): prepare for PLL support: improve error...
authorMarc Kleine-Budde <mkl@pengutronix.de>
Wed, 21 Oct 2020 08:33:58 +0000 (10:33 +0200)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Thu, 24 Feb 2022 07:46:59 +0000 (08:46 +0100)
This patch prepares the __mcp251xfd_chip_set_mode() function for PLL
support by adding more error checks and diagnostics.

Link: https://lore.kernel.org/all/20220207131047.282110-13-mkl@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c

index 154e6c37667044c428d3d9e71add843f81d49bf4..d08e0481df35f3f3701c26d836b3a383c14d10e7 100644 (file)
@@ -218,34 +218,55 @@ static int
 __mcp251xfd_chip_set_mode(const struct mcp251xfd_priv *priv,
                          const u8 mode_req, bool nowait)
 {
-       u32 con, con_reqop;
+       u32 con = 0, con_reqop, osc = 0;
+       u8 mode;
        int err;
 
        con_reqop = FIELD_PREP(MCP251XFD_REG_CON_REQOP_MASK, mode_req);
        err = regmap_update_bits(priv->map_reg, MCP251XFD_REG_CON,
                                 MCP251XFD_REG_CON_REQOP_MASK, con_reqop);
-       if (err)
+       if (err == -EBADMSG) {
+               netdev_err(priv->ndev,
+                          "Failed to set Requested Operation Mode.\n");
+
+               return -ENODEV;
+       } else if (err) {
                return err;
+       }
 
        if (mode_req == MCP251XFD_REG_CON_MODE_SLEEP || nowait)
                return 0;
 
        err = regmap_read_poll_timeout(priv->map_reg, MCP251XFD_REG_CON, con,
+                                      !mcp251xfd_reg_invalid(con) &&
                                       FIELD_GET(MCP251XFD_REG_CON_OPMOD_MASK,
                                                 con) == mode_req,
                                       MCP251XFD_POLL_SLEEP_US,
                                       MCP251XFD_POLL_TIMEOUT_US);
-       if (err) {
-               u8 mode = FIELD_GET(MCP251XFD_REG_CON_OPMOD_MASK, con);
+       if (err != -ETIMEDOUT && err != -EBADMSG)
+               return err;
+
+       /* Ignore return value.
+        * Print below error messages, even if this fails.
+        */
+       regmap_read(priv->map_reg, MCP251XFD_REG_OSC, &osc);
 
+       if (mcp251xfd_reg_invalid(con)) {
                netdev_err(priv->ndev,
-                          "Controller failed to enter mode %s Mode (%u) and stays in %s Mode (%u).\n",
-                          mcp251xfd_get_mode_str(mode_req), mode_req,
-                          mcp251xfd_get_mode_str(mode), mode);
-               return err;
+                          "Failed to read CAN Control Register (con=0x%08x, osc=0x%08x).\n",
+                          con, osc);
+
+               return -ENODEV;
        }
 
-       return 0;
+       mode = FIELD_GET(MCP251XFD_REG_CON_OPMOD_MASK, con);
+       netdev_err(priv->ndev,
+                  "Controller failed to enter mode %s Mode (%u) and stays in %s Mode (%u) (con=0x%08x, osc=0x%08x).\n",
+                  mcp251xfd_get_mode_str(mode_req), mode_req,
+                  mcp251xfd_get_mode_str(mode), mode,
+                  con, osc);
+
+       return -ETIMEDOUT;
 }
 
 static inline int