Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / drivers / net / sunlance.c
index 6e4bb57..ec04136 100644 (file)
 
 #undef DEBUG_DRIVER
 
-static char version[] =
-       "sunlance.c:v2.02 24/Aug/03 Miguel de Icaza (miguel@nuclecu.unam.mx)\n";
-
 static char lancestr[] = "LANCE";
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -94,9 +90,9 @@ static char lancestr[] = "LANCE";
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/ethtool.h>
+#include <linux/bitops.h>
 
 #include <asm/system.h>
-#include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/pgtable.h>
@@ -108,6 +104,19 @@ static char lancestr[] = "LANCE";
 #include <asm/auxio.h>         /* For tpe-link-test? setting */
 #include <asm/irq.h>
 
+#define DRV_NAME       "sunlance"
+#define DRV_VERSION    "2.02"
+#define DRV_RELDATE    "8/24/03"
+#define DRV_AUTHOR     "Miguel de Icaza (miguel@nuclecu.unam.mx)"
+
+static char version[] =
+       DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n";
+
+MODULE_VERSION(DRV_VERSION);
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_DESCRIPTION("Sun Lance ethernet driver");
+MODULE_LICENSE("GPL");
+
 /* Define: 2^4 Tx buffers and 2^4 Rx buffers */
 #ifndef LANCE_LOG_TX_BUFFERS
 #define LANCE_LOG_TX_BUFFERS 4
