@@ -40,15 +40,14 @@ struct rtsx_usb_ms {
40
40
41
41
struct mutex host_mutex ;
42
42
struct work_struct handle_req ;
43
-
44
- struct task_struct * detect_ms ;
45
- struct completion detect_ms_exit ;
43
+ struct delayed_work poll_card ;
46
44
47
45
u8 ssc_depth ;
48
46
unsigned int clock ;
49
47
int power_mode ;
50
48
unsigned char ifmode ;
51
49
bool eject ;
50
+ bool system_suspending ;
52
51
};
53
52
54
53
static inline struct device * ms_dev (struct rtsx_usb_ms * host )
@@ -545,7 +544,7 @@ static void rtsx_usb_ms_handle_req(struct work_struct *work)
545
544
host -> req -> error );
546
545
}
547
546
} while (!rc );
548
- pm_runtime_put (ms_dev (host ));
547
+ pm_runtime_put_sync (ms_dev (host ));
549
548
}
550
549
551
550
}
@@ -585,14 +584,14 @@ static int rtsx_usb_ms_set_param(struct memstick_host *msh,
585
584
break ;
586
585
587
586
if (value == MEMSTICK_POWER_ON ) {
588
- pm_runtime_get_sync (ms_dev (host ));
587
+ pm_runtime_get_noresume (ms_dev (host ));
589
588
err = ms_power_on (host );
589
+ if (err )
590
+ pm_runtime_put_noidle (ms_dev (host ));
590
591
} else if (value == MEMSTICK_POWER_OFF ) {
591
592
err = ms_power_off (host );
592
- if (host -> msh -> card )
593
+ if (! err )
593
594
pm_runtime_put_noidle (ms_dev (host ));
594
- else
595
- pm_runtime_put (ms_dev (host ));
596
595
} else
597
596
err = - EINVAL ;
598
597
if (!err )
@@ -638,12 +637,16 @@ static int rtsx_usb_ms_set_param(struct memstick_host *msh,
638
637
}
639
638
out :
640
639
mutex_unlock (& ucr -> dev_mutex );
641
- pm_runtime_put (ms_dev (host ));
640
+ pm_runtime_put_sync (ms_dev (host ));
642
641
643
642
/* power-on delay */
644
- if (param == MEMSTICK_POWER && value == MEMSTICK_POWER_ON )
643
+ if (param == MEMSTICK_POWER && value == MEMSTICK_POWER_ON ) {
645
644
usleep_range (10000 , 12000 );
646
645
646
+ if (!host -> eject )
647
+ schedule_delayed_work (& host -> poll_card , 100 );
648
+ }
649
+
647
650
dev_dbg (ms_dev (host ), "%s: return = %d\n" , __func__ , err );
648
651
return err ;
649
652
}
@@ -654,9 +657,24 @@ static int rtsx_usb_ms_suspend(struct device *dev)
654
657
struct rtsx_usb_ms * host = dev_get_drvdata (dev );
655
658
struct memstick_host * msh = host -> msh ;
656
659
657
- dev_dbg (ms_dev (host ), "--> %s\n" , __func__ );
660
+ /* Since we use rtsx_usb's resume callback to runtime resume its
661
+ * children to implement remote wakeup signaling, this causes
662
+ * rtsx_usb_ms' runtime resume callback runs after its suspend
663
+ * callback:
664
+ * rtsx_usb_ms_suspend()
665
+ * rtsx_usb_resume()
666
+ * -> rtsx_usb_ms_runtime_resume()
667
+ * -> memstick_detect_change()
668
+ *
669
+ * rtsx_usb_suspend()
670
+ *
671
+ * To avoid this, skip runtime resume/suspend if system suspend is
672
+ * underway.
673
+ */
658
674
675
+ host -> system_suspending = true;
659
676
memstick_suspend_host (msh );
677
+
660
678
return 0 ;
661
679
}
662
680
@@ -665,58 +683,85 @@ static int rtsx_usb_ms_resume(struct device *dev)
665
683
struct rtsx_usb_ms * host = dev_get_drvdata (dev );
666
684
struct memstick_host * msh = host -> msh ;
667
685
668
- dev_dbg (ms_dev (host ), "--> %s\n" , __func__ );
669
-
670
686
memstick_resume_host (msh );
687
+ host -> system_suspending = false;
688
+
671
689
return 0 ;
672
690
}
673
691
#endif /* CONFIG_PM_SLEEP */
674
692
675
- /*
676
- * Thread function of ms card slot detection. The thread starts right after
677
- * successful host addition. It stops while the driver removal function sets
678
- * host->eject true.
679
- */
680
- static int rtsx_usb_detect_ms_card (void * __host )
693
+ #ifdef CONFIG_PM
694
+ static int rtsx_usb_ms_runtime_suspend (struct device * dev )
695
+ {
696
+ struct rtsx_usb_ms * host = dev_get_drvdata (dev );
697
+
698
+ if (host -> system_suspending )
699
+ return 0 ;
700
+
701
+ if (host -> msh -> card || host -> power_mode != MEMSTICK_POWER_OFF )
702
+ return - EAGAIN ;
703
+
704
+ return 0 ;
705
+ }
706
+
707
+ static int rtsx_usb_ms_runtime_resume (struct device * dev )
708
+ {
709
+ struct rtsx_usb_ms * host = dev_get_drvdata (dev );
710
+
711
+
712
+ if (host -> system_suspending )
713
+ return 0 ;
714
+
715
+ memstick_detect_change (host -> msh );
716
+
717
+ return 0 ;
718
+ }
719
+ #endif /* CONFIG_PM */
720
+
721
+ static const struct dev_pm_ops rtsx_usb_ms_pm_ops = {
722
+ SET_SYSTEM_SLEEP_PM_OPS (rtsx_usb_ms_suspend , rtsx_usb_ms_resume )
723
+ SET_RUNTIME_PM_OPS (rtsx_usb_ms_runtime_suspend , rtsx_usb_ms_runtime_resume , NULL )
724
+ };
725
+
726
+
727
+ static void rtsx_usb_ms_poll_card (struct work_struct * work )
681
728
{
682
- struct rtsx_usb_ms * host = (struct rtsx_usb_ms * )__host ;
729
+ struct rtsx_usb_ms * host = container_of (work , struct rtsx_usb_ms ,
730
+ poll_card .work );
683
731
struct rtsx_ucr * ucr = host -> ucr ;
684
- u8 val = 0 ;
685
732
int err ;
733
+ u8 val ;
686
734
687
- for (;;) {
688
- pm_runtime_get_sync (ms_dev (host ));
689
- mutex_lock (& ucr -> dev_mutex );
690
-
691
- /* Check pending MS card changes */
692
- err = rtsx_usb_read_register (ucr , CARD_INT_PEND , & val );
693
- if (err ) {
694
- mutex_unlock (& ucr -> dev_mutex );
695
- goto poll_again ;
696
- }
735
+ if (host -> eject || host -> power_mode != MEMSTICK_POWER_ON )
736
+ return ;
697
737
698
- /* Clear the pending */
699
- rtsx_usb_write_register (ucr , CARD_INT_PEND ,
700
- XD_INT | MS_INT | SD_INT ,
701
- XD_INT | MS_INT | SD_INT );
738
+ pm_runtime_get_sync (ms_dev (host ));
739
+ mutex_lock (& ucr -> dev_mutex );
702
740
741
+ /* Check pending MS card changes */
742
+ err = rtsx_usb_read_register (ucr , CARD_INT_PEND , & val );
743
+ if (err ) {
703
744
mutex_unlock (& ucr -> dev_mutex );
745
+ goto poll_again ;
746
+ }
704
747
705
- if ( val & MS_INT ) {
706
- dev_dbg ( ms_dev ( host ), "MS slot change detected\n" );
707
- memstick_detect_change ( host -> msh );
708
- }
748
+ /* Clear the pending */
749
+ rtsx_usb_write_register ( ucr , CARD_INT_PEND ,
750
+ XD_INT | MS_INT | SD_INT ,
751
+ XD_INT | MS_INT | SD_INT );
709
752
710
- poll_again :
711
- pm_runtime_put (ms_dev (host ));
712
- if (host -> eject )
713
- break ;
753
+ mutex_unlock (& ucr -> dev_mutex );
714
754
715
- schedule_timeout_idle (HZ );
755
+ if (val & MS_INT ) {
756
+ dev_dbg (ms_dev (host ), "MS slot change detected\n" );
757
+ memstick_detect_change (host -> msh );
716
758
}
717
759
718
- complete (& host -> detect_ms_exit );
719
- return 0 ;
760
+ poll_again :
761
+ pm_runtime_put_sync (ms_dev (host ));
762
+
763
+ if (!host -> eject && host -> power_mode == MEMSTICK_POWER_ON )
764
+ schedule_delayed_work (& host -> poll_card , 100 );
720
765
}
721
766
722
767
static int rtsx_usb_ms_drv_probe (struct platform_device * pdev )
@@ -747,40 +792,36 @@ static int rtsx_usb_ms_drv_probe(struct platform_device *pdev)
747
792
mutex_init (& host -> host_mutex );
748
793
INIT_WORK (& host -> handle_req , rtsx_usb_ms_handle_req );
749
794
750
- init_completion (& host -> detect_ms_exit );
751
- host -> detect_ms = kthread_create (rtsx_usb_detect_ms_card , host ,
752
- "rtsx_usb_ms_%d" , pdev -> id );
753
- if (IS_ERR (host -> detect_ms )) {
754
- dev_dbg (& (pdev -> dev ),
755
- "Unable to create polling thread.\n" );
756
- err = PTR_ERR (host -> detect_ms );
757
- goto err_out ;
758
- }
795
+ INIT_DELAYED_WORK (& host -> poll_card , rtsx_usb_ms_poll_card );
759
796
760
797
msh -> request = rtsx_usb_ms_request ;
761
798
msh -> set_param = rtsx_usb_ms_set_param ;
762
799
msh -> caps = MEMSTICK_CAP_PAR4 ;
763
800
764
- pm_runtime_enable (& pdev -> dev );
801
+ pm_runtime_get_noresume (ms_dev (host ));
802
+ pm_runtime_set_active (ms_dev (host ));
803
+ pm_runtime_enable (ms_dev (host ));
804
+
765
805
err = memstick_add_host (msh );
766
806
if (err )
767
807
goto err_out ;
768
808
769
- wake_up_process (host -> detect_ms );
809
+ pm_runtime_put (ms_dev (host ));
810
+
770
811
return 0 ;
771
812
err_out :
772
813
memstick_free_host (msh );
773
814
pm_runtime_disable (ms_dev (host ));
815
+ pm_runtime_put_noidle (ms_dev (host ));
774
816
return err ;
775
817
}
776
818
777
819
static int rtsx_usb_ms_drv_remove (struct platform_device * pdev )
778
820
{
779
821
struct rtsx_usb_ms * host = platform_get_drvdata (pdev );
780
- struct memstick_host * msh ;
822
+ struct memstick_host * msh = host -> msh ;
781
823
int err ;
782
824
783
- msh = host -> msh ;
784
825
host -> eject = true;
785
826
cancel_work_sync (& host -> handle_req );
786
827
@@ -798,7 +839,6 @@ static int rtsx_usb_ms_drv_remove(struct platform_device *pdev)
798
839
}
799
840
mutex_unlock (& host -> host_mutex );
800
841
801
- wait_for_completion (& host -> detect_ms_exit );
802
842
memstick_remove_host (msh );
803
843
memstick_free_host (msh );
804
844
@@ -817,9 +857,6 @@ static int rtsx_usb_ms_drv_remove(struct platform_device *pdev)
817
857
return 0 ;
818
858
}
819
859
820
- static SIMPLE_DEV_PM_OPS (rtsx_usb_ms_pm_ops ,
821
- rtsx_usb_ms_suspend , rtsx_usb_ms_resume ) ;
822
-
823
860
static struct platform_device_id rtsx_usb_ms_ids [] = {
824
861
{
825
862
.name = "rtsx_usb_ms" ,
0 commit comments