On one hand, the mv88e6xxx driver has a work queue called in loop
which will attempt register accesses after MDIO bus suspension, that
entirely freezes the platform during suspend.

On the other hand, the DSA core is not ready yet to support suspend to
RAM operation because so far there is no way to recover reliably the
switch configuration.

To avoid the kernel to freeze when suspending with a switch driven by
the mv88e6xxx driver, we choose to prevent the driver suspension and
in the same way, the whole platform.

Signed-off-by: Miquel Raynal <miquel.ray...@bootlin.com>
---

Changes since v1/v2
===================
* After having discussed with Vivien and Andrew, it seems that
  preventing the mv88e6xxx driver to suspend is the best option we
  have as of today. I removed the code saving the switch rules at
  driver level, I forgot about saving them at DSA level, so here are
  just two dummy PM hooks that prevent suspension.
  For people interested in picking-up what has been written and
  continue working on it, my initial proposal is available there:
  https://lore.kernel.org/netdev/20190130104606.31639abb@xps13/T/


 drivers/net/dsa/mv88e6xxx/chip.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 8a517d8fb9d1..28764d6d7388 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -4651,6 +4651,21 @@ static const void *pdata_device_get_match_data(struct 
device *dev)
        return NULL;
 }
 
+/* There is no suspend to RAM support at DSA level yet, the switch 
configuration
+ * would be lost after a power cycle so prevent it to be suspended.
+ */
+static int __maybe_unused mv88e6xxx_suspend(struct device *dev)
+{
+       return -EOPNOTSUPP;
+}
+
+static int __maybe_unused mv88e6xxx_resume(struct device *dev)
+{
+       return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(mv88e6xxx_pm_ops, mv88e6xxx_suspend, 
mv88e6xxx_resume);
+
 static int mv88e6xxx_probe(struct mdio_device *mdiodev)
 {
        struct dsa_mv88e6xxx_pdata *pdata = mdiodev->dev.platform_data;
@@ -4835,6 +4850,7 @@ static struct mdio_driver mv88e6xxx_driver = {
        .mdiodrv.driver = {
                .name = "mv88e6085",
                .of_match_table = mv88e6xxx_of_match,
+               .pm = &mv88e6xxx_pm_ops,
        },
 };
 
-- 
2.19.1

Reply via email to