clk_disable_unprepare(priv->clk_per);
}
+static void flexcan_wake_mask_enable(struct flexcan_priv *priv)
+{
+ struct flexcan_regs __iomem *regs = priv->regs;
+ u32 reg_mcr;
+
+ reg_mcr = priv->read(®s->mcr);
+ reg_mcr |= FLEXCAN_MCR_WAK_MSK;
+ priv->write(reg_mcr, ®s->mcr);
+}
+
+static void flexcan_wake_mask_disable(struct flexcan_priv *priv)
+{
+ struct flexcan_regs __iomem *regs = priv->regs;
+ u32 reg_mcr;
+
+ reg_mcr = priv->read(®s->mcr);
+ reg_mcr &= ~FLEXCAN_MCR_WAK_MSK;
+ priv->write(reg_mcr, ®s->mcr);
+}
+
static inline void flexcan_enter_stop_mode(struct flexcan_priv *priv)
{
/* enable stop request */
reg_mcr |= FLEXCAN_MCR_FEN;
/* enable self wakeup */
- reg_mcr |= FLEXCAN_MCR_WAK_MSK | FLEXCAN_MCR_SLF_WAK;
+ reg_mcr |= FLEXCAN_MCR_SLF_WAK;
netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
priv->write(reg_mcr, ®s->mcr);
netif_start_queue(dev);
if (device_may_wakeup(device)) {
- disable_irq_wake(dev->irq);
- flexcan_exit_stop_mode(priv);
+ flexcan_wake_mask_disable(priv);
} else {
+ pinctrl_pm_select_default_state(device);
+
err = pm_runtime_force_resume(device);
if (err)
return err;
return 0;
}
+static int __maybe_unused flexcan_noirq_suspend(struct device *device)
+{
+ struct net_device *dev = dev_get_drvdata(device);
+ struct flexcan_priv *priv = netdev_priv(dev);
+
+ if (netif_running(dev) && device_may_wakeup(device))
+ flexcan_wake_mask_enable(priv);
+
+ return 0;
+}
+
+static int __maybe_unused flexcan_noirq_resume(struct device *device)
+{
+ struct net_device *dev = dev_get_drvdata(device);
+ struct flexcan_priv *priv = netdev_priv(dev);
+
+ if (netif_running(dev) && device_may_wakeup(device)) {
+ disable_irq_wake(dev->irq);
+ flexcan_exit_stop_mode(priv);
+ }
+
+ return 0;
+}
+
static const struct dev_pm_ops flexcan_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(flexcan_suspend, flexcan_resume)
SET_RUNTIME_PM_OPS(flexcan_runtime_suspend, flexcan_runtime_resume, NULL)
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(flexcan_noirq_suspend, flexcan_noirq_resume)
};
static struct platform_driver flexcan_driver = {