diff options
Diffstat (limited to 'drivers')
| -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 */ |
