aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/myri_sbus.c116
1 files changed, 61 insertions, 55 deletions
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
index 6c86dca62e2a..d9f616fea3d9 100644
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -1,10 +1,10 @@
1/* myri_sbus.h: MyriCOM MyriNET SBUS card driver. 1/* myri_sbus.c: MyriCOM MyriNET SBUS card driver.
2 * 2 *
3 * Copyright (C) 1996, 1999 David S. Miller (davem@redhat.com) 3 * Copyright (C) 1996, 1999, 2006 David S. Miller (davem@davemloft.net)
4 */ 4 */
5 5
6static char version[] = 6static char version[] =
7 "myri_sbus.c:v1.9 12/Sep/99 David S. Miller (davem@redhat.com)\n"; 7 "myri_sbus.c:v2.0 June 23, 2006 David S. Miller (davem@davemloft.net)\n";
8 8
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/config.h> 10#include <linux/config.h>
@@ -81,10 +81,6 @@ static char version[] =
81#define DHDR(x) 81#define DHDR(x)
82#endif 82#endif
83 83
84#ifdef MODULE
85static struct myri_eth *root_myri_dev;
86#endif
87
88static void myri_reset_off(void __iomem *lp, void __iomem *cregs) 84static void myri_reset_off(void __iomem *lp, void __iomem *cregs)
89{ 85{
90 /* Clear IRQ mask. */ 86 /* Clear IRQ mask. */
@@ -896,8 +892,9 @@ static void dump_eeprom(struct myri_eth *mp)
896} 892}
897#endif 893#endif
898 894
899static int __init myri_ether_init(struct sbus_dev *sdev, int num) 895static int __init myri_ether_init(struct sbus_dev *sdev)
900{ 896{
897 static int num;
901 static unsigned version_printed; 898 static unsigned version_printed;
902 struct net_device *dev; 899 struct net_device *dev;
903 struct myri_eth *mp; 900 struct myri_eth *mp;
@@ -913,6 +910,9 @@ static int __init myri_ether_init(struct sbus_dev *sdev, int num)
913 if (version_printed++ == 0) 910 if (version_printed++ == 0)
914 printk(version); 911 printk(version);
915 912
913 SET_MODULE_OWNER(dev);
914 SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
915
916 mp = (struct myri_eth *) dev->priv; 916 mp = (struct myri_eth *) dev->priv;
917 spin_lock_init(&mp->irq_lock); 917 spin_lock_init(&mp->irq_lock);
918 mp->myri_sdev = sdev; 918 mp->myri_sdev = sdev;
@@ -1092,10 +1092,9 @@ static int __init myri_ether_init(struct sbus_dev *sdev, int num)
1092 goto err_free_irq; 1092 goto err_free_irq;
1093 } 1093 }
1094 1094
1095#ifdef MODULE 1095 dev_set_drvdata(&sdev->ofdev.dev, mp);
1096 mp->next_module = root_myri_dev; 1096
1097 root_myri_dev = mp; 1097 num++;
1098#endif
1099 1098
1100 printk("%s: MyriCOM MyriNET Ethernet ", dev->name); 1099 printk("%s: MyriCOM MyriNET Ethernet ", dev->name);
1101 1100
@@ -1114,61 +1113,68 @@ err:
1114 return -ENODEV; 1113 return -ENODEV;
1115} 1114}
1116 1115
1117static int __init myri_sbus_match(struct sbus_dev *sdev)
1118{
1119 char *name = sdev->prom_name;
1120 1116
1121 if (!strcmp(name, "MYRICOM,mlanai") || 1117static int __devinit myri_sbus_probe(struct of_device *dev, const struct of_device_id *match)
1122 !strcmp(name, "myri")) 1118{
1123 return 1; 1119 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
1124 1120
1125 return 0; 1121 return myri_ether_init(sdev);
1126} 1122}
1127 1123
1128static int __init myri_sbus_probe(void) 1124static int __devexit myri_sbus_remove(struct of_device *dev)
1129{ 1125{
1130 struct sbus_bus *bus; 1126 struct myri_eth *mp = dev_get_drvdata(&dev->dev);
1131 struct sbus_dev *sdev = NULL; 1127 struct net_device *net_dev = mp->dev;
1132 static int called;
1133 int cards = 0, v;
1134 1128
1135#ifdef MODULE 1129 unregister_netdevice(net_dev);
1136 root_myri_dev = NULL;
1137#endif
1138 1130
1139 if (called) 1131 free_irq(net_dev->irq, net_dev);
1140 return -ENODEV; 1132
1141 called++; 1133 if (mp->eeprom.cpuvers < CPUVERS_4_0) {
1142 1134 sbus_iounmap(mp->regs, mp->reg_size);
1143 for_each_sbus(bus) { 1135 } else {
1144 for_each_sbusdev(sdev, bus) { 1136 sbus_iounmap(mp->cregs, PAGE_SIZE);
1145 if (myri_sbus_match(sdev)) { 1137 sbus_iounmap(mp->lregs, (256 * 1024));
1146 cards++; 1138 sbus_iounmap(mp->lanai, (512 * 1024));
1147 DET(("Found myricom myrinet as %s\n", sdev->prom_name));
1148 if ((v = myri_ether_init(sdev, (cards - 1))))
1149 return v;
1150 }
1151 }
1152 } 1139 }
1153 if (!cards) 1140
1154 return -ENODEV; 1141 free_netdev(net_dev);
1142
1143 dev_set_drvdata(&dev->dev, NULL);
1144
1155 return 0; 1145 return 0;
1156} 1146}
1157 1147
1158static void __exit myri_sbus_cleanup(void) 1148static struct of_device_id myri_sbus_match[] = {
1149 {
1150 .name = "MYRICOM,mlanai",
1151 },
1152 {
1153 .name = "myri",
1154 },
1155 {},
1156};
1157
1158MODULE_DEVICE_TABLE(of, myri_sbus_match);
1159
1160static struct of_platform_driver myri_sbus_driver = {
1161 .name = "myri",
1162 .match_table = myri_sbus_match,
1163 .probe = myri_sbus_probe,
1164 .remove = __devexit_p(myri_sbus_remove),
1165};
1166
1167static int __init myri_sbus_init(void)
1168{
1169 return of_register_driver(&myri_sbus_driver, &sbus_bus_type);
1170}
1171
1172static void __exit myri_sbus_exit(void)
1159{ 1173{
1160#ifdef MODULE 1174 of_unregister_driver(&myri_sbus_driver);
1161 while (root_myri_dev) {
1162 struct myri_eth *next = root_myri_dev->next_module;
1163
1164 unregister_netdev(root_myri_dev->dev);
1165 /* this will also free the co-allocated 'root_myri_dev' */
1166 free_netdev(root_myri_dev->dev);
1167 root_myri_dev = next;
1168 }
1169#endif /* MODULE */
1170} 1175}
1171 1176
1172module_init(myri_sbus_probe); 1177module_init(myri_sbus_init);
1173module_exit(myri_sbus_cleanup); 1178module_exit(myri_sbus_exit);
1179
1174MODULE_LICENSE("GPL"); 1180MODULE_LICENSE("GPL");