diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2007-05-11 10:48:58 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2007-05-11 12:00:29 -0400 |
commit | df9f54084f1faf611cedd846d38b0631f9d4e9a5 (patch) | |
tree | a4e5f46b26a761d62d79d5b367e885cc8a88b4b6 /drivers/net/sgiseeq.c | |
parent | 129a84de2347002f09721cda3155ccfd19fade40 (diff) |
Convert SGI IP22 and specific drivers to platform_device.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'drivers/net/sgiseeq.c')
-rw-r--r-- | drivers/net/sgiseeq.c | 83 |
1 files changed, 37 insertions, 46 deletions
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index 1fc77300b055..2106becf6990 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c | |||
@@ -16,11 +16,13 @@ | |||
16 | #include <linux/string.h> | 16 | #include <linux/string.h> |
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/netdevice.h> | 18 | #include <linux/netdevice.h> |
19 | #include <linux/platform_device.h> | ||
19 | #include <linux/etherdevice.h> | 20 | #include <linux/etherdevice.h> |
20 | #include <linux/skbuff.h> | 21 | #include <linux/skbuff.h> |
21 | 22 | ||
22 | #include <asm/sgi/hpc3.h> | 23 | #include <asm/sgi/hpc3.h> |
23 | #include <asm/sgi/ip22.h> | 24 | #include <asm/sgi/ip22.h> |
25 | #include <asm/sgi/seeq.h> | ||
24 | 26 | ||
25 | #include "sgiseeq.h" | 27 | #include "sgiseeq.h" |
26 | 28 | ||
@@ -92,13 +94,9 @@ struct sgiseeq_private { | |||
92 | 94 | ||
93 | struct net_device_stats stats; | 95 | struct net_device_stats stats; |
94 | 96 | ||
95 | struct net_device *next_module; | ||
96 | spinlock_t tx_lock; | 97 | spinlock_t tx_lock; |
97 | }; | 98 | }; |
98 | 99 | ||
99 | /* A list of all installed seeq devices, for removing the driver module. */ | ||
100 | static struct net_device *root_sgiseeq_dev; | ||
101 | |||
102 | static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs) | 100 | static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs) |
103 | { | 101 | { |
104 | hregs->reset = HPC3_ERST_CRESET | HPC3_ERST_CLRIRQ; | 102 | hregs->reset = HPC3_ERST_CRESET | HPC3_ERST_CLRIRQ; |
@@ -624,9 +622,12 @@ static inline void setup_rx_ring(struct sgiseeq_rx_desc *buf, int nbufs) | |||
624 | 622 | ||
625 | #define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf)) | 623 | #define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf)) |
626 | 624 | ||
627 | static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom) | 625 | static int __init sgiseeq_probe(struct platform_device *pdev) |
628 | { | 626 | { |
627 | struct sgiseeq_platform_data *pd = pdev->dev.platform_data; | ||
628 | struct hpc3_regs *hpcregs = pd->hpc; | ||
629 | struct sgiseeq_init_block *sr; | 629 | struct sgiseeq_init_block *sr; |
630 | unsigned int irq = pd->irq; | ||
630 | struct sgiseeq_private *sp; | 631 | struct sgiseeq_private *sp; |
631 | struct net_device *dev; | 632 | struct net_device *dev; |
632 | int err, i; | 633 | int err, i; |
@@ -637,6 +638,8 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom) | |||
637 | err = -ENOMEM; | 638 | err = -ENOMEM; |
638 | goto err_out; | 639 | goto err_out; |
639 | } | 640 | } |
641 | |||
642 | platform_set_drvdata(pdev, dev); | ||
640 | sp = netdev_priv(dev); | 643 | sp = netdev_priv(dev); |
641 | 644 | ||
642 | /* Make private data page aligned */ | 645 | /* Make private data page aligned */ |
@@ -648,15 +651,7 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom) | |||
648 | } | 651 | } |
649 | sp->srings = sr; | 652 | sp->srings = sr; |
650 | 653 | ||
651 | #define EADDR_NVOFS 250 | 654 | memcpy(dev->dev_addr, pd->mac, ETH_ALEN); |
652 | for (i = 0; i < 3; i++) { | ||
653 | unsigned short tmp = has_eeprom ? | ||
654 | ip22_eeprom_read(&hpcregs->eeprom, EADDR_NVOFS / 2+i) : | ||
655 | ip22_nvram_read(EADDR_NVOFS / 2+i); | ||
656 | |||
657 | dev->dev_addr[2 * i] = tmp >> 8; | ||
658 | dev->dev_addr[2 * i + 1] = tmp & 0xff; | ||
659 | } | ||
660 | 655 | ||
661 | #ifdef DEBUG | 656 | #ifdef DEBUG |
662 | gpriv = sp; | 657 | gpriv = sp; |
@@ -720,9 +715,6 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom) | |||
720 | for (i = 0; i < 6; i++) | 715 | for (i = 0; i < 6; i++) |
721 | printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); | 716 | printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); |
722 | 717 | ||
723 | sp->next_module = root_sgiseeq_dev; | ||
724 | root_sgiseeq_dev = dev; | ||
725 | |||
726 | return 0; | 718 | return 0; |
727 | 719 | ||
728 | err_out_free_page: | 720 | err_out_free_page: |
@@ -734,43 +726,42 @@ err_out: | |||
734 | return err; | 726 | return err; |
735 | } | 727 | } |
736 | 728 | ||
737 | static int __init sgiseeq_probe(void) | 729 | static void __exit sgiseeq_remove(struct platform_device *pdev) |
738 | { | 730 | { |
739 | unsigned int tmp, ret1, ret2 = 0; | 731 | struct net_device *dev = platform_get_drvdata(pdev); |
740 | 732 | struct sgiseeq_private *sp = netdev_priv(dev); | |
741 | /* On board adapter on 1st HPC is always present */ | ||
742 | ret1 = sgiseeq_init(hpc3c0, SGI_ENET_IRQ, 0); | ||
743 | /* Let's see if second HPC is there */ | ||
744 | if (!(ip22_is_fullhouse()) && | ||
745 | get_dbe(tmp, (unsigned int *)&hpc3c1->pbdma[1]) == 0) { | ||
746 | sgimc->giopar |= SGIMC_GIOPAR_MASTEREXP1 | | ||
747 | SGIMC_GIOPAR_EXP164 | | ||
748 | SGIMC_GIOPAR_HPC264; | ||
749 | hpc3c1->pbus_piocfg[0][0] = 0x3ffff; | ||
750 | /* interrupt/config register on Challenge S Mezz board */ | ||
751 | hpc3c1->pbus_extregs[0][0] = 0x30; | ||
752 | ret2 = sgiseeq_init(hpc3c1, SGI_GIO_0_IRQ, 1); | ||
753 | } | ||
754 | 733 | ||
755 | return (ret1 & ret2) ? ret1 : 0; | 734 | unregister_netdev(dev); |
735 | free_page((unsigned long) sp->srings); | ||
736 | free_netdev(dev); | ||
737 | platform_set_drvdata(pdev, NULL); | ||
756 | } | 738 | } |
757 | 739 | ||
758 | static void __exit sgiseeq_exit(void) | 740 | static struct platform_driver sgiseeq_driver = { |
759 | { | 741 | .probe = sgiseeq_probe, |
760 | struct net_device *next, *dev; | 742 | .remove = __devexit_p(sgiseeq_remove), |
761 | struct sgiseeq_private *sp; | 743 | .driver = { |
744 | .name = "sgiseeq" | ||
745 | } | ||
746 | }; | ||
762 | 747 | ||
763 | for (dev = root_sgiseeq_dev; dev; dev = next) { | 748 | static int __init sgiseeq_module_init(void) |
764 | sp = (struct sgiseeq_private *) netdev_priv(dev); | 749 | { |
765 | next = sp->next_module; | 750 | if (platform_driver_register(&sgiseeq_driver)) { |
766 | unregister_netdev(dev); | 751 | printk(KERN_ERR "Driver registration failed\n"); |
767 | free_page((unsigned long) sp->srings); | 752 | return -ENODEV; |
768 | free_netdev(dev); | ||
769 | } | 753 | } |
754 | |||
755 | return 0; | ||
756 | } | ||
757 | |||
758 | static void __exit sgiseeq_module_exit(void) | ||
759 | { | ||
760 | platform_driver_unregister(&sgiseeq_driver); | ||
770 | } | 761 | } |
771 | 762 | ||
772 | module_init(sgiseeq_probe); | 763 | module_init(sgiseeq_module_init); |
773 | module_exit(sgiseeq_exit); | 764 | module_exit(sgiseeq_module_exit); |
774 | 765 | ||
775 | MODULE_DESCRIPTION("SGI Seeq 8003 driver"); | 766 | MODULE_DESCRIPTION("SGI Seeq 8003 driver"); |
776 | MODULE_AUTHOR("Linux/MIPS Mailing List <linux-mips@linux-mips.org>"); | 767 | MODULE_AUTHOR("Linux/MIPS Mailing List <linux-mips@linux-mips.org>"); |