aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2005-11-14 15:21:18 -0500
committerDominik Brodowski <linux@dominikbrodowski.net>2006-01-05 17:59:02 -0500
commit98e4c28b7ec390c2dad6a4c69d69629c0f7e8b10 (patch)
treeb3d46f0643352e541d6a39e6da09059687cf713d
parent63e7ebd06402951bc8863ba5b7bc9b9f42044849 (diff)
[PATCH] pcmcia: new suspend core
Move the suspend and resume methods out of the event handler, and into special functions. Also use these functions for pre- and post-reset, as almost all drivers already do, and the remaining ones can easily be converted. Bugfix to include/pcmcia/ds.c Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
-rw-r--r--Documentation/pcmcia/driver-changes.txt6
-rw-r--r--drivers/bluetooth/bluecard_cs.c37
-rw-r--r--drivers/bluetooth/bt3c_cs.c37
-rw-r--r--drivers/bluetooth/btuart_cs.c38
-rw-r--r--drivers/bluetooth/dtl1_cs.c37
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c61
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c50
-rw-r--r--drivers/char/pcmcia/synclink_cs.c47
-rw-r--r--drivers/ide/legacy/ide-cs.c38
-rw-r--r--drivers/isdn/hardware/avm/avm_cs.c38
-rw-r--r--drivers/isdn/hisax/avma1_cs.c38
-rw-r--r--drivers/isdn/hisax/elsa_cs.c46
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c50
-rw-r--r--drivers/isdn/hisax/teles_cs.c46
-rw-r--r--drivers/mtd/maps/pcmciamtd.c36
-rw-r--r--drivers/net/pcmcia/3c574_cs.c56
-rw-r--r--drivers/net/pcmcia/3c589_cs.c56
-rw-r--r--drivers/net/pcmcia/axnet_cs.c59
-rw-r--r--drivers/net/pcmcia/com20020_cs.c62
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c57
-rw-r--r--drivers/net/pcmcia/ibmtr_cs.c59
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c57
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c58
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c109
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c61
-rw-r--r--drivers/net/wireless/airo_cs.c50
-rw-r--r--drivers/net/wireless/atmel_cs.c50
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c88
-rw-r--r--drivers/net/wireless/netwave_cs.c57
-rw-r--r--drivers/net/wireless/orinoco_cs.c145
-rw-r--r--drivers/net/wireless/ray_cs.c59
-rw-r--r--drivers/net/wireless/spectrum_cs.c96
-rw-r--r--drivers/net/wireless/wavelan_cs.c92
-rw-r--r--drivers/net/wireless/wl3501_cs.c61
-rw-r--r--drivers/parport/parport_cs.c39
-rw-r--r--drivers/pcmcia/ds.c10
-rw-r--r--drivers/scsi/pcmcia/aha152x_stub.c48
-rw-r--r--drivers/scsi/pcmcia/fdomain_stub.c42
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c102
-rw-r--r--drivers/scsi/pcmcia/qlogic_stub.c59
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c69
-rw-r--r--drivers/serial/serial_cs.c31
-rw-r--r--drivers/telephony/ixj_pcmcia.c38
-rw-r--r--drivers/usb/host/sl811_cs.c41
-rw-r--r--include/pcmcia/ds.h6
45 files changed, 1431 insertions, 991 deletions
diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt
index 403e7b4dcdd4..5c822f54d46c 100644
--- a/Documentation/pcmcia/driver-changes.txt
+++ b/Documentation/pcmcia/driver-changes.txt
@@ -1,5 +1,11 @@
1This file details changes in 2.6 which affect PCMCIA card driver authors: 1This file details changes in 2.6 which affect PCMCIA card driver authors:
2 2
3* Move suspend, resume and reset out of event handler (as of 2.6.16)
4 int (*suspend) (struct pcmcia_device *dev);
5 int (*resume) (struct pcmcia_device *dev);
6 should be initialized in struct pcmcia_driver, and handle
7 (SUSPEND == RESET_PHYSICAL) and (RESUME == CARD_RESET) events
8
3* event handler initialization in struct pcmcia_driver (as of 2.6.13) 9* event handler initialization in struct pcmcia_driver (as of 2.6.13)
4 The event handler is notified of all events, and must be initialized 10 The event handler is notified of all events, and must be initialized
5 as the event() callback in the driver's struct pcmcia_driver. 11 as the event() callback in the driver's struct pcmcia_driver.
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index f36c563d72c4..5b24131e5430 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -1045,6 +1045,27 @@ static void bluecard_release(dev_link_t *link)
1045 link->state &= ~DEV_CONFIG; 1045 link->state &= ~DEV_CONFIG;
1046} 1046}
1047 1047
1048static int bluecard_suspend(struct pcmcia_device *dev)
1049{
1050 dev_link_t *link = dev_to_instance(dev);
1051
1052 link->state |= DEV_SUSPEND;
1053 if (link->state & DEV_CONFIG)
1054 pcmcia_release_configuration(link->handle);
1055
1056 return 0;
1057}
1058
1059static int bluecard_resume(struct pcmcia_device *dev)
1060{
1061 dev_link_t *link = dev_to_instance(dev);
1062
1063 link->state &= ~DEV_SUSPEND;
1064 if (DEV_OK(link))
1065 pcmcia_request_configuration(link->handle, &link->conf);
1066
1067 return 0;
1068}
1048 1069
1049static int bluecard_event(event_t event, int priority, event_callback_args_t *args) 1070static int bluecard_event(event_t event, int priority, event_callback_args_t *args)
1050{ 1071{
@@ -1063,20 +1084,6 @@ static int bluecard_event(event_t event, int priority, event_callback_args_t *ar
1063 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 1084 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
1064 bluecard_config(link); 1085 bluecard_config(link);
1065 break; 1086 break;
1066 case CS_EVENT_PM_SUSPEND:
1067 link->state |= DEV_SUSPEND;
1068 /* Fall through... */
1069 case CS_EVENT_RESET_PHYSICAL:
1070 if (link->state & DEV_CONFIG)
1071 pcmcia_release_configuration(link->handle);
1072 break;
1073 case CS_EVENT_PM_RESUME:
1074 link->state &= ~DEV_SUSPEND;
1075 /* Fall through... */
1076 case CS_EVENT_CARD_RESET:
1077 if (DEV_OK(link))
1078 pcmcia_request_configuration(link->handle, &link->conf);
1079 break;
1080 } 1087 }
1081 1088
1082 return 0; 1089 return 0;
@@ -1099,6 +1106,8 @@ static struct pcmcia_driver bluecard_driver = {
1099 .event = bluecard_event, 1106 .event = bluecard_event,
1100 .detach = bluecard_detach, 1107 .detach = bluecard_detach,
1101 .id_table = bluecard_ids, 1108 .id_table = bluecard_ids,
1109 .suspend = bluecard_suspend,
1110 .resume = bluecard_resume,
1102}; 1111};
1103 1112
1104static int __init init_bluecard_cs(void) 1113static int __init init_bluecard_cs(void)
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index d2a0add19cc8..1d524baa24a0 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -891,6 +891,27 @@ static void bt3c_release(dev_link_t *link)
891 link->state &= ~DEV_CONFIG; 891 link->state &= ~DEV_CONFIG;
892} 892}
893 893
894static int bt3c_suspend(struct pcmcia_device *dev)
895{
896 dev_link_t *link = dev_to_instance(dev);
897
898 link->state |= DEV_SUSPEND;
899 if (link->state & DEV_CONFIG)
900 pcmcia_release_configuration(link->handle);
901
902 return 0;
903}
904
905static int bt3c_resume(struct pcmcia_device *dev)
906{
907 dev_link_t *link = dev_to_instance(dev);
908
909 link->state &= ~DEV_SUSPEND;
910 if (DEV_OK(link))
911 pcmcia_request_configuration(link->handle, &link->conf);
912
913 return 0;
914}
894 915
895static int bt3c_event(event_t event, int priority, event_callback_args_t *args) 916static int bt3c_event(event_t event, int priority, event_callback_args_t *args)
896{ 917{
@@ -909,20 +930,6 @@ static int bt3c_event(event_t event, int priority, event_callback_args_t *args)
909 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 930 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
910 bt3c_config(link); 931 bt3c_config(link);
911 break; 932 break;
912 case CS_EVENT_PM_SUSPEND:
913 link->state |= DEV_SUSPEND;
914 /* Fall through... */
915 case CS_EVENT_RESET_PHYSICAL:
916 if (link->state & DEV_CONFIG)
917 pcmcia_release_configuration(link->handle);
918 break;
919 case CS_EVENT_PM_RESUME:
920 link->state &= ~DEV_SUSPEND;
921 /* Fall through... */
922 case CS_EVENT_CARD_RESET:
923 if (DEV_OK(link))
924 pcmcia_request_configuration(link->handle, &link->conf);
925 break;
926 } 933 }
927 934
928 return 0; 935 return 0;
@@ -943,6 +950,8 @@ static struct pcmcia_driver bt3c_driver = {
943 .event = bt3c_event, 950 .event = bt3c_event,
944 .detach = bt3c_detach, 951 .detach = bt3c_detach,
945 .id_table = bt3c_ids, 952 .id_table = bt3c_ids,
953 .suspend = bt3c_suspend,
954 .resume = bt3c_resume,
946}; 955};
947 956
948static int __init init_bt3c_cs(void) 957static int __init init_bt3c_cs(void)
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index 529a28a3209d..1828ba6ca25e 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -811,6 +811,28 @@ static void btuart_release(dev_link_t *link)
811 link->state &= ~DEV_CONFIG; 811 link->state &= ~DEV_CONFIG;
812} 812}
813 813
814static int btuart_suspend(struct pcmcia_device *dev)
815{
816 dev_link_t *link = dev_to_instance(dev);
817
818 link->state |= DEV_SUSPEND;
819 if (link->state & DEV_CONFIG)
820 pcmcia_release_configuration(link->handle);
821
822 return 0;
823}
824
825static int btuart_resume(struct pcmcia_device *dev)
826{
827 dev_link_t *link = dev_to_instance(dev);
828
829 link->state &= ~DEV_SUSPEND;
830 if (DEV_OK(link))
831 pcmcia_request_configuration(link->handle, &link->conf);
832
833 return 0;
834}
835
814 836
815static int btuart_event(event_t event, int priority, event_callback_args_t *args) 837static int btuart_event(event_t event, int priority, event_callback_args_t *args)
816{ 838{
@@ -829,20 +851,6 @@ static int btuart_event(event_t event, int priority, event_callback_args_t *args
829 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 851 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
830 btuart_config(link); 852 btuart_config(link);
831 break; 853 break;
832 case CS_EVENT_PM_SUSPEND:
833 link->state |= DEV_SUSPEND;
834 /* Fall through... */
835 case CS_EVENT_RESET_PHYSICAL:
836 if (link->state & DEV_CONFIG)
837 pcmcia_release_configuration(link->handle);
838 break;
839 case CS_EVENT_PM_RESUME:
840 link->state &= ~DEV_SUSPEND;
841 /* Fall through... */
842 case CS_EVENT_CARD_RESET:
843 if (DEV_OK(link))
844 pcmcia_request_configuration(link->handle, &link->conf);
845 break;
846 } 854 }
847 855
848 return 0; 856 return 0;
@@ -863,6 +871,8 @@ static struct pcmcia_driver btuart_driver = {
863 .event = btuart_event, 871 .event = btuart_event,
864 .detach = btuart_detach, 872 .detach = btuart_detach,
865 .id_table = btuart_ids, 873 .id_table = btuart_ids,
874 .suspend = btuart_suspend,
875 .resume = btuart_resume,
866}; 876};
867 877
868static int __init init_btuart_cs(void) 878static int __init init_btuart_cs(void)
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index dec5980a1cd6..9f9d3f91f455 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -763,6 +763,27 @@ static void dtl1_release(dev_link_t *link)
763 link->state &= ~DEV_CONFIG; 763 link->state &= ~DEV_CONFIG;
764} 764}
765 765
766static int dtl1_suspend(struct pcmcia_device *dev)
767{
768 dev_link_t *link = dev_to_instance(dev);
769
770 link->state |= DEV_SUSPEND;
771 if (link->state & DEV_CONFIG)
772 pcmcia_release_configuration(link->handle);
773
774 return 0;
775}
776
777static int dtl1_resume(struct pcmcia_device *dev)
778{
779 dev_link_t *link = dev_to_instance(dev);
780
781 link->state &= ~DEV_SUSPEND;
782 if (DEV_OK(link))
783 pcmcia_request_configuration(link->handle, &link->conf);
784
785 return 0;
786}
766 787
767static int dtl1_event(event_t event, int priority, event_callback_args_t *args) 788static int dtl1_event(event_t event, int priority, event_callback_args_t *args)
768{ 789{
@@ -781,20 +802,6 @@ static int dtl1_event(event_t event, int priority, event_callback_args_t *args)
781 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 802 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
782 dtl1_config(link); 803 dtl1_config(link);
783 break; 804 break;
784 case CS_EVENT_PM_SUSPEND:
785 link->state |= DEV_SUSPEND;
786 /* Fall through... */
787 case CS_EVENT_RESET_PHYSICAL:
788 if (link->state & DEV_CONFIG)
789 pcmcia_release_configuration(link->handle);
790 break;
791 case CS_EVENT_PM_RESUME:
792 link->state &= ~DEV_SUSPEND;
793 /* Fall through... */
794 case CS_EVENT_CARD_RESET:
795 if (DEV_OK(link))
796 pcmcia_request_configuration(link->handle, &link->conf);
797 break;
798 } 805 }
799 806
800 return 0; 807 return 0;
@@ -816,6 +823,8 @@ static struct pcmcia_driver dtl1_driver = {
816 .event = dtl1_event, 823 .event = dtl1_event,
817 .detach = dtl1_detach, 824 .detach = dtl1_detach,
818 .id_table = dtl1_ids, 825 .id_table = dtl1_ids,
826 .suspend = dtl1_suspend,
827 .resume = dtl1_resume,
819}; 828};
820 829
821static int __init init_dtl1_cs(void) 830static int __init init_dtl1_cs(void)
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index 61681c9f3f72..05e93054c98c 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -1893,33 +1893,6 @@ static int cm4000_event(event_t event, int priority,
1893 link->state &= ~DEV_PRESENT; 1893 link->state &= ~DEV_PRESENT;
1894 stop_monitor(dev); 1894 stop_monitor(dev);
1895 break; 1895 break;
1896 case CS_EVENT_PM_SUSPEND:
1897 DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND "
1898 "(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
1899 link->state |= DEV_SUSPEND;
1900 /* fall-through */
1901 case CS_EVENT_RESET_PHYSICAL:
1902 DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
1903 if (link->state & DEV_CONFIG) {
1904 DEBUGP(5, dev, "ReleaseConfiguration\n");
1905 pcmcia_release_configuration(link->handle);
1906 }
1907 stop_monitor(dev);
1908 break;
1909 case CS_EVENT_PM_RESUME:
1910 DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
1911 "(fall-through to CS_EVENT_CARD_RESET)\n");
1912 link->state &= ~DEV_SUSPEND;
1913 /* fall-through */
1914 case CS_EVENT_CARD_RESET:
1915 DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
1916 if ((link->state & DEV_CONFIG)) {
1917 DEBUGP(5, dev, "RequestConfiguration\n");
1918 pcmcia_request_configuration(link->handle, &link->conf);
1919 }
1920 if (link->open)
1921 start_monitor(dev);
1922 break;
1923 default: 1896 default:
1924 DEBUGP(5, dev, "unknown event %.2x\n", event); 1897 DEBUGP(5, dev, "unknown event %.2x\n", event);
1925 break; 1898 break;
@@ -1928,6 +1901,38 @@ static int cm4000_event(event_t event, int priority,
1928 return CS_SUCCESS; 1901 return CS_SUCCESS;
1929} 1902}
1930 1903
1904static int cm4000_suspend(struct pcmcia_device *p_dev)
1905{
1906 dev_link_t *link = dev_to_instance(p_dev);
1907 struct cm4000_dev *dev;
1908
1909 dev = link->priv;
1910
1911 link->state |= DEV_SUSPEND;
1912 if (link->state & DEV_CONFIG)
1913 pcmcia_release_configuration(link->handle);
1914 stop_monitor(dev);
1915
1916 return 0;
1917}
1918
1919static int cm4000_resume(struct pcmcia_device *p_dev)
1920{
1921 dev_link_t *link = dev_to_instance(p_dev);
1922 struct cm4000_dev *dev;
1923
1924 dev = link->priv;
1925
1926 link->state &= ~DEV_SUSPEND;
1927 if (link->state & DEV_CONFIG)
1928 pcmcia_request_configuration(link->handle, &link->conf);
1929
1930 if (link->open)
1931 start_monitor(dev);
1932
1933 return 0;
1934}
1935
1931static void cm4000_release(dev_link_t *link) 1936static void cm4000_release(dev_link_t *link)
1932{ 1937{
1933 cmm_cm4000_release(link->priv); /* delay release until device closed */ 1938 cmm_cm4000_release(link->priv); /* delay release until device closed */
@@ -2044,6 +2049,8 @@ static struct pcmcia_driver cm4000_driver = {
2044 }, 2049 },
2045 .attach = cm4000_attach, 2050 .attach = cm4000_attach,
2046 .detach = cm4000_detach, 2051 .detach = cm4000_detach,
2052 .suspend = cm4000_suspend,
2053 .resume = cm4000_resume,
2047 .event = cm4000_event, 2054 .event = cm4000_event,
2048 .id_table = cm4000_ids, 2055 .id_table = cm4000_ids,
2049}; 2056};
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 4c698d908ffa..3622fd39c47b 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -656,31 +656,7 @@ static int reader_event(event_t event, int priority,
656 DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n"); 656 DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n");
657 link->state &= ~DEV_PRESENT; 657 link->state &= ~DEV_PRESENT;
658 break; 658 break;
659 case CS_EVENT_PM_SUSPEND: 659
660 DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND "
661 "(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
662 link->state |= DEV_SUSPEND;
663
664 case CS_EVENT_RESET_PHYSICAL:
665 DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
666 if (link->state & DEV_CONFIG) {
667 DEBUGP(5, dev, "ReleaseConfiguration\n");
668 pcmcia_release_configuration(link->handle);
669 }
670 break;
671 case CS_EVENT_PM_RESUME:
672 DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
673 "(fall-through to CS_EVENT_CARD_RESET)\n");
674 link->state &= ~DEV_SUSPEND;
675
676 case CS_EVENT_CARD_RESET:
677 DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
678 if ((link->state & DEV_CONFIG)) {
679 DEBUGP(5, dev, "RequestConfiguration\n");
680 pcmcia_request_configuration(link->handle,
681 &link->conf);
682 }
683 break;
684 default: 660 default:
685 DEBUGP(5, dev, "reader_event: unknown event %.2x\n", 661 DEBUGP(5, dev, "reader_event: unknown event %.2x\n",
686 event); 662 event);
@@ -690,6 +666,28 @@ static int reader_event(event_t event, int priority,
690 return CS_SUCCESS; 666 return CS_SUCCESS;
691} 667}
692 668
669static int reader_suspend(struct pcmcia_device *p_dev)
670{
671 dev_link_t *link = dev_to_instance(p_dev);
672
673 link->state |= DEV_SUSPEND;
674 if (link->state & DEV_CONFIG)
675 pcmcia_release_configuration(link->handle);
676
677 return 0;
678}
679
680static int reader_resume(struct pcmcia_device *p_dev)
681{
682 dev_link_t *link = dev_to_instance(p_dev);
683
684 link->state &= ~DEV_SUSPEND;
685 if (link->state & DEV_CONFIG)
686 pcmcia_request_configuration(link->handle, &link->conf);
687
688 return 0;
689}
690
693static void reader_release(dev_link_t *link) 691static void reader_release(dev_link_t *link)
694{ 692{
695 cm4040_reader_release(link->priv); 693 cm4040_reader_release(link->priv);
@@ -806,6 +804,8 @@ static struct pcmcia_driver reader_driver = {
806 }, 804 },
807 .attach = reader_attach, 805 .attach = reader_attach,
808 .detach = reader_detach, 806 .detach = reader_detach,
807 .suspend = reader_suspend,
808 .resume = reader_resume,
809 .event = reader_event, 809 .event = reader_event,
810 .id_table = cm4040_ids, 810 .id_table = cm4040_ids,
811}; 811};
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 2c326ea53421..776103e56042 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -773,11 +773,37 @@ static void mgslpc_detach(dev_link_t *link)
773 mgslpc_remove_device((MGSLPC_INFO *)link->priv); 773 mgslpc_remove_device((MGSLPC_INFO *)link->priv);
774} 774}
775 775
776static int mgslpc_suspend(struct pcmcia_device *dev)
777{
778 dev_link_t *link = dev_to_instance(dev);
779 MGSLPC_INFO *info = link->priv;
780
781 link->state |= DEV_SUSPEND;
782 info->stop = 1;
783 if (link->state & DEV_CONFIG)
784 pcmcia_release_configuration(link->handle);
785
786 return 0;
787}
788
789static int mgslpc_resume(struct pcmcia_device *dev)
790{
791 dev_link_t *link = dev_to_instance(dev);
792 MGSLPC_INFO *info = link->priv;
793
794 link->state &= ~DEV_SUSPEND;
795 if (link->state & DEV_CONFIG)
796 pcmcia_request_configuration(link->handle, &link->conf);
797 info->stop = 0;
798
799 return 0;
800}
801
802
776static int mgslpc_event(event_t event, int priority, 803static int mgslpc_event(event_t event, int priority,
777 event_callback_args_t *args) 804 event_callback_args_t *args)
778{ 805{
779 dev_link_t *link = args->client_data; 806 dev_link_t *link = args->client_data;
780 MGSLPC_INFO *info = link->priv;
781 807
782 if (debug_level >= DEBUG_LEVEL_INFO) 808 if (debug_level >= DEBUG_LEVEL_INFO)
783 printk("mgslpc_event(0x%06x)\n", event); 809 printk("mgslpc_event(0x%06x)\n", event);
@@ -794,23 +820,6 @@ static int mgslpc_event(event_t event, int priority,
794 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 820 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
795 mgslpc_config(link); 821 mgslpc_config(link);
796 break; 822 break;
797 case CS_EVENT_PM_SUSPEND:
798 link->state |= DEV_SUSPEND;
799 /* Fall through... */
800 case CS_EVENT_RESET_PHYSICAL:
801 /* Mark the device as stopped, to block IO until later */
802 info->stop = 1;
803 if (link->state & DEV_CONFIG)
804 pcmcia_release_configuration(link->handle);
805 break;
806 case CS_EVENT_PM_RESUME:
807 link->state &= ~DEV_SUSPEND;
808 /* Fall through... */
809 case CS_EVENT_CARD_RESET:
810 if (link->state & DEV_CONFIG)
811 pcmcia_request_configuration(link->handle, &link->conf);
812 info->stop = 0;
813 break;
814 } 823 }
815 return 0; 824 return 0;
816} 825}
@@ -3095,6 +3104,8 @@ static struct pcmcia_driver mgslpc_driver = {
3095 .event = mgslpc_event, 3104 .event = mgslpc_event,
3096 .detach = mgslpc_detach, 3105 .detach = mgslpc_detach,
3097 .id_table = mgslpc_ids, 3106 .id_table = mgslpc_ids,
3107 .suspend = mgslpc_suspend,
3108 .resume = mgslpc_resume,
3098}; 3109};
3099 3110
3100static struct tty_operations mgslpc_ops = { 3111static struct tty_operations mgslpc_ops = {
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index ef79805218e4..982b74af8c29 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -406,6 +406,28 @@ void ide_release(dev_link_t *link)
406 406
407} /* ide_release */ 407} /* ide_release */
408 408
409static int ide_suspend(struct pcmcia_device *dev)
410{
411 dev_link_t *link = dev_to_instance(dev);
412
413 link->state |= DEV_SUSPEND;
414 if (link->state & DEV_CONFIG)
415 pcmcia_release_configuration(link->handle);
416
417 return 0;
418}
419
420static int ide_resume(struct pcmcia_device *dev)
421{
422 dev_link_t *link = dev_to_instance(dev);
423
424 link->state &= ~DEV_SUSPEND;
425 if (DEV_OK(link))
426 pcmcia_request_configuration(link->handle, &link->conf);
427
428 return 0;
429}
430
409/*====================================================================== 431/*======================================================================
410 432
411 The card status event handler. Mostly, this schedules other 433 The card status event handler. Mostly, this schedules other
@@ -432,20 +454,6 @@ int ide_event(event_t event, int priority,
432 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 454 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
433 ide_config(link); 455 ide_config(link);
434 break; 456 break;
435 case CS_EVENT_PM_SUSPEND:
436 link->state |= DEV_SUSPEND;
437 /* Fall through... */
438 case CS_EVENT_RESET_PHYSICAL:
439 if (link->state & DEV_CONFIG)
440 pcmcia_release_configuration(link->handle);
441 break;
442 case CS_EVENT_PM_RESUME:
443 link->state &= ~DEV_SUSPEND;
444 /* Fall through... */
445 case CS_EVENT_CARD_RESET:
446 if (DEV_OK(link))
447 pcmcia_request_configuration(link->handle, &link->conf);
448 break;
449 } 457 }
450 return 0; 458 return 0;
451} /* ide_event */ 459} /* ide_event */
@@ -498,6 +506,8 @@ static struct pcmcia_driver ide_cs_driver = {
498 .event = ide_event, 506 .event = ide_event,
499 .detach = ide_detach, 507 .detach = ide_detach,
500 .id_table = ide_ids, 508 .id_table = ide_ids,
509 .suspend = ide_suspend,
510 .resume = ide_resume,
501}; 511};
502 512
503static int __init init_ide_cs(void) 513static int __init init_ide_cs(void)
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
index 27391c32f3eb..6d9816e10ecb 100644
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -430,6 +430,28 @@ static void avmcs_release(dev_link_t *link)
430 430
431} /* avmcs_release */ 431} /* avmcs_release */
432 432
433static int avmcs_suspend(struct pcmcia_device *dev)
434{
435 dev_link_t *link = dev_to_instance(dev);
436
437 link->state |= DEV_SUSPEND;
438 if (link->state & DEV_CONFIG)
439 pcmcia_release_configuration(link->handle);
440
441 return 0;
442}
443
444static int avmcs_resume(struct pcmcia_device *dev)
445{
446 dev_link_t *link = dev_to_instance(dev);
447
448 link->state &= ~DEV_SUSPEND;
449 if (link->state & DEV_CONFIG)
450 pcmcia_request_configuration(link->handle, &link->conf);
451
452 return 0;
453}
454
433/*====================================================================== 455/*======================================================================
434 456
435 The card status event handler. Mostly, this schedules other 457 The card status event handler. Mostly, this schedules other
@@ -459,20 +481,6 @@ static int avmcs_event(event_t event, int priority,
459 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 481 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
460 avmcs_config(link); 482 avmcs_config(link);
461 break; 483 break;
462 case CS_EVENT_PM_SUSPEND:
463 link->state |= DEV_SUSPEND;
464 /* Fall through... */
465 case CS_EVENT_RESET_PHYSICAL:
466 if (link->state & DEV_CONFIG)
467 pcmcia_release_configuration(link->handle);
468 break;
469 case CS_EVENT_PM_RESUME:
470 link->state &= ~DEV_SUSPEND;
471 /* Fall through... */
472 case CS_EVENT_CARD_RESET:
473 if (link->state & DEV_CONFIG)
474 pcmcia_request_configuration(link->handle, &link->conf);
475 break;
476 } 484 }
477 return 0; 485 return 0;
478} /* avmcs_event */ 486} /* avmcs_event */
@@ -494,6 +502,8 @@ static struct pcmcia_driver avmcs_driver = {
494 .event = avmcs_event, 502 .event = avmcs_event,
495 .detach = avmcs_detach, 503 .detach = avmcs_detach,
496 .id_table = avmcs_ids, 504 .id_table = avmcs_ids,
505 .suspend= avmcs_suspend,
506 .resume = avmcs_resume,
497}; 507};
498 508
499static int __init avmcs_init(void) 509static int __init avmcs_init(void)
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index 5f5a5ae740d2..433cec4269a3 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -445,6 +445,28 @@ static void avma1cs_release(dev_link_t *link)
445 avma1cs_detach(link); 445 avma1cs_detach(link);
446} /* avma1cs_release */ 446} /* avma1cs_release */
447 447
448static int avma1cs_suspend(struct pcmcia_device *dev)
449{
450 dev_link_t *link = dev_to_instance(dev);
451
452 link->state |= DEV_SUSPEND;
453 if (link->state & DEV_CONFIG)
454 pcmcia_release_configuration(link->handle);
455
456 return 0;
457}
458
459static int avma1cs_resume(struct pcmcia_device *dev)
460{
461 dev_link_t *link = dev_to_instance(dev);
462
463 link->state &= ~DEV_SUSPEND;
464 if (link->state & DEV_CONFIG)
465 pcmcia_request_configuration(link->handle, &link->conf);
466
467 return 0;
468}
469
448/*====================================================================== 470/*======================================================================
449 471
450 The card status event handler. Mostly, this schedules other 472 The card status event handler. Mostly, this schedules other
@@ -475,20 +497,6 @@ static int avma1cs_event(event_t event, int priority,
475 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 497 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
476 avma1cs_config(link); 498 avma1cs_config(link);
477 break; 499 break;
478 case CS_EVENT_PM_SUSPEND:
479 link->state |= DEV_SUSPEND;
480 /* Fall through... */
481 case CS_EVENT_RESET_PHYSICAL:
482 if (link->state & DEV_CONFIG)
483 pcmcia_release_configuration(link->handle);
484 break;
485 case CS_EVENT_PM_RESUME:
486 link->state &= ~DEV_SUSPEND;
487 /* Fall through... */
488 case CS_EVENT_CARD_RESET:
489 if (link->state & DEV_CONFIG)
490 pcmcia_request_configuration(link->handle, &link->conf);
491 break;
492 } 500 }
493 return 0; 501 return 0;
494} /* avma1cs_event */ 502} /* avma1cs_event */
@@ -509,6 +517,8 @@ static struct pcmcia_driver avma1cs_driver = {
509 .event = avma1cs_event, 517 .event = avma1cs_event,
510 .detach = avma1cs_detach, 518 .detach = avma1cs_detach,
511 .id_table = avma1cs_ids, 519 .id_table = avma1cs_ids,
520 .suspend = avma1cs_suspend,
521 .resume = avma1cs_resume,
512}; 522};
513 523
514/*====================================================================*/ 524/*====================================================================*/
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index 6fc6868de0b0..0cbe04593d87 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -447,6 +447,32 @@ static void elsa_cs_release(dev_link_t *link)
447 link->state &= ~DEV_CONFIG; 447 link->state &= ~DEV_CONFIG;
448} /* elsa_cs_release */ 448} /* elsa_cs_release */
449 449
450static int elsa_suspend(struct pcmcia_device *p_dev)
451{
452 dev_link_t *link = dev_to_instance(p_dev);
453 local_info_t *dev = link->priv;
454
455 link->state |= DEV_SUSPEND;
456 dev->busy = 1;
457 if (link->state & DEV_CONFIG)
458 pcmcia_release_configuration(link->handle);
459
460 return 0;
461}
462
463static int elsa_resume(struct pcmcia_device *p_dev)
464{
465 dev_link_t *link = dev_to_instance(p_dev);
466 local_info_t *dev = link->priv;
467
468 link->state &= ~DEV_SUSPEND;
469 if (link->state & DEV_CONFIG)
470 pcmcia_request_configuration(link->handle, &link->conf);
471 dev->busy = 0;
472
473 return 0;
474}
475
450/*====================================================================== 476/*======================================================================
451 477
452 The card status event handler. Mostly, this schedules other 478 The card status event handler. Mostly, this schedules other
@@ -465,7 +491,6 @@ static int elsa_cs_event(event_t event, int priority,
465 event_callback_args_t *args) 491 event_callback_args_t *args)
466{ 492{
467 dev_link_t *link = args->client_data; 493 dev_link_t *link = args->client_data;
468 local_info_t *dev = link->priv;
469 494
470 DEBUG(1, "elsa_cs_event(%d)\n", event); 495 DEBUG(1, "elsa_cs_event(%d)\n", event);
471 496
@@ -481,23 +506,6 @@ static int elsa_cs_event(event_t event, int priority,
481 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 506 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
482 elsa_cs_config(link); 507 elsa_cs_config(link);
483 break; 508 break;
484 case CS_EVENT_PM_SUSPEND:
485 link->state |= DEV_SUSPEND;
486 /* Fall through... */
487 case CS_EVENT_RESET_PHYSICAL:
488 /* Mark the device as stopped, to block IO until later */
489 dev->busy = 1;
490 if (link->state & DEV_CONFIG)
491 pcmcia_release_configuration(link->handle);
492 break;
493 case CS_EVENT_PM_RESUME:
494 link->state &= ~DEV_SUSPEND;
495 /* Fall through... */
496 case CS_EVENT_CARD_RESET:
497 if (link->state & DEV_CONFIG)
498 pcmcia_request_configuration(link->handle, &link->conf);
499 dev->busy = 0;
500 break;
501 } 509 }
502 return 0; 510 return 0;
503} /* elsa_cs_event */ 511} /* elsa_cs_event */
@@ -518,6 +526,8 @@ static struct pcmcia_driver elsa_cs_driver = {
518 .event = elsa_cs_event, 526 .event = elsa_cs_event,
519 .detach = elsa_cs_detach, 527 .detach = elsa_cs_detach,
520 .id_table = elsa_ids, 528 .id_table = elsa_ids,
529 .suspend = elsa_suspend,
530 .resume = elsa_resume,
521}; 531};
522 532
523static int __init init_elsa_cs(void) 533static int __init init_elsa_cs(void)
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index dc334aab433e..27dce7c7b760 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -553,6 +553,32 @@ static void sedlbauer_release(dev_link_t *link)
553 553
554} /* sedlbauer_release */ 554} /* sedlbauer_release */
555 555
556static int sedlbauer_suspend(struct pcmcia_device *p_dev)
557{
558 dev_link_t *link = dev_to_instance(p_dev);
559 local_info_t *dev = link->priv;
560
561 link->state |= DEV_SUSPEND;
562 dev->stop = 1;
563 if (link->state & DEV_CONFIG)
564 pcmcia_release_configuration(link->handle);
565
566 return 0;
567}
568
569static int sedlbauer_resume(struct pcmcia_device *p_dev)
570{
571 dev_link_t *link = dev_to_instance(p_dev);
572 local_info_t *dev = link->priv;
573
574 link->state &= ~DEV_SUSPEND;
575 if (link->state & DEV_CONFIG)
576 pcmcia_request_configuration(link->handle, &link->conf);
577 dev->stop = 0;
578
579 return 0;
580}
581
556/*====================================================================== 582/*======================================================================
557 583
558 The card status event handler. Mostly, this schedules other 584 The card status event handler. Mostly, this schedules other
@@ -569,7 +595,6 @@ static int sedlbauer_event(event_t event, int priority,
569 event_callback_args_t *args) 595 event_callback_args_t *args)
570{ 596{
571 dev_link_t *link = args->client_data; 597 dev_link_t *link = args->client_data;
572 local_info_t *dev = link->priv;
573 598
574 DEBUG(1, "sedlbauer_event(0x%06x)\n", event); 599 DEBUG(1, "sedlbauer_event(0x%06x)\n", event);
575 600
@@ -585,27 +610,6 @@ static int sedlbauer_event(event_t event, int priority,
585 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 610 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
586 sedlbauer_config(link); 611 sedlbauer_config(link);
587 break; 612 break;
588 case CS_EVENT_PM_SUSPEND:
589 link->state |= DEV_SUSPEND;
590 /* Fall through... */
591 case CS_EVENT_RESET_PHYSICAL:
592 /* Mark the device as stopped, to block IO until later */
593 dev->stop = 1;
594 if (link->state & DEV_CONFIG)
595 pcmcia_release_configuration(link->handle);
596 break;
597 case CS_EVENT_PM_RESUME:
598 link->state &= ~DEV_SUSPEND;
599 /* Fall through... */
600 case CS_EVENT_CARD_RESET:
601 if (link->state & DEV_CONFIG)
602 pcmcia_request_configuration(link->handle, &link->conf);
603 dev->stop = 0;
604 /*
605 In a normal driver, additional code may go here to restore
606 the device state and restart IO.
607 */
608 break;
609 } 613 }
610 return 0; 614 return 0;
611} /* sedlbauer_event */ 615} /* sedlbauer_event */
@@ -631,6 +635,8 @@ static struct pcmcia_driver sedlbauer_driver = {
631 .event = sedlbauer_event, 635 .event = sedlbauer_event,
632 .detach = sedlbauer_detach, 636 .detach = sedlbauer_detach,
633 .id_table = sedlbauer_ids, 637 .id_table = sedlbauer_ids,
638 .suspend = sedlbauer_suspend,
639 .resume = sedlbauer_resume,
634}; 640};
635 641
636static int __init init_sedlbauer_cs(void) 642static int __init init_sedlbauer_cs(void)
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index 0ddef1bf778b..70213bc1d30c 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -428,6 +428,32 @@ static void teles_cs_release(dev_link_t *link)
428 link->state &= ~DEV_CONFIG; 428 link->state &= ~DEV_CONFIG;
429} /* teles_cs_release */ 429} /* teles_cs_release */
430 430
431static int teles_suspend(struct pcmcia_device *p_dev)
432{
433 dev_link_t *link = dev_to_instance(p_dev);
434 local_info_t *dev = link->priv;
435
436 link->state |= DEV_SUSPEND;
437 dev->busy = 1;
438 if (link->state & DEV_CONFIG)
439 pcmcia_release_configuration(link->handle);
440
441 return 0;
442}
443
444static int teles_resume(struct pcmcia_device *p_dev)
445{
446 dev_link_t *link = dev_to_instance(p_dev);
447 local_info_t *dev = link->priv;
448
449 link->state &= ~DEV_SUSPEND;
450 if (link->state & DEV_CONFIG)
451 pcmcia_request_configuration(link->handle, &link->conf);
452 dev->busy = 0;
453
454 return 0;
455}
456
431/*====================================================================== 457/*======================================================================
432 458
433 The card status event handler. Mostly, this schedules other 459 The card status event handler. Mostly, this schedules other
@@ -446,7 +472,6 @@ static int teles_cs_event(event_t event, int priority,
446 event_callback_args_t *args) 472 event_callback_args_t *args)
447{ 473{
448 dev_link_t *link = args->client_data; 474 dev_link_t *link = args->client_data;
449 local_info_t *dev = link->priv;
450 475
451 DEBUG(1, "teles_cs_event(%d)\n", event); 476 DEBUG(1, "teles_cs_event(%d)\n", event);
452 477
@@ -462,23 +487,6 @@ static int teles_cs_event(event_t event, int priority,
462 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 487 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
463 teles_cs_config(link); 488 teles_cs_config(link);
464 break; 489 break;
465 case CS_EVENT_PM_SUSPEND:
466 link->state |= DEV_SUSPEND;
467 /* Fall through... */
468 case CS_EVENT_RESET_PHYSICAL:
469 /* Mark the device as stopped, to block IO until later */
470 dev->busy = 1;
471 if (link->state & DEV_CONFIG)
472 pcmcia_release_configuration(link->handle);
473 break;
474 case CS_EVENT_PM_RESUME:
475 link->state &= ~DEV_SUSPEND;
476 /* Fall through... */
477 case CS_EVENT_CARD_RESET:
478 if (link->state & DEV_CONFIG)
479 pcmcia_request_configuration(link->handle, &link->conf);
480 dev->busy = 0;
481 break;
482 } 490 }
483 return 0; 491 return 0;
484} /* teles_cs_event */ 492} /* teles_cs_event */
@@ -498,6 +506,8 @@ static struct pcmcia_driver teles_cs_driver = {
498 .event = teles_cs_event, 506 .event = teles_cs_event,
499 .detach = teles_detach, 507 .detach = teles_detach,
500 .id_table = teles_ids, 508 .id_table = teles_ids,
509 .suspend = teles_suspend,
510 .resume = teles_resume,
501}; 511};
502 512
503static int __init init_teles_cs(void) 513static int __init init_teles_cs(void)
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index af24216a0626..86443cf44dc6 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -691,6 +691,24 @@ static void pcmciamtd_config(dev_link_t *link)
691} 691}
692 692
693 693
694static int pcmciamtd_suspend(struct pcmcia_device *dev)
695{
696 DEBUG(2, "EVENT_PM_RESUME");
697
698 /* get_lock(link); */
699
700 return 0;
701}
702
703static int pcmciamtd_resume(struct pcmcia_device *dev)
704{
705 DEBUG(2, "EVENT_PM_SUSPEND");
706
707 /* free_lock(link); */
708
709 return 0;
710}
711
694/* The card status event handler. Mostly, this schedules other 712/* The card status event handler. Mostly, this schedules other
695 * stuff to run after an event is received. A CARD_REMOVAL event 713 * stuff to run after an event is received. A CARD_REMOVAL event
696 * also sets some flags to discourage the driver from trying 714 * also sets some flags to discourage the driver from trying
@@ -721,22 +739,6 @@ static int pcmciamtd_event(event_t event, int priority,
721 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 739 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
722 pcmciamtd_config(link); 740 pcmciamtd_config(link);
723 break; 741 break;
724 case CS_EVENT_PM_SUSPEND:
725 DEBUG(2, "EVENT_PM_SUSPEND");
726 link->state |= DEV_SUSPEND;
727 /* Fall through... */
728 case CS_EVENT_RESET_PHYSICAL:
729 DEBUG(2, "EVENT_RESET_PHYSICAL");
730 /* get_lock(link); */
731 break;
732 case CS_EVENT_PM_RESUME:
733 DEBUG(2, "EVENT_PM_RESUME");
734 link->state &= ~DEV_SUSPEND;
735 /* Fall through... */
736 case CS_EVENT_CARD_RESET:
737 DEBUG(2, "EVENT_CARD_RESET");
738 /* free_lock(link); */
739 break;
740 default: 742 default:
741 DEBUG(2, "Unknown event %d", event); 743 DEBUG(2, "Unknown event %d", event);
742 } 744 }
@@ -848,6 +850,8 @@ static struct pcmcia_driver pcmciamtd_driver = {
848 .detach = pcmciamtd_detach, 850 .detach = pcmciamtd_detach,
849 .owner = THIS_MODULE, 851 .owner = THIS_MODULE,
850 .id_table = pcmciamtd_ids, 852 .id_table = pcmciamtd_ids,
853 .suspend = pcmciamtd_suspend,
854 .resume = pcmciamtd_resume,
851}; 855};
852 856
853 857
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 71fd41122c91..80414a77fe75 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -547,6 +547,38 @@ static void tc574_release(dev_link_t *link)
547 link->state &= ~DEV_CONFIG; 547 link->state &= ~DEV_CONFIG;
548} 548}
549 549
550static int tc574_suspend(struct pcmcia_device *p_dev)
551{
552 dev_link_t *link = dev_to_instance(p_dev);
553 struct net_device *dev = link->priv;
554
555 link->state |= DEV_SUSPEND;
556 if (link->state & DEV_CONFIG) {
557 if (link->open)
558 netif_device_detach(dev);
559 pcmcia_release_configuration(link->handle);
560 }
561
562 return 0;
563}
564
565static int tc574_resume(struct pcmcia_device *p_dev)
566{
567 dev_link_t *link = dev_to_instance(p_dev);
568 struct net_device *dev = link->priv;
569
570 link->state &= ~DEV_SUSPEND;
571 if (link->state & DEV_CONFIG) {
572 pcmcia_request_configuration(link->handle, &link->conf);
573 if (link->open) {
574 tc574_reset(dev);
575 netif_device_attach(dev);
576 }
577 }
578
579 return 0;
580}
581
550/* 582/*
551 The card status event handler. Mostly, this schedules other 583 The card status event handler. Mostly, this schedules other
552 stuff to run after an event is received. A CARD_REMOVAL event 584 stuff to run after an event is received. A CARD_REMOVAL event
@@ -572,28 +604,6 @@ static int tc574_event(event_t event, int priority,
572 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 604 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
573 tc574_config(link); 605 tc574_config(link);
574 break; 606 break;
575 case CS_EVENT_PM_SUSPEND:
576 link->state |= DEV_SUSPEND;
577 /* Fall through... */
578 case CS_EVENT_RESET_PHYSICAL:
579 if (link->state & DEV_CONFIG) {
580 if (link->open)
581 netif_device_detach(dev);
582 pcmcia_release_configuration(link->handle);
583 }
584 break;
585 case CS_EVENT_PM_RESUME:
586 link->state &= ~DEV_SUSPEND;
587 /* Fall through... */
588 case CS_EVENT_CARD_RESET:
589 if (link->state & DEV_CONFIG) {
590 pcmcia_request_configuration(link->handle, &link->conf);
591 if (link->open) {
592 tc574_reset(dev);
593 netif_device_attach(dev);
594 }
595 }
596 break;
597 } 607 }
598 return 0; 608 return 0;
599} /* tc574_event */ 609} /* tc574_event */
@@ -1296,6 +1306,8 @@ static struct pcmcia_driver tc574_driver = {
1296 .event = tc574_event, 1306 .event = tc574_event,
1297 .detach = tc574_detach, 1307 .detach = tc574_detach,
1298 .id_table = tc574_ids, 1308 .id_table = tc574_ids,
1309 .suspend = tc574_suspend,
1310 .resume = tc574_resume,
1299}; 1311};
1300 1312
1301static int __init init_tc574(void) 1313static int __init init_tc574(void)
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index d83fdd8c1943..bbda681ac102 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -421,6 +421,38 @@ static void tc589_release(dev_link_t *link)
421 link->state &= ~DEV_CONFIG; 421 link->state &= ~DEV_CONFIG;
422} 422}
423 423
424static int tc589_suspend(struct pcmcia_device *p_dev)
425{
426 dev_link_t *link = dev_to_instance(p_dev);
427 struct net_device *dev = link->priv;
428
429 link->state |= DEV_SUSPEND;
430 if (link->state & DEV_CONFIG) {
431 if (link->open)
432 netif_device_detach(dev);
433 pcmcia_release_configuration(link->handle);
434 }
435
436 return 0;
437}
438
439static int tc589_resume(struct pcmcia_device *p_dev)
440{
441 dev_link_t *link = dev_to_instance(p_dev);
442 struct net_device *dev = link->priv;
443
444 link->state &= ~DEV_SUSPEND;
445 if (link->state & DEV_CONFIG) {
446 pcmcia_request_configuration(link->handle, &link->conf);
447 if (link->open) {
448 tc589_reset(dev);
449 netif_device_attach(dev);
450 }
451 }
452
453 return 0;
454}
455
424/*====================================================================== 456/*======================================================================
425 457
426 The card status event handler. Mostly, this schedules other 458 The card status event handler. Mostly, this schedules other
@@ -448,28 +480,6 @@ static int tc589_event(event_t event, int priority,
448 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 480 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
449 tc589_config(link); 481 tc589_config(link);
450 break; 482 break;
451 case CS_EVENT_PM_SUSPEND:
452 link->state |= DEV_SUSPEND;
453 /* Fall through... */
454 case CS_EVENT_RESET_PHYSICAL:
455 if (link->state & DEV_CONFIG) {
456 if (link->open)
457 netif_device_detach(dev);
458 pcmcia_release_configuration(link->handle);
459 }
460 break;
461 case CS_EVENT_PM_RESUME:
462 link->state &= ~DEV_SUSPEND;
463 /* Fall through... */
464 case CS_EVENT_CARD_RESET:
465 if (link->state & DEV_CONFIG) {
466 pcmcia_request_configuration(link->handle, &link->conf);
467 if (link->open) {
468 tc589_reset(dev);
469 netif_device_attach(dev);
470 }
471 }
472 break;
473 } 483 }
474 return 0; 484 return 0;
475} /* tc589_event */ 485} /* tc589_event */
@@ -1071,6 +1081,8 @@ static struct pcmcia_driver tc589_driver = {
1071 .event = tc589_event, 1081 .event = tc589_event,
1072 .detach = tc589_detach, 1082 .detach = tc589_detach,
1073 .id_table = tc589_ids, 1083 .id_table = tc589_ids,
1084 .suspend = tc589_suspend,
1085 .resume = tc589_resume,
1074}; 1086};
1075 1087
1076static int __init init_tc589(void) 1088static int __init init_tc589(void)
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 8bb4e85689ea..6c6b25265659 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -490,6 +490,40 @@ static void axnet_release(dev_link_t *link)
490 link->state &= ~DEV_CONFIG; 490 link->state &= ~DEV_CONFIG;
491} 491}
492 492
493static int axnet_suspend(struct pcmcia_device *p_dev)
494{
495 dev_link_t *link = dev_to_instance(p_dev);
496 struct net_device *dev = link->priv;
497
498 link->state |= DEV_SUSPEND;
499 if (link->state & DEV_CONFIG) {
500 if (link->open)
501 netif_device_detach(dev);
502 pcmcia_release_configuration(link->handle);
503 }
504
505 return 0;
506}
507
508static int axnet_resume(struct pcmcia_device *p_dev)
509{
510 dev_link_t *link = dev_to_instance(p_dev);
511 struct net_device *dev = link->priv;
512
513 link->state &= ~DEV_SUSPEND;
514 if (link->state & DEV_CONFIG) {
515 pcmcia_request_configuration(link->handle, &link->conf);
516 if (link->open) {
517 axnet_reset_8390(dev);
518 AX88190_init(dev, 1);
519 netif_device_attach(dev);
520 }
521 }
522
523 return 0;
524}
525
526
493/*====================================================================== 527/*======================================================================
494 528
495 The card status event handler. Mostly, this schedules other 529 The card status event handler. Mostly, this schedules other
@@ -517,29 +551,6 @@ static int axnet_event(event_t event, int priority,
517 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 551 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
518 axnet_config(link); 552 axnet_config(link);
519 break; 553 break;
520 case CS_EVENT_PM_SUSPEND:
521 link->state |= DEV_SUSPEND;
522 /* Fall through... */
523 case CS_EVENT_RESET_PHYSICAL:
524 if (link->state & DEV_CONFIG) {
525 if (link->open)
526 netif_device_detach(dev);
527 pcmcia_release_configuration(link->handle);
528 }
529 break;
530 case CS_EVENT_PM_RESUME:
531 link->state &= ~DEV_SUSPEND;
532 /* Fall through... */
533 case CS_EVENT_CARD_RESET:
534 if (link->state & DEV_CONFIG) {
535 pcmcia_request_configuration(link->handle, &link->conf);
536 if (link->open) {
537 axnet_reset_8390(dev);
538 AX88190_init(dev, 1);
539 netif_device_attach(dev);
540 }
541 }
542 break;
543 } 554 }
544 return 0; 555 return 0;
545} /* axnet_event */ 556} /* axnet_event */
@@ -881,6 +892,8 @@ static struct pcmcia_driver axnet_cs_driver = {
881 .event = axnet_event, 892 .event = axnet_event,
882 .detach = axnet_detach, 893 .detach = axnet_detach,
883 .id_table = axnet_ids, 894 .id_table = axnet_ids,
895 .suspend = axnet_suspend,
896 .resume = axnet_resume,
884}; 897};
885 898
886static int __init init_axnet_cs(void) 899static int __init init_axnet_cs(void)
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
index b9355d9498a3..68612222de6e 100644
--- a/drivers/net/pcmcia/com20020_cs.c
+++ b/drivers/net/pcmcia/com20020_cs.c
@@ -421,6 +421,42 @@ static void com20020_release(dev_link_t *link)
421 link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING); 421 link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);
422} 422}
423 423
424static int com20020_suspend(struct pcmcia_device *p_dev)
425{
426 dev_link_t *link = dev_to_instance(p_dev);
427 com20020_dev_t *info = link->priv;
428 struct net_device *dev = info->dev;
429
430 link->state |= DEV_SUSPEND;
431 if (link->state & DEV_CONFIG) {
432 if (link->open) {
433 netif_device_detach(dev);
434 }
435 pcmcia_release_configuration(link->handle);
436 }
437
438 return 0;
439}
440
441static int com20020_resume(struct pcmcia_device *p_dev)
442{
443 dev_link_t *link = dev_to_instance(p_dev);
444 com20020_dev_t *info = link->priv;
445 struct net_device *dev = info->dev;
446
447 link->state &= ~DEV_SUSPEND;
448 if (link->state & DEV_CONFIG) {
449 pcmcia_request_configuration(link->handle, &link->conf);
450 if (link->open) {
451 int ioaddr = dev->base_addr;
452 struct arcnet_local *lp = dev->priv;
453 ARCRESET;
454 }
455 }
456
457 return 0;
458}
459
424/*====================================================================== 460/*======================================================================
425 461
426 The card status event handler. Mostly, this schedules other 462 The card status event handler. Mostly, this schedules other
@@ -449,30 +485,6 @@ static int com20020_event(event_t event, int priority,
449 link->state |= DEV_PRESENT; 485 link->state |= DEV_PRESENT;
450 com20020_config(link); 486 com20020_config(link);
451 break; 487 break;
452 case CS_EVENT_PM_SUSPEND:
453 link->state |= DEV_SUSPEND;
454 /* Fall through... */
455 case CS_EVENT_RESET_PHYSICAL:
456 if (link->state & DEV_CONFIG) {
457 if (link->open) {
458 netif_device_detach(dev);
459 }
460 pcmcia_release_configuration(link->handle);
461 }
462 break;
463 case CS_EVENT_PM_RESUME:
464 link->state &= ~DEV_SUSPEND;
465 /* Fall through... */
466 case CS_EVENT_CARD_RESET:
467 if (link->state & DEV_CONFIG) {
468 pcmcia_request_configuration(link->handle, &link->conf);
469 if (link->open) {
470 int ioaddr = dev->base_addr;
471 struct arcnet_local *lp = dev->priv;
472 ARCRESET;
473 }
474 }
475 break;
476 } 488 }
477 return 0; 489 return 0;
478} /* com20020_event */ 490} /* com20020_event */
@@ -492,6 +504,8 @@ static struct pcmcia_driver com20020_cs_driver = {
492 .event = com20020_event, 504 .event = com20020_event,
493 .detach = com20020_detach, 505 .detach = com20020_detach,
494 .id_table = com20020_ids, 506 .id_table = com20020_ids,
507 .suspend = com20020_suspend,
508 .resume = com20020_resume,
495}; 509};
496 510
497static int __init init_com20020_cs(void) 511static int __init init_com20020_cs(void)
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 356f50909222..388ecade13de 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -713,6 +713,39 @@ static void fmvj18x_release(dev_link_t *link)
713 link->state &= ~DEV_CONFIG; 713 link->state &= ~DEV_CONFIG;
714} 714}
715 715
716static int fmvj18x_suspend(struct pcmcia_device *p_dev)
717{
718 dev_link_t *link = dev_to_instance(p_dev);
719 struct net_device *dev = link->priv;
720
721 link->state |= DEV_SUSPEND;
722 if (link->state & DEV_CONFIG) {
723 if (link->open)
724 netif_device_detach(dev);
725 pcmcia_release_configuration(link->handle);
726 }
727
728
729 return 0;
730}
731
732static int fmvj18x_resume(struct pcmcia_device *p_dev)
733{
734 dev_link_t *link = dev_to_instance(p_dev);
735 struct net_device *dev = link->priv;
736
737 link->state &= ~DEV_SUSPEND;
738 if (link->state & DEV_CONFIG) {
739 pcmcia_request_configuration(link->handle, &link->conf);
740 if (link->open) {
741 fjn_reset(dev);
742 netif_device_attach(dev);
743 }
744 }
745
746 return 0;
747}
748
716/*====================================================================*/ 749/*====================================================================*/
717 750
718static int fmvj18x_event(event_t event, int priority, 751static int fmvj18x_event(event_t event, int priority,
@@ -733,28 +766,6 @@ static int fmvj18x_event(event_t event, int priority,
733 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 766 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
734 fmvj18x_config(link); 767 fmvj18x_config(link);
735 break; 768 break;
736 case CS_EVENT_PM_SUSPEND:
737 link->state |= DEV_SUSPEND;
738 /* Fall through... */
739 case CS_EVENT_RESET_PHYSICAL:
740 if (link->state & DEV_CONFIG) {
741 if (link->open)
742 netif_device_detach(dev);
743 pcmcia_release_configuration(link->handle);
744 }
745 break;
746 case CS_EVENT_PM_RESUME:
747 link->state &= ~DEV_SUSPEND;
748 /* Fall through... */
749 case CS_EVENT_CARD_RESET:
750 if (link->state & DEV_CONFIG) {
751 pcmcia_request_configuration(link->handle, &link->conf);
752 if (link->open) {
753 fjn_reset(dev);
754 netif_device_attach(dev);
755 }
756 }
757 break;
758 } 769 }
759 return 0; 770 return 0;
760} /* fmvj18x_event */ 771} /* fmvj18x_event */
@@ -793,6 +804,8 @@ static struct pcmcia_driver fmvj18x_cs_driver = {
793 .event = fmvj18x_event, 804 .event = fmvj18x_event,
794 .detach = fmvj18x_detach, 805 .detach = fmvj18x_detach,
795 .id_table = fmvj18x_ids, 806 .id_table = fmvj18x_ids,
807 .suspend = fmvj18x_suspend,
808 .resume = fmvj18x_resume,
796}; 809};
797 810
798static int __init init_fmvj18x_cs(void) 811static int __init init_fmvj18x_cs(void)
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index b6c140eb9799..3a7218e51b73 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -401,6 +401,41 @@ static void ibmtr_release(dev_link_t *link)
401 link->state &= ~DEV_CONFIG; 401 link->state &= ~DEV_CONFIG;
402} 402}
403 403
404static int ibmtr_suspend(struct pcmcia_device *p_dev)
405{
406 dev_link_t *link = dev_to_instance(p_dev);
407 ibmtr_dev_t *info = link->priv;
408 struct net_device *dev = info->dev;
409
410 link->state |= DEV_SUSPEND;
411 if (link->state & DEV_CONFIG) {
412 if (link->open)
413 netif_device_detach(dev);
414 pcmcia_release_configuration(link->handle);
415 }
416
417 return 0;
418}
419
420static int ibmtr_resume(struct pcmcia_device *p_dev)
421{
422 dev_link_t *link = dev_to_instance(p_dev);
423 ibmtr_dev_t *info = link->priv;
424 struct net_device *dev = info->dev;
425
426 link->state &= ~DEV_SUSPEND;
427 if (link->state & DEV_CONFIG) {
428 pcmcia_request_configuration(link->handle, &link->conf);
429 if (link->open) {
430 ibmtr_probe(dev); /* really? */
431 netif_device_attach(dev);
432 }
433 }
434
435 return 0;
436}
437
438
404/*====================================================================== 439/*======================================================================
405 440
406 The card status event handler. Mostly, this schedules other 441 The card status event handler. Mostly, this schedules other
@@ -433,28 +468,6 @@ static int ibmtr_event(event_t event, int priority,
433 link->state |= DEV_PRESENT; 468 link->state |= DEV_PRESENT;
434 ibmtr_config(link); 469 ibmtr_config(link);
435 break; 470 break;
436 case CS_EVENT_PM_SUSPEND:
437 link->state |= DEV_SUSPEND;
438 /* Fall through... */
439 case CS_EVENT_RESET_PHYSICAL:
440 if (link->state & DEV_CONFIG) {
441 if (link->open)
442 netif_device_detach(dev);
443 pcmcia_release_configuration(link->handle);
444 }
445 break;
446 case CS_EVENT_PM_RESUME:
447 link->state &= ~DEV_SUSPEND;
448 /* Fall through... */
449 case CS_EVENT_CARD_RESET:
450 if (link->state & DEV_CONFIG) {
451 pcmcia_request_configuration(link->handle, &link->conf);
452 if (link->open) {
453 ibmtr_probe(dev); /* really? */
454 netif_device_attach(dev);
455 }
456 }
457 break;
458 } 471 }
459 return 0; 472 return 0;
460} /* ibmtr_event */ 473} /* ibmtr_event */
@@ -518,6 +531,8 @@ static struct pcmcia_driver ibmtr_cs_driver = {
518 .event = ibmtr_event, 531 .event = ibmtr_event,
519 .detach = ibmtr_detach, 532 .detach = ibmtr_detach,
520 .id_table = ibmtr_ids, 533 .id_table = ibmtr_ids,
534 .suspend = ibmtr_suspend,
535 .resume = ibmtr_resume,
521}; 536};
522 537
523static int __init init_ibmtr_cs(void) 538static int __init init_ibmtr_cs(void)
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 980d7e5d66cb..fa4921f8b9fc 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -801,6 +801,39 @@ static void nmclan_release(dev_link_t *link)
801 link->state &= ~DEV_CONFIG; 801 link->state &= ~DEV_CONFIG;
802} 802}
803 803
804static int nmclan_suspend(struct pcmcia_device *p_dev)
805{
806 dev_link_t *link = dev_to_instance(p_dev);
807 struct net_device *dev = link->priv;
808
809 link->state |= DEV_SUSPEND;
810 if (link->state & DEV_CONFIG) {
811 if (link->open)
812 netif_device_detach(dev);
813 pcmcia_release_configuration(link->handle);
814 }
815
816
817 return 0;
818}
819
820static int nmclan_resume(struct pcmcia_device *p_dev)
821{
822 dev_link_t *link = dev_to_instance(p_dev);
823 struct net_device *dev = link->priv;
824
825 link->state &= ~DEV_SUSPEND;
826 if (link->state & DEV_CONFIG) {
827 pcmcia_request_configuration(link->handle, &link->conf);
828 if (link->open) {
829 nmclan_reset(dev);
830 netif_device_attach(dev);
831 }
832 }
833
834 return 0;
835}
836
804/* ---------------------------------------------------------------------------- 837/* ----------------------------------------------------------------------------
805nmclan_event 838nmclan_event
806 The card status event handler. Mostly, this schedules other 839 The card status event handler. Mostly, this schedules other
@@ -826,28 +859,6 @@ static int nmclan_event(event_t event, int priority,
826 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 859 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
827 nmclan_config(link); 860 nmclan_config(link);
828 break; 861 break;
829 case CS_EVENT_PM_SUSPEND:
830 link->state |= DEV_SUSPEND;
831 /* Fall through... */
832 case CS_EVENT_RESET_PHYSICAL:
833 if (link->state & DEV_CONFIG) {
834 if (link->open)
835 netif_device_detach(dev);
836 pcmcia_release_configuration(link->handle);
837 }
838 break;
839 case CS_EVENT_PM_RESUME:
840 link->state &= ~DEV_SUSPEND;
841 /* Fall through... */
842 case CS_EVENT_CARD_RESET:
843 if (link->state & DEV_CONFIG) {
844 pcmcia_request_configuration(link->handle, &link->conf);
845 if (link->open) {
846 nmclan_reset(dev);
847 netif_device_attach(dev);
848 }
849 }
850 break;
851 case CS_EVENT_RESET_REQUEST: 862 case CS_EVENT_RESET_REQUEST:
852 return 1; 863 return 1;
853 break; 864 break;
@@ -1685,6 +1696,8 @@ static struct pcmcia_driver nmclan_cs_driver = {
1685 .event = nmclan_event, 1696 .event = nmclan_event,
1686 .detach = nmclan_detach, 1697 .detach = nmclan_detach,
1687 .id_table = nmclan_ids, 1698 .id_table = nmclan_ids,
1699 .suspend = nmclan_suspend,
1700 .resume = nmclan_resume,
1688}; 1701};
1689 1702
1690static int __init init_nmclan_cs(void) 1703static int __init init_nmclan_cs(void)
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 818c185d6438..7db4d6f3db45 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -780,6 +780,39 @@ static void pcnet_release(dev_link_t *link)
780 780
781======================================================================*/ 781======================================================================*/
782 782
783static int pcnet_suspend(struct pcmcia_device *p_dev)
784{
785 dev_link_t *link = dev_to_instance(p_dev);
786 struct net_device *dev = link->priv;
787
788 link->state |= DEV_SUSPEND;
789 if (link->state & DEV_CONFIG) {
790 if (link->open)
791 netif_device_detach(dev);
792 pcmcia_release_configuration(link->handle);
793 }
794
795 return 0;
796}
797
798static int pcnet_resume(struct pcmcia_device *p_dev)
799{
800 dev_link_t *link = dev_to_instance(p_dev);
801 struct net_device *dev = link->priv;
802
803 link->state &= ~DEV_SUSPEND;
804 if (link->state & DEV_CONFIG) {
805 pcmcia_request_configuration(link->handle, &link->conf);
806 if (link->open) {
807 pcnet_reset_8390(dev);
808 NS8390_init(dev, 1);
809 netif_device_attach(dev);
810 }
811 }
812
813 return 0;
814}
815
783static int pcnet_event(event_t event, int priority, 816static int pcnet_event(event_t event, int priority,
784 event_callback_args_t *args) 817 event_callback_args_t *args)
785{ 818{
@@ -798,29 +831,6 @@ static int pcnet_event(event_t event, int priority,
798 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 831 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
799 pcnet_config(link); 832 pcnet_config(link);
800 break; 833 break;
801 case CS_EVENT_PM_SUSPEND:
802 link->state |= DEV_SUSPEND;
803 /* Fall through... */
804 case CS_EVENT_RESET_PHYSICAL:
805 if (link->state & DEV_CONFIG) {
806 if (link->open)
807 netif_device_detach(dev);
808 pcmcia_release_configuration(link->handle);
809 }
810 break;
811 case CS_EVENT_PM_RESUME:
812 link->state &= ~DEV_SUSPEND;
813 /* Fall through... */
814 case CS_EVENT_CARD_RESET:
815 if (link->state & DEV_CONFIG) {
816 pcmcia_request_configuration(link->handle, &link->conf);
817 if (link->open) {
818 pcnet_reset_8390(dev);
819 NS8390_init(dev, 1);
820 netif_device_attach(dev);
821 }
822 }
823 break;
824 } 834 }
825 return 0; 835 return 0;
826} /* pcnet_event */ 836} /* pcnet_event */
@@ -1849,6 +1859,8 @@ static struct pcmcia_driver pcnet_driver = {
1849 .detach = pcnet_detach, 1859 .detach = pcnet_detach,
1850 .owner = THIS_MODULE, 1860 .owner = THIS_MODULE,
1851 .id_table = pcnet_ids, 1861 .id_table = pcnet_ids,
1862 .suspend = pcnet_suspend,
1863 .resume = pcnet_resume,
1852}; 1864};
1853 1865
1854static int __init init_pcnet_cs(void) 1866static int __init init_pcnet_cs(void)
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index c7cca842e5ee..7c61ec90c2c3 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -895,6 +895,62 @@ free_cfg_mem:
895 return rc; 895 return rc;
896} 896}
897 897
898static int smc91c92_suspend(struct pcmcia_device *p_dev)
899{
900 dev_link_t *link = dev_to_instance(p_dev);
901 struct net_device *dev = link->priv;
902
903 link->state |= DEV_SUSPEND;
904 if (link->state & DEV_CONFIG) {
905 if (link->open)
906 netif_device_detach(dev);
907 pcmcia_release_configuration(link->handle);
908 }
909
910 return 0;
911}
912
913static int smc91c92_resume(struct pcmcia_device *p_dev)
914{
915 dev_link_t *link = dev_to_instance(p_dev);
916 struct net_device *dev = link->priv;
917 struct smc_private *smc = netdev_priv(dev);
918 int i;
919
920 link->state &= ~DEV_SUSPEND;
921 if (link->state & DEV_CONFIG) {
922 if ((smc->manfid == MANFID_MEGAHERTZ) &&
923 (smc->cardid == PRODID_MEGAHERTZ_EM3288))
924 mhz_3288_power(link);
925 pcmcia_request_configuration(link->handle, &link->conf);
926 if (smc->manfid == MANFID_MOTOROLA)
927 mot_config(link);
928 if ((smc->manfid == MANFID_OSITECH) &&
929 (smc->cardid != PRODID_OSITECH_SEVEN)) {
930 /* Power up the card and enable interrupts */
931 set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
932 set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
933 }
934 if (((smc->manfid == MANFID_OSITECH) &&
935 (smc->cardid == PRODID_OSITECH_SEVEN)) ||
936 ((smc->manfid == MANFID_PSION) &&
937 (smc->cardid == PRODID_PSION_NET100))) {
938 /* Download the Seven of Diamonds firmware */
939 for (i = 0; i < sizeof(__Xilinx7OD); i++) {
940 outb(__Xilinx7OD[i], link->io.BasePort1+2);
941 udelay(50);
942 }
943 }
944 if (link->open) {
945 smc_reset(dev);
946 netif_device_attach(dev);
947 }
948 }
949
950 return 0;
951}
952
953
898/*====================================================================== 954/*======================================================================
899 955
900 This verifies that the chip is some SMC91cXX variant, and returns 956 This verifies that the chip is some SMC91cXX variant, and returns
@@ -935,14 +991,12 @@ static int check_sig(dev_link_t *link)
935 } 991 }
936 992
937 if (width) { 993 if (width) {
938 event_callback_args_t args;
939 printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n"); 994 printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n");
940 args.client_data = link; 995 smc91c92_suspend(link->handle);
941 smc91c92_event(CS_EVENT_RESET_PHYSICAL, 0, &args);
942 pcmcia_release_io(link->handle, &link->io); 996 pcmcia_release_io(link->handle, &link->io);
943 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 997 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
944 pcmcia_request_io(link->handle, &link->io); 998 pcmcia_request_io(link->handle, &link->io);
945 smc91c92_event(CS_EVENT_CARD_RESET, 0, &args); 999 smc91c92_resume(link->handle);
946 return check_sig(link); 1000 return check_sig(link);
947 } 1001 }
948 return -ENODEV; 1002 return -ENODEV;
@@ -1184,8 +1238,6 @@ static int smc91c92_event(event_t event, int priority,
1184{ 1238{
1185 dev_link_t *link = args->client_data; 1239 dev_link_t *link = args->client_data;
1186 struct net_device *dev = link->priv; 1240 struct net_device *dev = link->priv;
1187 struct smc_private *smc = netdev_priv(dev);
1188 int i;
1189 1241
1190 DEBUG(1, "smc91c92_event(0x%06x)\n", event); 1242 DEBUG(1, "smc91c92_event(0x%06x)\n", event);
1191 1243
@@ -1199,49 +1251,6 @@ static int smc91c92_event(event_t event, int priority,
1199 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 1251 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
1200 smc91c92_config(link); 1252 smc91c92_config(link);
1201 break; 1253 break;
1202 case CS_EVENT_PM_SUSPEND:
1203 link->state |= DEV_SUSPEND;
1204 /* Fall through... */
1205 case CS_EVENT_RESET_PHYSICAL:
1206 if (link->state & DEV_CONFIG) {
1207 if (link->open)
1208 netif_device_detach(dev);
1209 pcmcia_release_configuration(link->handle);
1210 }
1211 break;
1212 case CS_EVENT_PM_RESUME:
1213 link->state &= ~DEV_SUSPEND;
1214 /* Fall through... */
1215 case CS_EVENT_CARD_RESET:
1216 if (link->state & DEV_CONFIG) {
1217 if ((smc->manfid == MANFID_MEGAHERTZ) &&
1218 (smc->cardid == PRODID_MEGAHERTZ_EM3288))
1219 mhz_3288_power(link);
1220 pcmcia_request_configuration(link->handle, &link->conf);
1221 if (smc->manfid == MANFID_MOTOROLA)
1222 mot_config(link);
1223 if ((smc->manfid == MANFID_OSITECH) &&
1224 (smc->cardid != PRODID_OSITECH_SEVEN)) {
1225 /* Power up the card and enable interrupts */
1226 set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
1227 set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
1228 }
1229 if (((smc->manfid == MANFID_OSITECH) &&
1230 (smc->cardid == PRODID_OSITECH_SEVEN)) ||
1231 ((smc->manfid == MANFID_PSION) &&
1232 (smc->cardid == PRODID_PSION_NET100))) {
1233 /* Download the Seven of Diamonds firmware */
1234 for (i = 0; i < sizeof(__Xilinx7OD); i++) {
1235 outb(__Xilinx7OD[i], link->io.BasePort1+2);
1236 udelay(50);
1237 }
1238 }
1239 if (link->open) {
1240 smc_reset(dev);
1241 netif_device_attach(dev);
1242 }
1243 }
1244 break;
1245 } 1254 }
1246 return 0; 1255 return 0;
1247} /* smc91c92_event */ 1256} /* smc91c92_event */
@@ -2364,6 +2373,8 @@ static struct pcmcia_driver smc91c92_cs_driver = {
2364 .event = smc91c92_event, 2373 .event = smc91c92_event,
2365 .detach = smc91c92_detach, 2374 .detach = smc91c92_detach,
2366 .id_table = smc91c92_ids, 2375 .id_table = smc91c92_ids,
2376 .suspend = smc91c92_suspend,
2377 .resume = smc91c92_resume,
2367}; 2378};
2368 2379
2369static int __init init_smc91c92_cs(void) 2380static int __init init_smc91c92_cs(void)
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index ce143f08638a..917e50ac37f3 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -1157,6 +1157,41 @@ xirc2ps_release(dev_link_t *link)
1157 1157
1158/*====================================================================*/ 1158/*====================================================================*/
1159 1159
1160
1161static int xirc2ps_suspend(struct pcmcia_device *p_dev)
1162{
1163 dev_link_t *link = dev_to_instance(p_dev);
1164 struct net_device *dev = link->priv;
1165
1166 link->state |= DEV_SUSPEND;
1167 if (link->state & DEV_CONFIG) {
1168 if (link->open) {
1169 netif_device_detach(dev);
1170 do_powerdown(dev);
1171 }
1172 pcmcia_release_configuration(link->handle);
1173 }
1174
1175 return 0;
1176}
1177
1178static int xirc2ps_resume(struct pcmcia_device *p_dev)
1179{
1180 dev_link_t *link = dev_to_instance(p_dev);
1181 struct net_device *dev = link->priv;
1182
1183 link->state &= ~DEV_SUSPEND;
1184 if (link->state & DEV_CONFIG) {
1185 pcmcia_request_configuration(link->handle, &link->conf);
1186 if (link->open) {
1187 do_reset(dev,1);
1188 netif_device_attach(dev);
1189 }
1190 }
1191
1192 return 0;
1193}
1194
1160/**************** 1195/****************
1161 * The card status event handler. Mostly, this schedules other 1196 * The card status event handler. Mostly, this schedules other
1162 * stuff to run after an event is received. A CARD_REMOVAL event 1197 * stuff to run after an event is received. A CARD_REMOVAL event
@@ -1191,30 +1226,6 @@ xirc2ps_event(event_t event, int priority,
1191 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 1226 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
1192 xirc2ps_config(link); 1227 xirc2ps_config(link);
1193 break; 1228 break;
1194 case CS_EVENT_PM_SUSPEND:
1195 link->state |= DEV_SUSPEND;
1196 /* Fall through... */
1197 case CS_EVENT_RESET_PHYSICAL:
1198 if (link->state & DEV_CONFIG) {
1199 if (link->open) {
1200 netif_device_detach(dev);
1201 do_powerdown(dev);
1202 }
1203 pcmcia_release_configuration(link->handle);
1204 }
1205 break;
1206 case CS_EVENT_PM_RESUME:
1207 link->state &= ~DEV_SUSPEND;
1208 /* Fall through... */
1209 case CS_EVENT_CARD_RESET:
1210 if (link->state & DEV_CONFIG) {
1211 pcmcia_request_configuration(link->handle, &link->conf);
1212 if (link->open) {
1213 do_reset(dev,1);
1214 netif_device_attach(dev);
1215 }
1216 }
1217 break;
1218 } 1229 }
1219 return 0; 1230 return 0;
1220} /* xirc2ps_event */ 1231} /* xirc2ps_event */
@@ -2013,6 +2024,8 @@ static struct pcmcia_driver xirc2ps_cs_driver = {
2013 .event = xirc2ps_event, 2024 .event = xirc2ps_event,
2014 .detach = xirc2ps_detach, 2025 .detach = xirc2ps_detach,
2015 .id_table = xirc2ps_ids, 2026 .id_table = xirc2ps_ids,
2027 .suspend = xirc2ps_suspend,
2028 .resume = xirc2ps_resume,
2016}; 2029};
2017 2030
2018static int __init 2031static int __init
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index e328547599dc..80c9de749b52 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -492,6 +492,35 @@ static void airo_release(dev_link_t *link)
492 link->state &= ~DEV_CONFIG; 492 link->state &= ~DEV_CONFIG;
493} 493}
494 494
495static int airo_suspend(struct pcmcia_device *p_dev)
496{
497 dev_link_t *link = dev_to_instance(p_dev);
498 local_info_t *local = link->priv;
499
500 link->state |= DEV_SUSPEND;
501 if (link->state & DEV_CONFIG) {
502 netif_device_detach(local->eth_dev);
503 pcmcia_release_configuration(link->handle);
504 }
505
506 return 0;
507}
508
509static int airo_resume(struct pcmcia_device *p_dev)
510{
511 dev_link_t *link = dev_to_instance(p_dev);
512 local_info_t *local = link->priv;
513
514 link->state &= ~DEV_SUSPEND;
515 if (link->state & DEV_CONFIG) {
516 pcmcia_request_configuration(link->handle, &link->conf);
517 reset_airo_card(local->eth_dev);
518 netif_device_attach(local->eth_dev);
519 }
520
521 return 0;
522}
523
495/*====================================================================== 524/*======================================================================
496 525
497 The card status event handler. Mostly, this schedules other 526 The card status event handler. Mostly, this schedules other
@@ -524,25 +553,6 @@ static int airo_event(event_t event, int priority,
524 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 553 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
525 airo_config(link); 554 airo_config(link);
526 break; 555 break;
527 case CS_EVENT_PM_SUSPEND:
528 link->state |= DEV_SUSPEND;
529 /* Fall through... */
530 case CS_EVENT_RESET_PHYSICAL:
531 if (link->state & DEV_CONFIG) {
532 netif_device_detach(local->eth_dev);
533 pcmcia_release_configuration(link->handle);
534 }
535 break;
536 case CS_EVENT_PM_RESUME:
537 link->state &= ~DEV_SUSPEND;
538 /* Fall through... */
539 case CS_EVENT_CARD_RESET:
540 if (link->state & DEV_CONFIG) {
541 pcmcia_request_configuration(link->handle, &link->conf);
542 reset_airo_card(local->eth_dev);
543 netif_device_attach(local->eth_dev);
544 }
545 break;
546 } 556 }
547 return 0; 557 return 0;
548} /* airo_event */ 558} /* airo_event */
@@ -565,6 +575,8 @@ static struct pcmcia_driver airo_driver = {
565 .event = airo_event, 575 .event = airo_event,
566 .detach = airo_detach, 576 .detach = airo_detach,
567 .id_table = airo_ids, 577 .id_table = airo_ids,
578 .suspend = airo_suspend,
579 .resume = airo_resume,
568}; 580};
569 581
570static int airo_cs_init(void) 582static int airo_cs_init(void)
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 17d1fd90f832..598a9cd0f83e 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -477,6 +477,35 @@ static void atmel_release(dev_link_t *link)
477 link->state &= ~DEV_CONFIG; 477 link->state &= ~DEV_CONFIG;
478} 478}
479 479
480static int atmel_suspend(struct pcmcia_device *dev)
481{
482 dev_link_t *link = dev_to_instance(dev);
483 local_info_t *local = link->priv;
484
485 link->state |= DEV_SUSPEND;
486 if (link->state & DEV_CONFIG) {
487 netif_device_detach(local->eth_dev);
488 pcmcia_release_configuration(link->handle);
489 }
490
491 return 0;
492}
493
494static int atmel_resume(struct pcmcia_device *dev)
495{
496 dev_link_t *link = dev_to_instance(dev);
497 local_info_t *local = link->priv;
498
499 link->state &= ~DEV_SUSPEND;
500 if (link->state & DEV_CONFIG) {
501 pcmcia_request_configuration(link->handle, &link->conf);
502 atmel_open(local->eth_dev);
503 netif_device_attach(local->eth_dev);
504 }
505
506 return 0;
507}
508
480/*====================================================================== 509/*======================================================================
481 510
482 The card status event handler. Mostly, this schedules other 511 The card status event handler. Mostly, this schedules other
@@ -509,25 +538,6 @@ static int atmel_event(event_t event, int priority,
509 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 538 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
510 atmel_config(link); 539 atmel_config(link);
511 break; 540 break;
512 case CS_EVENT_PM_SUSPEND:
513 link->state |= DEV_SUSPEND;
514 /* Fall through... */
515 case CS_EVENT_RESET_PHYSICAL:
516 if (link->state & DEV_CONFIG) {
517 netif_device_detach(local->eth_dev);
518 pcmcia_release_configuration(link->handle);
519 }
520 break;
521 case CS_EVENT_PM_RESUME:
522 link->state &= ~DEV_SUSPEND;
523 /* Fall through... */
524 case CS_EVENT_CARD_RESET:
525 if (link->state & DEV_CONFIG) {
526 pcmcia_request_configuration(link->handle, &link->conf);
527 atmel_open(local->eth_dev);
528 netif_device_attach(local->eth_dev);
529 }
530 break;
531 } 541 }
532 return 0; 542 return 0;
533} /* atmel_event */ 543} /* atmel_event */
@@ -585,6 +595,8 @@ static struct pcmcia_driver atmel_driver = {
585 .event = atmel_event, 595 .event = atmel_event,
586 .detach = atmel_detach, 596 .detach = atmel_detach,
587 .id_table = atmel_ids, 597 .id_table = atmel_ids,
598 .suspend = atmel_suspend,
599 .resume = atmel_resume,
588}; 600};
589 601
590static int atmel_cs_init(void) 602static int atmel_cs_init(void)
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 2643976a6677..ba4a7da98ccd 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -846,20 +846,64 @@ static void prism2_release(u_long arg)
846 PDEBUG(DEBUG_FLOW, "release - done\n"); 846 PDEBUG(DEBUG_FLOW, "release - done\n");
847} 847}
848 848
849static int hostap_cs_suspend(struct pcmcia_device *p_dev)
850{
851 dev_link_t *link = dev_to_instance(p_dev);
852 struct net_device *dev = (struct net_device *) link->priv;
853 int dev_open = 0;
849 854
850static int prism2_event(event_t event, int priority, 855 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
851 event_callback_args_t *args) 856
857 link->state |= DEV_SUSPEND;
858
859 if (link->state & DEV_CONFIG) {
860 struct hostap_interface *iface = netdev_priv(dev);
861 if (iface && iface->local)
862 dev_open = iface->local->num_dev_open > 0;
863 if (dev_open) {
864 netif_stop_queue(dev);
865 netif_device_detach(dev);
866 }
867 prism2_suspend(dev);
868 pcmcia_release_configuration(link->handle);
869 }
870
871 return 0;
872}
873
874static int hostap_cs_resume(struct pcmcia_device *p_dev)
852{ 875{
853 dev_link_t *link = args->client_data; 876 dev_link_t *link = dev_to_instance(p_dev);
854 struct net_device *dev = (struct net_device *) link->priv; 877 struct net_device *dev = (struct net_device *) link->priv;
855 int dev_open = 0; 878 int dev_open = 0;
856 879
880 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
881
882 link->state &= ~DEV_SUSPEND;
857 if (link->state & DEV_CONFIG) { 883 if (link->state & DEV_CONFIG) {
858 struct hostap_interface *iface = netdev_priv(dev); 884 struct hostap_interface *iface = netdev_priv(dev);
859 if (iface && iface->local) 885 if (iface && iface->local)
860 dev_open = iface->local->num_dev_open > 0; 886 dev_open = iface->local->num_dev_open > 0;
887
888 pcmcia_request_configuration(link->handle, &link->conf);
889
890 prism2_hw_shutdown(dev, 1);
891 prism2_hw_config(dev, dev_open ? 0 : 1);
892 if (dev_open) {
893 netif_device_attach(dev);
894 netif_start_queue(dev);
895 }
861 } 896 }
862 897
898 return 0;
899}
900
901static int prism2_event(event_t event, int priority,
902 event_callback_args_t *args)
903{
904 dev_link_t *link = args->client_data;
905 struct net_device *dev = (struct net_device *) link->priv;
906
863 switch (event) { 907 switch (event) {
864 case CS_EVENT_CARD_INSERTION: 908 case CS_EVENT_CARD_INSERTION:
865 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_INSERTION\n", dev_info); 909 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_INSERTION\n", dev_info);
@@ -879,42 +923,6 @@ static int prism2_event(event_t event, int priority,
879 } 923 }
880 break; 924 break;
881 925
882 case CS_EVENT_PM_SUSPEND:
883 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
884 link->state |= DEV_SUSPEND;
885 /* fall through */
886
887 case CS_EVENT_RESET_PHYSICAL:
888 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info);
889 if (link->state & DEV_CONFIG) {
890 if (dev_open) {
891 netif_stop_queue(dev);
892 netif_device_detach(dev);
893 }
894 prism2_suspend(dev);
895 pcmcia_release_configuration(link->handle);
896 }
897 break;
898
899 case CS_EVENT_PM_RESUME:
900 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
901 link->state &= ~DEV_SUSPEND;
902 /* fall through */
903
904 case CS_EVENT_CARD_RESET:
905 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_RESET\n", dev_info);
906 if (link->state & DEV_CONFIG) {
907 pcmcia_request_configuration(link->handle,
908 &link->conf);
909 prism2_hw_shutdown(dev, 1);
910 prism2_hw_config(dev, dev_open ? 0 : 1);
911 if (dev_open) {
912 netif_device_attach(dev);
913 netif_start_queue(dev);
914 }
915 }
916 break;
917
918 default: 926 default:
919 PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n", 927 PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n",
920 dev_info, event); 928 dev_info, event);
@@ -987,6 +995,8 @@ static struct pcmcia_driver hostap_driver = {
987 .owner = THIS_MODULE, 995 .owner = THIS_MODULE,
988 .event = prism2_event, 996 .event = prism2_event,
989 .id_table = hostap_cs_ids, 997 .id_table = hostap_cs_ids,
998 .suspend = hostap_cs_suspend,
999 .resume = hostap_cs_resume,
990}; 1000};
991 1001
992static int __init init_prism2_pccard(void) 1002static int __init init_prism2_pccard(void)
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index 92793b958e32..7ab2d70ffddf 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -935,6 +935,39 @@ static void netwave_release(dev_link_t *link)
935 link->state &= ~DEV_CONFIG; 935 link->state &= ~DEV_CONFIG;
936} 936}
937 937
938static int netwave_suspend(struct pcmcia_device *p_dev)
939{
940 dev_link_t *link = dev_to_instance(p_dev);
941 struct net_device *dev = link->priv;
942
943 link->state |= DEV_SUSPEND;
944 if (link->state & DEV_CONFIG) {
945 if (link->open)
946 netif_device_detach(dev);
947 pcmcia_release_configuration(link->handle);
948 }
949
950 return 0;
951}
952
953static int netwave_resume(struct pcmcia_device *p_dev)
954{
955 dev_link_t *link = dev_to_instance(p_dev);
956 struct net_device *dev = link->priv;
957
958 link->state &= ~DEV_SUSPEND;
959 if (link->state & DEV_CONFIG) {
960 pcmcia_request_configuration(link->handle, &link->conf);
961 if (link->open) {
962 netwave_reset(dev);
963 netif_device_attach(dev);
964 }
965 }
966
967 return 0;
968}
969
970
938/* 971/*
939 * Function netwave_event (event, priority, args) 972 * Function netwave_event (event, priority, args)
940 * 973 *
@@ -973,28 +1006,6 @@ static int netwave_event(event_t event, int priority,
973 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 1006 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
974 netwave_pcmcia_config( link); 1007 netwave_pcmcia_config( link);
975 break; 1008 break;
976 case CS_EVENT_PM_SUSPEND:
977 link->state |= DEV_SUSPEND;
978 /* Fall through... */
979 case CS_EVENT_RESET_PHYSICAL:
980 if (link->state & DEV_CONFIG) {
981 if (link->open)
982 netif_device_detach(dev);
983 pcmcia_release_configuration(link->handle);
984 }
985 break;
986 case CS_EVENT_PM_RESUME:
987 link->state &= ~DEV_SUSPEND;
988 /* Fall through... */
989 case CS_EVENT_CARD_RESET:
990 if (link->state & DEV_CONFIG) {
991 pcmcia_request_configuration(link->handle, &link->conf);
992 if (link->open) {
993 netwave_reset(dev);
994 netif_device_attach(dev);
995 }
996 }
997 break;
998 } 1009 }
999 return 0; 1010 return 0;
1000} /* netwave_event */ 1011} /* netwave_event */
@@ -1495,6 +1506,8 @@ static struct pcmcia_driver netwave_driver = {
1495 .event = netwave_event, 1506 .event = netwave_event,
1496 .detach = netwave_detach, 1507 .detach = netwave_detach,
1497 .id_table = netwave_ids, 1508 .id_table = netwave_ids,
1509 .suspend = netwave_suspend,
1510 .resume = netwave_resume,
1498}; 1511};
1499 1512
1500static int __init init_netwave_cs(void) 1513static int __init init_netwave_cs(void)
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index dc1128a00971..1d66050e3d6a 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -465,6 +465,83 @@ orinoco_cs_release(dev_link_t *link)
465 ioport_unmap(priv->hw.iobase); 465 ioport_unmap(priv->hw.iobase);
466} /* orinoco_cs_release */ 466} /* orinoco_cs_release */
467 467
468static int orinoco_cs_suspend(struct pcmcia_device *p_dev)
469{
470 dev_link_t *link = dev_to_instance(p_dev);
471 struct net_device *dev = link->priv;
472 struct orinoco_private *priv = netdev_priv(dev);
473 struct orinoco_pccard *card = priv->card;
474 int err = 0;
475 unsigned long flags;
476
477 link->state |= DEV_SUSPEND;
478 if (link->state & DEV_CONFIG) {
479 /* This is probably racy, but I can't think of
480 a better way, short of rewriting the PCMCIA
481 layer to not suck :-( */
482 if (! test_bit(0, &card->hard_reset_in_progress)) {
483 spin_lock_irqsave(&priv->lock, flags);
484
485 err = __orinoco_down(dev);
486 if (err)
487 printk(KERN_WARNING "%s: Error %d downing interface\n",
488 dev->name, err);
489
490 netif_device_detach(dev);
491 priv->hw_unavailable++;
492
493 spin_unlock_irqrestore(&priv->lock, flags);
494 }
495
496 pcmcia_release_configuration(link->handle);
497 }
498
499 return 0;
500}
501
502static int orinoco_cs_resume(struct pcmcia_device *p_dev)
503{
504 dev_link_t *link = dev_to_instance(p_dev);
505 struct net_device *dev = link->priv;
506 struct orinoco_private *priv = netdev_priv(dev);
507 struct orinoco_pccard *card = priv->card;
508 int err = 0;
509 unsigned long flags;
510
511 link->state &= ~DEV_SUSPEND;
512 if (link->state & DEV_CONFIG) {
513 /* FIXME: should we double check that this is
514 * the same card as we had before */
515 pcmcia_request_configuration(link->handle, &link->conf);
516
517 if (! test_bit(0, &card->hard_reset_in_progress)) {
518 err = orinoco_reinit_firmware(dev);
519 if (err) {
520 printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
521 dev->name, err);
522 return -EIO;
523 }
524
525 spin_lock_irqsave(&priv->lock, flags);
526
527 netif_device_attach(dev);
528 priv->hw_unavailable--;
529
530 if (priv->open && ! priv->hw_unavailable) {
531 err = __orinoco_up(dev);
532 if (err)
533 printk(KERN_ERR "%s: Error %d restarting card\n",
534 dev->name, err);
535 }
536
537 spin_unlock_irqrestore(&priv->lock, flags);
538 }
539 }
540
541 return 0;
542}
543
544
468/* 545/*
469 * The card status event handler. Mostly, this schedules other stuff 546 * The card status event handler. Mostly, this schedules other stuff
470 * to run after an event is received. 547 * to run after an event is received.
@@ -476,9 +553,7 @@ orinoco_cs_event(event_t event, int priority,
476 dev_link_t *link = args->client_data; 553 dev_link_t *link = args->client_data;
477 struct net_device *dev = link->priv; 554 struct net_device *dev = link->priv;
478 struct orinoco_private *priv = netdev_priv(dev); 555 struct orinoco_private *priv = netdev_priv(dev);
479 struct orinoco_pccard *card = priv->card;
480 int err = 0; 556 int err = 0;
481 unsigned long flags;
482 557
483 switch (event) { 558 switch (event) {
484 case CS_EVENT_CARD_REMOVAL: 559 case CS_EVENT_CARD_REMOVAL:
@@ -497,70 +572,6 @@ orinoco_cs_event(event_t event, int priority,
497 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 572 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
498 orinoco_cs_config(link); 573 orinoco_cs_config(link);
499 break; 574 break;
500
501 case CS_EVENT_PM_SUSPEND:
502 link->state |= DEV_SUSPEND;
503 /* Fall through... */
504 case CS_EVENT_RESET_PHYSICAL:
505 /* Mark the device as stopped, to block IO until later */
506 if (link->state & DEV_CONFIG) {
507 /* This is probably racy, but I can't think of
508 a better way, short of rewriting the PCMCIA
509 layer to not suck :-( */
510 if (! test_bit(0, &card->hard_reset_in_progress)) {
511 spin_lock_irqsave(&priv->lock, flags);
512
513 err = __orinoco_down(dev);
514 if (err)
515 printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
516 dev->name,
517 event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
518 err);
519
520 netif_device_detach(dev);
521 priv->hw_unavailable++;
522
523 spin_unlock_irqrestore(&priv->lock, flags);
524 }
525
526 pcmcia_release_configuration(link->handle);
527 }
528 break;
529
530 case CS_EVENT_PM_RESUME:
531 link->state &= ~DEV_SUSPEND;
532 /* Fall through... */
533 case CS_EVENT_CARD_RESET:
534 if (link->state & DEV_CONFIG) {
535 /* FIXME: should we double check that this is
536 * the same card as we had before */
537 pcmcia_request_configuration(link->handle, &link->conf);
538
539 if (! test_bit(0, &card->hard_reset_in_progress)) {
540 err = orinoco_reinit_firmware(dev);
541 if (err) {
542 printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
543 dev->name, err);
544 break;
545 }
546
547 spin_lock_irqsave(&priv->lock, flags);
548
549 netif_device_attach(dev);
550 priv->hw_unavailable--;
551
552 if (priv->open && ! priv->hw_unavailable) {
553 err = __orinoco_up(dev);
554 if (err)
555 printk(KERN_ERR "%s: Error %d restarting card\n",
556 dev->name, err);
557
558 }
559
560 spin_unlock_irqrestore(&priv->lock, flags);
561 }
562 }
563 break;
564 } 575 }
565 576
566 return err; 577 return err;
@@ -669,6 +680,8 @@ static struct pcmcia_driver orinoco_driver = {
669 .detach = orinoco_cs_detach, 680 .detach = orinoco_cs_detach,
670 .event = orinoco_cs_event, 681 .event = orinoco_cs_event,
671 .id_table = orinoco_cs_ids, 682 .id_table = orinoco_cs_ids,
683 .suspend = orinoco_cs_suspend,
684 .resume = orinoco_cs_resume,
672}; 685};
673 686
674static int __init 687static int __init
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 70fd6fd8feb9..c2cb6c8e6d7c 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -891,6 +891,40 @@ static void ray_release(dev_link_t *link)
891 DEBUG(2,"ray_release ending\n"); 891 DEBUG(2,"ray_release ending\n");
892} 892}
893 893
894static int ray_suspend(struct pcmcia_device *p_dev)
895{
896 dev_link_t *link = dev_to_instance(p_dev);
897 struct net_device *dev = link->priv;
898
899 link->state |= DEV_SUSPEND;
900 if (link->state & DEV_CONFIG) {
901 if (link->open)
902 netif_device_detach(dev);
903
904 pcmcia_release_configuration(link->handle);
905 }
906
907
908 return 0;
909}
910
911static int ray_resume(struct pcmcia_device *p_dev)
912{
913 dev_link_t *link = dev_to_instance(p_dev);
914 struct net_device *dev = link->priv;
915
916 link->state &= ~DEV_SUSPEND;
917 if (link->state & DEV_CONFIG) {
918 pcmcia_request_configuration(link->handle, &link->conf);
919 if (link->open) {
920 ray_reset(dev);
921 netif_device_attach(dev);
922 }
923 }
924
925 return 0;
926}
927
894/*============================================================================= 928/*=============================================================================
895 The card status event handler. Mostly, this schedules other 929 The card status event handler. Mostly, this schedules other
896 stuff to run after an event is received. A CARD_REMOVAL event 930 stuff to run after an event is received. A CARD_REMOVAL event
@@ -923,29 +957,6 @@ static int ray_event(event_t event, int priority,
923 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 957 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
924 ray_config(link); 958 ray_config(link);
925 break; 959 break;
926 case CS_EVENT_PM_SUSPEND:
927 link->state |= DEV_SUSPEND;
928 /* Fall through... */
929 case CS_EVENT_RESET_PHYSICAL:
930 if (link->state & DEV_CONFIG) {
931 if (link->open)
932 netif_device_detach(dev);
933
934 pcmcia_release_configuration(link->handle);
935 }
936 break;
937 case CS_EVENT_PM_RESUME:
938 link->state &= ~DEV_SUSPEND;
939 /* Fall through... */
940 case CS_EVENT_CARD_RESET:
941 if (link->state & DEV_CONFIG) {
942 pcmcia_request_configuration(link->handle, &link->conf);
943 if (link->open) {
944 ray_reset(dev);
945 netif_device_attach(dev);
946 }
947 }
948 break;
949 } 960 }
950 return 0; 961 return 0;
951 DEBUG(2,"ray_event ending\n"); 962 DEBUG(2,"ray_event ending\n");
@@ -2949,6 +2960,8 @@ static struct pcmcia_driver ray_driver = {
2949 .event = ray_event, 2960 .event = ray_event,
2950 .detach = ray_detach, 2961 .detach = ray_detach,
2951 .id_table = ray_ids, 2962 .id_table = ray_ids,
2963 .suspend = ray_suspend,
2964 .resume = ray_resume,
2952}; 2965};
2953 2966
2954static int __init init_ray_cs(void) 2967static int __init init_ray_cs(void)
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index b1bbc8e8e91f..3938a5735659 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -948,6 +948,56 @@ spectrum_cs_release(dev_link_t *link)
948 ioport_unmap(priv->hw.iobase); 948 ioport_unmap(priv->hw.iobase);
949} /* spectrum_cs_release */ 949} /* spectrum_cs_release */
950 950
951
952static int
953spectrum_cs_suspend(struct pcmcia_device *p_dev)
954{
955 dev_link_t *link = dev_to_instance(p_dev);
956 struct net_device *dev = link->priv;
957 struct orinoco_private *priv = netdev_priv(dev);
958 unsigned long flags;
959 int err = 0;
960
961 link->state |= DEV_SUSPEND;
962 /* Mark the device as stopped, to block IO until later */
963 if (link->state & DEV_CONFIG) {
964 spin_lock_irqsave(&priv->lock, flags);
965
966 err = __orinoco_down(dev);
967 if (err)
968 printk(KERN_WARNING "%s: Error %d downing interface\n",
969 dev->name, err);
970
971 netif_device_detach(dev);
972 priv->hw_unavailable++;
973
974 spin_unlock_irqrestore(&priv->lock, flags);
975
976 pcmcia_release_configuration(link->handle);
977 }
978
979 return 0;
980}
981
982static int
983spectrum_cs_resume(struct pcmcia_device *p_dev)
984{
985 dev_link_t *link = dev_to_instance(p_dev);
986 struct net_device *dev = link->priv;
987 struct orinoco_private *priv = netdev_priv(dev);
988
989 link->state &= ~DEV_SUSPEND;
990 if (link->state & DEV_CONFIG) {
991 /* FIXME: should we double check that this is
992 * the same card as we had before */
993 pcmcia_request_configuration(link->handle, &link->conf);
994 netif_device_attach(dev);
995 priv->hw_unavailable--;
996 schedule_work(&priv->reset_work);
997 }
998 return 0;
999}
1000
951/* 1001/*
952 * The card status event handler. Mostly, this schedules other stuff 1002 * The card status event handler. Mostly, this schedules other stuff
953 * to run after an event is received. 1003 * to run after an event is received.
@@ -959,8 +1009,6 @@ spectrum_cs_event(event_t event, int priority,
959 dev_link_t *link = args->client_data; 1009 dev_link_t *link = args->client_data;
960 struct net_device *dev = link->priv; 1010 struct net_device *dev = link->priv;
961 struct orinoco_private *priv = netdev_priv(dev); 1011 struct orinoco_private *priv = netdev_priv(dev);
962 int err = 0;
963 unsigned long flags;
964 1012
965 switch (event) { 1013 switch (event) {
966 case CS_EVENT_CARD_REMOVAL: 1014 case CS_EVENT_CARD_REMOVAL:
@@ -980,49 +1028,9 @@ spectrum_cs_event(event_t event, int priority,
980 spectrum_cs_config(link); 1028 spectrum_cs_config(link);
981 break; 1029 break;
982 1030
983 case CS_EVENT_PM_SUSPEND:
984 link->state |= DEV_SUSPEND;
985 /* Fall through... */
986 case CS_EVENT_RESET_PHYSICAL:
987 /* Mark the device as stopped, to block IO until later */
988 if (link->state & DEV_CONFIG) {
989 /* This is probably racy, but I can't think of
990 a better way, short of rewriting the PCMCIA
991 layer to not suck :-( */
992 spin_lock_irqsave(&priv->lock, flags);
993
994 err = __orinoco_down(dev);
995 if (err)
996 printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
997 dev->name,
998 event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
999 err);
1000
1001 netif_device_detach(dev);
1002 priv->hw_unavailable++;
1003
1004 spin_unlock_irqrestore(&priv->lock, flags);
1005
1006 pcmcia_release_configuration(link->handle);
1007 }
1008 break;
1009
1010 case CS_EVENT_PM_RESUME:
1011 link->state &= ~DEV_SUSPEND;
1012 /* Fall through... */
1013 case CS_EVENT_CARD_RESET:
1014 if (link->state & DEV_CONFIG) {
1015 /* FIXME: should we double check that this is
1016 * the same card as we had before */
1017 pcmcia_request_configuration(link->handle, &link->conf);
1018 netif_device_attach(dev);
1019 priv->hw_unavailable--;
1020 schedule_work(&priv->reset_work);
1021 }
1022 break;
1023 } 1031 }
1024 1032
1025 return err; 1033 return 0;
1026} /* spectrum_cs_event */ 1034} /* spectrum_cs_event */
1027 1035
1028/********************************************************************/ 1036/********************************************************************/
@@ -1050,6 +1058,8 @@ static struct pcmcia_driver orinoco_driver = {
1050 }, 1058 },
1051 .attach = spectrum_cs_attach, 1059 .attach = spectrum_cs_attach,
1052 .detach = spectrum_cs_detach, 1060 .detach = spectrum_cs_detach,
1061 .suspend = spectrum_cs_suspend,
1062 .resume = spectrum_cs_resume,
1053 .event = spectrum_cs_event, 1063 .event = spectrum_cs_event,
1054 .id_table = spectrum_cs_ids, 1064 .id_table = spectrum_cs_ids,
1055}; 1065};
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index c822cad3333f..3e3532830c26 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -4775,6 +4775,56 @@ wavelan_detach(dev_link_t * link)
4775#endif 4775#endif
4776} 4776}
4777 4777
4778static int wavelan_suspend(struct pcmcia_device *p_dev)
4779{
4780 dev_link_t *link = dev_to_instance(p_dev);
4781 struct net_device * dev = (struct net_device *) link->priv;
4782
4783 /* NB: wavelan_close will be called, but too late, so we are
4784 * obliged to close nicely the wavelan here. David, could you
4785 * close the device before suspending them ? And, by the way,
4786 * could you, on resume, add a "route add -net ..." after the
4787 * ifconfig up ? Thanks... */
4788
4789 /* Stop receiving new messages and wait end of transmission */
4790 wv_ru_stop(dev);
4791
4792 /* Power down the module */
4793 hacr_write(dev->base_addr, HACR_DEFAULT & (~HACR_PWR_STAT));
4794
4795 /* The card is now suspended */
4796 link->state |= DEV_SUSPEND;
4797
4798 if(link->state & DEV_CONFIG)
4799 {
4800 if(link->open)
4801 netif_device_detach(dev);
4802 pcmcia_release_configuration(link->handle);
4803 }
4804
4805 return 0;
4806}
4807
4808static int wavelan_resume(struct pcmcia_device *p_dev)
4809{
4810 dev_link_t *link = dev_to_instance(p_dev);
4811 struct net_device * dev = (struct net_device *) link->priv;
4812
4813 link->state &= ~DEV_SUSPEND;
4814 if(link->state & DEV_CONFIG)
4815 {
4816 pcmcia_request_configuration(link->handle, &link->conf);
4817 if(link->open) /* If RESET -> True, If RESUME -> False ? */
4818 {
4819 wv_hw_reset(dev);
4820 netif_device_attach(dev);
4821 }
4822 }
4823
4824 return 0;
4825}
4826
4827
4778/*------------------------------------------------------------------*/ 4828/*------------------------------------------------------------------*/
4779/* 4829/*
4780 * The card status event handler. Mostly, this schedules other stuff 4830 * The card status event handler. Mostly, this schedules other stuff
@@ -4832,46 +4882,6 @@ wavelan_event(event_t event, /* The event received */
4832 else 4882 else
4833 dev->irq = 0; 4883 dev->irq = 0;
4834 break; 4884 break;
4835
4836 case CS_EVENT_PM_SUSPEND:
4837 /* NB: wavelan_close will be called, but too late, so we are
4838 * obliged to close nicely the wavelan here. David, could you
4839 * close the device before suspending them ? And, by the way,
4840 * could you, on resume, add a "route add -net ..." after the
4841 * ifconfig up ? Thanks... */
4842
4843 /* Stop receiving new messages and wait end of transmission */
4844 wv_ru_stop(dev);
4845
4846 /* Power down the module */
4847 hacr_write(dev->base_addr, HACR_DEFAULT & (~HACR_PWR_STAT));
4848
4849 /* The card is now suspended */
4850 link->state |= DEV_SUSPEND;
4851 /* Fall through... */
4852 case CS_EVENT_RESET_PHYSICAL:
4853 if(link->state & DEV_CONFIG)
4854 {
4855 if(link->open)
4856 netif_device_detach(dev);
4857 pcmcia_release_configuration(link->handle);
4858 }
4859 break;
4860
4861 case CS_EVENT_PM_RESUME:
4862 link->state &= ~DEV_SUSPEND;
4863 /* Fall through... */
4864 case CS_EVENT_CARD_RESET:
4865 if(link->state & DEV_CONFIG)
4866 {
4867 pcmcia_request_configuration(link->handle, &link->conf);
4868 if(link->open) /* If RESET -> True, If RESUME -> False ? */
4869 {
4870 wv_hw_reset(dev);
4871 netif_device_attach(dev);
4872 }
4873 }
4874 break;
4875 } 4885 }
4876 4886
4877#ifdef DEBUG_CALLBACK_TRACE 4887#ifdef DEBUG_CALLBACK_TRACE
@@ -4898,6 +4908,8 @@ static struct pcmcia_driver wavelan_driver = {
4898 .event = wavelan_event, 4908 .event = wavelan_event,
4899 .detach = wavelan_detach, 4909 .detach = wavelan_detach,
4900 .id_table = wavelan_ids, 4910 .id_table = wavelan_ids,
4911 .suspend = wavelan_suspend,
4912 .resume = wavelan_resume,
4901}; 4913};
4902 4914
4903static int __init 4915static int __init
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 978fdc606781..75114318457e 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -2173,6 +2173,41 @@ static void wl3501_release(dev_link_t *link)
2173 link->state &= ~DEV_CONFIG; 2173 link->state &= ~DEV_CONFIG;
2174} 2174}
2175 2175
2176static int wl3501_suspend(struct pcmcia_device *p_dev)
2177{
2178 dev_link_t *link = dev_to_instance(p_dev);
2179 struct net_device *dev = link->priv;
2180
2181 link->state |= DEV_SUSPEND;
2182
2183 wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND);
2184 if (link->state & DEV_CONFIG) {
2185 if (link->open)
2186 netif_device_detach(dev);
2187 pcmcia_release_configuration(link->handle);
2188 }
2189
2190 return 0;
2191}
2192
2193static int wl3501_resume(struct pcmcia_device *p_dev)
2194{
2195 dev_link_t *link = dev_to_instance(p_dev);
2196 struct net_device *dev = link->priv;
2197
2198 wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
2199 if (link->state & DEV_CONFIG) {
2200 pcmcia_request_configuration(link->handle, &link->conf);
2201 if (link->open) {
2202 wl3501_reset(dev);
2203 netif_device_attach(dev);
2204 }
2205 }
2206
2207 return 0;
2208}
2209
2210
2176/** 2211/**
2177 * wl3501_event - The card status event handler 2212 * wl3501_event - The card status event handler
2178 * @event - event 2213 * @event - event
@@ -2206,30 +2241,6 @@ static int wl3501_event(event_t event, int pri, event_callback_args_t *args)
2206 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 2241 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2207 wl3501_config(link); 2242 wl3501_config(link);
2208 break; 2243 break;
2209 case CS_EVENT_PM_SUSPEND:
2210 link->state |= DEV_SUSPEND;
2211 wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND);
2212 /* Fall through... */
2213 case CS_EVENT_RESET_PHYSICAL:
2214 if (link->state & DEV_CONFIG) {
2215 if (link->open)
2216 netif_device_detach(dev);
2217 pcmcia_release_configuration(link->handle);
2218 }
2219 break;
2220 case CS_EVENT_PM_RESUME:
2221 link->state &= ~DEV_SUSPEND;
2222 wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
2223 /* Fall through... */
2224 case CS_EVENT_CARD_RESET:
2225 if (link->state & DEV_CONFIG) {
2226 pcmcia_request_configuration(link->handle, &link->conf);
2227 if (link->open) {
2228 wl3501_reset(dev);
2229 netif_device_attach(dev);
2230 }
2231 }
2232 break;
2233 } 2244 }
2234 return 0; 2245 return 0;
2235} 2246}
@@ -2249,6 +2260,8 @@ static struct pcmcia_driver wl3501_driver = {
2249 .event = wl3501_event, 2260 .event = wl3501_event,
2250 .detach = wl3501_detach, 2261 .detach = wl3501_detach,
2251 .id_table = wl3501_ids, 2262 .id_table = wl3501_ids,
2263 .suspend = wl3501_suspend,
2264 .resume = wl3501_resume,
2252}; 2265};
2253 2266
2254static int __init wl3501_init_module(void) 2267static int __init wl3501_init_module(void)
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
index 24e6aacddb74..4c89853785ed 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -325,6 +325,28 @@ void parport_cs_release(dev_link_t *link)
325 325
326} /* parport_cs_release */ 326} /* parport_cs_release */
327 327
328static int parport_suspend(struct pcmcia_device *dev)
329{
330 dev_link_t *link = dev_to_instance(dev);
331
332 link->state |= DEV_SUSPEND;
333 if (link->state & DEV_CONFIG)
334 pcmcia_release_configuration(link->handle);
335
336 return 0;
337}
338
339static int parport_resume(struct pcmcia_device *dev)
340{
341 dev_link_t *link = dev_to_instance(dev);
342
343 link->state &= ~DEV_SUSPEND;
344 if (DEV_OK(link))
345 pcmcia_request_configuration(link->handle, &link->conf);
346
347 return 0;
348}
349
328/*====================================================================== 350/*======================================================================
329 351
330 The card status event handler. Mostly, this schedules other 352 The card status event handler. Mostly, this schedules other
@@ -349,20 +371,6 @@ int parport_event(event_t event, int priority,
349 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 371 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
350 parport_config(link); 372 parport_config(link);
351 break; 373 break;
352 case CS_EVENT_PM_SUSPEND:
353 link->state |= DEV_SUSPEND;
354 /* Fall through... */
355 case CS_EVENT_RESET_PHYSICAL:
356 if (link->state & DEV_CONFIG)
357 pcmcia_release_configuration(link->handle);
358 break;
359 case CS_EVENT_PM_RESUME:
360 link->state &= ~DEV_SUSPEND;
361 /* Fall through... */
362 case CS_EVENT_CARD_RESET:
363 if (DEV_OK(link))
364 pcmcia_request_configuration(link->handle, &link->conf);
365 break;
366 } 374 }
367 return 0; 375 return 0;
368} /* parport_event */ 376} /* parport_event */
@@ -383,7 +391,8 @@ static struct pcmcia_driver parport_cs_driver = {
383 .event = parport_event, 391 .event = parport_event,
384 .detach = parport_detach, 392 .detach = parport_detach,
385 .id_table = parport_ids, 393 .id_table = parport_ids,
386 394 .suspend = parport_suspend,
395 .resume = parport_resume,
387}; 396};
388 397
389static int __init init_parport_cs(void) 398static int __init init_parport_cs(void)
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index b120794c03a9..a802c65c3534 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -951,6 +951,16 @@ static int send_event_callback(struct device *dev, void * _data)
951 if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE)) 951 if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE))
952 return 0; 952 return 0;
953 953
954 if ((data->event == CS_EVENT_PM_SUSPEND) ||
955 (data->event == CS_EVENT_RESET_PHYSICAL)) {
956 if (p_drv->suspend)
957 return p_drv->suspend(p_dev);
958 } else if ((data->event == CS_EVENT_PM_RESUME) ||
959 (data->event == CS_EVENT_CARD_RESET)) {
960 if (p_drv->resume)
961 return p_drv->resume(p_dev);
962 }
963
954 if (p_drv->event) 964 if (p_drv->event)
955 return p_drv->event(data->event, data->priority, 965 return p_drv->event(data->event, data->priority,
956 &p_dev->event_callback_args); 966 &p_dev->event_callback_args);
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
index 7c5306499832..82988a3e35ec 100644
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -272,11 +272,37 @@ static void aha152x_release_cs(dev_link_t *link)
272 link->state &= ~DEV_CONFIG; 272 link->state &= ~DEV_CONFIG;
273} 273}
274 274
275static int aha152x_suspend(struct pcmcia_device *dev)
276{
277 dev_link_t *link = dev_to_instance(dev);
278
279 link->state |= DEV_SUSPEND;
280 if (link->state & DEV_CONFIG)
281 pcmcia_release_configuration(link->handle);
282
283 return 0;
284}
285
286static int aha152x_resume(struct pcmcia_device *dev)
287{
288 dev_link_t *link = dev_to_instance(dev);
289 scsi_info_t *info = link->priv;
290
291 link->state &= ~DEV_SUSPEND;
292 if (link->state & DEV_CONFIG) {
293 Scsi_Cmnd tmp;
294 pcmcia_request_configuration(link->handle, &link->conf);
295 tmp.device->host = info->host;
296 aha152x_host_reset(&tmp);
297 }
298
299 return 0;
300}
301
275static int aha152x_event(event_t event, int priority, 302static int aha152x_event(event_t event, int priority,
276 event_callback_args_t *args) 303 event_callback_args_t *args)
277{ 304{
278 dev_link_t *link = args->client_data; 305 dev_link_t *link = args->client_data;
279 scsi_info_t *info = link->priv;
280 306
281 DEBUG(0, "aha152x_event(0x%06x)\n", event); 307 DEBUG(0, "aha152x_event(0x%06x)\n", event);
282 308
@@ -290,24 +316,6 @@ static int aha152x_event(event_t event, int priority,
290 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 316 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
291 aha152x_config_cs(link); 317 aha152x_config_cs(link);
292 break; 318 break;
293 case CS_EVENT_PM_SUSPEND:
294 link->state |= DEV_SUSPEND;
295 /* Fall through... */
296 case CS_EVENT_RESET_PHYSICAL:
297 if (link->state & DEV_CONFIG)
298 pcmcia_release_configuration(link->handle);
299 break;
300 case CS_EVENT_PM_RESUME:
301 link->state &= ~DEV_SUSPEND;
302 /* Fall through... */
303 case CS_EVENT_CARD_RESET:
304 if (link->state & DEV_CONFIG) {
305 Scsi_Cmnd tmp;
306 pcmcia_request_configuration(link->handle, &link->conf);
307 tmp.device->host = info->host;
308 aha152x_host_reset(&tmp);
309 }
310 break;
311 } 319 }
312 return 0; 320 return 0;
313} 321}
@@ -331,6 +339,8 @@ static struct pcmcia_driver aha152x_cs_driver = {
331 .event = aha152x_event, 339 .event = aha152x_event,
332 .detach = aha152x_detach, 340 .detach = aha152x_detach,
333 .id_table = aha152x_ids, 341 .id_table = aha152x_ids,
342 .suspend = aha152x_suspend,
343 .resume = aha152x_resume,
334}; 344};
335 345
336static int __init init_aha152x_cs(void) 346static int __init init_aha152x_cs(void)
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
index db8f5cd85ffe..9e1d68c14694 100644
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -256,6 +256,30 @@ static void fdomain_release(dev_link_t *link)
256 256
257/*====================================================================*/ 257/*====================================================================*/
258 258
259static int fdomain_suspend(struct pcmcia_device *dev)
260{
261 dev_link_t *link = dev_to_instance(dev);
262
263 link->state |= DEV_SUSPEND;
264 if (link->state & DEV_CONFIG)
265 pcmcia_release_configuration(link->handle);
266
267 return 0;
268}
269
270static int fdomain_resume(struct pcmcia_device *dev)
271{
272 dev_link_t *link = dev_to_instance(dev);
273
274 link->state &= ~DEV_SUSPEND;
275 if (link->state & DEV_CONFIG) {
276 pcmcia_request_configuration(link->handle, &link->conf);
277 fdomain_16x0_bus_reset(NULL);
278 }
279
280 return 0;
281}
282
259static int fdomain_event(event_t event, int priority, 283static int fdomain_event(event_t event, int priority,
260 event_callback_args_t *args) 284 event_callback_args_t *args)
261{ 285{
@@ -273,22 +297,6 @@ static int fdomain_event(event_t event, int priority,
273 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 297 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
274 fdomain_config(link); 298 fdomain_config(link);
275 break; 299 break;
276 case CS_EVENT_PM_SUSPEND:
277 link->state |= DEV_SUSPEND;
278 /* Fall through... */
279 case CS_EVENT_RESET_PHYSICAL:
280 if (link->state & DEV_CONFIG)
281 pcmcia_release_configuration(link->handle);
282 break;
283 case CS_EVENT_PM_RESUME:
284 link->state &= ~DEV_SUSPEND;
285 /* Fall through... */
286 case CS_EVENT_CARD_RESET:
287 if (link->state & DEV_CONFIG) {
288 pcmcia_request_configuration(link->handle, &link->conf);
289 fdomain_16x0_bus_reset(NULL);
290 }
291 break;
292 } 300 }
293 return 0; 301 return 0;
294} /* fdomain_event */ 302} /* fdomain_event */
@@ -311,6 +319,8 @@ static struct pcmcia_driver fdomain_cs_driver = {
311 .event = fdomain_event, 319 .event = fdomain_event,
312 .detach = fdomain_detach, 320 .detach = fdomain_detach,
313 .id_table = fdomain_ids, 321 .id_table = fdomain_ids,
322 .suspend = fdomain_suspend,
323 .resume = fdomain_resume,
314}; 324};
315 325
316static int __init init_fdomain_cs(void) 326static int __init init_fdomain_cs(void)
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 050ea13ff80b..870e87180d12 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -2021,6 +2021,59 @@ static void nsp_cs_release(dev_link_t *link)
2021#endif 2021#endif
2022} /* nsp_cs_release */ 2022} /* nsp_cs_release */
2023 2023
2024static int nsp_cs_suspend(struct pcmcia_device *dev)
2025{
2026 dev_link_t *link = dev_to_instance(dev);
2027 scsi_info_t *info = link->priv;
2028 nsp_hw_data *data;
2029
2030 link->state |= DEV_SUSPEND;
2031
2032 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
2033
2034 if (info->host != NULL) {
2035 nsp_msg(KERN_INFO, "clear SDTR status");
2036
2037 data = (nsp_hw_data *)info->host->hostdata;
2038
2039 nsphw_init_sync(data);
2040 }
2041
2042 info->stop = 1;
2043
2044 if (link->state & DEV_CONFIG)
2045 pcmcia_release_configuration(link->handle);
2046
2047 return 0;
2048}
2049
2050static int nsp_cs_resume(struct pcmcia_device *dev)
2051{
2052 dev_link_t *link = dev_to_instance(dev);
2053 scsi_info_t *info = link->priv;
2054 nsp_hw_data *data;
2055
2056 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
2057
2058 link->state &= ~DEV_SUSPEND;
2059
2060 if (link->state & DEV_CONFIG)
2061 pcmcia_request_configuration(link->handle, &link->conf);
2062
2063 info->stop = 0;
2064
2065 if (info->host != NULL) {
2066 nsp_msg(KERN_INFO, "reset host and bus");
2067
2068 data = (nsp_hw_data *)info->host->hostdata;
2069
2070 nsphw_init (data);
2071 nsp_bus_reset(data);
2072 }
2073
2074 return 0;
2075}
2076
2024/*====================================================================== 2077/*======================================================================
2025 2078
2026 The card status event handler. Mostly, this schedules other 2079 The card status event handler. Mostly, this schedules other
@@ -2039,8 +2092,6 @@ static int nsp_cs_event(event_t event,
2039 event_callback_args_t *args) 2092 event_callback_args_t *args)
2040{ 2093{
2041 dev_link_t *link = args->client_data; 2094 dev_link_t *link = args->client_data;
2042 scsi_info_t *info = link->priv;
2043 nsp_hw_data *data;
2044 2095
2045 nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event); 2096 nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event);
2046 2097
@@ -2062,51 +2113,6 @@ static int nsp_cs_event(event_t event,
2062#endif 2113#endif
2063 nsp_cs_config(link); 2114 nsp_cs_config(link);
2064 break; 2115 break;
2065
2066 case CS_EVENT_PM_SUSPEND:
2067 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
2068 link->state |= DEV_SUSPEND;
2069 /* Fall through... */
2070 case CS_EVENT_RESET_PHYSICAL:
2071 /* Mark the device as stopped, to block IO until later */
2072 nsp_dbg(NSP_DEBUG_INIT, "event: reset physical");
2073
2074 if (info->host != NULL) {
2075 nsp_msg(KERN_INFO, "clear SDTR status");
2076
2077 data = (nsp_hw_data *)info->host->hostdata;
2078
2079 nsphw_init_sync(data);
2080 }
2081
2082 info->stop = 1;
2083 if (link->state & DEV_CONFIG) {
2084 pcmcia_release_configuration(link->handle);
2085 }
2086 break;
2087
2088 case CS_EVENT_PM_RESUME:
2089 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
2090 link->state &= ~DEV_SUSPEND;
2091 /* Fall through... */
2092 case CS_EVENT_CARD_RESET:
2093 nsp_dbg(NSP_DEBUG_INIT, "event: reset");
2094 if (link->state & DEV_CONFIG) {
2095 pcmcia_request_configuration(link->handle, &link->conf);
2096 }
2097 info->stop = 0;
2098
2099 if (info->host != NULL) {
2100 nsp_msg(KERN_INFO, "reset host and bus");
2101
2102 data = (nsp_hw_data *)info->host->hostdata;
2103
2104 nsphw_init (data);
2105 nsp_bus_reset(data);
2106 }
2107
2108 break;
2109
2110 default: 2116 default:
2111 nsp_dbg(NSP_DEBUG_INIT, "event: unknown"); 2117 nsp_dbg(NSP_DEBUG_INIT, "event: unknown");
2112 break; 2118 break;
@@ -2140,6 +2146,8 @@ static struct pcmcia_driver nsp_driver = {
2140 .event = nsp_cs_event, 2146 .event = nsp_cs_event,
2141 .detach = nsp_cs_detach, 2147 .detach = nsp_cs_detach,
2142 .id_table = nsp_cs_ids, 2148 .id_table = nsp_cs_ids,
2149 .suspend = nsp_cs_suspend,
2150 .resume = nsp_cs_resume,
2143}; 2151};
2144#endif 2152#endif
2145 2153
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index bb091a45a880..2541a999a0e5 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -349,6 +349,40 @@ static void qlogic_release(dev_link_t *link)
349 349
350/*====================================================================*/ 350/*====================================================================*/
351 351
352static int qlogic_suspend(struct pcmcia_device *dev)
353{
354 dev_link_t *link = dev_to_instance(dev);
355
356 link->state |= DEV_SUSPEND;
357 if (link->state & DEV_CONFIG)
358 pcmcia_release_configuration(link->handle);
359
360 return 0;
361}
362
363static int qlogic_resume(struct pcmcia_device *dev)
364{
365 dev_link_t *link = dev_to_instance(dev);
366
367 link->state &= ~DEV_SUSPEND;
368 if (link->state & DEV_CONFIG) {
369 scsi_info_t *info = link->priv;
370
371 pcmcia_request_configuration(link->handle, &link->conf);
372 if ((info->manf_id == MANFID_MACNICA) ||
373 (info->manf_id == MANFID_PIONEER) ||
374 (info->manf_id == 0x0098)) {
375 outb(0x80, link->io.BasePort1 + 0xd);
376 outb(0x24, link->io.BasePort1 + 0x9);
377 outb(0x04, link->io.BasePort1 + 0xd);
378 }
379 /* Ugggglllyyyy!!! */
380 qlogicfas408_bus_reset(NULL);
381 }
382
383 return 0;
384}
385
352static int qlogic_event(event_t event, int priority, event_callback_args_t * args) 386static int qlogic_event(event_t event, int priority, event_callback_args_t * args)
353{ 387{
354 dev_link_t *link = args->client_data; 388 dev_link_t *link = args->client_data;
@@ -365,29 +399,6 @@ static int qlogic_event(event_t event, int priority, event_callback_args_t * arg
365 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 399 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
366 qlogic_config(link); 400 qlogic_config(link);
367 break; 401 break;
368 case CS_EVENT_PM_SUSPEND:
369 link->state |= DEV_SUSPEND;
370 /* Fall through... */
371 case CS_EVENT_RESET_PHYSICAL:
372 if (link->state & DEV_CONFIG)
373 pcmcia_release_configuration(link->handle);
374 break;
375 case CS_EVENT_PM_RESUME:
376 link->state &= ~DEV_SUSPEND;
377 /* Fall through... */
378 case CS_EVENT_CARD_RESET:
379 if (link->state & DEV_CONFIG) {
380 scsi_info_t *info = link->priv;
381 pcmcia_request_configuration(link->handle, &link->conf);
382 if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
383 outb(0x80, link->io.BasePort1 + 0xd);
384 outb(0x24, link->io.BasePort1 + 0x9);
385 outb(0x04, link->io.BasePort1 + 0xd);
386 }
387 /* Ugggglllyyyy!!! */
388 qlogicfas408_bus_reset(NULL);
389 }
390 break;
391 } 402 }
392 return 0; 403 return 0;
393} /* qlogic_event */ 404} /* qlogic_event */
@@ -423,6 +434,8 @@ static struct pcmcia_driver qlogic_cs_driver = {
423 .event = qlogic_event, 434 .event = qlogic_event,
424 .detach = qlogic_detach, 435 .detach = qlogic_detach,
425 .id_table = qlogic_ids, 436 .id_table = qlogic_ids,
437 .suspend = qlogic_suspend,
438 .resume = qlogic_resume,
426}; 439};
427 440
428static int __init init_qlogic_cs(void) 441static int __init init_qlogic_cs(void)
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 98b64b2aa8ee..c4e3e2294c66 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -872,11 +872,48 @@ cs_failed:
872 return; 872 return;
873} /* SYM53C500_config */ 873} /* SYM53C500_config */
874 874
875static int sym53c500_suspend(struct pcmcia_device *dev)
876{
877 dev_link_t *link = dev_to_instance(dev);
878
879 link->state |= DEV_SUSPEND;
880 if (link->state & DEV_CONFIG)
881 pcmcia_release_configuration(link->handle);
882
883 return 0;
884}
885
886static int sym53c500_resume(struct pcmcia_device *dev)
887{
888 dev_link_t *link = dev_to_instance(dev);
889 struct scsi_info_t *info = link->priv;
890
891 link->state &= ~DEV_SUSPEND;
892 if (link->state & DEV_CONFIG) {
893 pcmcia_request_configuration(link->handle, &link->conf);
894
895 /* See earlier comment about manufacturer IDs. */
896 if ((info->manf_id == MANFID_MACNICA) ||
897 (info->manf_id == MANFID_PIONEER) ||
898 (info->manf_id == 0x0098)) {
899 outb(0x80, link->io.BasePort1 + 0xd);
900 outb(0x24, link->io.BasePort1 + 0x9);
901 outb(0x04, link->io.BasePort1 + 0xd);
902 }
903 /*
904 * If things don't work after a "resume",
905 * this is a good place to start looking.
906 */
907 SYM53C500_int_host_reset(link->io.BasePort1);
908 }
909
910 return 0;
911}
912
875static int 913static int
876SYM53C500_event(event_t event, int priority, event_callback_args_t *args) 914SYM53C500_event(event_t event, int priority, event_callback_args_t *args)
877{ 915{
878 dev_link_t *link = args->client_data; 916 dev_link_t *link = args->client_data;
879 struct scsi_info_t *info = link->priv;
880 917
881 DEBUG(1, "SYM53C500_event(0x%06x)\n", event); 918 DEBUG(1, "SYM53C500_event(0x%06x)\n", event);
882 919
@@ -890,34 +927,6 @@ SYM53C500_event(event_t event, int priority, event_callback_args_t *args)
890 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 927 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
891 SYM53C500_config(link); 928 SYM53C500_config(link);
892 break; 929 break;
893 case CS_EVENT_PM_SUSPEND:
894 link->state |= DEV_SUSPEND;
895 /* Fall through... */
896 case CS_EVENT_RESET_PHYSICAL:
897 if (link->state & DEV_CONFIG)
898 pcmcia_release_configuration(link->handle);
899 break;
900 case CS_EVENT_PM_RESUME:
901 link->state &= ~DEV_SUSPEND;
902 /* Fall through... */
903 case CS_EVENT_CARD_RESET:
904 if (link->state & DEV_CONFIG) {
905 pcmcia_request_configuration(link->handle, &link->conf);
906 /* See earlier comment about manufacturer IDs. */
907 if ((info->manf_id == MANFID_MACNICA) ||
908 (info->manf_id == MANFID_PIONEER) ||
909 (info->manf_id == 0x0098)) {
910 outb(0x80, link->io.BasePort1 + 0xd);
911 outb(0x24, link->io.BasePort1 + 0x9);
912 outb(0x04, link->io.BasePort1 + 0xd);
913 }
914 /*
915 * If things don't work after a "resume",
916 * this is a good place to start looking.
917 */
918 SYM53C500_int_host_reset(link->io.BasePort1);
919 }
920 break;
921 } 930 }
922 return 0; 931 return 0;
923} /* SYM53C500_event */ 932} /* SYM53C500_event */
@@ -1012,6 +1021,8 @@ static struct pcmcia_driver sym53c500_cs_driver = {
1012 .event = SYM53C500_event, 1021 .event = SYM53C500_event,
1013 .detach = SYM53C500_detach, 1022 .detach = SYM53C500_detach,
1014 .id_table = sym53c500_ids, 1023 .id_table = sym53c500_ids,
1024 .suspend = sym53c500_suspend,
1025 .resume = sym53c500_resume,
1015}; 1026};
1016 1027
1017static int __init 1028static int __init
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 7ce0c7e66d37..3487ee9eab1d 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -159,8 +159,9 @@ static void serial_remove(dev_link_t *link)
159 } 159 }
160} 160}
161 161
162static void serial_suspend(dev_link_t *link) 162static int serial_suspend(struct pcmcia_device *dev)
163{ 163{
164 dev_link_t *link = dev_to_instance(dev);
164 link->state |= DEV_SUSPEND; 165 link->state |= DEV_SUSPEND;
165 166
166 if (link->state & DEV_CONFIG) { 167 if (link->state & DEV_CONFIG) {
@@ -173,10 +174,13 @@ static void serial_suspend(dev_link_t *link)
173 if (!info->slave) 174 if (!info->slave)
174 pcmcia_release_configuration(link->handle); 175 pcmcia_release_configuration(link->handle);
175 } 176 }
177
178 return 0;
176} 179}
177 180
178static void serial_resume(dev_link_t *link) 181static int serial_resume(struct pcmcia_device *dev)
179{ 182{
183 dev_link_t *link = dev_to_instance(dev);
180 link->state &= ~DEV_SUSPEND; 184 link->state &= ~DEV_SUSPEND;
181 185
182 if (DEV_OK(link)) { 186 if (DEV_OK(link)) {
@@ -189,6 +193,8 @@ static void serial_resume(dev_link_t *link)
189 for (i = 0; i < info->ndev; i++) 193 for (i = 0; i < info->ndev; i++)
190 serial8250_resume_port(info->line[i]); 194 serial8250_resume_port(info->line[i]);
191 } 195 }
196
197 return 0;
192} 198}
193 199
194/*====================================================================== 200/*======================================================================
@@ -731,7 +737,6 @@ static int
731serial_event(event_t event, int priority, event_callback_args_t * args) 737serial_event(event_t event, int priority, event_callback_args_t * args)
732{ 738{
733 dev_link_t *link = args->client_data; 739 dev_link_t *link = args->client_data;
734 struct serial_info *info = link->priv;
735 740
736 DEBUG(1, "serial_event(0x%06x)\n", event); 741 DEBUG(1, "serial_event(0x%06x)\n", event);
737 742
@@ -744,24 +749,6 @@ serial_event(event_t event, int priority, event_callback_args_t * args)
744 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 749 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
745 serial_config(link); 750 serial_config(link);
746 break; 751 break;
747
748 case CS_EVENT_PM_SUSPEND:
749 serial_suspend(link);
750 break;
751
752 case CS_EVENT_RESET_PHYSICAL:
753 if ((link->state & DEV_CONFIG) && !info->slave)
754 pcmcia_release_configuration(link->handle);
755 break;
756
757 case CS_EVENT_PM_RESUME:
758 serial_resume(link);
759 break;
760
761 case CS_EVENT_CARD_RESET:
762 if (DEV_OK(link) && !info->slave)
763 pcmcia_request_configuration(link->handle, &link->conf);
764 break;
765 } 752 }
766 return 0; 753 return 0;
767} 754}
@@ -881,6 +868,8 @@ static struct pcmcia_driver serial_cs_driver = {
881 .event = serial_event, 868 .event = serial_event,
882 .detach = serial_detach, 869 .detach = serial_detach,
883 .id_table = serial_ids, 870 .id_table = serial_ids,
871 .suspend = serial_suspend,
872 .resume = serial_resume,
884}; 873};
885 874
886static int __init init_serial_cs(void) 875static int __init init_serial_cs(void)
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
index 57c0c6e3fbed..7cca46be0c0f 100644
--- a/drivers/telephony/ixj_pcmcia.c
+++ b/drivers/telephony/ixj_pcmcia.c
@@ -255,6 +255,28 @@ static void ixj_cs_release(dev_link_t *link)
255 link->state &= ~DEV_CONFIG; 255 link->state &= ~DEV_CONFIG;
256} 256}
257 257
258static int ixj_suspend(struct pcmcia_device *dev)
259{
260 dev_link_t *link = dev_to_instance(dev);
261
262 link->state |= DEV_SUSPEND;
263 if (link->state & DEV_CONFIG)
264 pcmcia_release_configuration(link->handle);
265
266 return 0;
267}
268
269static int ixj_resume(struct pcmcia_device *dev)
270{
271 dev_link_t *link = dev_to_instance(dev);
272
273 link->state &= ~DEV_SUSPEND;
274 if (DEV_OK(link))
275 pcmcia_request_configuration(link->handle, &link->conf);
276
277 return 0;
278}
279
258static int ixj_event(event_t event, int priority, event_callback_args_t * args) 280static int ixj_event(event_t event, int priority, event_callback_args_t * args)
259{ 281{
260 dev_link_t *link = args->client_data; 282 dev_link_t *link = args->client_data;
@@ -271,20 +293,6 @@ static int ixj_event(event_t event, int priority, event_callback_args_t * args)
271 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 293 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
272 ixj_config(link); 294 ixj_config(link);
273 break; 295 break;
274 case CS_EVENT_PM_SUSPEND:
275 link->state |= DEV_SUSPEND;
276 /* Fall through... */
277 case CS_EVENT_RESET_PHYSICAL:
278 if (link->state & DEV_CONFIG)
279 pcmcia_release_configuration(link->handle);
280 break;
281 case CS_EVENT_PM_RESUME:
282 link->state &= ~DEV_SUSPEND;
283 /* Fall through... */
284 case CS_EVENT_CARD_RESET:
285 if (DEV_OK(link))
286 pcmcia_request_configuration(link->handle, &link->conf);
287 break;
288 } 296 }
289 return 0; 297 return 0;
290} 298}
@@ -304,6 +312,8 @@ static struct pcmcia_driver ixj_driver = {
304 .event = ixj_event, 312 .event = ixj_event,
305 .detach = ixj_detach, 313 .detach = ixj_detach,
306 .id_table = ixj_ids, 314 .id_table = ixj_ids,
315 .suspend = ixj_suspend,
316 .resume = ixj_resume,
307}; 317};
308 318
309static int __init ixj_pcmcia_init(void) 319static int __init ixj_pcmcia_init(void)
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
index 5056b7459994..cb8c2bdbbd04 100644
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -323,6 +323,28 @@ cs_failed:
323 } 323 }
324} 324}
325 325
326static int sl811_suspend(struct pcmcia_device *dev)
327{
328 dev_link_t *link = dev_to_instance(dev);
329
330 link->state |= DEV_SUSPEND;
331 if (link->state & DEV_CONFIG)
332 pcmcia_release_configuration(link->handle);
333
334 return 0;
335}
336
337static int sl811_resume(struct pcmcia_device *dev)
338{
339 dev_link_t *link = dev_to_instance(dev);
340
341 link->state &= ~DEV_SUSPEND;
342 if (link->state & DEV_CONFIG)
343 pcmcia_request_configuration(link->handle, &link->conf);
344
345 return 0;
346}
347
326static int 348static int
327sl811_cs_event(event_t event, int priority, event_callback_args_t *args) 349sl811_cs_event(event_t event, int priority, event_callback_args_t *args)
328{ 350{
@@ -341,23 +363,6 @@ sl811_cs_event(event_t event, int priority, event_callback_args_t *args)
341 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 363 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
342 sl811_cs_config(link); 364 sl811_cs_config(link);
343 break; 365 break;
344
345 case CS_EVENT_PM_SUSPEND:
346 link->state |= DEV_SUSPEND;
347 /* Fall through... */
348 case CS_EVENT_RESET_PHYSICAL:
349 if (link->state & DEV_CONFIG)
350 pcmcia_release_configuration(link->handle);
351 break;
352
353 case CS_EVENT_PM_RESUME:
354 link->state &= ~DEV_SUSPEND;
355 /* Fall through... */
356 case CS_EVENT_CARD_RESET:
357 if (link->state & DEV_CONFIG)
358 pcmcia_request_configuration(link->handle, &link->conf);
359 DBG(0, "reset sl811-hcd here?\n");
360 break;
361 } 366 }
362 return 0; 367 return 0;
363} 368}
@@ -417,6 +422,8 @@ static struct pcmcia_driver sl811_cs_driver = {
417 .event = sl811_cs_event, 422 .event = sl811_cs_event,
418 .detach = sl811_cs_detach, 423 .detach = sl811_cs_detach,
419 .id_table = sl811_ids, 424 .id_table = sl811_ids,
425 .suspend = sl811_suspend,
426 .resume = sl811_resume,
420}; 427};
421 428
422/*====================================================================*/ 429/*====================================================================*/
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
index cb8b6e6ce66c..020055199008 100644
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -137,6 +137,10 @@ struct pcmcia_driver {
137 int (*event) (event_t event, int priority, 137 int (*event) (event_t event, int priority,
138 event_callback_args_t *); 138 event_callback_args_t *);
139 void (*detach)(dev_link_t *); 139 void (*detach)(dev_link_t *);
140
141 int (*suspend) (struct pcmcia_device *dev);
142 int (*resume) (struct pcmcia_device *dev);
143
140 struct module *owner; 144 struct module *owner;
141 struct pcmcia_device_id *id_table; 145 struct pcmcia_device_id *id_table;
142 struct device_driver drv; 146 struct device_driver drv;
@@ -193,6 +197,8 @@ struct pcmcia_device {
193#define handle_to_pdev(handle) (handle) 197#define handle_to_pdev(handle) (handle)
194#define handle_to_dev(handle) (handle->dev) 198#define handle_to_dev(handle) (handle->dev)
195 199
200#define dev_to_instance(dev) (dev->instance)
201
196/* error reporting */ 202/* error reporting */
197void cs_error(client_handle_t handle, int func, int ret); 203void cs_error(client_handle_t handle, int func, int ret);
198 204