@@ -232,7 +241,8 @@ struct lance_init_block {
 struct lance_private {
        void __iomem    *lregs;         /* Lance RAP/RDP regs.          */
        void __iomem    *dregs;         /* DMA controller regs.         */
-       struct lance_init_block *init_block;
+       struct lance_init_block __iomem *init_block_iomem;
+       struct lance_init_block *init_block_mem;
     
        spinlock_t      lock;
 
@@ -255,7 +265,6 @@ struct lance_private {
        char                   *name;
        dma_addr_t              init_block_dvma;
        struct net_device      *dev;              /* Backpointer        */
-       struct lance_private   *next_module;
        struct sbus_dev        *sdev;
        struct timer_list       multicast_timer;
 };
@@ -287,8 +296,6 @@ int sparc_lance_debug = 2;
 
 #define LANCE_ADDR(x) ((long)(x) & ~0xff000000)
 
-static struct lance_private *root_lance_dev;
-
 /* Load the CSR registers */
 static void load_csrs(struct lance_private *lp)
 {
@@ -314,7 +321,7 @@ static void load_csrs(struct lance_private *lp)
 static void lance_init_ring_dvma(struct net_device *dev)
 {
        struct lance_private *lp = netdev_priv(dev);
-       struct lance_init_block *ib = lp->init_block;
+       struct lance_init_block *ib = lp->init_block_mem;
        dma_addr_t aib = lp->init_block_dvma;
        __u32 leptr;
        int i;
@@ -371,7 +378,7 @@ static void lance_init_ring_dvma(struct net_device *dev)
 static void lance_init_ring_pio(struct net_device *dev)
 {
        struct lance_private *lp = netdev_priv(dev);
-       struct lance_init_block *ib = lp->init_block;
+       struct lance_init_block __iomem *ib = lp->init_block_iomem;
        u32 leptr;
        int i;
     
@@ -501,7 +508,7 @@ static int init_restart_lance(struct lance_private *lp)
 static void lance_rx_dvma(struct net_device *dev)
 {
        struct lance_private *lp = netdev_priv(dev);
-       struct lance_init_block *ib = lp->init_block;
+       struct lance_init_block *ib = lp->init_block_mem;
        struct lance_rx_desc *rd;
        u8 bits;
        int len, entry = lp->rx_new;
@@ -564,7 +571,7 @@ static void lance_rx_dvma(struct net_device *dev)
 static void lance_tx_dvma(struct net_device *dev)
 {
        struct lance_private *lp = netdev_priv(dev);
-       struct lance_init_block *ib = lp->init_block;
+       struct lance_init_block *ib = lp->init_block_mem;
        int i, j;
 
        spin_lock(&lp->lock);
@@ -674,8 +681,8 @@ static void lance_piocopy_to_skb(struct sk_buff *skb, void __iomem *piobuf, int
 static void lance_rx_pio(struct net_device *dev)
 {
        struct lance_private *lp = netdev_priv(dev);
-       struct lance_init_block *ib = lp->init_block;
-       struct lance_rx_desc *rd;
+       struct lance_init_block __iomem *ib = lp->init_block_iomem;
+       struct lance_rx_desc __iomem *rd;
        unsigned char bits;
        int len, entry;
        struct sk_buff *skb;
@@ -736,14 +743,14 @@ static void lance_rx_pio(struct net_device *dev)
 static void lance_tx_pio(struct net_device *dev)
 {
        struct lance_private *lp = netdev_priv(dev);
-       struct lance_init_block *ib = lp->init_block;
+       struct lance_init_block __iomem *ib = lp->init_block_iomem;
        int i, j;
 
        spin_lock(&lp->lock);
 
        j = lp->tx_old;
        for (i = j; i != lp->tx_new; i = j) {
-               struct lance_tx_desc *td = &ib->btx_ring [i];
+               struct lance_tx_desc __iomem *td = &ib->btx_ring [i];
                u8 bits = sbus_readb(&td->tmd1_bits);
 
                /* If we hit a packet not owned by us, stop */
@@ -880,15 +887,13 @@ static irqreturn_t lance_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 static void build_fake_packet(struct lance_private *lp)
 {
        struct net_device *dev = lp->dev;
-       struct lance_init_block *ib = lp->init_block;
-       u16 *packet;
-       struct ethhdr *eth;
        int i, entry;
 
        entry = lp->tx_new & TX_RING_MOD_MASK;
-       packet = (u16 *) &(ib->tx_buf[entry][0]);
-       eth = (struct ethhdr *) packet;
        if (lp->pio_buffer) {
+               struct lance_init_block __iomem *ib = lp->init_block_iomem;
+               u16 __iomem *packet = (u16 __iomem *) &(ib->tx_buf[entry][0]);
+               struct ethhdr __iomem *eth = (struct ethhdr __iomem *) packet;
                for (i = 0; i < (ETH_ZLEN / sizeof(u16)); i++)
                        sbus_writew(0, &packet[i]);
                for (i = 0; i < 6; i++) {
@@ -899,6 +904,9 @@ static void build_fake_packet(struct lance_private *lp)
                sbus_writew(0, &ib->btx_ring[entry].misc);
                sbus_writeb(LE_T1_POK|LE_T1_OWN, &ib->btx_ring[entry].tmd1_bits);
        } else {
+               struct lance_init_block *ib = lp->init_block_mem;
+               u16 *packet = (u16 *) &(ib->tx_buf[entry][0]);
+               struct ethhdr *eth = (struct ethhdr *) packet;
                memset(packet, 0, ETH_ZLEN);
                for (i = 0; i < 6; i++) {
                        eth->h_dest[i] = dev->dev_addr[i];
@@ -916,16 +924,15 @@ struct net_device *last_dev;
 static int lance_open(struct net_device *dev)
 {
        struct lance_private *lp = netdev_priv(dev);
-       struct lance_init_block *ib = lp->init_block;
        int status = 0;
 
        last_dev = dev;
 
        STOP_LANCE(lp);
 
-       if (request_irq(dev->irq, &lance_interrupt, SA_SHIRQ,
+       if (request_irq(dev->irq, &lance_interrupt, IRQF_SHARED,
                        lancestr, (void *) dev)) {
-               printk(KERN_ERR "Lance: Can't get irq %s\n", __irq_itoa(dev->irq));
+               printk(KERN_ERR "Lance: Can't get irq %d\n", dev->irq);
                return -EAGAIN;
        }
 
@@ -943,10 +950,12 @@ static int lance_open(struct net_device *dev)
         * BTW it is common bug in all lance drivers! --ANK
         */
        if (lp->pio_buffer) {
+               struct lance_init_block __iomem *ib = lp->init_block_iomem;
                sbus_writew(0, &ib->mode);
                sbus_writel(0, &ib->filter[0]);
                sbus_writel(0, &ib->filter[1]);
        } else {
+               struct lance_init_block *ib = lp->init_block_mem;
                ib->mode = 0;
                ib->filter [0] = 0;
                ib->filter [1] = 0;
@@ -1113,7 +1122,6 @@ static void lance_tx_timeout(struct net_device *dev)
 static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct lance_private *lp = netdev_priv(dev);
-       struct lance_init_block *ib = lp->init_block;
        int entry, skblen, len;
 
        skblen = skb->len;
@@ -1126,6 +1134,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        entry = lp->tx_new & TX_RING_MOD_MASK;
        if (lp->pio_buffer) {
+               struct lance_init_block __iomem *ib = lp->init_block_iomem;
                sbus_writew((-len) | 0xf000, &ib->btx_ring[entry].length);
                sbus_writew(0, &ib->btx_ring[entry].misc);
                lance_piocopy_from_skb(&ib->tx_buf[entry][0], skb->data, skblen);
@@ -1133,6 +1142,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        lance_piozero(&ib->tx_buf[entry][skblen], len - skblen);
                sbus_writeb(LE_T1_POK | LE_T1_OWN, &ib->btx_ring[entry].tmd1_bits);
        } else {
+               struct lance_init_block *ib = lp->init_block_mem;
                ib->btx_ring [entry].length = (-len) | 0xf000;
                ib->btx_ring [entry].misc = 0;
                memcpy((char *)&ib->tx_buf [entry][0], skb->data, skblen);
@@ -1174,33 +1184,31 @@ static struct net_device_stats *lance_get_stats(struct net_device *dev)
 static void lance_load_multicast(struct net_device *dev)
 {
        struct lance_private *lp = netdev_priv(dev);
-       struct lance_init_block *ib = lp->init_block;
-       u16 *mcast_table = (u16 *) &ib->filter;
        struct dev_mc_list *dmi = dev->mc_list;
        char *addrs;
        int i;
        u32 crc;
+       u32 val;
        
        /* set all multicast bits */
-       if (dev->flags & IFF_ALLMULTI) {
-               if (lp->pio_buffer) {
-                       sbus_writel(0xffffffff, &ib->filter[0]);
-                       sbus_writel(0xffffffff, &ib->filter[1]);
-               } else {
-                       ib->filter [0] = 0xffffffff;
-                       ib->filter [1] = 0xffffffff;
-               }
-               return;
-       }
-       /* clear the multicast filter */
+       if (dev->flags & IFF_ALLMULTI)
+               val = ~0;
+       else
+               val = 0;
+
        if (lp->pio_buffer) {
-               sbus_writel(0, &ib->filter[0]);
-               sbus_writel(0, &ib->filter[1]);
+               struct lance_init_block __iomem *ib = lp->init_block_iomem;
+               sbus_writel(val, &ib->filter[0]);
+               sbus_writel(val, &ib->filter[1]);
        } else {
-               ib->filter [0] = 0;
-               ib->filter [1] = 0;
+               struct lance_init_block *ib = lp->init_block_mem;
+               ib->filter [0] = val;
+               ib->filter [1] = val;
        }
 
+       if (dev->flags & IFF_ALLMULTI)
+               return;
+       
        /* Add addresses */
        for (i = 0; i < dev->mc_count; i++) {
                addrs = dmi->dmi_addr;
@@ -1212,10 +1220,14 @@ static void lance_load_multicast(struct net_device *dev)
                crc = ether_crc_le(6, addrs);
                crc = crc >> 26;
                if (lp->pio_buffer) {
+                       struct lance_init_block __iomem *ib = lp->init_block_iomem;
+                       u16 __iomem *mcast_table = (u16 __iomem *) &ib->filter;
                        u16 tmp = sbus_readw(&mcast_table[crc>>4]);
                        tmp |= 1 << (crc & 0xf);
                        sbus_writew(tmp, &mcast_table[crc>>4]);
                } else {
+                       struct lance_init_block *ib = lp->init_block_mem;
+                       u16 *mcast_table = (u16 *) &ib->filter;
                        mcast_table [crc >> 4] |= 1 << (crc & 0xf);
                }
        }
@@ -1224,7 +1236,8 @@ static void lance_load_multicast(struct net_device *dev)
 static void lance_set_multicast(struct net_device *dev)
 {
        struct lance_private *lp = netdev_priv(dev);
-       struct lance_init_block *ib = lp->init_block;
+       struct lance_init_block *ib_mem = lp->init_block_mem;
+       struct lance_init_block __iomem *ib_iomem = lp->init_block_iomem;
        u16 mode;
 
        if (!netif_running(dev))
@@ -1242,21 +1255,21 @@ static void lance_set_multicast(struct net_device *dev)
        lp->init_ring(dev);
 
        if (lp->pio_buffer)
-               mode = sbus_readw(&ib->mode);
+               mode = sbus_readw(&ib_iomem->mode);
        else
-               mode = ib->mode;
+               mode = ib_mem->mode;
        if (dev->flags & IFF_PROMISC) {
                mode |= LE_MO_PROM;
                if (lp->pio_buffer)
-                       sbus_writew(mode, &ib->mode);
+                       sbus_writew(mode, &ib_iomem->mode);
                else
-                       ib->mode = mode;
+                       ib_mem->mode = mode;
        } else {
                mode &= ~LE_MO_PROM;
                if (lp->pio_buffer)
-                       sbus_writew(mode, &ib->mode);
+                       sbus_writew(mode, &ib_iomem->mode);
                else
-                       ib->mode = mode;
+                       ib_mem->mode = mode;
                lance_load_multicast(dev);
        }
        load_csrs(lp);
@@ -1275,16 +1288,14 @@ static void lance_free_hwresources(struct lance_private *lp)
 {
        if (lp->lregs)
                sbus_iounmap(lp->lregs, LANCE_REG_SIZE);
-       if (lp->init_block != NULL) {
-               if (lp->pio_buffer) {
-                       sbus_iounmap(lp->init_block,
-                                    sizeof(struct lance_init_block));
-               } else {
-                       sbus_free_consistent(lp->sdev,
-                                            sizeof(struct lance_init_block),
-                                            lp->init_block,
-                                            lp->init_block_dvma);
-               }
+       if (lp->init_block_iomem) {
+               sbus_iounmap(lp->init_block_iomem,
+                            sizeof(struct lance_init_block));
+       } else if (lp->init_block_mem) {
+               sbus_free_consistent(lp->sdev,
+                                    sizeof(struct lance_init_block),
+                                    lp->init_block_mem,
+                                    lp->init_block_dvma);
        }
 }
 
@@ -1312,9 +1323,9 @@ static struct ethtool_ops sparc_lance_ethtool_ops = {
        .get_link               = sparc_lance_get_link,
 };
 
-static int __init sparc_lance_init(struct sbus_dev *sdev,
-                                  struct sbus_dma *ledma,
-                                  struct sbus_dev *lebuffer)
+static int __init sparc_lance_probe_one(struct sbus_dev *sdev,
+                                       struct sbus_dma *ledma,
+                                       struct sbus_dev *lebuffer)
 {
        static unsigned version_printed;
        struct net_device *dev;
@@ -1326,6 +1337,7 @@ static int __init sparc_lance_init(struct sbus_dev *sdev,
                return -ENOMEM;
 
        lp = netdev_priv(dev);
+       memset(lp, 0, sizeof(*lp));
 
        if (sparc_lance_debug && version_printed++ == 0)
                printk (KERN_INFO "%s", version);
@@ -1342,17 +1354,22 @@ static int __init sparc_lance_init(struct sbus_dev *sdev,
        /* Get the IO region */
        lp->lregs = sbus_ioremap(&sdev->resource[0], 0,
                                 LANCE_REG_SIZE, lancestr);
-       if (lp->lregs == 0UL) {
+       if (!lp->lregs) {
                printk(KERN_ERR "SunLance: Cannot map registers.\n");
                goto fail;
        }
 
        lp->sdev = sdev;
        if (lebuffer) {
-               lp->init_block =
+               /* sanity check */
+               if (lebuffer->resource[0].start & 7) {
+                       printk(KERN_ERR "SunLance: ERROR: Rx and Tx rings not on even boundary.\n");
+                       goto fail;
+               }
+               lp->init_block_iomem =
                        sbus_ioremap(&lebuffer->resource[0], 0,
                                     sizeof(struct lance_init_block), "lebuffer");
-               if (lp->init_block == NULL) {
+               if (!lp->init_block_iomem) {
                        printk(KERN_ERR "SunLance: Cannot map PIO buffer.\n");
                        goto fail;
                }
@@ -1362,11 +1379,10 @@ static int __init sparc_lance_init(struct sbus_dev *sdev,
                lp->rx = lance_rx_pio;
                lp->tx = lance_tx_pio;
        } else {
-               lp->init_block =
+               lp->init_block_mem =
                        sbus_alloc_consistent(sdev, sizeof(struct lance_init_block),
                                              &lp->init_block_dvma);
-               if (lp->init_block == NULL ||
-                   lp->init_block_dvma == 0) {
+               if (!lp->init_block_mem || lp->init_block_dvma == 0) {
                        printk(KERN_ERR "SunLance: Cannot allocate consistent DMA memory.\n");
                        goto fail;
                }
@@ -1449,16 +1465,11 @@ no_link_test:
                udelay(200);
                sbus_writel(csr & ~DMA_RST_ENET, lp->dregs + DMA_CSR);
        } else
-               lp->dregs = 0;
-
-       /* This should never happen. */
-       if ((unsigned long)(lp->init_block->brx_ring) & 0x07) {
-               printk(KERN_ERR "SunLance: ERROR: Rx and Tx rings not on even boundary.\n");
-               goto fail;
-       }
+               lp->dregs = NULL;
 
        lp->dev = dev;
        SET_MODULE_OWNER(dev);
+       SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
        dev->open = &lance_open;
        dev->stop = &lance_close;
        dev->hard_start_xmit = &lance_start_xmit;
@@ -1486,8 +1497,7 @@ no_link_test:
                goto fail;
        }
 
-       lp->next_module = root_lance_dev;
-       root_lance_dev = lp;
+       dev_set_drvdata(&sdev->ofdev.dev, lp);
 
        printk(KERN_INFO "%s: LANCE ", dev->name);
 
@@ -1499,8 +1509,7 @@ no_link_test:
        return 0;
 
 fail:
-       if (lp != NULL)
-               lance_free_hwresources(lp);
+       lance_free_hwresources(lp);
        free_netdev(dev);
        return -ENODEV;
 }
@@ -1523,89 +1532,107 @@ static inline struct sbus_dma *find_ledma(struct sbus_dev *sdev)
 #include <asm/machines.h>
 
 /* Find all the lance cards on the system and initialize them */
-static int __init sparc_lance_probe(void)
+static struct sbus_dev sun4_sdev;
+static int __init sparc_lance_init(void)
 {
-       static struct sbus_dev sdev;
-       static int called;
-
-       root_lance_dev = NULL;
-
-       if (called)
-               return -ENODEV;
-       called++;
-
        if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) ||
            (idprom->id_machtype == (SM_SUN4|SM_4_470))) {
-               memset(&sdev, 0, sizeof(sdev));
-               sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr;
-               sdev.irqs[0] = 6;
-               return sparc_lance_init(&sdev, 0, 0);
+               memset(&sun4_sdev, 0, sizeof(struct sbus_dev));
+               sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr;
+               sun4_sdev.irqs[0] = 6;
+               return sparc_lance_probe_one(&sun4_sdev, NULL, NULL);
        }
        return -ENODEV;
 }
 
+static int __exit sunlance_sun4_remove(void)
+{
+       struct lance_private *lp = dev_get_drvdata(&sun4_sdev.ofdev.dev);
+       struct net_device *net_dev = lp->dev;
+
+       unregister_netdevice(net_dev);
+
+       lance_free_hwresources(lp);
+
+       free_netdev(net_dev);
+
+       dev_set_drvdata(&sun4_sdev.ofdev.dev, NULL);
+
+       return 0;
+}
+
 #else /* !CONFIG_SUN4 */
 
-/* Find all the lance cards on the system and initialize them */
-static int __init sparc_lance_probe(void)
+static int __devinit sunlance_sbus_probe(struct of_device *dev, const struct of_device_id *match)
 {
-       struct sbus_bus *bus;
-       struct sbus_dev *sdev = NULL;
-       struct sbus_dma *ledma = NULL;
-       static int called;
-       int cards = 0, v;
-
-       root_lance_dev = NULL;
-
-       if (called)
-               return -ENODEV;
-       called++;
-
-       for_each_sbus (bus) {
-               for_each_sbusdev (sdev, bus) {
-                       if (strcmp(sdev->prom_name, "le") == 0) {
-                               cards++;
-                               if ((v = sparc_lance_init(sdev, NULL, NULL)))
-                                       return v;
-                               continue;
-                       }
-                       if (strcmp(sdev->prom_name, "ledma") == 0) {
-                               cards++;
-                               ledma = find_ledma(sdev);
-                               if ((v = sparc_lance_init(sdev->child,
-                                                         ledma, NULL)))
-                                       return v;
-                               continue;
-                       }
-                       if (strcmp(sdev->prom_name, "lebuffer") == 0){
-                               cards++;
-                               if ((v = sparc_lance_init(sdev->child,
-                                                         NULL, sdev)))
-                                       return v;
-                               continue;
-                       }
-               } /* for each sbusdev */
-       } /* for each sbus */
-       if (!cards)
-               return -ENODEV;
-       return 0;
+       struct sbus_dev *sdev = to_sbus_device(&dev->dev);
+       int err;
+
+       if (sdev->parent) {
+               struct of_device *parent = &sdev->parent->ofdev;
+
+               if (!strcmp(parent->node->name, "ledma")) {
+                       struct sbus_dma *ledma = find_ledma(to_sbus_device(&parent->dev));
+
+                       err = sparc_lance_probe_one(sdev, ledma, NULL);
+               } else if (!strcmp(parent->node->name, "lebuffer")) {
+                       err = sparc_lance_probe_one(sdev, NULL, to_sbus_device(&parent->dev));
+               } else
+                       err = sparc_lance_probe_one(sdev, NULL, NULL);
+       } else
+               err = sparc_lance_probe_one(sdev, NULL, NULL);
+
+       return err;
 }
-#endif /* !CONFIG_SUN4 */
 
-static void __exit sparc_lance_cleanup(void)
+static int __devexit sunlance_sbus_remove(struct of_device *dev)
 {
-       struct lance_private *lp;
+       struct lance_private *lp = dev_get_drvdata(&dev->dev);
+       struct net_device *net_dev = lp->dev;
 
-       while (root_lance_dev) {
-               lp = root_lance_dev->next_module;
+       unregister_netdevice(net_dev);
 
-               unregister_netdev(root_lance_dev->dev);
-               lance_free_hwresources(root_lance_dev);
-               free_netdev(root_lance_dev->dev);
-               root_lance_dev = lp;
-       }
+       lance_free_hwresources(lp);
+
+       free_netdev(net_dev);
+
+       dev_set_drvdata(&dev->dev, NULL);
+
+       return 0;
 }
 
-module_init(sparc_lance_probe);
-module_exit(sparc_lance_cleanup);
-MODULE_LICENSE("GPL");
+static struct of_device_id sunlance_sbus_match[] = {
+       {
+               .name = "le",
+       },
+       {},
+};
+
+MODULE_DEVICE_TABLE(of, sunlance_sbus_match);
+
+static struct of_platform_driver sunlance_sbus_driver = {
+       .name           = "sunlance",
+       .match_table    = sunlance_sbus_match,
+       .probe          = sunlance_sbus_probe,
+       .remove         = __devexit_p(sunlance_sbus_remove),
+};
+
+
+/* Find all the lance cards on the system and initialize them */
+static int __init sparc_lance_init(void)
+{
+       return of_register_driver(&sunlance_sbus_driver, &sbus_bus_type);
+}
+#endif /* !CONFIG_SUN4 */
+
+static void __exit sparc_lance_exit(void)
+{
+#ifdef CONFIG_SUN4
+       sunlance_sun4_remove();
+#else
+       of_unregister_driver(&sunlance_sbus_driver);
+#endif
+}
+
+module_init(sparc_lance_init);
+module_exit(sparc_lance_exit);