Skip to content

Commit b7603d0

Browse files
Joakim Zhangmarckleinebudde
authored andcommitted
can: flexcan: add low power enter/exit acknowledgment helper
The MCR[LPMACK] read-only bit indicates that FlexCAN is in a lower-power mode (Disabled mode, Doze mode, Stop mode). The CPU can poll this bit to know when FlexCAN has actually entered low power mode. The low power enter/exit acknowledgment helper will reduce code duplication for disabled mode, doze mode and stop mode. Tested-by: Sean Nyekjaer <[email protected]> Signed-off-by: Joakim Zhang <[email protected]> Signed-off-by: Marc Kleine-Budde <[email protected]>
1 parent e707180 commit b7603d0

File tree

1 file changed

+30
-16
lines changed

1 file changed

+30
-16
lines changed

drivers/net/can/flexcan.c

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,34 @@ static struct flexcan_mb __iomem *flexcan_get_mb(const struct flexcan_priv *priv
389389
(&priv->regs->mb[bank][priv->mb_size * mb_index]);
390390
}
391391

392+
static int flexcan_low_power_enter_ack(struct flexcan_priv *priv)
393+
{
394+
struct flexcan_regs __iomem *regs = priv->regs;
395+
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
396+
397+
while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
398+
udelay(10);
399+
400+
if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
401+
return -ETIMEDOUT;
402+
403+
return 0;
404+
}
405+
406+
static int flexcan_low_power_exit_ack(struct flexcan_priv *priv)
407+
{
408+
struct flexcan_regs __iomem *regs = priv->regs;
409+
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
410+
411+
while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
412+
udelay(10);
413+
414+
if (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
415+
return -ETIMEDOUT;
416+
417+
return 0;
418+
}
419+
392420
static void flexcan_enable_wakeup_irq(struct flexcan_priv *priv, bool enable)
393421
{
394422
struct flexcan_regs __iomem *regs = priv->regs;
@@ -506,39 +534,25 @@ static inline int flexcan_transceiver_disable(const struct flexcan_priv *priv)
506534
static int flexcan_chip_enable(struct flexcan_priv *priv)
507535
{
508536
struct flexcan_regs __iomem *regs = priv->regs;
509-
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
510537
u32 reg;
511538

512539
reg = priv->read(&regs->mcr);
513540
reg &= ~FLEXCAN_MCR_MDIS;
514541
priv->write(reg, &regs->mcr);
515542

516-
while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
517-
udelay(10);
518-
519-
if (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
520-
return -ETIMEDOUT;
521-
522-
return 0;
543+
return flexcan_low_power_exit_ack(priv);
523544
}
524545

525546
static int flexcan_chip_disable(struct flexcan_priv *priv)
526547
{
527548
struct flexcan_regs __iomem *regs = priv->regs;
528-
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
529549
u32 reg;
530550

531551
reg = priv->read(&regs->mcr);
532552
reg |= FLEXCAN_MCR_MDIS;
533553
priv->write(reg, &regs->mcr);
534554

535-
while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
536-
udelay(10);
537-
538-
if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
539-
return -ETIMEDOUT;
540-
541-
return 0;
555+
return flexcan_low_power_enter_ack(priv);
542556
}
543557

544558
static int flexcan_chip_freeze(struct flexcan_priv *priv)

0 commit comments

Comments
 (0)