Skip to content

Commit d844dff

Browse files
Merge patch series "can: tcan4x5x/m_can: use standby mode when down and in suspend"
Sean Nyekjaer <[email protected]> says: When downing the tcan4x5x there is no reason to keep the tcan4x5x in "normal" mode and waste power. So set standby mode when the interface is down and normal mode when interface is up. Also when going into suspend, set the tcan4x5x into standby mode. The tcan4x5x can still be used as a wake-source when in standby as low power RX is enabled. Link: https://patch.msgid.link/[email protected] Signed-off-by: Marc Kleine-Budde <[email protected]>
2 parents d50c837 + ad1ddb3 commit d844dff

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

drivers/net/can/m_can/m_can.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1756,6 +1756,13 @@ static void m_can_stop(struct net_device *dev)
17561756

17571757
/* set the state as STOPPED */
17581758
cdev->can.state = CAN_STATE_STOPPED;
1759+
1760+
if (cdev->ops->deinit) {
1761+
ret = cdev->ops->deinit(cdev);
1762+
if (ret)
1763+
netdev_err(dev, "failed to deinitialize: %pe\n",
1764+
ERR_PTR(ret));
1765+
}
17591766
}
17601767

17611768
static int m_can_close(struct net_device *dev)
@@ -2437,6 +2444,7 @@ int m_can_class_suspend(struct device *dev)
24372444
{
24382445
struct m_can_classdev *cdev = dev_get_drvdata(dev);
24392446
struct net_device *ndev = cdev->net;
2447+
int ret = 0;
24402448

24412449
if (netif_running(ndev)) {
24422450
netif_stop_queue(ndev);
@@ -2449,6 +2457,9 @@ int m_can_class_suspend(struct device *dev)
24492457
if (cdev->pm_wake_source) {
24502458
hrtimer_cancel(&cdev->hrtimer);
24512459
m_can_write(cdev, M_CAN_IE, IR_RF0N);
2460+
2461+
if (cdev->ops->deinit)
2462+
ret = cdev->ops->deinit(cdev);
24522463
} else {
24532464
m_can_stop(ndev);
24542465
}
@@ -2460,22 +2471,21 @@ int m_can_class_suspend(struct device *dev)
24602471

24612472
cdev->can.state = CAN_STATE_SLEEPING;
24622473

2463-
return 0;
2474+
return ret;
24642475
}
24652476
EXPORT_SYMBOL_GPL(m_can_class_suspend);
24662477

24672478
int m_can_class_resume(struct device *dev)
24682479
{
24692480
struct m_can_classdev *cdev = dev_get_drvdata(dev);
24702481
struct net_device *ndev = cdev->net;
2482+
int ret = 0;
24712483

24722484
pinctrl_pm_select_default_state(dev);
24732485

24742486
cdev->can.state = CAN_STATE_ERROR_ACTIVE;
24752487

24762488
if (netif_running(ndev)) {
2477-
int ret;
2478-
24792489
ret = m_can_clk_start(cdev);
24802490
if (ret)
24812491
return ret;
@@ -2488,6 +2498,10 @@ int m_can_class_resume(struct device *dev)
24882498
* again.
24892499
*/
24902500
cdev->active_interrupts |= IR_RF0N | IR_TEFN;
2501+
2502+
if (cdev->ops->init)
2503+
ret = cdev->ops->init(cdev);
2504+
24912505
m_can_write(cdev, M_CAN_IE, cdev->active_interrupts);
24922506
} else {
24932507
ret = m_can_start(ndev);
@@ -2501,7 +2515,7 @@ int m_can_class_resume(struct device *dev)
25012515
netif_start_queue(ndev);
25022516
}
25032517

2504-
return 0;
2518+
return ret;
25052519
}
25062520
EXPORT_SYMBOL_GPL(m_can_class_resume);
25072521

drivers/net/can/m_can/m_can.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ struct m_can_ops {
6868
int (*write_fifo)(struct m_can_classdev *cdev, int addr_offset,
6969
const void *val, size_t val_count);
7070
int (*init)(struct m_can_classdev *cdev);
71+
int (*deinit)(struct m_can_classdev *cdev);
7172
};
7273

7374
struct m_can_tx_op {

drivers/net/can/m_can/tcan4x5x-core.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,14 @@ static int tcan4x5x_init(struct m_can_classdev *cdev)
279279
return ret;
280280
}
281281

282+
static int tcan4x5x_deinit(struct m_can_classdev *cdev)
283+
{
284+
struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev);
285+
286+
return regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG,
287+
TCAN4X5X_MODE_SEL_MASK, TCAN4X5X_MODE_STANDBY);
288+
};
289+
282290
static int tcan4x5x_disable_wake(struct m_can_classdev *cdev)
283291
{
284292
struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev);
@@ -376,6 +384,7 @@ static int tcan4x5x_get_gpios(struct m_can_classdev *cdev,
376384

377385
static const struct m_can_ops tcan4x5x_ops = {
378386
.init = tcan4x5x_init,
387+
.deinit = tcan4x5x_deinit,
379388
.read_reg = tcan4x5x_read_reg,
380389
.write_reg = tcan4x5x_write_reg,
381390
.write_fifo = tcan4x5x_write_fifo,

0 commit comments

Comments
 (0)