aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/ds.c
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2006-01-05 18:02:03 -0500
committerDominik Brodowski <linux@dominikbrodowski.net>2006-01-05 18:02:03 -0500
commit8e9e793d68fcda6cc84c18cedf85ca0f91d801a8 (patch)
tree3dcceaaa676f1221e532e24106bb661143733eaf /drivers/pcmcia/ds.c
parent98e4c28b7ec390c2dad6a4c69d69629c0f7e8b10 (diff)
[PATCH] pcmcia: merge suspend into device model
Merge the suspend and resume methods for 16-bit PCMCIA cards into the device model -- for both runtime power management and suspend to ram/disk. Bugfix in ds.c by Richard Purdie Signed-Off-By: Richard Purdie <rpurdie@rpsys.net> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/pcmcia/ds.c')
-rw-r--r--drivers/pcmcia/ds.c94
1 files changed, 84 insertions, 10 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index a802c65c353..5223395b246 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -920,6 +920,78 @@ static struct device_attribute pcmcia_dev_attrs[] = {
920 __ATTR_NULL, 920 __ATTR_NULL,
921}; 921};
922 922
923/* PM support, also needed for reset */
924
925static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
926{
927 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
928 struct pcmcia_driver *p_drv = NULL;
929
930 if (dev->driver)
931 p_drv = to_pcmcia_drv(dev->driver);
932
933 if (p_drv && p_drv->suspend)
934 return p_drv->suspend(p_dev);
935
936 return 0;
937}
938
939
940static int pcmcia_dev_resume(struct device * dev)
941{
942 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
943 struct pcmcia_driver *p_drv = NULL;
944
945 if (dev->driver)
946 p_drv = to_pcmcia_drv(dev->driver);
947
948 if (p_drv && p_drv->resume)
949 return p_drv->resume(p_dev);
950
951 return 0;
952}
953
954
955static int pcmcia_bus_suspend_callback(struct device *dev, void * _data)
956{
957 struct pcmcia_socket *skt = _data;
958 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
959
960 if (p_dev->socket != skt)
961 return 0;
962
963 return dpm_runtime_suspend(dev, PMSG_SUSPEND);
964}
965
966static int pcmcia_bus_resume_callback(struct device *dev, void * _data)
967{
968 struct pcmcia_socket *skt = _data;
969 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
970
971 if (p_dev->socket != skt)
972 return 0;
973
974 dpm_runtime_resume(dev);
975
976 return 0;
977}
978
979static int pcmcia_bus_resume(struct pcmcia_socket *skt)
980{
981 bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback);
982 return 0;
983}
984
985static int pcmcia_bus_suspend(struct pcmcia_socket *skt)
986{
987 if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt,
988 pcmcia_bus_suspend_callback)) {
989 pcmcia_bus_resume(skt);
990 return -EIO;
991 }
992 return 0;
993}
994
923 995
924/*====================================================================== 996/*======================================================================
925 997
@@ -951,16 +1023,6 @@ static int send_event_callback(struct device *dev, void * _data)
951 if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE)) 1023 if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE))
952 return 0; 1024 return 0;
953 1025
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
964 if (p_drv->event) 1026 if (p_drv->event)
965 return p_drv->event(data->event, data->priority, 1027 return p_drv->event(data->event, data->priority,
966 &p_dev->event_callback_args); 1028 &p_dev->event_callback_args);
@@ -1012,6 +1074,13 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
1012 ret = send_event(skt, event, priority); 1074 ret = send_event(skt, event, priority);
1013 break; 1075 break;
1014 1076
1077 case CS_EVENT_PM_SUSPEND:
1078 case CS_EVENT_PM_RESUME:
1079 case CS_EVENT_RESET_PHYSICAL:
1080 case CS_EVENT_CARD_RESET:
1081 handle_event(skt, event);
1082 break;
1083
1015 default: 1084 default:
1016 handle_event(skt, event); 1085 handle_event(skt, event);
1017 send_event(skt, event, priority); 1086 send_event(skt, event, priority);
@@ -1166,10 +1235,13 @@ int pcmcia_deregister_client(struct pcmcia_device *p_dev)
1166} /* deregister_client */ 1235} /* deregister_client */
1167EXPORT_SYMBOL(pcmcia_deregister_client); 1236EXPORT_SYMBOL(pcmcia_deregister_client);
1168 1237
1238
1169static struct pcmcia_callback pcmcia_bus_callback = { 1239static struct pcmcia_callback pcmcia_bus_callback = {
1170 .owner = THIS_MODULE, 1240 .owner = THIS_MODULE,
1171 .event = ds_event, 1241 .event = ds_event,
1172 .requery = pcmcia_bus_rescan, 1242 .requery = pcmcia_bus_rescan,
1243 .suspend = pcmcia_bus_suspend,
1244 .resume = pcmcia_bus_resume,
1173}; 1245};
1174 1246
1175static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev, 1247static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev,
@@ -1238,6 +1310,8 @@ struct bus_type pcmcia_bus_type = {
1238 .uevent = pcmcia_bus_uevent, 1310 .uevent = pcmcia_bus_uevent,
1239 .match = pcmcia_bus_match, 1311 .match = pcmcia_bus_match,
1240 .dev_attrs = pcmcia_dev_attrs, 1312 .dev_attrs = pcmcia_dev_attrs,
1313 .suspend = pcmcia_dev_suspend,
1314 .resume = pcmcia_dev_resume,
1241}; 1315};
1242 1316
1243 1317