Re: [PATCH v2 1/2] can: m_can: allow keeping the transceiver running in suspend

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Martin,

On Tue, Sep 19, 2023 at 02:28:32PM +0200, Martin Hundebøll wrote:
> Add a flag to the suspend class function that leaves the chip in a
> running state with rx interrupt enabled, so that m_can device driver can
> configure and use the interrupt as a wakeup source.

As far as I know the wakeup-source property is static, so maybe it would
be possible to store a property in m_can_classdev instead of using a
function parameter?

Looking into m_can_classdev there is already a pm_clock_support field.
Maybe you can put one right next to it for wakeup source?

Best,
Markus

> 
> Signed-off-by: Martin Hundebøll <martin@xxxxxxxxxx>
> ---
> 
> Changes since v1:
>  * Fixed comment formatting
>  * Updated m_can_class_{suspend,resume} calls in m_can_pci.c too
>  * Skipped calling m_can_start() when resuming a wake-source device
> 
>  drivers/net/can/m_can/m_can.c          | 26 +++++++++++++++++++-------
>  drivers/net/can/m_can/m_can.h          |  4 ++--
>  drivers/net/can/m_can/m_can_pci.c      |  4 ++--
>  drivers/net/can/m_can/m_can_platform.c |  4 ++--
>  4 files changed, 25 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
> index 16ecc11c7f62..ec345f6fd6b0 100644
> --- a/drivers/net/can/m_can/m_can.c
> +++ b/drivers/net/can/m_can/m_can.c
> @@ -2113,7 +2113,7 @@ void m_can_class_unregister(struct m_can_classdev *cdev)
>  }
>  EXPORT_SYMBOL_GPL(m_can_class_unregister);
>  
> -int m_can_class_suspend(struct device *dev)
> +int m_can_class_suspend(struct device *dev, bool is_wake_source)
>  {
>  	struct m_can_classdev *cdev = dev_get_drvdata(dev);
>  	struct net_device *ndev = cdev->net;
> @@ -2121,7 +2121,15 @@ int m_can_class_suspend(struct device *dev)
>  	if (netif_running(ndev)) {
>  		netif_stop_queue(ndev);
>  		netif_device_detach(ndev);
> -		m_can_stop(ndev);
> +
> +		/* leave the chip running with rx interrupt enabled if it used
> +		 * as a wake-up source.
> +		 */
> +		if (is_wake_source)
> +			m_can_write(cdev, M_CAN_IE, IR_RF0N);
> +		else
> +			m_can_stop(ndev);
> +
>  		m_can_clk_stop(cdev);
>  	}
>  
> @@ -2133,7 +2141,7 @@ int m_can_class_suspend(struct device *dev)
>  }
>  EXPORT_SYMBOL_GPL(m_can_class_suspend);
>  
> -int m_can_class_resume(struct device *dev)
> +int m_can_class_resume(struct device *dev, bool is_wake_source)
>  {
>  	struct m_can_classdev *cdev = dev_get_drvdata(dev);
>  	struct net_device *ndev = cdev->net;
> @@ -2148,11 +2156,15 @@ int m_can_class_resume(struct device *dev)
>  		ret = m_can_clk_start(cdev);
>  		if (ret)
>  			return ret;
> -		ret  = m_can_start(ndev);
> -		if (ret) {
> -			m_can_clk_stop(cdev);
>  
> -			return ret;
> +		if (is_wake_source) {
> +			m_can_write(cdev, M_CAN_IE, cdev->active_interrupts);
> +		} else {
> +			ret  = m_can_start(ndev);
> +			if (ret) {
> +				m_can_clk_stop(cdev);
> +				return ret;
> +			}
>  		}
>  
>  		netif_device_attach(ndev);
> diff --git a/drivers/net/can/m_can/m_can.h b/drivers/net/can/m_can/m_can.h
> index 520e14277dff..5d86bcf66e83 100644
> --- a/drivers/net/can/m_can/m_can.h
> +++ b/drivers/net/can/m_can/m_can.h
> @@ -105,6 +105,6 @@ int m_can_class_get_clocks(struct m_can_classdev *cdev);
>  int m_can_init_ram(struct m_can_classdev *priv);
>  int m_can_check_mram_cfg(struct m_can_classdev *cdev, u32 mram_max_size);
>  
> -int m_can_class_suspend(struct device *dev);
> -int m_can_class_resume(struct device *dev);
> +int m_can_class_suspend(struct device *dev, bool is_wake_source);
> +int m_can_class_resume(struct device *dev, bool is_wake_source);
>  #endif	/* _CAN_M_H_ */
> diff --git a/drivers/net/can/m_can/m_can_pci.c b/drivers/net/can/m_can/m_can_pci.c
> index f2219aa2824b..7ffbe06d96d0 100644
> --- a/drivers/net/can/m_can/m_can_pci.c
> +++ b/drivers/net/can/m_can/m_can_pci.c
> @@ -169,12 +169,12 @@ static void m_can_pci_remove(struct pci_dev *pci)
>  
>  static __maybe_unused int m_can_pci_suspend(struct device *dev)
>  {
> -	return m_can_class_suspend(dev);
> +	return m_can_class_suspend(dev, false);
>  }
>  
>  static __maybe_unused int m_can_pci_resume(struct device *dev)
>  {
> -	return m_can_class_resume(dev);
> +	return m_can_class_resume(dev, false);
>  }
>  
>  static SIMPLE_DEV_PM_OPS(m_can_pci_pm_ops,
> diff --git a/drivers/net/can/m_can/m_can_platform.c b/drivers/net/can/m_can/m_can_platform.c
> index cdb28d6a092c..e49bef50d52c 100644
> --- a/drivers/net/can/m_can/m_can_platform.c
> +++ b/drivers/net/can/m_can/m_can_platform.c
> @@ -169,12 +169,12 @@ static int m_can_plat_probe(struct platform_device *pdev)
>  
>  static __maybe_unused int m_can_suspend(struct device *dev)
>  {
> -	return m_can_class_suspend(dev);
> +	return m_can_class_suspend(dev, false);
>  }
>  
>  static __maybe_unused int m_can_resume(struct device *dev)
>  {
> -	return m_can_class_resume(dev);
> +	return m_can_class_resume(dev, false);
>  }
>  
>  static void m_can_plat_remove(struct platform_device *pdev)
> -- 
> 2.42.0
> 



[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux