Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
[firefly-linux-kernel-4.4.55.git] / net / dsa / dsa.c
index b34d6978d7734dd992655e6e9bfa81282d86d64b..6905f2d84c44f48ba8611b222910a3b06a6464f6 100644 (file)
@@ -238,6 +238,49 @@ static void dsa_switch_destroy(struct dsa_switch *ds)
 {
 }
 
+static int dsa_switch_suspend(struct dsa_switch *ds)
+{
+       int i, ret = 0;
+
+       /* Suspend slave network devices */
+       for (i = 0; i < DSA_MAX_PORTS; i++) {
+               if (!(ds->phys_port_mask & (1 << i)))
+                       continue;
+
+               ret = dsa_slave_suspend(ds->ports[i]);
+               if (ret)
+                       return ret;
+       }
+
+       if (ds->drv->suspend)
+               ret = ds->drv->suspend(ds);
+
+       return ret;
+}
+
+static int dsa_switch_resume(struct dsa_switch *ds)
+{
+       int i, ret = 0;
+
+       if (ds->drv->resume)
+               ret = ds->drv->resume(ds);
+
+       if (ret)
+               return ret;
+
+       /* Resume slave network devices */
+       for (i = 0; i < DSA_MAX_PORTS; i++) {
+               if (!(ds->phys_port_mask & (1 << i)))
+                       continue;
+
+               ret = dsa_slave_resume(ds->ports[i]);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
 
 /* link polling *************************************************************/
 static void dsa_link_poll_work(struct work_struct *ugly)
@@ -440,7 +483,7 @@ static int dsa_of_probe(struct platform_device *pdev)
                cd = &pd->chip[chip_index];
 
                cd->of_node = child;
-               cd->mii_bus = &mdio_bus->dev;
+               cd->host_dev = &mdio_bus->dev;
 
                sw_addr = of_get_property(child, "reg", NULL);
                if (!sw_addr)
@@ -650,6 +693,42 @@ static struct packet_type dsa_pack_type __read_mostly = {
        .func   = dsa_switch_rcv,
 };
 
+#ifdef CONFIG_PM_SLEEP
+static int dsa_suspend(struct device *d)
+{
+       struct platform_device *pdev = to_platform_device(d);
+       struct dsa_switch_tree *dst = platform_get_drvdata(pdev);
+       int i, ret = 0;
+
+       for (i = 0; i < dst->pd->nr_chips; i++) {
+               struct dsa_switch *ds = dst->ds[i];
+
+               if (ds != NULL)
+                       ret = dsa_switch_suspend(ds);
+       }
+
+       return ret;
+}
+
+static int dsa_resume(struct device *d)
+{
+       struct platform_device *pdev = to_platform_device(d);
+       struct dsa_switch_tree *dst = platform_get_drvdata(pdev);
+       int i, ret = 0;
+
+       for (i = 0; i < dst->pd->nr_chips; i++) {
+               struct dsa_switch *ds = dst->ds[i];
+
+               if (ds != NULL)
+                       ret = dsa_switch_resume(ds);
+       }
+
+       return ret;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(dsa_pm_ops, dsa_suspend, dsa_resume);
+
 static const struct of_device_id dsa_of_match_table[] = {
        { .compatible = "brcm,bcm7445-switch-v4.0" },
        { .compatible = "marvell,dsa", },
@@ -665,6 +744,7 @@ static struct platform_driver dsa_driver = {
                .name   = "dsa",
                .owner  = THIS_MODULE,
                .of_match_table = dsa_of_match_table,
+               .pm     = &dsa_pm_ops,
        },
 };