* [PATCH v6 1/6] can: mcp251xfd: move chip sleep mode into runtime pm
2025-10-01 9:10 [PATCH v6 0/6] can: mcp251xfd: add gpio functionality Viken Dadhaniya
@ 2025-10-01 9:10 ` Viken Dadhaniya
2025-10-01 9:10 ` [PATCH v6 2/6] can: mcp251xfd: utilize gather_write function for all non-CRC writes Viken Dadhaniya
` (6 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Viken Dadhaniya @ 2025-10-01 9:10 UTC (permalink / raw)
To: mkl, mani, thomas.kopp, mailhol.vincent, robh, krzk+dt, conor+dt,
linus.walleij, brgl, linux-can, devicetree, linux-kernel
Cc: mukesh.savaliya, anup.kulkarni, Gregor Herburger, Viken Dadhaniya
From: Marc Kleine-Budde <mkl@pengutronix.de>
This is a preparation patch to add GPIO support.
Up to now, the Vdd regulator and the clocks have been managed by
Runtime-PM (on systems without CONFIG_PM these remain permanently
switched on).
During the mcp251xfd_open() callback the mcp251xfd is powered,
soft-reset and configured. In mcp251xfd_stop() the chip is shut down
again. To support the on-chip GPIOs, the chip must be supplied with
power while GPIOs are being requested, even if the networking
interface is down.
To support this, move the functions mcp251xfd_chip_softreset() and
mcp251xfd_chip_clock_init() from mcp251xfd_chip_start() to
mcp251xfd_runtime_resume(). Instead of setting the controller to sleep
mode in mcp251xfd_chip_stop(), bring it into configuration mode. This
way it doesn't take part in bus activity and doesn't enter sleep mode.
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Gregor Herburger <gregor.herburger@ew.tq-group.com>
Tested-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
Signed-off-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
---
.../net/can/spi/mcp251xfd/mcp251xfd-core.c | 91 ++++++++++++-------
1 file changed, 57 insertions(+), 34 deletions(-)
diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
index 7450ea42c1ea..f9eabb1810cf 100644
--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
@@ -767,21 +767,13 @@ static void mcp251xfd_chip_stop(struct mcp251xfd_priv *priv,
mcp251xfd_chip_interrupts_disable(priv);
mcp251xfd_chip_rx_int_disable(priv);
mcp251xfd_timestamp_stop(priv);
- mcp251xfd_chip_sleep(priv);
+ mcp251xfd_chip_set_mode(priv, MCP251XFD_REG_CON_MODE_CONFIG);
}
static int mcp251xfd_chip_start(struct mcp251xfd_priv *priv)
{
int err;
- err = mcp251xfd_chip_softreset(priv);
- if (err)
- goto out_chip_stop;
-
- err = mcp251xfd_chip_clock_init(priv);
- if (err)
- goto out_chip_stop;
-
err = mcp251xfd_chip_timestamp_init(priv);
if (err)
goto out_chip_stop;
@@ -1625,8 +1617,11 @@ static int mcp251xfd_open(struct net_device *ndev)
return err;
err = pm_runtime_resume_and_get(ndev->dev.parent);
- if (err)
+ if (err) {
+ if (err == -ETIMEDOUT || err == -ENODEV)
+ pm_runtime_set_suspended(ndev->dev.parent);
goto out_close_candev;
+ }
err = mcp251xfd_ring_alloc(priv);
if (err)
@@ -1907,53 +1902,53 @@ static int mcp251xfd_register(struct mcp251xfd_priv *priv)
struct net_device *ndev = priv->ndev;
int err;
+ mcp251xfd_register_quirks(priv);
+
err = mcp251xfd_clks_and_vdd_enable(priv);
if (err)
return err;
- pm_runtime_get_noresume(ndev->dev.parent);
- err = pm_runtime_set_active(ndev->dev.parent);
- if (err)
- goto out_runtime_put_noidle;
- pm_runtime_enable(ndev->dev.parent);
-
- mcp251xfd_register_quirks(priv);
-
err = mcp251xfd_chip_softreset(priv);
if (err == -ENODEV)
- goto out_runtime_disable;
+ goto out_clks_and_vdd_disable;
if (err)
goto out_chip_sleep;
err = mcp251xfd_chip_clock_init(priv);
if (err == -ENODEV)
- goto out_runtime_disable;
+ goto out_clks_and_vdd_disable;
if (err)
goto out_chip_sleep;
+ pm_runtime_get_noresume(ndev->dev.parent);
+ err = pm_runtime_set_active(ndev->dev.parent);
+ if (err)
+ goto out_runtime_put_noidle;
+ pm_runtime_enable(ndev->dev.parent);
+
err = mcp251xfd_register_chip_detect(priv);
if (err)
- goto out_chip_sleep;
+ goto out_runtime_disable;
err = mcp251xfd_register_check_rx_int(priv);
if (err)
- goto out_chip_sleep;
+ goto out_runtime_disable;
mcp251xfd_ethtool_init(priv);
err = register_candev(ndev);
if (err)
- goto out_chip_sleep;
+ goto out_runtime_disable;
err = mcp251xfd_register_done(priv);
if (err)
goto out_unregister_candev;
- /* Put controller into sleep mode and let pm_runtime_put()
- * disable the clocks and vdd. If CONFIG_PM is not enabled,
- * the clocks and vdd will stay powered.
+ /* Put controller into Config mode and let pm_runtime_put()
+ * put in sleep mode, disable the clocks and vdd. If CONFIG_PM
+ * is not enabled, the clocks and vdd will stay powered.
*/
- err = mcp251xfd_chip_sleep(priv);
+ err = mcp251xfd_chip_set_mode(priv, MCP251XFD_REG_CON_MODE_CONFIG);
if (err)
goto out_unregister_candev;
@@ -1963,12 +1958,13 @@ static int mcp251xfd_register(struct mcp251xfd_priv *priv)
out_unregister_candev:
unregister_candev(ndev);
-out_chip_sleep:
- mcp251xfd_chip_sleep(priv);
out_runtime_disable:
pm_runtime_disable(ndev->dev.parent);
out_runtime_put_noidle:
pm_runtime_put_noidle(ndev->dev.parent);
+out_chip_sleep:
+ mcp251xfd_chip_sleep(priv);
+out_clks_and_vdd_disable:
mcp251xfd_clks_and_vdd_disable(priv);
return err;
@@ -1980,10 +1976,12 @@ static inline void mcp251xfd_unregister(struct mcp251xfd_priv *priv)
unregister_candev(ndev);
- if (pm_runtime_enabled(ndev->dev.parent))
+ if (pm_runtime_enabled(ndev->dev.parent)) {
pm_runtime_disable(ndev->dev.parent);
- else
+ } else {
+ mcp251xfd_chip_sleep(priv);
mcp251xfd_clks_and_vdd_disable(priv);
+ }
}
static const struct of_device_id mcp251xfd_of_match[] = {
@@ -2206,16 +2204,41 @@ static void mcp251xfd_remove(struct spi_device *spi)
static int __maybe_unused mcp251xfd_runtime_suspend(struct device *device)
{
- const struct mcp251xfd_priv *priv = dev_get_drvdata(device);
+ struct mcp251xfd_priv *priv = dev_get_drvdata(device);
+ mcp251xfd_chip_sleep(priv);
return mcp251xfd_clks_and_vdd_disable(priv);
}
static int __maybe_unused mcp251xfd_runtime_resume(struct device *device)
{
- const struct mcp251xfd_priv *priv = dev_get_drvdata(device);
+ struct mcp251xfd_priv *priv = dev_get_drvdata(device);
+ int err;
+
+ err = mcp251xfd_clks_and_vdd_enable(priv);
+ if (err)
+ return err;
- return mcp251xfd_clks_and_vdd_enable(priv);
+ err = mcp251xfd_chip_softreset(priv);
+ if (err == -ENODEV)
+ goto out_clks_and_vdd_disable;
+ if (err)
+ goto out_chip_sleep;
+
+ err = mcp251xfd_chip_clock_init(priv);
+ if (err == -ENODEV)
+ goto out_clks_and_vdd_disable;
+ if (err)
+ goto out_chip_sleep;
+
+ return 0;
+
+out_chip_sleep:
+ mcp251xfd_chip_sleep(priv);
+out_clks_and_vdd_disable:
+ mcp251xfd_clks_and_vdd_disable(priv);
+
+ return err;
}
static const struct dev_pm_ops mcp251xfd_pm_ops = {
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v6 2/6] can: mcp251xfd: utilize gather_write function for all non-CRC writes
2025-10-01 9:10 [PATCH v6 0/6] can: mcp251xfd: add gpio functionality Viken Dadhaniya
2025-10-01 9:10 ` [PATCH v6 1/6] can: mcp251xfd: move chip sleep mode into runtime pm Viken Dadhaniya
@ 2025-10-01 9:10 ` Viken Dadhaniya
2025-10-01 9:10 ` [PATCH v6 3/6] can: mcp251xfd: add workaround for errata 5 Viken Dadhaniya
` (5 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Viken Dadhaniya @ 2025-10-01 9:10 UTC (permalink / raw)
To: mkl, mani, thomas.kopp, mailhol.vincent, robh, krzk+dt, conor+dt,
linus.walleij, brgl, linux-can, devicetree, linux-kernel
Cc: mukesh.savaliya, anup.kulkarni, Gregor Herburger, Viken Dadhaniya
From: Gregor Herburger <gregor.herburger@ew.tq-group.com>
This is a preparation patch to add errata workaround for non crc writes.
Currently for non-crc writes to the chip can go through the
.gather_write, .write or the reg_update_bits callback.
To allow the addition of the errata fix at a single location use
mcp251xfd_regmap_nocrc_gather_write for all non-CRC write instructions,
similar to the crc regmap.
Signed-off-by: Gregor Herburger <gregor.herburger@ew.tq-group.com>
Tested-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
Signed-off-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
---
.../net/can/spi/mcp251xfd/mcp251xfd-regmap.c | 25 ++++++++++---------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c
index 8c5be8d1c519..e61cbd209955 100644
--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c
+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c
@@ -12,14 +12,6 @@
static const struct regmap_config mcp251xfd_regmap_crc;
-static int
-mcp251xfd_regmap_nocrc_write(void *context, const void *data, size_t count)
-{
- struct spi_device *spi = context;
-
- return spi_write(spi, data, count);
-}
-
static int
mcp251xfd_regmap_nocrc_gather_write(void *context,
const void *reg, size_t reg_len,
@@ -47,6 +39,15 @@ mcp251xfd_regmap_nocrc_gather_write(void *context,
return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
}
+static int
+mcp251xfd_regmap_nocrc_write(void *context, const void *data, size_t count)
+{
+ const size_t data_offset = sizeof(__be16);
+
+ return mcp251xfd_regmap_nocrc_gather_write(context, data, data_offset,
+ data + data_offset, count - data_offset);
+}
+
static inline bool
mcp251xfd_update_bits_read_reg(const struct mcp251xfd_priv *priv,
unsigned int reg)
@@ -64,6 +65,7 @@ mcp251xfd_update_bits_read_reg(const struct mcp251xfd_priv *priv,
case MCP251XFD_REG_CON:
case MCP251XFD_REG_OSC:
case MCP251XFD_REG_ECCCON:
+ case MCP251XFD_REG_IOCON:
return true;
default:
mcp251xfd_for_each_rx_ring(priv, ring, n) {
@@ -139,10 +141,9 @@ mcp251xfd_regmap_nocrc_update_bits(void *context, unsigned int reg,
tmp_le32 = orig_le32 & ~mask_le32;
tmp_le32 |= val_le32 & mask_le32;
- mcp251xfd_spi_cmd_write_nocrc(&buf_tx->cmd, reg + first_byte);
- memcpy(buf_tx->data, &tmp_le32, len);
-
- return spi_write(spi, buf_tx, sizeof(buf_tx->cmd) + len);
+ reg += first_byte;
+ mcp251xfd_spi_cmd_write_nocrc(&buf_tx->cmd, reg);
+ return mcp251xfd_regmap_nocrc_gather_write(context, &buf_tx->cmd, 2, &tmp_le32, len);
}
static int
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v6 3/6] can: mcp251xfd: add workaround for errata 5
2025-10-01 9:10 [PATCH v6 0/6] can: mcp251xfd: add gpio functionality Viken Dadhaniya
2025-10-01 9:10 ` [PATCH v6 1/6] can: mcp251xfd: move chip sleep mode into runtime pm Viken Dadhaniya
2025-10-01 9:10 ` [PATCH v6 2/6] can: mcp251xfd: utilize gather_write function for all non-CRC writes Viken Dadhaniya
@ 2025-10-01 9:10 ` Viken Dadhaniya
2025-10-01 9:10 ` [PATCH v6 4/6] can: mcp251xfd: only configure PIN1 when rx_int is set Viken Dadhaniya
` (4 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Viken Dadhaniya @ 2025-10-01 9:10 UTC (permalink / raw)
To: mkl, mani, thomas.kopp, mailhol.vincent, robh, krzk+dt, conor+dt,
linus.walleij, brgl, linux-can, devicetree, linux-kernel
Cc: mukesh.savaliya, anup.kulkarni, Gregor Herburger, Viken Dadhaniya
From: Gregor Herburger <gregor.herburger@ew.tq-group.com>
According to Errata DS80000789E 5 writing IOCON register using one SPI
write command clears LAT0/LAT1.
Errata Fix/Work Around suggests to write registers with single byte write
instructions. However, it seems that every write to the second byte
causes the overwrite of LAT0/LAT1.
Never write byte 2 of IOCON register to avoid clearing of LAT0/LAT1.
Signed-off-by: Gregor Herburger <gregor.herburger@ew.tq-group.com>
Tested-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
Signed-off-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
---
.../net/can/spi/mcp251xfd/mcp251xfd-regmap.c | 89 +++++++++++++++++--
1 file changed, 83 insertions(+), 6 deletions(-)
diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c
index e61cbd209955..70d5ff0ae7ac 100644
--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c
+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c
@@ -13,9 +13,9 @@
static const struct regmap_config mcp251xfd_regmap_crc;
static int
-mcp251xfd_regmap_nocrc_gather_write(void *context,
- const void *reg, size_t reg_len,
- const void *val, size_t val_len)
+_mcp251xfd_regmap_nocrc_gather_write(void *context,
+ const void *reg, size_t reg_len,
+ const void *val, size_t val_len)
{
struct spi_device *spi = context;
struct mcp251xfd_priv *priv = spi_get_drvdata(spi);
@@ -39,6 +39,45 @@ mcp251xfd_regmap_nocrc_gather_write(void *context,
return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
}
+static int
+mcp251xfd_regmap_nocrc_gather_write(void *context,
+ const void *reg_p, size_t reg_len,
+ const void *val, size_t val_len)
+{
+ const u16 byte_exclude = MCP251XFD_REG_IOCON +
+ mcp251xfd_first_byte_set(MCP251XFD_REG_IOCON_GPIO_MASK);
+ u16 reg = be16_to_cpu(*(__be16 *)reg_p) & MCP251XFD_SPI_ADDRESS_MASK;
+ int ret;
+
+ /* Never write to bits 16..23 of IOCON register to avoid clearing of LAT0/LAT1
+ *
+ * According to MCP2518FD Errata DS80000789E 5 writing IOCON register using one
+ * SPI write command clears LAT0/LAT1.
+ *
+ * Errata Fix/Work Around suggests to write registers with single byte
+ * write instructions. However, it seems that the byte at 0xe06(IOCON[23:16])
+ * is for read-only access and writing to it causes the clearing of LAT0/LAT1.
+ */
+ if (reg <= byte_exclude && reg + val_len > byte_exclude) {
+ size_t len = byte_exclude - reg;
+
+ /* Write up to 0xe05 */
+ ret = _mcp251xfd_regmap_nocrc_gather_write(context, reg_p, reg_len, val, len);
+ if (ret)
+ return ret;
+
+ /* Write from 0xe07 on */
+ reg += len + 1;
+ reg = (__force unsigned short)cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_WRITE | reg);
+ return _mcp251xfd_regmap_nocrc_gather_write(context, ®, reg_len,
+ val + len + 1,
+ val_len - len - 1);
+ }
+
+ return _mcp251xfd_regmap_nocrc_gather_write(context, reg_p, reg_len,
+ val, val_len);
+}
+
static int
mcp251xfd_regmap_nocrc_write(void *context, const void *data, size_t count)
{
@@ -197,9 +236,9 @@ mcp251xfd_regmap_nocrc_read(void *context,
}
static int
-mcp251xfd_regmap_crc_gather_write(void *context,
- const void *reg_p, size_t reg_len,
- const void *val, size_t val_len)
+_mcp251xfd_regmap_crc_gather_write(void *context,
+ const void *reg_p, size_t reg_len,
+ const void *val, size_t val_len)
{
struct spi_device *spi = context;
struct mcp251xfd_priv *priv = spi_get_drvdata(spi);
@@ -230,6 +269,44 @@ mcp251xfd_regmap_crc_gather_write(void *context,
return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
}
+static int
+mcp251xfd_regmap_crc_gather_write(void *context,
+ const void *reg_p, size_t reg_len,
+ const void *val, size_t val_len)
+{
+ const u16 byte_exclude = MCP251XFD_REG_IOCON +
+ mcp251xfd_first_byte_set(MCP251XFD_REG_IOCON_GPIO_MASK);
+ u16 reg = *(u16 *)reg_p;
+ int ret;
+
+ /* Never write to bits 16..23 of IOCON register to avoid clearing of LAT0/LAT1
+ *
+ * According to MCP2518FD Errata DS80000789E 5 writing IOCON register using one
+ * SPI write command clears LAT0/LAT1.
+ *
+ * Errata Fix/Work Around suggests to write registers with single byte
+ * write instructions. However, it seems that the byte at 0xe06(IOCON[23:16])
+ * is for read-only access and writing to it causes the clearing of LAT0/LAT1.
+ */
+ if (reg <= byte_exclude && reg + val_len > byte_exclude) {
+ size_t len = byte_exclude - reg;
+
+ /* Write up to 0xe05 */
+ ret = _mcp251xfd_regmap_crc_gather_write(context, ®, reg_len, val, len);
+ if (ret)
+ return ret;
+
+ /* Write from 0xe07 on */
+ reg += len + 1;
+ return _mcp251xfd_regmap_crc_gather_write(context, ®, reg_len,
+ val + len + 1,
+ val_len - len - 1);
+ }
+
+ return _mcp251xfd_regmap_crc_gather_write(context, reg_p, reg_len,
+ val, val_len);
+}
+
static int
mcp251xfd_regmap_crc_write(void *context,
const void *data, size_t count)
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v6 4/6] can: mcp251xfd: only configure PIN1 when rx_int is set
2025-10-01 9:10 [PATCH v6 0/6] can: mcp251xfd: add gpio functionality Viken Dadhaniya
` (2 preceding siblings ...)
2025-10-01 9:10 ` [PATCH v6 3/6] can: mcp251xfd: add workaround for errata 5 Viken Dadhaniya
@ 2025-10-01 9:10 ` Viken Dadhaniya
2025-10-01 9:10 ` [PATCH v6 5/6] can: mcp251xfd: add gpio functionality Viken Dadhaniya
` (3 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Viken Dadhaniya @ 2025-10-01 9:10 UTC (permalink / raw)
To: mkl, mani, thomas.kopp, mailhol.vincent, robh, krzk+dt, conor+dt,
linus.walleij, brgl, linux-can, devicetree, linux-kernel
Cc: mukesh.savaliya, anup.kulkarni, Gregor Herburger, Viken Dadhaniya
From: Gregor Herburger <gregor.herburger@ew.tq-group.com>
When rx_int is used th mcp251xfd_chip_rx_int_enable and
mcp251xfd_chip_rx_int_disable function configure both PIN0 and PIN1. To
prepare the support of the GPIOS only configure PIN1 with
regmap_update_bits.
This way PIN0 can be used as GPIO while PIN1 is used as rx_int
interrupt.
Signed-off-by: Gregor Herburger <gregor.herburger@ew.tq-group.com>
Tested-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
Signed-off-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
---
.../net/can/spi/mcp251xfd/mcp251xfd-core.c | 22 +++++++------------
drivers/net/can/spi/mcp251xfd/mcp251xfd.h | 6 +++++
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
index f9eabb1810cf..ea41f04ae1a6 100644
--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
@@ -608,23 +608,21 @@ static int mcp251xfd_set_bittiming(const struct mcp251xfd_priv *priv)
static int mcp251xfd_chip_rx_int_enable(const struct mcp251xfd_priv *priv)
{
- u32 val;
+ u32 val, mask;
if (!priv->rx_int)
return 0;
- /* Configure GPIOs:
- * - PIN0: GPIO Input
- * - PIN1: GPIO Input/RX Interrupt
+ /* Configure PIN1 as RX Interrupt:
*
* PIN1 must be Input, otherwise there is a glitch on the
* rx-INT line. It happens between setting the PIN as output
* (in the first byte of the SPI transfer) and configuring the
* PIN as interrupt (in the last byte of the SPI transfer).
*/
- val = MCP251XFD_REG_IOCON_PM0 | MCP251XFD_REG_IOCON_TRIS1 |
- MCP251XFD_REG_IOCON_TRIS0;
- return regmap_write(priv->map_reg, MCP251XFD_REG_IOCON, val);
+ val = MCP251XFD_REG_IOCON_TRIS(1);
+ mask = MCP251XFD_REG_IOCON_TRIS(1) | MCP251XFD_REG_IOCON_PM(1);
+ return regmap_update_bits(priv->map_reg, MCP251XFD_REG_IOCON, mask, val);
}
static int mcp251xfd_chip_rx_int_disable(const struct mcp251xfd_priv *priv)
@@ -634,13 +632,9 @@ static int mcp251xfd_chip_rx_int_disable(const struct mcp251xfd_priv *priv)
if (!priv->rx_int)
return 0;
- /* Configure GPIOs:
- * - PIN0: GPIO Input
- * - PIN1: GPIO Input
- */
- val = MCP251XFD_REG_IOCON_PM1 | MCP251XFD_REG_IOCON_PM0 |
- MCP251XFD_REG_IOCON_TRIS1 | MCP251XFD_REG_IOCON_TRIS0;
- return regmap_write(priv->map_reg, MCP251XFD_REG_IOCON, val);
+ /* Configure PIN1 as GPIO Input */
+ val = MCP251XFD_REG_IOCON_PM(1) | MCP251XFD_REG_IOCON_TRIS(1);
+ return regmap_update_bits(priv->map_reg, MCP251XFD_REG_IOCON, val, val);
}
static int mcp251xfd_chip_ecc_init(struct mcp251xfd_priv *priv)
diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h
index dcbbd2b2fae8..bd28510a6583 100644
--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h
+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h
@@ -335,13 +335,19 @@
#define MCP251XFD_REG_IOCON_TXCANOD BIT(28)
#define MCP251XFD_REG_IOCON_PM1 BIT(25)
#define MCP251XFD_REG_IOCON_PM0 BIT(24)
+#define MCP251XFD_REG_IOCON_PM(n) (MCP251XFD_REG_IOCON_PM0 << (n))
#define MCP251XFD_REG_IOCON_GPIO1 BIT(17)
#define MCP251XFD_REG_IOCON_GPIO0 BIT(16)
+#define MCP251XFD_REG_IOCON_GPIO(n) (MCP251XFD_REG_IOCON_GPIO0 << (n))
+#define MCP251XFD_REG_IOCON_GPIO_MASK GENMASK(17, 16)
#define MCP251XFD_REG_IOCON_LAT1 BIT(9)
#define MCP251XFD_REG_IOCON_LAT0 BIT(8)
+#define MCP251XFD_REG_IOCON_LAT(n) (MCP251XFD_REG_IOCON_LAT0 << (n))
+#define MCP251XFD_REG_IOCON_LAT_MASK GENMASK(9, 8)
#define MCP251XFD_REG_IOCON_XSTBYEN BIT(6)
#define MCP251XFD_REG_IOCON_TRIS1 BIT(1)
#define MCP251XFD_REG_IOCON_TRIS0 BIT(0)
+#define MCP251XFD_REG_IOCON_TRIS(n) (MCP251XFD_REG_IOCON_TRIS0 << (n))
#define MCP251XFD_REG_CRC 0xe08
#define MCP251XFD_REG_CRC_FERRIE BIT(25)
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v6 5/6] can: mcp251xfd: add gpio functionality
2025-10-01 9:10 [PATCH v6 0/6] can: mcp251xfd: add gpio functionality Viken Dadhaniya
` (3 preceding siblings ...)
2025-10-01 9:10 ` [PATCH v6 4/6] can: mcp251xfd: only configure PIN1 when rx_int is set Viken Dadhaniya
@ 2025-10-01 9:10 ` Viken Dadhaniya
2025-10-01 13:52 ` Bartosz Golaszewski
2025-10-01 9:10 ` [PATCH v6 6/6] dt-bindings: can: mcp251xfd: add gpio-controller property Viken Dadhaniya
` (2 subsequent siblings)
7 siblings, 1 reply; 13+ messages in thread
From: Viken Dadhaniya @ 2025-10-01 9:10 UTC (permalink / raw)
To: mkl, mani, thomas.kopp, mailhol.vincent, robh, krzk+dt, conor+dt,
linus.walleij, brgl, linux-can, devicetree, linux-kernel
Cc: mukesh.savaliya, anup.kulkarni, Gregor Herburger,
Bartosz Golaszewski, Viken Dadhaniya
From: Gregor Herburger <gregor.herburger@ew.tq-group.com>
The mcp251xfd devices allow two pins to be configured as gpio. Add this
functionality to driver.
Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: Gregor Herburger <gregor.herburger@ew.tq-group.com>
Tested-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
Signed-off-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
---
drivers/net/can/spi/mcp251xfd/Kconfig | 1 +
.../net/can/spi/mcp251xfd/mcp251xfd-core.c | 160 ++++++++++++++++++
drivers/net/can/spi/mcp251xfd/mcp251xfd.h | 2 +
3 files changed, 163 insertions(+)
diff --git a/drivers/net/can/spi/mcp251xfd/Kconfig b/drivers/net/can/spi/mcp251xfd/Kconfig
index 877e4356010d..7c29846e6051 100644
--- a/drivers/net/can/spi/mcp251xfd/Kconfig
+++ b/drivers/net/can/spi/mcp251xfd/Kconfig
@@ -5,6 +5,7 @@ config CAN_MCP251XFD
select CAN_RX_OFFLOAD
select REGMAP
select WANT_DEV_COREDUMP
+ select GPIOLIB
help
Driver for the Microchip MCP251XFD SPI FD-CAN controller
family.
diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
index ea41f04ae1a6..586336d9e421 100644
--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
@@ -1797,6 +1797,160 @@ static int mcp251xfd_register_check_rx_int(struct mcp251xfd_priv *priv)
return 0;
}
+static const char * const mcp251xfd_gpio_names[] = { "GPIO0", "GPIO1" };
+
+static int mcp251xfd_gpio_request(struct gpio_chip *chip, unsigned int offset)
+{
+ struct mcp251xfd_priv *priv = gpiochip_get_data(chip);
+ u32 pin_mask = MCP251XFD_REG_IOCON_PM(offset);
+ int ret;
+
+ if (priv->rx_int && offset == 1) {
+ netdev_err(priv->ndev, "Can't use GPIO 1 with RX-INT!\n");
+ return -EINVAL;
+ }
+
+ ret = pm_runtime_resume_and_get(priv->ndev->dev.parent);
+ if (ret)
+ return ret;
+
+ return regmap_update_bits(priv->map_reg, MCP251XFD_REG_IOCON, pin_mask, pin_mask);
+}
+
+static void mcp251xfd_gpio_free(struct gpio_chip *chip, unsigned int offset)
+{
+ struct mcp251xfd_priv *priv = gpiochip_get_data(chip);
+
+ pm_runtime_put(priv->ndev->dev.parent);
+}
+
+static int mcp251xfd_gpio_get_direction(struct gpio_chip *chip,
+ unsigned int offset)
+{
+ struct mcp251xfd_priv *priv = gpiochip_get_data(chip);
+ u32 mask = MCP251XFD_REG_IOCON_TRIS(offset);
+ u32 val;
+ int ret;
+
+ ret = regmap_read(priv->map_reg, MCP251XFD_REG_IOCON, &val);
+ if (ret)
+ return ret;
+
+ if (mask & val)
+ return GPIO_LINE_DIRECTION_IN;
+
+ return GPIO_LINE_DIRECTION_OUT;
+}
+
+static int mcp251xfd_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+ struct mcp251xfd_priv *priv = gpiochip_get_data(chip);
+ u32 mask = MCP251XFD_REG_IOCON_GPIO(offset);
+ u32 val;
+ int ret;
+
+ ret = regmap_read(priv->map_reg, MCP251XFD_REG_IOCON, &val);
+ if (ret)
+ return ret;
+
+ return !!(mask & val);
+}
+
+static int mcp251xfd_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
+ unsigned long *bit)
+{
+ struct mcp251xfd_priv *priv = gpiochip_get_data(chip);
+ u32 val;
+ int ret;
+
+ ret = regmap_read(priv->map_reg, MCP251XFD_REG_IOCON, &val);
+ if (ret)
+ return ret;
+
+ *bit = FIELD_GET(MCP251XFD_REG_IOCON_GPIO_MASK, val) & *mask;
+
+ return 0;
+}
+
+static int mcp251xfd_gpio_direction_output(struct gpio_chip *chip,
+ unsigned int offset, int value)
+{
+ struct mcp251xfd_priv *priv = gpiochip_get_data(chip);
+ u32 dir_mask = MCP251XFD_REG_IOCON_TRIS(offset);
+ u32 val_mask = MCP251XFD_REG_IOCON_LAT(offset);
+ u32 val;
+
+ if (value)
+ val = val_mask;
+ else
+ val = 0;
+
+ return regmap_update_bits(priv->map_reg, MCP251XFD_REG_IOCON,
+ dir_mask | val_mask, val);
+}
+
+static int mcp251xfd_gpio_direction_input(struct gpio_chip *chip,
+ unsigned int offset)
+{
+ struct mcp251xfd_priv *priv = gpiochip_get_data(chip);
+ u32 dir_mask = MCP251XFD_REG_IOCON_TRIS(offset);
+
+ return regmap_update_bits(priv->map_reg, MCP251XFD_REG_IOCON, dir_mask, dir_mask);
+}
+
+static int mcp251xfd_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
+{
+ struct mcp251xfd_priv *priv = gpiochip_get_data(chip);
+ u32 val_mask = MCP251XFD_REG_IOCON_LAT(offset);
+ u32 val;
+
+ if (value)
+ val = val_mask;
+ else
+ val = 0;
+
+ return regmap_update_bits(priv->map_reg, MCP251XFD_REG_IOCON, val_mask, val);
+}
+
+static int mcp251xfd_gpio_set_multiple(struct gpio_chip *chip, unsigned long *mask,
+ unsigned long *bits)
+{
+ struct mcp251xfd_priv *priv = gpiochip_get_data(chip);
+ u32 val;
+
+ val = FIELD_PREP(MCP251XFD_REG_IOCON_LAT_MASK, *bits);
+
+ return regmap_update_bits(priv->map_reg, MCP251XFD_REG_IOCON,
+ MCP251XFD_REG_IOCON_LAT_MASK, val);
+}
+
+static int mcp251fdx_gpio_setup(struct mcp251xfd_priv *priv)
+{
+ struct gpio_chip *gc = &priv->gc;
+
+ if (!device_property_present(&priv->spi->dev, "gpio-controller"))
+ return 0;
+
+ gc->label = dev_name(&priv->spi->dev);
+ gc->parent = &priv->spi->dev;
+ gc->owner = THIS_MODULE;
+ gc->request = mcp251xfd_gpio_request;
+ gc->free = mcp251xfd_gpio_free;
+ gc->get_direction = mcp251xfd_gpio_get_direction;
+ gc->direction_output = mcp251xfd_gpio_direction_output;
+ gc->direction_input = mcp251xfd_gpio_direction_input;
+ gc->get = mcp251xfd_gpio_get;
+ gc->get_multiple = mcp251xfd_gpio_get_multiple;
+ gc->set = mcp251xfd_gpio_set;
+ gc->set_multiple = mcp251xfd_gpio_set_multiple;
+ gc->base = -1;
+ gc->can_sleep = true;
+ gc->ngpio = ARRAY_SIZE(mcp251xfd_gpio_names);
+ gc->names = mcp251xfd_gpio_names;
+
+ return devm_gpiochip_add_data(&priv->spi->dev, gc, priv);
+}
+
static int
mcp251xfd_register_get_dev_id(const struct mcp251xfd_priv *priv, u32 *dev_id,
u32 *effective_speed_hz_slow,
@@ -1930,6 +2084,12 @@ static int mcp251xfd_register(struct mcp251xfd_priv *priv)
mcp251xfd_ethtool_init(priv);
+ err = mcp251fdx_gpio_setup(priv);
+ if (err) {
+ dev_err_probe(&priv->spi->dev, err, "Failed to register gpio-controller.\n");
+ goto out_runtime_disable;
+ }
+
err = register_candev(ndev);
if (err)
goto out_runtime_disable;
diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h
index bd28510a6583..085d7101e595 100644
--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h
+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h
@@ -15,6 +15,7 @@
#include <linux/can/dev.h>
#include <linux/can/rx-offload.h>
#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/regmap.h>
@@ -676,6 +677,7 @@ struct mcp251xfd_priv {
struct mcp251xfd_devtype_data devtype_data;
struct can_berr_counter bec;
+ struct gpio_chip gc;
};
#define MCP251XFD_IS(_model) \
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v6 5/6] can: mcp251xfd: add gpio functionality
2025-10-01 9:10 ` [PATCH v6 5/6] can: mcp251xfd: add gpio functionality Viken Dadhaniya
@ 2025-10-01 13:52 ` Bartosz Golaszewski
2025-10-01 13:59 ` Marc Kleine-Budde
0 siblings, 1 reply; 13+ messages in thread
From: Bartosz Golaszewski @ 2025-10-01 13:52 UTC (permalink / raw)
To: Viken Dadhaniya
Cc: mkl, mani, thomas.kopp, mailhol.vincent, robh, krzk+dt, conor+dt,
linus.walleij, linux-can, devicetree, linux-kernel,
mukesh.savaliya, anup.kulkarni, Gregor Herburger,
Bartosz Golaszewski
On Wed, Oct 1, 2025 at 11:10 AM Viken Dadhaniya
<viken.dadhaniya@oss.qualcomm.com> wrote:
> +
> + if (!device_property_present(&priv->spi->dev, "gpio-controller"))
> + return 0;
> +
Hi! I didn't notice this before you're returning 0 here, meaning the
device will be attached to the driver even though it doesn't do
anything. It would make more sense to return -ENODEV.
Bart
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v6 5/6] can: mcp251xfd: add gpio functionality
2025-10-01 13:52 ` Bartosz Golaszewski
@ 2025-10-01 13:59 ` Marc Kleine-Budde
2025-10-01 14:11 ` Bartosz Golaszewski
0 siblings, 1 reply; 13+ messages in thread
From: Marc Kleine-Budde @ 2025-10-01 13:59 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Viken Dadhaniya, mani, thomas.kopp, mailhol.vincent, robh,
krzk+dt, conor+dt, linus.walleij, linux-can, devicetree,
linux-kernel, mukesh.savaliya, anup.kulkarni, Gregor Herburger,
Bartosz Golaszewski
[-- Attachment #1: Type: text/plain, Size: 925 bytes --]
On 01.10.2025 15:52:56, Bartosz Golaszewski wrote:
> On Wed, Oct 1, 2025 at 11:10 AM Viken Dadhaniya
> <viken.dadhaniya@oss.qualcomm.com> wrote:
> > +
> > + if (!device_property_present(&priv->spi->dev, "gpio-controller"))
> > + return 0;
> > +
>
> Hi! I didn't notice this before you're returning 0 here, meaning the
> device will be attached to the driver even though it doesn't do
> anything. It would make more sense to return -ENODEV.
I consider the GPIO functionality of the mcp251xfd CAN controllers
optional. So if the DT doesn't contain gpio-controller, continue without
GPIO functionality.
regards,
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Embedded Linux | https://www.pengutronix.de |
Vertretung Nürnberg | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v6 5/6] can: mcp251xfd: add gpio functionality
2025-10-01 13:59 ` Marc Kleine-Budde
@ 2025-10-01 14:11 ` Bartosz Golaszewski
0 siblings, 0 replies; 13+ messages in thread
From: Bartosz Golaszewski @ 2025-10-01 14:11 UTC (permalink / raw)
To: Marc Kleine-Budde
Cc: Viken Dadhaniya, mani, thomas.kopp, mailhol.vincent, robh,
krzk+dt, conor+dt, linus.walleij, linux-can, devicetree,
linux-kernel, mukesh.savaliya, anup.kulkarni, Gregor Herburger,
Bartosz Golaszewski
On Wed, Oct 1, 2025 at 3:59 PM Marc Kleine-Budde <mkl@pengutronix.de> wrote:
>
> On 01.10.2025 15:52:56, Bartosz Golaszewski wrote:
> > On Wed, Oct 1, 2025 at 11:10 AM Viken Dadhaniya
> > <viken.dadhaniya@oss.qualcomm.com> wrote:
> > > +
> > > + if (!device_property_present(&priv->spi->dev, "gpio-controller"))
> > > + return 0;
> > > +
> >
> > Hi! I didn't notice this before you're returning 0 here, meaning the
> > device will be attached to the driver even though it doesn't do
> > anything. It would make more sense to return -ENODEV.
>
> I consider the GPIO functionality of the mcp251xfd CAN controllers
> optional. So if the DT doesn't contain gpio-controller, continue without
> GPIO functionality.
>
Ah, sorry, I thought this was the driver's probe() callback. It's
actually just a function. This could probably be registered as an
auxiliary device for less build-time dependencies but whatever.
Nevermind my last comment.
Bart
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v6 6/6] dt-bindings: can: mcp251xfd: add gpio-controller property
2025-10-01 9:10 [PATCH v6 0/6] can: mcp251xfd: add gpio functionality Viken Dadhaniya
` (4 preceding siblings ...)
2025-10-01 9:10 ` [PATCH v6 5/6] can: mcp251xfd: add gpio functionality Viken Dadhaniya
@ 2025-10-01 9:10 ` Viken Dadhaniya
2025-10-23 5:16 ` [PATCH v6 0/6] can: mcp251xfd: add gpio functionality Manivannan Sadhasivam
2025-11-12 8:49 ` Marc Kleine-Budde
7 siblings, 0 replies; 13+ messages in thread
From: Viken Dadhaniya @ 2025-10-01 9:10 UTC (permalink / raw)
To: mkl, mani, thomas.kopp, mailhol.vincent, robh, krzk+dt, conor+dt,
linus.walleij, brgl, linux-can, devicetree, linux-kernel
Cc: mukesh.savaliya, anup.kulkarni, Gregor Herburger,
Krzysztof Kozlowski, Viken Dadhaniya
From: Gregor Herburger <gregor.herburger@ew.tq-group.com>
The mcp251xfd has two pins that can be used as gpio. Add gpio-controller
property to binding description.
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Gregor Herburger <gregor.herburger@ew.tq-group.com>
Signed-off-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
---
.../devicetree/bindings/net/can/microchip,mcp251xfd.yaml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/can/microchip,mcp251xfd.yaml b/Documentation/devicetree/bindings/net/can/microchip,mcp251xfd.yaml
index c155c9c6db39..2d13638ebc6a 100644
--- a/Documentation/devicetree/bindings/net/can/microchip,mcp251xfd.yaml
+++ b/Documentation/devicetree/bindings/net/can/microchip,mcp251xfd.yaml
@@ -49,6 +49,11 @@ properties:
Must be half or less of "clocks" frequency.
maximum: 20000000
+ gpio-controller: true
+
+ "#gpio-cells":
+ const: 2
+
required:
- compatible
- reg
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v6 0/6] can: mcp251xfd: add gpio functionality
2025-10-01 9:10 [PATCH v6 0/6] can: mcp251xfd: add gpio functionality Viken Dadhaniya
` (5 preceding siblings ...)
2025-10-01 9:10 ` [PATCH v6 6/6] dt-bindings: can: mcp251xfd: add gpio-controller property Viken Dadhaniya
@ 2025-10-23 5:16 ` Manivannan Sadhasivam
2025-11-10 10:08 ` Viken Dadhaniya
2025-11-12 8:49 ` Marc Kleine-Budde
7 siblings, 1 reply; 13+ messages in thread
From: Manivannan Sadhasivam @ 2025-10-23 5:16 UTC (permalink / raw)
To: Viken Dadhaniya
Cc: mkl, thomas.kopp, mailhol.vincent, robh, krzk+dt, conor+dt,
linus.walleij, brgl, linux-can, devicetree, linux-kernel,
mukesh.savaliya, anup.kulkarni
On Wed, Oct 01, 2025 at 02:40:00PM +0530, Viken Dadhaniya wrote:
> Hi all,
>
> The mcp251xfd allows two pins to be configured as GPIOs. This series
> adds support for this feature.
>
> The GPIO functionality is controlled with the IOCON register which has
> an erratum.
>
> Patch 1 from https://lore.kernel.org/linux-can/20240429-mcp251xfd-runtime_pm-v1-3-c26a93a66544@pengutronix.de/
> Patch 2 refactor of no-crc functions to prepare workaround for non-crc writes
> Patch 3 is the fix/workaround for the aforementioned erratum
> Patch 4 only configure pin1 for rx-int
> Patch 5 adds the gpio support
> Patch 6 updates dt-binding
>
> As per Marc's comment on below patch, we aim to get this series into
> linux-next since the functionality is essential for CAN on the RB3 Gen2
> board. As progress has stalled, Take this series forward with minor code
> adjustments. Include a Tested-by tag to reflect validation performed on the
> target hardware.
>
LGTM! For the series,
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
- Mani
> https://lore.kernel.org/all/20240806-industrious-augmented-crane-44239a-mkl@pengutronix.de/
> ---
> Changes in v6:
> - Simplified error handling by directly returning regmap_update_bits() result.
> - Added Acked-By tag.
> - Link to v5: https://lore.kernel.org/all/20250926133018.3071446-1-viken.dadhaniya@oss.qualcomm.com/
>
> Changes in v5:
> - Removed #ifdef GPIOLIB and added select GPIOLIB in Kconfig
> - Rebased patch on latest baseline
> - Resolved Kernel Test Robot warnings
> - Link to v4: https://lore.kernel.org/all/20250918064903.241372-1-viken.dadhaniya@oss.qualcomm.com/
>
> Changes in v4:
> - Moved GPIO register initialization into mcp251xfd_register after enabling
> runtime PM to avoid GPIO request failures when using the gpio-hog
> property to set default GPIO state.
> - Added Tested-by and Signed-off-by tags.
> - Dropped the 1st and 2nd patches from the v3 series as they have already been merged.
> - Link to v3: https://lore.kernel.org/linux-can/20240522-mcp251xfd-gpio-feature-v3-0-8829970269c5@ew.tq-group.com/
>
> Changes in v3:
> - Implement workaround for non-crc writes
> - Configure only Pin1 for rx-int feature
> - moved errata check to .gather_write callback function
> - Added MCP251XFD_REG_IOCON_*() macros
> - Added Marcs suggestions
> - Collect Krzysztofs Acked-By
> - Link to v2: https://lore.kernel.org/r/20240506-mcp251xfd-gpio-feature-v2-0-615b16fa8789@ew.tq-group.com
>
> ---
> Gregor Herburger (5):
> can: mcp251xfd: utilize gather_write function for all non-CRC writes
> can: mcp251xfd: add workaround for errata 5
> can: mcp251xfd: only configure PIN1 when rx_int is set
> can: mcp251xfd: add gpio functionality
> dt-bindings: can: mcp251xfd: add gpio-controller property
>
> Marc Kleine-Budde (1):
> can: mcp251xfd: move chip sleep mode into runtime pm
>
> .../bindings/net/can/microchip,mcp251xfd.yaml | 5 +
> drivers/net/can/spi/mcp251xfd/Kconfig | 1 +
> .../net/can/spi/mcp251xfd/mcp251xfd-core.c | 273 +++++++++++++++---
> .../net/can/spi/mcp251xfd/mcp251xfd-regmap.c | 114 ++++++--
> drivers/net/can/spi/mcp251xfd/mcp251xfd.h | 8 +
> 5 files changed, 335 insertions(+), 66 deletions(-)
>
> --
> 2.34.1
>
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v6 0/6] can: mcp251xfd: add gpio functionality
2025-10-23 5:16 ` [PATCH v6 0/6] can: mcp251xfd: add gpio functionality Manivannan Sadhasivam
@ 2025-11-10 10:08 ` Viken Dadhaniya
0 siblings, 0 replies; 13+ messages in thread
From: Viken Dadhaniya @ 2025-11-10 10:08 UTC (permalink / raw)
To: Manivannan Sadhasivam, mkl
Cc: thomas.kopp, mailhol.vincent, robh, krzk+dt, conor+dt,
linus.walleij, brgl, linux-can, devicetree, linux-kernel,
mukesh.savaliya, anup.kulkarni
Hi Marc
I wanted to follow up on this patch series. I noticed it hasn’t been picked up yet,
so I wanted to check if there are any remaining concerns or comments that need to be addressed.
Thanks
Viken Dadhaniya
On 10/23/2025 10:46 AM, Manivannan Sadhasivam wrote:
> On Wed, Oct 01, 2025 at 02:40:00PM +0530, Viken Dadhaniya wrote:
>> Hi all,
>>
>> The mcp251xfd allows two pins to be configured as GPIOs. This series
>> adds support for this feature.
>>
>> The GPIO functionality is controlled with the IOCON register which has
>> an erratum.
>>
>> Patch 1 from https://lore.kernel.org/linux-can/20240429-mcp251xfd-runtime_pm-v1-3-c26a93a66544@pengutronix.de/
>> Patch 2 refactor of no-crc functions to prepare workaround for non-crc writes
>> Patch 3 is the fix/workaround for the aforementioned erratum
>> Patch 4 only configure pin1 for rx-int
>> Patch 5 adds the gpio support
>> Patch 6 updates dt-binding
>>
>> As per Marc's comment on below patch, we aim to get this series into
>> linux-next since the functionality is essential for CAN on the RB3 Gen2
>> board. As progress has stalled, Take this series forward with minor code
>> adjustments. Include a Tested-by tag to reflect validation performed on the
>> target hardware.
>>
>
> LGTM! For the series,
>
> Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
>
> - Mani>
>> https://lore.kernel.org/all/20240806-industrious-augmented-crane-44239a-mkl@pengutronix.de/
>> ---
>> Changes in v6:
>> - Simplified error handling by directly returning regmap_update_bits() result.
>> - Added Acked-By tag.
>> - Link to v5: https://lore.kernel.org/all/20250926133018.3071446-1-viken.dadhaniya@oss.qualcomm.com/
>>
>> Changes in v5:
>> - Removed #ifdef GPIOLIB and added select GPIOLIB in Kconfig
>> - Rebased patch on latest baseline
>> - Resolved Kernel Test Robot warnings
>> - Link to v4: https://lore.kernel.org/all/20250918064903.241372-1-viken.dadhaniya@oss.qualcomm.com/
>>
>> Changes in v4:
>> - Moved GPIO register initialization into mcp251xfd_register after enabling
>> runtime PM to avoid GPIO request failures when using the gpio-hog
>> property to set default GPIO state.
>> - Added Tested-by and Signed-off-by tags.
>> - Dropped the 1st and 2nd patches from the v3 series as they have already been merged.
>> - Link to v3: https://lore.kernel.org/linux-can/20240522-mcp251xfd-gpio-feature-v3-0-8829970269c5@ew.tq-group.com/
>>
>> Changes in v3:
>> - Implement workaround for non-crc writes
>> - Configure only Pin1 for rx-int feature
>> - moved errata check to .gather_write callback function
>> - Added MCP251XFD_REG_IOCON_*() macros
>> - Added Marcs suggestions
>> - Collect Krzysztofs Acked-By
>> - Link to v2: https://lore.kernel.org/r/20240506-mcp251xfd-gpio-feature-v2-0-615b16fa8789@ew.tq-group.com
>>
>> ---
>> Gregor Herburger (5):
>> can: mcp251xfd: utilize gather_write function for all non-CRC writes
>> can: mcp251xfd: add workaround for errata 5
>> can: mcp251xfd: only configure PIN1 when rx_int is set
>> can: mcp251xfd: add gpio functionality
>> dt-bindings: can: mcp251xfd: add gpio-controller property
>>
>> Marc Kleine-Budde (1):
>> can: mcp251xfd: move chip sleep mode into runtime pm
>>
>> .../bindings/net/can/microchip,mcp251xfd.yaml | 5 +
>> drivers/net/can/spi/mcp251xfd/Kconfig | 1 +
>> .../net/can/spi/mcp251xfd/mcp251xfd-core.c | 273 +++++++++++++++---
>> .../net/can/spi/mcp251xfd/mcp251xfd-regmap.c | 114 ++++++--
>> drivers/net/can/spi/mcp251xfd/mcp251xfd.h | 8 +
>> 5 files changed, 335 insertions(+), 66 deletions(-)
>>
>> --
>> 2.34.1
>>
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v6 0/6] can: mcp251xfd: add gpio functionality
2025-10-01 9:10 [PATCH v6 0/6] can: mcp251xfd: add gpio functionality Viken Dadhaniya
` (6 preceding siblings ...)
2025-10-23 5:16 ` [PATCH v6 0/6] can: mcp251xfd: add gpio functionality Manivannan Sadhasivam
@ 2025-11-12 8:49 ` Marc Kleine-Budde
7 siblings, 0 replies; 13+ messages in thread
From: Marc Kleine-Budde @ 2025-11-12 8:49 UTC (permalink / raw)
To: Viken Dadhaniya
Cc: mani, thomas.kopp, mailhol.vincent, robh, krzk+dt, conor+dt,
linus.walleij, brgl, linux-can, devicetree, linux-kernel,
mukesh.savaliya, anup.kulkarni
[-- Attachment #1: Type: text/plain, Size: 1365 bytes --]
On 01.10.2025 14:40:00, Viken Dadhaniya wrote:
> Hi all,
>
> The mcp251xfd allows two pins to be configured as GPIOs. This series
> adds support for this feature.
>
> The GPIO functionality is controlled with the IOCON register which has
> an erratum.
>
> Patch 1 from https://lore.kernel.org/linux-can/20240429-mcp251xfd-runtime_pm-v1-3-c26a93a66544@pengutronix.de/
> Patch 2 refactor of no-crc functions to prepare workaround for non-crc writes
> Patch 3 is the fix/workaround for the aforementioned erratum
> Patch 4 only configure pin1 for rx-int
> Patch 5 adds the gpio support
> Patch 6 updates dt-binding
>
> As per Marc's comment on below patch, we aim to get this series into
> linux-next since the functionality is essential for CAN on the RB3 Gen2
> board. As progress has stalled, Take this series forward with minor code
> adjustments. Include a Tested-by tag to reflect validation performed on the
> target hardware.
>
> https://lore.kernel.org/all/20240806-industrious-augmented-crane-44239a-mkl@pengutronix.de/
Applied to linux-can-next.
Thanks,
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Embedded Linux | https://www.pengutronix.de |
Vertretung Nürnberg | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread