net: ethernet: ti: am65-cpsw: retain PORT_VLAN_REG after suspend/resume
authorRoger Quadros <rogerq@kernel.org>
Tue, 6 Dec 2022 09:44:18 +0000 (11:44 +0200)
committerJakub Kicinski <kuba@kernel.org>
Thu, 8 Dec 2022 04:17:31 +0000 (20:17 -0800)
During suspend resume the context of PORT_VLAN_REG is lost so
save it during suspend and restore it during resume for
host port and slave ports.

Signed-off-by: Roger Quadros <rogerq@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/ti/am65-cpsw-nuss.c
drivers/net/ethernet/ti/am65-cpsw-nuss.h

index 797da62..61a3332 100644 (file)
@@ -2872,10 +2872,12 @@ static int am65_cpsw_nuss_remove(struct platform_device *pdev)
 static int am65_cpsw_nuss_suspend(struct device *dev)
 {
        struct am65_cpsw_common *common = dev_get_drvdata(dev);
+       struct am65_cpsw_host *host_p = am65_common_get_host(common);
        struct am65_cpsw_port *port;
        struct net_device *ndev;
        int i, ret;
 
+       host_p->vid_context = readl(host_p->port_base + AM65_CPSW_PORT_VLAN_REG_OFFSET);
        for (i = 0; i < common->port_num; i++) {
                port = &common->ports[i];
                ndev = port->ndev;
@@ -2883,6 +2885,7 @@ static int am65_cpsw_nuss_suspend(struct device *dev)
                if (!ndev)
                        continue;
 
+               port->vid_context = readl(port->port_base + AM65_CPSW_PORT_VLAN_REG_OFFSET);
                netif_device_detach(ndev);
                if (netif_running(ndev)) {
                        rtnl_lock();
@@ -2909,6 +2912,7 @@ static int am65_cpsw_nuss_resume(struct device *dev)
        struct am65_cpsw_port *port;
        struct net_device *ndev;
        int i, ret;
+       struct am65_cpsw_host *host_p = am65_common_get_host(common);
 
        ret = am65_cpsw_nuss_init_tx_chns(common);
        if (ret)
@@ -2941,8 +2945,11 @@ static int am65_cpsw_nuss_resume(struct device *dev)
                }
 
                netif_device_attach(ndev);
+               writel(port->vid_context, port->port_base + AM65_CPSW_PORT_VLAN_REG_OFFSET);
        }
 
+       writel(host_p->vid_context, host_p->port_base + AM65_CPSW_PORT_VLAN_REG_OFFSET);
+
        return 0;
 }
 #endif /* CONFIG_PM_SLEEP */
index 2c9850f..e95cc37 100644 (file)
@@ -55,12 +55,16 @@ struct am65_cpsw_port {
        bool                            rx_ts_enabled;
        struct am65_cpsw_qos            qos;
        struct devlink_port             devlink_port;
+       /* Only for suspend resume context */
+       u32                             vid_context;
 };
 
 struct am65_cpsw_host {
        struct am65_cpsw_common         *common;
        void __iomem                    *port_base;
        void __iomem                    *stat_base;
+       /* Only for suspend resume context */
+       u32                             vid_context;
 };
 
 struct am65_cpsw_tx_chn {