diff options
Diffstat (limited to 'drivers/net/ne.c')
-rw-r--r-- | drivers/net/ne.c | 91 |
1 files changed, 89 insertions, 2 deletions
diff --git a/drivers/net/ne.c b/drivers/net/ne.c index a5c4199e2754..aef470d6b9ab 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c | |||
@@ -51,6 +51,7 @@ static const char version2[] = | |||
51 | #include <linux/netdevice.h> | 51 | #include <linux/netdevice.h> |
52 | #include <linux/etherdevice.h> | 52 | #include <linux/etherdevice.h> |
53 | #include <linux/jiffies.h> | 53 | #include <linux/jiffies.h> |
54 | #include <linux/platform_device.h> | ||
54 | 55 | ||
55 | #include <asm/system.h> | 56 | #include <asm/system.h> |
56 | #include <asm/io.h> | 57 | #include <asm/io.h> |
@@ -807,6 +808,87 @@ retry: | |||
807 | return; | 808 | return; |
808 | } | 809 | } |
809 | 810 | ||
811 | static int __init ne_drv_probe(struct platform_device *pdev) | ||
812 | { | ||
813 | struct net_device *dev; | ||
814 | struct resource *res; | ||
815 | int err, irq; | ||
816 | |||
817 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
818 | irq = platform_get_irq(pdev, 0); | ||
819 | if (!res || irq < 0) | ||
820 | return -ENODEV; | ||
821 | |||
822 | dev = alloc_ei_netdev(); | ||
823 | if (!dev) | ||
824 | return -ENOMEM; | ||
825 | dev->irq = irq; | ||
826 | dev->base_addr = res->start; | ||
827 | err = do_ne_probe(dev); | ||
828 | if (err) { | ||
829 | free_netdev(dev); | ||
830 | return err; | ||
831 | } | ||
832 | platform_set_drvdata(pdev, dev); | ||
833 | return 0; | ||
834 | } | ||
835 | |||
836 | static int __exit ne_drv_remove(struct platform_device *pdev) | ||
837 | { | ||
838 | struct net_device *dev = platform_get_drvdata(pdev); | ||
839 | |||
840 | unregister_netdev(dev); | ||
841 | free_irq(dev->irq, dev); | ||
842 | release_region(dev->base_addr, NE_IO_EXTENT); | ||
843 | free_netdev(dev); | ||
844 | return 0; | ||
845 | } | ||
846 | |||
847 | #ifdef CONFIG_PM | ||
848 | static int ne_drv_suspend(struct platform_device *pdev, pm_message_t state) | ||
849 | { | ||
850 | struct net_device *dev = platform_get_drvdata(pdev); | ||
851 | |||
852 | if (netif_running(dev)) | ||
853 | netif_device_detach(dev); | ||
854 | return 0; | ||
855 | } | ||
856 | |||
857 | static int ne_drv_resume(struct platform_device *pdev) | ||
858 | { | ||
859 | struct net_device *dev = platform_get_drvdata(pdev); | ||
860 | |||
861 | if (netif_running(dev)) { | ||
862 | ne_reset_8390(dev); | ||
863 | NS8390_init(dev, 1); | ||
864 | netif_device_attach(dev); | ||
865 | } | ||
866 | return 0; | ||
867 | } | ||
868 | #else | ||
869 | #define ne_drv_suspend NULL | ||
870 | #define ne_drv_resume NULL | ||
871 | #endif | ||
872 | |||
873 | static struct platform_driver ne_driver = { | ||
874 | .remove = __exit_p(ne_drv_remove), | ||
875 | .suspend = ne_drv_suspend, | ||
876 | .resume = ne_drv_resume, | ||
877 | .driver = { | ||
878 | .name = DRV_NAME, | ||
879 | .owner = THIS_MODULE, | ||
880 | }, | ||
881 | }; | ||
882 | |||
883 | static int __init ne_init(void) | ||
884 | { | ||
885 | return platform_driver_probe(&ne_driver, ne_drv_probe); | ||
886 | } | ||
887 | |||
888 | static void __exit ne_exit(void) | ||
889 | { | ||
890 | platform_driver_unregister(&ne_driver); | ||
891 | } | ||
810 | 892 | ||
811 | #ifdef MODULE | 893 | #ifdef MODULE |
812 | #define MAX_NE_CARDS 4 /* Max number of NE cards per module */ | 894 | #define MAX_NE_CARDS 4 /* Max number of NE cards per module */ |
@@ -832,6 +914,7 @@ ISA device autoprobes on a running machine are not recommended anyway. */ | |||
832 | int __init init_module(void) | 914 | int __init init_module(void) |
833 | { | 915 | { |
834 | int this_dev, found = 0; | 916 | int this_dev, found = 0; |
917 | int plat_found = !ne_init(); | ||
835 | 918 | ||
836 | for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { | 919 | for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { |
837 | struct net_device *dev = alloc_ei_netdev(); | 920 | struct net_device *dev = alloc_ei_netdev(); |
@@ -845,7 +928,7 @@ int __init init_module(void) | |||
845 | continue; | 928 | continue; |
846 | } | 929 | } |
847 | free_netdev(dev); | 930 | free_netdev(dev); |
848 | if (found) | 931 | if (found || plat_found) |
849 | break; | 932 | break; |
850 | if (io[this_dev] != 0) | 933 | if (io[this_dev] != 0) |
851 | printk(KERN_WARNING "ne.c: No NE*000 card found at i/o = %#x\n", io[this_dev]); | 934 | printk(KERN_WARNING "ne.c: No NE*000 card found at i/o = %#x\n", io[this_dev]); |
@@ -853,7 +936,7 @@ int __init init_module(void) | |||
853 | printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n"); | 936 | printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n"); |
854 | return -ENXIO; | 937 | return -ENXIO; |
855 | } | 938 | } |
856 | if (found) | 939 | if (found || plat_found) |
857 | return 0; | 940 | return 0; |
858 | return -ENODEV; | 941 | return -ENODEV; |
859 | } | 942 | } |
@@ -871,6 +954,7 @@ void __exit cleanup_module(void) | |||
871 | { | 954 | { |
872 | int this_dev; | 955 | int this_dev; |
873 | 956 | ||
957 | ne_exit(); | ||
874 | for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { | 958 | for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { |
875 | struct net_device *dev = dev_ne[this_dev]; | 959 | struct net_device *dev = dev_ne[this_dev]; |
876 | if (dev) { | 960 | if (dev) { |
@@ -880,4 +964,7 @@ void __exit cleanup_module(void) | |||
880 | } | 964 | } |
881 | } | 965 | } |
882 | } | 966 | } |
967 | #else /* MODULE */ | ||
968 | module_init(ne_init); | ||
969 | module_exit(ne_exit); | ||
883 | #endif /* MODULE */ | 970 | #endif /* MODULE */ |