aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r--drivers/pcmcia/cs.c69
-rw-r--r--drivers/pcmcia/yenta_socket.c12
2 files changed, 54 insertions, 27 deletions
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index fc1c0c6baae2..790af87a922f 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -87,10 +87,13 @@ EXPORT_SYMBOL(pcmcia_socket_list_rwsem);
87 * These functions check for the appropriate struct pcmcia_soket arrays, 87 * These functions check for the appropriate struct pcmcia_soket arrays,
88 * and pass them to the low-level functions pcmcia_{suspend,resume}_socket 88 * and pass them to the low-level functions pcmcia_{suspend,resume}_socket
89 */ 89 */
90static int socket_early_resume(struct pcmcia_socket *skt);
91static int socket_late_resume(struct pcmcia_socket *skt);
90static int socket_resume(struct pcmcia_socket *skt); 92static int socket_resume(struct pcmcia_socket *skt);
91static int socket_suspend(struct pcmcia_socket *skt); 93static int socket_suspend(struct pcmcia_socket *skt);
92 94
93int pcmcia_socket_dev_suspend(struct device *dev) 95static void pcmcia_socket_dev_run(struct device *dev,
96 int (*cb)(struct pcmcia_socket *))
94{ 97{
95 struct pcmcia_socket *socket; 98 struct pcmcia_socket *socket;
96 99
@@ -99,29 +102,34 @@ int pcmcia_socket_dev_suspend(struct device *dev)
99 if (socket->dev.parent != dev) 102 if (socket->dev.parent != dev)
100 continue; 103 continue;
101 mutex_lock(&socket->skt_mutex); 104 mutex_lock(&socket->skt_mutex);
102 socket_suspend(socket); 105 cb(socket);
103 mutex_unlock(&socket->skt_mutex); 106 mutex_unlock(&socket->skt_mutex);
104 } 107 }
105 up_read(&pcmcia_socket_list_rwsem); 108 up_read(&pcmcia_socket_list_rwsem);
109}
106 110
111int pcmcia_socket_dev_suspend(struct device *dev)
112{
113 pcmcia_socket_dev_run(dev, socket_suspend);
107 return 0; 114 return 0;
108} 115}
109EXPORT_SYMBOL(pcmcia_socket_dev_suspend); 116EXPORT_SYMBOL(pcmcia_socket_dev_suspend);
110 117
111int pcmcia_socket_dev_resume(struct device *dev) 118void pcmcia_socket_dev_early_resume(struct device *dev)
112{ 119{
113 struct pcmcia_socket *socket; 120 pcmcia_socket_dev_run(dev, socket_early_resume);
121}
122EXPORT_SYMBOL(pcmcia_socket_dev_early_resume);
114 123
115 down_read(&pcmcia_socket_list_rwsem); 124void pcmcia_socket_dev_late_resume(struct device *dev)
116 list_for_each_entry(socket, &pcmcia_socket_list, socket_list) { 125{
117 if (socket->dev.parent != dev) 126 pcmcia_socket_dev_run(dev, socket_late_resume);
118 continue; 127}
119 mutex_lock(&socket->skt_mutex); 128EXPORT_SYMBOL(pcmcia_socket_dev_late_resume);
120 socket_resume(socket);
121 mutex_unlock(&socket->skt_mutex);
122 }
123 up_read(&pcmcia_socket_list_rwsem);
124 129
130int pcmcia_socket_dev_resume(struct device *dev)
131{
132 pcmcia_socket_dev_run(dev, socket_resume);
125 return 0; 133 return 0;
126} 134}
127EXPORT_SYMBOL(pcmcia_socket_dev_resume); 135EXPORT_SYMBOL(pcmcia_socket_dev_resume);
@@ -544,29 +552,24 @@ static int socket_suspend(struct pcmcia_socket *skt)
544 return 0; 552 return 0;
545} 553}
546 554
547/* 555static int socket_early_resume(struct pcmcia_socket *skt)
548 * Resume a socket. If a card is present, verify its CIS against
549 * our cached copy. If they are different, the card has been
550 * replaced, and we need to tell the drivers.
551 */
552static int socket_resume(struct pcmcia_socket *skt)
553{ 556{
554 int ret;
555
556 if (!(skt->state & SOCKET_SUSPEND))
557 return -EBUSY;
558
559 skt->socket = dead_socket; 557 skt->socket = dead_socket;
560 skt->ops->init(skt); 558 skt->ops->init(skt);
561 skt->ops->set_socket(skt, &skt->socket); 559 skt->ops->set_socket(skt, &skt->socket);
560 if (skt->state & SOCKET_PRESENT)
561 skt->resume_status = socket_setup(skt, resume_delay);
562 return 0;
563}
562 564
565static int socket_late_resume(struct pcmcia_socket *skt)
566{
563 if (!(skt->state & SOCKET_PRESENT)) { 567 if (!(skt->state & SOCKET_PRESENT)) {
564 skt->state &= ~SOCKET_SUSPEND; 568 skt->state &= ~SOCKET_SUSPEND;
565 return socket_insert(skt); 569 return socket_insert(skt);
566 } 570 }
567 571
568 ret = socket_setup(skt, resume_delay); 572 if (skt->resume_status == 0) {
569 if (ret == 0) {
570 /* 573 /*
571 * FIXME: need a better check here for cardbus cards. 574 * FIXME: need a better check here for cardbus cards.
572 */ 575 */
@@ -594,6 +597,20 @@ static int socket_resume(struct pcmcia_socket *skt)
594 return 0; 597 return 0;
595} 598}
596 599
600/*
601 * Resume a socket. If a card is present, verify its CIS against
602 * our cached copy. If they are different, the card has been
603 * replaced, and we need to tell the drivers.
604 */
605static int socket_resume(struct pcmcia_socket *skt)
606{
607 if (!(skt->state & SOCKET_SUSPEND))
608 return -EBUSY;
609
610 socket_early_resume(skt);
611 return socket_late_resume(skt);
612}
613
597static void socket_remove(struct pcmcia_socket *skt) 614static void socket_remove(struct pcmcia_socket *skt)
598{ 615{
599 dev_printk(KERN_NOTICE, &skt->dev, 616 dev_printk(KERN_NOTICE, &skt->dev,
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index abe0e44c6e9e..8be4cc447a17 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -1275,16 +1275,26 @@ static int yenta_dev_resume_noirq(struct device *dev)
1275 if (socket->type && socket->type->restore_state) 1275 if (socket->type && socket->type->restore_state)
1276 socket->type->restore_state(socket); 1276 socket->type->restore_state(socket);
1277 1277
1278 return pcmcia_socket_dev_resume(dev); 1278 pcmcia_socket_dev_early_resume(dev);
1279 return 0;
1280}
1281
1282static int yenta_dev_resume(struct device *dev)
1283{
1284 pcmcia_socket_dev_late_resume(dev);
1285 return 0;
1279} 1286}
1280 1287
1281static struct dev_pm_ops yenta_pm_ops = { 1288static struct dev_pm_ops yenta_pm_ops = {
1282 .suspend_noirq = yenta_dev_suspend_noirq, 1289 .suspend_noirq = yenta_dev_suspend_noirq,
1283 .resume_noirq = yenta_dev_resume_noirq, 1290 .resume_noirq = yenta_dev_resume_noirq,
1291 .resume = yenta_dev_resume,
1284 .freeze_noirq = yenta_dev_suspend_noirq, 1292 .freeze_noirq = yenta_dev_suspend_noirq,
1285 .thaw_noirq = yenta_dev_resume_noirq, 1293 .thaw_noirq = yenta_dev_resume_noirq,
1294 .thaw = yenta_dev_resume,
1286 .poweroff_noirq = yenta_dev_suspend_noirq, 1295 .poweroff_noirq = yenta_dev_suspend_noirq,
1287 .restore_noirq = yenta_dev_resume_noirq, 1296 .restore_noirq = yenta_dev_resume_noirq,
1297 .restore = yenta_dev_resume,
1288}; 1298};
1289 1299
1290#define YENTA_PM_OPS (&yenta_pm_ops) 1300#define YENTA_PM_OPS (&yenta_pm_ops)