Skip to content

Commit 63ead53

Browse files
Haibo Chenmarckleinebudde
authored andcommitted
can: flexcan: remove the auto stop mode for IMX93
IMX93 A0 chip involve the internal q-channel handshake in LPCG and CCM to automatically handle the Flex-CAN IPG STOP signal. Only after FLEX-CAN enter stop mode then can support the self-wakeup feature. But meet issue when do the continue system PM stress test. When config the CAN as wakeup source, the first time after system suspend, any data on CAN bus can wakeup the system, this is as expect. But the second time when system suspend, data on CAN bus can't wakeup the system. If continue this test, we find in odd time system enter suspend, CAN can wakeup the system, but in even number system enter suspend, CAN can't wakeup the system. IC find a bug in the auto stop mode logic, and can't fix it easily. So for the new imx93 A1, IC drop the auto stop mode and involve the GPR to support stop mode (used before). IC define a bit in GPR which can trigger the IPG STOP signal to Flex-CAN, let it go into stop mode. And NXP claim to drop IMX93 A0, and only support IMX93 A1. So this patch remove the auto stop mode, and add flag FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR to imx93. Signed-off-by: Haibo Chen <[email protected]> Link: https://lore.kernel.org/all/[email protected] Signed-off-by: Marc Kleine-Budde <[email protected]>
1 parent 23ed2be commit 63ead53

File tree

2 files changed

+13
-35
lines changed

2 files changed

+13
-35
lines changed

drivers/net/can/flexcan/flexcan-core.c

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ static struct flexcan_devtype_data fsl_imx8mp_devtype_data = {
348348
static struct flexcan_devtype_data fsl_imx93_devtype_data = {
349349
.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
350350
FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_RX_MAILBOX |
351-
FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_AUTO_STOP_MODE |
351+
FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR |
352352
FLEXCAN_QUIRK_SUPPORT_FD | FLEXCAN_QUIRK_SUPPORT_ECC |
353353
FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX |
354354
FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR,
@@ -544,11 +544,6 @@ static inline int flexcan_enter_stop_mode(struct flexcan_priv *priv)
544544
} else if (priv->devtype_data.quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR) {
545545
regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr,
546546
1 << priv->stm.req_bit, 1 << priv->stm.req_bit);
547-
} else if (priv->devtype_data.quirks & FLEXCAN_QUIRK_AUTO_STOP_MODE) {
548-
/* For the auto stop mode, software do nothing, hardware will cover
549-
* all the operation automatically after system go into low power mode.
550-
*/
551-
return 0;
552547
}
553548

554549
return flexcan_low_power_enter_ack(priv);
@@ -574,12 +569,6 @@ static inline int flexcan_exit_stop_mode(struct flexcan_priv *priv)
574569
reg_mcr &= ~FLEXCAN_MCR_SLF_WAK;
575570
priv->write(reg_mcr, &regs->mcr);
576571

577-
/* For the auto stop mode, hardware will exist stop mode
578-
* automatically after system go out of low power mode.
579-
*/
580-
if (priv->devtype_data.quirks & FLEXCAN_QUIRK_AUTO_STOP_MODE)
581-
return 0;
582-
583572
return flexcan_low_power_exit_ack(priv);
584573
}
585574

@@ -1994,13 +1983,18 @@ static int flexcan_setup_stop_mode(struct platform_device *pdev)
19941983
ret = flexcan_setup_stop_mode_scfw(pdev);
19951984
else if (priv->devtype_data.quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR)
19961985
ret = flexcan_setup_stop_mode_gpr(pdev);
1997-
else if (priv->devtype_data.quirks & FLEXCAN_QUIRK_AUTO_STOP_MODE)
1998-
ret = 0;
19991986
else
20001987
/* return 0 directly if doesn't support stop mode feature */
20011988
return 0;
20021989

2003-
if (ret)
1990+
/* If ret is -EINVAL, this means SoC claim to support stop mode, but
1991+
* dts file lack the stop mode property definition. For this case,
1992+
* directly return 0, this will skip the wakeup capable setting and
1993+
* will not block the driver probe.
1994+
*/
1995+
if (ret == -EINVAL)
1996+
return 0;
1997+
else if (ret)
20041998
return ret;
20051999

20062000
device_set_wakeup_capable(&pdev->dev, true);
@@ -2320,16 +2314,8 @@ static int __maybe_unused flexcan_noirq_suspend(struct device *device)
23202314
if (netif_running(dev)) {
23212315
int err;
23222316

2323-
if (device_may_wakeup(device)) {
2317+
if (device_may_wakeup(device))
23242318
flexcan_enable_wakeup_irq(priv, true);
2325-
/* For auto stop mode, need to keep the clock on before
2326-
* system go into low power mode. After system go into
2327-
* low power mode, hardware will config the flexcan into
2328-
* stop mode, and gate off the clock automatically.
2329-
*/
2330-
if (priv->devtype_data.quirks & FLEXCAN_QUIRK_AUTO_STOP_MODE)
2331-
return 0;
2332-
}
23332319

23342320
err = pm_runtime_force_suspend(device);
23352321
if (err)
@@ -2347,15 +2333,9 @@ static int __maybe_unused flexcan_noirq_resume(struct device *device)
23472333
if (netif_running(dev)) {
23482334
int err;
23492335

2350-
/* For the wakeup in auto stop mode, no need to gate on the
2351-
* clock here, hardware will do this automatically.
2352-
*/
2353-
if (!(device_may_wakeup(device) &&
2354-
priv->devtype_data.quirks & FLEXCAN_QUIRK_AUTO_STOP_MODE)) {
2355-
err = pm_runtime_force_resume(device);
2356-
if (err)
2357-
return err;
2358-
}
2336+
err = pm_runtime_force_resume(device);
2337+
if (err)
2338+
return err;
23592339

23602340
if (device_may_wakeup(device))
23612341
flexcan_enable_wakeup_irq(priv, false);

drivers/net/can/flexcan/flexcan.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@
6868
#define FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR BIT(15)
6969
/* Device supports RX via FIFO */
7070
#define FLEXCAN_QUIRK_SUPPORT_RX_FIFO BIT(16)
71-
/* auto enter stop mode to support wakeup */
72-
#define FLEXCAN_QUIRK_AUTO_STOP_MODE BIT(17)
7371

7472
struct flexcan_devtype_data {
7573
u32 quirks; /* quirks needed for different IP cores */

0 commit comments

Comments
 (0)