Implement the "wakeup-source" device tree property, so the chip is left running when suspending, and its rx interrupt is used as a wakeup source to resume operation. Signed-off-by: Martin Hundebøll <martin@xxxxxxxxxx> --- drivers/net/can/m_can/tcan4x5x-core.c | 33 ++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/m_can/tcan4x5x-core.c b/drivers/net/can/m_can/tcan4x5x-core.c index 8a4143809d33..e0dee2ce3286 100644 --- a/drivers/net/can/m_can/tcan4x5x-core.c +++ b/drivers/net/can/m_can/tcan4x5x-core.c @@ -459,6 +459,9 @@ static int tcan4x5x_can_probe(struct spi_device *spi) goto out_power; } + if (device_property_read_bool(&spi->dev, "wakeup-source")) + device_init_wakeup(&spi->dev, true); + ret = m_can_class_register(mcan_class); if (ret) { dev_err(&spi->dev, "Failed registering m_can device %pe\n", @@ -487,6 +490,30 @@ static void tcan4x5x_can_remove(struct spi_device *spi) m_can_class_free_dev(priv->cdev.net); } +static int __maybe_unused tcan4x5x_suspend(struct device *dev) +{ + struct spi_device *spi = to_spi_device(dev); + + if (device_may_wakeup(dev)) { + enable_irq_wake(spi->irq); + + return m_can_class_suspend(dev, true); + } + + return m_can_class_suspend(dev, false); +} + +static int __maybe_unused tcan4x5x_resume(struct device *dev) +{ + struct spi_device *spi = to_spi_device(dev); + int ret = m_can_class_resume(dev); + + if (device_may_wakeup(dev)) + disable_irq_wake(spi->irq); + + return ret; +} + static const struct of_device_id tcan4x5x_of_match[] = { { .compatible = "ti,tcan4x5x", @@ -505,11 +532,15 @@ static const struct spi_device_id tcan4x5x_id_table[] = { }; MODULE_DEVICE_TABLE(spi, tcan4x5x_id_table); +const struct dev_pm_ops tcan4x5x_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(tcan4x5x_suspend, tcan4x5x_resume) +}; + static struct spi_driver tcan4x5x_can_driver = { .driver = { .name = KBUILD_MODNAME, .of_match_table = tcan4x5x_of_match, - .pm = NULL, + .pm = &tcan4x5x_pm_ops, }, .id_table = tcan4x5x_id_table, .probe = tcan4x5x_can_probe, -- 2.42.0