@@ -468,6 +468,39 @@ static void mcp251x_hw_sleep(struct spi_device *spi)
468468 mcp251x_write_reg (spi , CANCTRL , CANCTRL_REQOP_SLEEP );
469469}
470470
471+ /* May only be called when device is sleeping! */
472+ static int mcp251x_hw_wake (struct spi_device * spi )
473+ {
474+ unsigned long timeout ;
475+
476+ /* Force wakeup interrupt to wake device, but don't execute IST */
477+ disable_irq (spi -> irq );
478+ mcp251x_write_2regs (spi , CANINTE , CANINTE_WAKIE , CANINTF_WAKIF );
479+
480+ /* Wait for oscillator startup timer after wake up */
481+ mdelay (MCP251X_OST_DELAY_MS );
482+
483+ /* Put device into config mode */
484+ mcp251x_write_reg (spi , CANCTRL , CANCTRL_REQOP_CONF );
485+
486+ /* Wait for the device to enter config mode */
487+ timeout = jiffies + HZ ;
488+ while ((mcp251x_read_reg (spi , CANSTAT ) & CANCTRL_REQOP_MASK ) !=
489+ CANCTRL_REQOP_CONF ) {
490+ schedule ();
491+ if (time_after (jiffies , timeout )) {
492+ dev_err (& spi -> dev , "MCP251x didn't enter in config mode\n" );
493+ return - EBUSY ;
494+ }
495+ }
496+
497+ /* Disable and clear pending interrupts */
498+ mcp251x_write_2regs (spi , CANINTE , 0x00 , 0x00 );
499+ enable_irq (spi -> irq );
500+
501+ return 0 ;
502+ }
503+
471504static netdev_tx_t mcp251x_hard_start_xmit (struct sk_buff * skb ,
472505 struct net_device * net )
473506{
@@ -725,8 +758,12 @@ static void mcp251x_restart_work_handler(struct work_struct *ws)
725758
726759 mutex_lock (& priv -> mcp_lock );
727760 if (priv -> after_suspend ) {
728- mcp251x_hw_reset (spi );
729- mcp251x_setup (net , spi );
761+ if (priv -> after_suspend & AFTER_SUSPEND_POWER ) {
762+ mcp251x_hw_reset (spi );
763+ mcp251x_setup (net , spi );
764+ } else {
765+ mcp251x_hw_wake (spi );
766+ }
730767 priv -> force_quit = 0 ;
731768 if (priv -> after_suspend & AFTER_SUSPEND_RESTART ) {
732769 mcp251x_set_normal_mode (spi );
@@ -923,7 +960,7 @@ static int mcp251x_open(struct net_device *net)
923960 INIT_WORK (& priv -> tx_work , mcp251x_tx_work_handler );
924961 INIT_WORK (& priv -> restart_work , mcp251x_restart_work_handler );
925962
926- ret = mcp251x_hw_reset (spi );
963+ ret = mcp251x_hw_wake (spi );
927964 if (ret )
928965 goto out_free_wq ;
929966 ret = mcp251x_setup (net , spi );
@@ -1165,13 +1202,13 @@ static int __maybe_unused mcp251x_can_resume(struct device *dev)
11651202
11661203 if (priv -> after_suspend & AFTER_SUSPEND_POWER )
11671204 mcp251x_power_enable (priv -> power , 1 );
1168-
1169- if (priv -> after_suspend & AFTER_SUSPEND_UP ) {
1205+ if (priv -> after_suspend & AFTER_SUSPEND_UP )
11701206 mcp251x_power_enable (priv -> transceiver , 1 );
1207+
1208+ if (priv -> after_suspend & (AFTER_SUSPEND_POWER | AFTER_SUSPEND_UP ))
11711209 queue_work (priv -> wq , & priv -> restart_work );
1172- } else {
1210+ else
11731211 priv -> after_suspend = 0 ;
1174- }
11751212
11761213 priv -> force_quit = 0 ;
11771214 enable_irq (spi -> irq );
0 commit comments