aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-07-29 21:37:41 -0400
committerDavid S. Miller <davem@davemloft.net>2015-07-29 21:37:41 -0400
commitb2428f94f4f79cc6045e538ed3e8329b16711712 (patch)
tree5842dc91029bafd91c5c5a9619c2a9c49553f050
parent2482abb93ebf7bfbf85965ca907f0058ff968c59 (diff)
parent31a184b7acbc06d894c562ef884a94d6d78d0236 (diff)
Merge branch 'netcp-fixes'
Murali Karicheri says: ==================== net: netcp: bug fixes for dynamic module support This series fixes few bugs to allow keystone netcp modules to be dynamically loaded and removed. Currently it allows following sequence multiple times insmod cpsw_ale.ko insmod davinci_mdio.ko insmod keystone_netcp.ko insmod keystone_netcp_ethss.ko ifup eth0 ifup eth1 ping <hosts on eth0> ping <hosts on eth1> ifdown eth1 ifdown eth0 rmmod keystone_netcp_ethss.ko rmmod keystone_netcp.ko rmmod davinci_mdio.ko rmmod cpsw_ale.ko ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/ti/netcp_core.c14
-rw-r--r--drivers/net/ethernet/ti/netcp_ethss.c49
2 files changed, 30 insertions, 33 deletions
diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c
index ec8ed30196f3..9749dfd78c43 100644
--- a/drivers/net/ethernet/ti/netcp_core.c
+++ b/drivers/net/ethernet/ti/netcp_core.c
@@ -2112,6 +2112,7 @@ probe_quit:
2112static int netcp_remove(struct platform_device *pdev) 2112static int netcp_remove(struct platform_device *pdev)
2113{ 2113{
2114 struct netcp_device *netcp_device = platform_get_drvdata(pdev); 2114 struct netcp_device *netcp_device = platform_get_drvdata(pdev);
2115 struct netcp_intf *netcp_intf, *netcp_tmp;
2115 struct netcp_inst_modpriv *inst_modpriv, *tmp; 2116 struct netcp_inst_modpriv *inst_modpriv, *tmp;
2116 struct netcp_module *module; 2117 struct netcp_module *module;
2117 2118
@@ -2123,10 +2124,17 @@ static int netcp_remove(struct platform_device *pdev)
2123 list_del(&inst_modpriv->inst_list); 2124 list_del(&inst_modpriv->inst_list);
2124 kfree(inst_modpriv); 2125 kfree(inst_modpriv);
2125 } 2126 }
2126 WARN(!list_empty(&netcp_device->interface_head), "%s interface list not empty!\n",
2127 pdev->name);
2128 2127
2129 devm_kfree(&pdev->dev, netcp_device); 2128 /* now that all modules are removed, clean up the interfaces */
2129 list_for_each_entry_safe(netcp_intf, netcp_tmp,
2130 &netcp_device->interface_head,
2131 interface_list) {
2132 netcp_delete_interface(netcp_device, netcp_intf->ndev);
2133 }
2134
2135 WARN(!list_empty(&netcp_device->interface_head),
2136 "%s interface list not empty!\n", pdev->name);
2137
2130 pm_runtime_put_sync(&pdev->dev); 2138 pm_runtime_put_sync(&pdev->dev);
2131 pm_runtime_disable(&pdev->dev); 2139 pm_runtime_disable(&pdev->dev);
2132 platform_set_drvdata(pdev, NULL); 2140 platform_set_drvdata(pdev, NULL);
diff --git a/drivers/net/ethernet/ti/netcp_ethss.c b/drivers/net/ethernet/ti/netcp_ethss.c
index a21881219865..1974a8ae764a 100644
--- a/drivers/net/ethernet/ti/netcp_ethss.c
+++ b/drivers/net/ethernet/ti/netcp_ethss.c
@@ -2508,10 +2508,9 @@ static void free_secondary_ports(struct gbe_priv *gbe_dev)
2508{ 2508{
2509 struct gbe_slave *slave; 2509 struct gbe_slave *slave;
2510 2510
2511 for (;;) { 2511 while (!list_empty(&gbe_dev->secondary_slaves)) {
2512 slave = first_sec_slave(gbe_dev); 2512 slave = first_sec_slave(gbe_dev);
2513 if (!slave) 2513
2514 break;
2515 if (slave->phy) 2514 if (slave->phy)
2516 phy_disconnect(slave->phy); 2515 phy_disconnect(slave->phy);
2517 list_del(&slave->slave_list); 2516 list_del(&slave->slave_list);
@@ -2857,14 +2856,13 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
2857 &gbe_dev->dma_chan_name); 2856 &gbe_dev->dma_chan_name);
2858 if (ret < 0) { 2857 if (ret < 0) {
2859 dev_err(dev, "missing \"tx-channel\" parameter\n"); 2858 dev_err(dev, "missing \"tx-channel\" parameter\n");
2860 ret = -ENODEV; 2859 return -EINVAL;
2861 goto quit;
2862 } 2860 }
2863 2861
2864 if (!strcmp(node->name, "gbe")) { 2862 if (!strcmp(node->name, "gbe")) {
2865 ret = get_gbe_resource_version(gbe_dev, node); 2863 ret = get_gbe_resource_version(gbe_dev, node);
2866 if (ret) 2864 if (ret)
2867 goto quit; 2865 return ret;
2868 2866
2869 dev_dbg(dev, "ss_version: 0x%08x\n", gbe_dev->ss_version); 2867 dev_dbg(dev, "ss_version: 0x%08x\n", gbe_dev->ss_version);
2870 2868
@@ -2875,22 +2873,20 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
2875 else 2873 else
2876 ret = -ENODEV; 2874 ret = -ENODEV;
2877 2875
2878 if (ret)
2879 goto quit;
2880 } else if (!strcmp(node->name, "xgbe")) { 2876 } else if (!strcmp(node->name, "xgbe")) {
2881 ret = set_xgbe_ethss10_priv(gbe_dev, node); 2877 ret = set_xgbe_ethss10_priv(gbe_dev, node);
2882 if (ret) 2878 if (ret)
2883 goto quit; 2879 return ret;
2884 ret = netcp_xgbe_serdes_init(gbe_dev->xgbe_serdes_regs, 2880 ret = netcp_xgbe_serdes_init(gbe_dev->xgbe_serdes_regs,
2885 gbe_dev->ss_regs); 2881 gbe_dev->ss_regs);
2886 if (ret)
2887 goto quit;
2888 } else { 2882 } else {
2889 dev_err(dev, "unknown GBE node(%s)\n", node->name); 2883 dev_err(dev, "unknown GBE node(%s)\n", node->name);
2890 ret = -ENODEV; 2884 ret = -ENODEV;
2891 goto quit;
2892 } 2885 }
2893 2886
2887 if (ret)
2888 return ret;
2889
2894 interfaces = of_get_child_by_name(node, "interfaces"); 2890 interfaces = of_get_child_by_name(node, "interfaces");
2895 if (!interfaces) 2891 if (!interfaces)
2896 dev_err(dev, "could not find interfaces\n"); 2892 dev_err(dev, "could not find interfaces\n");
@@ -2898,11 +2894,11 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
2898 ret = netcp_txpipe_init(&gbe_dev->tx_pipe, netcp_device, 2894 ret = netcp_txpipe_init(&gbe_dev->tx_pipe, netcp_device,
2899 gbe_dev->dma_chan_name, gbe_dev->tx_queue_id); 2895 gbe_dev->dma_chan_name, gbe_dev->tx_queue_id);
2900 if (ret) 2896 if (ret)
2901 goto quit; 2897 return ret;
2902 2898
2903 ret = netcp_txpipe_open(&gbe_dev->tx_pipe); 2899 ret = netcp_txpipe_open(&gbe_dev->tx_pipe);
2904 if (ret) 2900 if (ret)
2905 goto quit; 2901 return ret;
2906 2902
2907 /* Create network interfaces */ 2903 /* Create network interfaces */
2908 INIT_LIST_HEAD(&gbe_dev->gbe_intf_head); 2904 INIT_LIST_HEAD(&gbe_dev->gbe_intf_head);
@@ -2917,6 +2913,7 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
2917 if (gbe_dev->num_slaves >= gbe_dev->max_num_slaves) 2913 if (gbe_dev->num_slaves >= gbe_dev->max_num_slaves)
2918 break; 2914 break;
2919 } 2915 }
2916 of_node_put(interfaces);
2920 2917
2921 if (!gbe_dev->num_slaves) 2918 if (!gbe_dev->num_slaves)
2922 dev_warn(dev, "No network interface configured\n"); 2919 dev_warn(dev, "No network interface configured\n");
@@ -2929,9 +2926,10 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
2929 of_node_put(secondary_ports); 2926 of_node_put(secondary_ports);
2930 2927
2931 if (!gbe_dev->num_slaves) { 2928 if (!gbe_dev->num_slaves) {
2932 dev_err(dev, "No network interface or secondary ports configured\n"); 2929 dev_err(dev,
2930 "No network interface or secondary ports configured\n");
2933 ret = -ENODEV; 2931 ret = -ENODEV;
2934 goto quit; 2932 goto free_sec_ports;
2935 } 2933 }
2936 2934
2937 memset(&ale_params, 0, sizeof(ale_params)); 2935 memset(&ale_params, 0, sizeof(ale_params));
@@ -2945,7 +2943,7 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
2945 if (!gbe_dev->ale) { 2943 if (!gbe_dev->ale) {
2946 dev_err(gbe_dev->dev, "error initializing ale engine\n"); 2944 dev_err(gbe_dev->dev, "error initializing ale engine\n");
2947 ret = -ENODEV; 2945 ret = -ENODEV;
2948 goto quit; 2946 goto free_sec_ports;
2949 } else { 2947 } else {
2950 dev_dbg(gbe_dev->dev, "Created a gbe ale engine\n"); 2948 dev_dbg(gbe_dev->dev, "Created a gbe ale engine\n");
2951 } 2949 }
@@ -2961,14 +2959,8 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
2961 *inst_priv = gbe_dev; 2959 *inst_priv = gbe_dev;
2962 return 0; 2960 return 0;
2963 2961
2964quit: 2962free_sec_ports:
2965 if (gbe_dev->hw_stats) 2963 free_secondary_ports(gbe_dev);
2966 devm_kfree(dev, gbe_dev->hw_stats);
2967 cpsw_ale_destroy(gbe_dev->ale);
2968 if (gbe_dev->ss_regs)
2969 devm_iounmap(dev, gbe_dev->ss_regs);
2970 of_node_put(interfaces);
2971 devm_kfree(dev, gbe_dev);
2972 return ret; 2964 return ret;
2973} 2965}
2974 2966
@@ -3041,12 +3033,9 @@ static int gbe_remove(struct netcp_device *netcp_device, void *inst_priv)
3041 free_secondary_ports(gbe_dev); 3033 free_secondary_ports(gbe_dev);
3042 3034
3043 if (!list_empty(&gbe_dev->gbe_intf_head)) 3035 if (!list_empty(&gbe_dev->gbe_intf_head))
3044 dev_alert(gbe_dev->dev, "unreleased ethss interfaces present\n"); 3036 dev_alert(gbe_dev->dev,
3037 "unreleased ethss interfaces present\n");
3045 3038
3046 devm_kfree(gbe_dev->dev, gbe_dev->hw_stats);
3047 devm_iounmap(gbe_dev->dev, gbe_dev->ss_regs);
3048 memset(gbe_dev, 0x00, sizeof(*gbe_dev));
3049 devm_kfree(gbe_dev->dev, gbe_dev);
3050 return 0; 3039 return 0;
3051} 3040}
3052 3041