@@ -40,15 +40,14 @@ struct rtsx_usb_ms {
4040
4141 struct mutex host_mutex ;
4242 struct work_struct handle_req ;
43-
44- struct task_struct * detect_ms ;
45- struct completion detect_ms_exit ;
43+ struct delayed_work poll_card ;
4644
4745 u8 ssc_depth ;
4846 unsigned int clock ;
4947 int power_mode ;
5048 unsigned char ifmode ;
5149 bool eject ;
50+ bool system_suspending ;
5251};
5352
5453static 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)
545544 host -> req -> error );
546545 }
547546 } while (!rc );
548- pm_runtime_put (ms_dev (host ));
547+ pm_runtime_put_sync (ms_dev (host ));
549548 }
550549
551550}
@@ -585,14 +584,14 @@ static int rtsx_usb_ms_set_param(struct memstick_host *msh,
585584 break ;
586585
587586 if (value == MEMSTICK_POWER_ON ) {
588- pm_runtime_get_sync (ms_dev (host ));
587+ pm_runtime_get_noresume (ms_dev (host ));
589588 err = ms_power_on (host );
589+ if (err )
590+ pm_runtime_put_noidle (ms_dev (host ));
590591 } else if (value == MEMSTICK_POWER_OFF ) {
591592 err = ms_power_off (host );
592- if (host -> msh -> card )
593+ if (! err )
593594 pm_runtime_put_noidle (ms_dev (host ));
594- else
595- pm_runtime_put (ms_dev (host ));
596595 } else
597596 err = - EINVAL ;
598597 if (!err )
@@ -638,12 +637,16 @@ static int rtsx_usb_ms_set_param(struct memstick_host *msh,
638637 }
639638out :
640639 mutex_unlock (& ucr -> dev_mutex );
641- pm_runtime_put (ms_dev (host ));
640+ pm_runtime_put_sync (ms_dev (host ));
642641
643642 /* power-on delay */
644- if (param == MEMSTICK_POWER && value == MEMSTICK_POWER_ON )
643+ if (param == MEMSTICK_POWER && value == MEMSTICK_POWER_ON ) {
645644 usleep_range (10000 , 12000 );
646645
646+ if (!host -> eject )
647+ schedule_delayed_work (& host -> poll_card , 100 );
648+ }
649+
647650 dev_dbg (ms_dev (host ), "%s: return = %d\n" , __func__ , err );
648651 return err ;
649652}
@@ -654,9 +657,24 @@ static int rtsx_usb_ms_suspend(struct device *dev)
654657 struct rtsx_usb_ms * host = dev_get_drvdata (dev );
655658 struct memstick_host * msh = host -> msh ;
656659
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+ */
658674
675+ host -> system_suspending = true;
659676 memstick_suspend_host (msh );
677+
660678 return 0 ;
661679}
662680
@@ -665,58 +683,85 @@ static int rtsx_usb_ms_resume(struct device *dev)
665683 struct rtsx_usb_ms * host = dev_get_drvdata (dev );
666684 struct memstick_host * msh = host -> msh ;
667685
668- dev_dbg (ms_dev (host ), "--> %s\n" , __func__ );
669-
670686 memstick_resume_host (msh );
687+ host -> system_suspending = false;
688+
671689 return 0 ;
672690}
673691#endif /* CONFIG_PM_SLEEP */
674692
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 )
681728{
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 );
683731 struct rtsx_ucr * ucr = host -> ucr ;
684- u8 val = 0 ;
685732 int err ;
733+ u8 val ;
686734
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 ;
697737
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 );
702740
741+ /* Check pending MS card changes */
742+ err = rtsx_usb_read_register (ucr , CARD_INT_PEND , & val );
743+ if (err ) {
703744 mutex_unlock (& ucr -> dev_mutex );
745+ goto poll_again ;
746+ }
704747
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 );
709752
710- poll_again :
711- pm_runtime_put (ms_dev (host ));
712- if (host -> eject )
713- break ;
753+ mutex_unlock (& ucr -> dev_mutex );
714754
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 );
716758 }
717759
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 );
720765}
721766
722767static 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)
747792 mutex_init (& host -> host_mutex );
748793 INIT_WORK (& host -> handle_req , rtsx_usb_ms_handle_req );
749794
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 );
759796
760797 msh -> request = rtsx_usb_ms_request ;
761798 msh -> set_param = rtsx_usb_ms_set_param ;
762799 msh -> caps = MEMSTICK_CAP_PAR4 ;
763800
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+
765805 err = memstick_add_host (msh );
766806 if (err )
767807 goto err_out ;
768808
769- wake_up_process (host -> detect_ms );
809+ pm_runtime_put (ms_dev (host ));
810+
770811 return 0 ;
771812err_out :
772813 memstick_free_host (msh );
773814 pm_runtime_disable (ms_dev (host ));
815+ pm_runtime_put_noidle (ms_dev (host ));
774816 return err ;
775817}
776818
777819static int rtsx_usb_ms_drv_remove (struct platform_device * pdev )
778820{
779821 struct rtsx_usb_ms * host = platform_get_drvdata (pdev );
780- struct memstick_host * msh ;
822+ struct memstick_host * msh = host -> msh ;
781823 int err ;
782824
783- msh = host -> msh ;
784825 host -> eject = true;
785826 cancel_work_sync (& host -> handle_req );
786827
@@ -798,7 +839,6 @@ static int rtsx_usb_ms_drv_remove(struct platform_device *pdev)
798839 }
799840 mutex_unlock (& host -> host_mutex );
800841
801- wait_for_completion (& host -> detect_ms_exit );
802842 memstick_remove_host (msh );
803843 memstick_free_host (msh );
804844
@@ -817,9 +857,6 @@ static int rtsx_usb_ms_drv_remove(struct platform_device *pdev)
817857 return 0 ;
818858}
819859
820- static SIMPLE_DEV_PM_OPS (rtsx_usb_ms_pm_ops ,
821- rtsx_usb_ms_suspend , rtsx_usb_ms_resume ) ;
822-
823860static struct platform_device_id rtsx_usb_ms_ids [] = {
824861 {
825862 .name = "rtsx_usb_ms" ,
0 commit comments