aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia/cs.c')
-rw-r--r--drivers/pcmcia/cs.c69
1 files changed, 43 insertions, 26 deletions
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index 934d4bee39a0..698d75cda084 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -98,10 +98,13 @@ EXPORT_SYMBOL(pcmcia_socket_list_rwsem);
98 * These functions check for the appropriate struct pcmcia_soket arrays, 98 * These functions check for the appropriate struct pcmcia_soket arrays,
99 * and pass them to the low-level functions pcmcia_{suspend,resume}_socket 99 * and pass them to the low-level functions pcmcia_{suspend,resume}_socket
100 */ 100 */
101static int socket_early_resume(struct pcmcia_socket *skt);
102static int socket_late_resume(struct pcmcia_socket *skt);
101static int socket_resume(struct pcmcia_socket *skt); 103static int socket_resume(struct pcmcia_socket *skt);
102static int socket_suspend(struct pcmcia_socket *skt); 104static int socket_suspend(struct pcmcia_socket *skt);
103 105
104int pcmcia_socket_dev_suspend(struct device *dev) 106static void pcmcia_socket_dev_run(struct device *dev,
107 int (*cb)(struct pcmcia_socket *))
105{ 108{
106 struct pcmcia_socket *socket; 109 struct pcmcia_socket *socket;
107 110
@@ -110,29 +113,34 @@ int pcmcia_socket_dev_suspend(struct device *dev)
110 if (socket->dev.parent != dev) 113 if (socket->dev.parent != dev)
111 continue; 114 continue;
112 mutex_lock(&socket->skt_mutex); 115 mutex_lock(&socket->skt_mutex);
113 socket_suspend(socket); 116 cb(socket);
114 mutex_unlock(&socket->skt_mutex); 117 mutex_unlock(&socket->skt_mutex);
115 } 118 }
116 up_read(&pcmcia_socket_list_rwsem); 119 up_read(&pcmcia_socket_list_rwsem);
120}
117 121
122int pcmcia_socket_dev_suspend(struct device *dev)
123{
124 pcmcia_socket_dev_run(dev, socket_suspend);
118 return 0; 125 return 0;
119} 126}
120EXPORT_SYMBOL(pcmcia_socket_dev_suspend); 127EXPORT_SYMBOL(pcmcia_socket_dev_suspend);
121 128
122int pcmcia_socket_dev_resume(struct device *dev) 129void pcmcia_socket_dev_early_resume(struct device *dev)
123{ 130{
124 struct pcmcia_socket *socket; 131 pcmcia_socket_dev_run(dev, socket_early_resume);
132}
133EXPORT_SYMBOL(pcmcia_socket_dev_early_resume);
125 134
126 down_read(&pcmcia_socket_list_rwsem); 135void pcmcia_socket_dev_late_resume(struct device *dev)
127 list_for_each_entry(socket, &pcmcia_socket_list, socket_list) { 136{
128 if (socket->dev.parent != dev) 137 pcmcia_socket_dev_run(dev, socket_late_resume);
129 continue; 138}
130 mutex_lock(&socket->skt_mutex); 139EXPORT_SYMBOL(pcmcia_socket_dev_late_resume);
131 socket_resume(socket);
132 mutex_unlock(&socket->skt_mutex);
133 }
134 up_read(&pcmcia_socket_list_rwsem);
135 140
141int pcmcia_socket_dev_resume(struct device *dev)
142{
143 pcmcia_socket_dev_run(dev, socket_resume);
136 return 0; 144 return 0;
137} 145}
138EXPORT_SYMBOL(pcmcia_socket_dev_resume); 146EXPORT_SYMBOL(pcmcia_socket_dev_resume);
@@ -546,29 +554,24 @@ static int socket_suspend(struct pcmcia_socket *skt)
546 return 0; 554 return 0;
547} 555}
548 556
549/* 557static int socket_early_resume(struct pcmcia_socket *skt)
550 * Resume a socket. If a card is present, verify its CIS against
551 * our cached copy. If they are different, the card has been
552 * replaced, and we need to tell the drivers.
553 */
554static int socket_resume(struct pcmcia_socket *skt)
555{ 558{
556 int ret;
557
558 if (!(skt->state & SOCKET_SUSPEND))
559 return -EBUSY;
560
561 skt->socket = dead_socket; 559 skt->socket = dead_socket;
562 skt->ops->init(skt); 560 skt->ops->init(skt);
563 skt->ops->set_socket(skt, &skt->socket); 561 skt->ops->set_socket(skt, &skt->socket);
562 if (skt->state & SOCKET_PRESENT)
563 skt->resume_status = socket_setup(skt, resume_delay);
564 return 0;
565}
564 566
567static int socket_late_resume(struct pcmcia_socket *skt)
568{
565 if (!(skt->state & SOCKET_PRESENT)) { 569 if (!(skt->state & SOCKET_PRESENT)) {
566 skt->state &= ~SOCKET_SUSPEND; 570 skt->state &= ~SOCKET_SUSPEND;
567 return socket_insert(skt); 571 return socket_insert(skt);
568 } 572 }
569 573
570 ret = socket_setup(skt, resume_delay); 574 if (skt->resume_status == 0) {
571 if (ret == 0) {
572 /* 575 /*
573 * FIXME: need a better check here for cardbus cards. 576 * FIXME: need a better check here for cardbus cards.
574 */ 577 */
@@ -596,6 +599,20 @@ static int socket_resume(struct pcmcia_socket *skt)
596 return 0; 599 return 0;
597} 600}
598 601
602/*
603 * Resume a socket. If a card is present, verify its CIS against
604 * our cached copy. If they are different, the card has been
605 * replaced, and we need to tell the drivers.
606 */
607static int socket_resume(struct pcmcia_socket *skt)
608{
609 if (!(skt->state & SOCKET_SUSPEND))
610 return -EBUSY;
611
612 socket_early_resume(skt);
613 return socket_late_resume(skt);
614}
615
599static void socket_remove(struct pcmcia_socket *skt) 616static void socket_remove(struct pcmcia_socket *skt)
600{ 617{
601 dev_printk(KERN_NOTICE, &skt->dev, 618 dev_printk(KERN_NOTICE, &skt->dev,