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.c37
1 files changed, 30 insertions, 7 deletions
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index 673c14ea11e3..5292db69c426 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -484,7 +484,7 @@ static int socket_early_resume(struct pcmcia_socket *skt)
484 484
485static int socket_late_resume(struct pcmcia_socket *skt) 485static int socket_late_resume(struct pcmcia_socket *skt)
486{ 486{
487 int ret; 487 int ret = 0;
488 488
489 mutex_lock(&skt->ops_mutex); 489 mutex_lock(&skt->ops_mutex);
490 skt->state &= ~SOCKET_SUSPEND; 490 skt->state &= ~SOCKET_SUSPEND;
@@ -511,19 +511,31 @@ static int socket_late_resume(struct pcmcia_socket *skt)
511 return socket_insert(skt); 511 return socket_insert(skt);
512 } 512 }
513 513
514 if (!(skt->state & SOCKET_CARDBUS) && (skt->callback))
515 ret = skt->callback->early_resume(skt);
516 return ret;
517}
518
519/*
520 * Finalize the resume. In case of a cardbus socket, we have
521 * to rebind the devices as we can't be certain that it has been
522 * replaced, or not.
523 */
524static int socket_complete_resume(struct pcmcia_socket *skt)
525{
526 int ret = 0;
514#ifdef CONFIG_CARDBUS 527#ifdef CONFIG_CARDBUS
515 if (skt->state & SOCKET_CARDBUS) { 528 if (skt->state & SOCKET_CARDBUS) {
516 /* We can't be sure the CardBus card is the same 529 /* We can't be sure the CardBus card is the same
517 * as the one previously inserted. Therefore, remove 530 * as the one previously inserted. Therefore, remove
518 * and re-add... */ 531 * and re-add... */
519 cb_free(skt); 532 cb_free(skt);
520 cb_alloc(skt); 533 ret = cb_alloc(skt);
521 return 0; 534 if (ret)
535 cb_free(skt);
522 } 536 }
523#endif 537#endif
524 if (!(skt->state & SOCKET_CARDBUS) && (skt->callback)) 538 return ret;
525 skt->callback->early_resume(skt);
526 return 0;
527} 539}
528 540
529/* 541/*
@@ -533,11 +545,15 @@ static int socket_late_resume(struct pcmcia_socket *skt)
533 */ 545 */
534static int socket_resume(struct pcmcia_socket *skt) 546static int socket_resume(struct pcmcia_socket *skt)
535{ 547{
548 int err;
536 if (!(skt->state & SOCKET_SUSPEND)) 549 if (!(skt->state & SOCKET_SUSPEND))
537 return -EBUSY; 550 return -EBUSY;
538 551
539 socket_early_resume(skt); 552 socket_early_resume(skt);
540 return socket_late_resume(skt); 553 err = socket_late_resume(skt);
554 if (!err)
555 err = socket_complete_resume(skt);
556 return err;
541} 557}
542 558
543static void socket_remove(struct pcmcia_socket *skt) 559static void socket_remove(struct pcmcia_socket *skt)
@@ -848,6 +864,12 @@ static int __used pcmcia_socket_dev_resume(struct device *dev)
848 return __pcmcia_pm_op(dev, socket_late_resume); 864 return __pcmcia_pm_op(dev, socket_late_resume);
849} 865}
850 866
867static void __used pcmcia_socket_dev_complete(struct device *dev)
868{
869 WARN(__pcmcia_pm_op(dev, socket_complete_resume),
870 "failed to complete resume");
871}
872
851static const struct dev_pm_ops pcmcia_socket_pm_ops = { 873static const struct dev_pm_ops pcmcia_socket_pm_ops = {
852 /* dev_resume may be called with IRQs enabled */ 874 /* dev_resume may be called with IRQs enabled */
853 SET_SYSTEM_SLEEP_PM_OPS(NULL, 875 SET_SYSTEM_SLEEP_PM_OPS(NULL,
@@ -862,6 +884,7 @@ static const struct dev_pm_ops pcmcia_socket_pm_ops = {
862 .resume_noirq = pcmcia_socket_dev_resume_noirq, 884 .resume_noirq = pcmcia_socket_dev_resume_noirq,
863 .thaw_noirq = pcmcia_socket_dev_resume_noirq, 885 .thaw_noirq = pcmcia_socket_dev_resume_noirq,
864 .restore_noirq = pcmcia_socket_dev_resume_noirq, 886 .restore_noirq = pcmcia_socket_dev_resume_noirq,
887 .complete = pcmcia_socket_dev_complete,
865}; 888};
866 889
867#define PCMCIA_SOCKET_CLASS_PM_OPS (&pcmcia_socket_pm_ops) 890#define PCMCIA_SOCKET_CLASS_PM_OPS (&pcmcia_socket_pm_ops)