diff options
-rw-r--r-- | drivers/usb/storage/Kconfig | 4 | ||||
-rw-r--r-- | drivers/usb/storage/realtek_cr.c | 377 |
2 files changed, 369 insertions, 12 deletions
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index 97987255be75..58aabe679c32 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig | |||
@@ -40,6 +40,10 @@ config USB_STORAGE_REALTEK | |||
40 | 40 | ||
41 | If this driver is compiled as a module, it will be named ums-realtek. | 41 | If this driver is compiled as a module, it will be named ums-realtek. |
42 | 42 | ||
43 | config REALTEK_AUTOPM | ||
44 | bool "Realtek Card Reader autosuspend support" | ||
45 | depends on USB_STORAGE_REALTEK && CONFIG_PM_RUNTIME | ||
46 | default y | ||
43 | 47 | ||
44 | config USB_STORAGE_DATAFAB | 48 | config USB_STORAGE_DATAFAB |
45 | tristate "Datafab Compact Flash Reader support" | 49 | tristate "Datafab Compact Flash Reader support" |
diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c index 2ea0da23306a..34adc4b42ceb 100644 --- a/drivers/usb/storage/realtek_cr.c +++ b/drivers/usb/storage/realtek_cr.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/blkdev.h> | 24 | #include <linux/blkdev.h> |
25 | #include <linux/kthread.h> | 25 | #include <linux/kthread.h> |
26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
27 | #include <linux/workqueue.h> | ||
28 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
29 | #include <linux/version.h> | 28 | #include <linux/version.h> |
30 | 29 | ||
@@ -51,6 +50,35 @@ static int auto_delink_en = 1; | |||
51 | module_param(auto_delink_en, int, S_IRUGO | S_IWUSR); | 50 | module_param(auto_delink_en, int, S_IRUGO | S_IWUSR); |
52 | MODULE_PARM_DESC(auto_delink_en, "enable auto delink"); | 51 | MODULE_PARM_DESC(auto_delink_en, "enable auto delink"); |
53 | 52 | ||
53 | #ifdef CONFIG_REALTEK_AUTOPM | ||
54 | static int ss_en = 1; | ||
55 | module_param(ss_en, int, S_IRUGO | S_IWUSR); | ||
56 | MODULE_PARM_DESC(ss_en, "enable selective suspend"); | ||
57 | |||
58 | static int ss_delay = 50; | ||
59 | module_param(ss_delay, int, S_IRUGO | S_IWUSR); | ||
60 | MODULE_PARM_DESC(ss_delay, | ||
61 | "seconds to delay before entering selective suspend"); | ||
62 | |||
63 | enum RTS51X_STAT { | ||
64 | RTS51X_STAT_INIT, | ||
65 | RTS51X_STAT_IDLE, | ||
66 | RTS51X_STAT_RUN, | ||
67 | RTS51X_STAT_SS | ||
68 | }; | ||
69 | |||
70 | #define POLLING_INTERVAL 50 | ||
71 | |||
72 | #define rts51x_set_stat(chip, stat) \ | ||
73 | ((chip)->state = (enum RTS51X_STAT)(stat)) | ||
74 | #define rts51x_get_stat(chip) ((chip)->state) | ||
75 | |||
76 | #define SET_LUN_READY(chip, lun) ((chip)->lun_ready |= ((u8)1 << (lun))) | ||
77 | #define CLR_LUN_READY(chip, lun) ((chip)->lun_ready &= ~((u8)1 << (lun))) | ||
78 | #define TST_LUN_READY(chip, lun) ((chip)->lun_ready & ((u8)1 << (lun))) | ||
79 | |||
80 | #endif | ||
81 | |||
54 | struct rts51x_status { | 82 | struct rts51x_status { |
55 | u16 vid; | 83 | u16 vid; |
56 | u16 pid; | 84 | u16 pid; |
@@ -77,7 +105,18 @@ struct rts51x_chip { | |||
77 | struct rts51x_status *status; | 105 | struct rts51x_status *status; |
78 | int status_len; | 106 | int status_len; |
79 | 107 | ||
80 | u32 flag; | 108 | u32 flag; |
109 | #ifdef CONFIG_REALTEK_AUTOPM | ||
110 | struct us_data *us; | ||
111 | struct timer_list rts51x_suspend_timer; | ||
112 | unsigned long timer_expires; | ||
113 | int pwr_state; | ||
114 | u8 lun_ready; | ||
115 | enum RTS51X_STAT state; | ||
116 | int support_auto_delink; | ||
117 | #endif | ||
118 | /* used to back up the protocal choosen in probe1 phase */ | ||
119 | proto_cmnd proto_handler_backup; | ||
81 | }; | 120 | }; |
82 | 121 | ||
83 | /* flag definition */ | 122 | /* flag definition */ |
@@ -97,9 +136,14 @@ struct rts51x_chip { | |||
97 | #define RTS51X_GET_VID(chip) ((chip)->vendor_id) | 136 | #define RTS51X_GET_VID(chip) ((chip)->vendor_id) |
98 | #define RTS51X_GET_PID(chip) ((chip)->product_id) | 137 | #define RTS51X_GET_PID(chip) ((chip)->product_id) |
99 | 138 | ||
139 | #define VENDOR_ID(chip) ((chip)->status[0].vid) | ||
140 | #define PRODUCT_ID(chip) ((chip)->status[0].pid) | ||
100 | #define FW_VERSION(chip) ((chip)->status[0].fw_ver) | 141 | #define FW_VERSION(chip) ((chip)->status[0].fw_ver) |
101 | #define STATUS_LEN(chip) ((chip)->status_len) | 142 | #define STATUS_LEN(chip) ((chip)->status_len) |
102 | 143 | ||
144 | #define STATUS_SUCCESS 0 | ||
145 | #define STATUS_FAIL 1 | ||
146 | |||
103 | /* Check card reader function */ | 147 | /* Check card reader function */ |
104 | #define SUPPORT_DETAILED_TYPE1(chip) \ | 148 | #define SUPPORT_DETAILED_TYPE1(chip) \ |
105 | CHK_BIT((chip)->status[0].function[0], 1) | 149 | CHK_BIT((chip)->status[0].function[0], 1) |
@@ -423,6 +467,8 @@ static int config_autodelink_after_power_on(struct us_data *us) | |||
423 | int retval; | 467 | int retval; |
424 | u8 value; | 468 | u8 value; |
425 | 469 | ||
470 | US_DEBUGP("%s: <---\n", __func__); | ||
471 | |||
426 | if (!CHK_AUTO_DELINK(chip)) | 472 | if (!CHK_AUTO_DELINK(chip)) |
427 | return 0; | 473 | return 0; |
428 | 474 | ||
@@ -478,6 +524,8 @@ static int config_autodelink_after_power_on(struct us_data *us) | |||
478 | } | 524 | } |
479 | } | 525 | } |
480 | 526 | ||
527 | US_DEBUGP("%s: --->\n", __func__); | ||
528 | |||
481 | return 0; | 529 | return 0; |
482 | } | 530 | } |
483 | 531 | ||
@@ -487,6 +535,8 @@ static int config_autodelink_before_power_down(struct us_data *us) | |||
487 | int retval; | 535 | int retval; |
488 | u8 value; | 536 | u8 value; |
489 | 537 | ||
538 | US_DEBUGP("%s: <---\n", __func__); | ||
539 | |||
490 | if (!CHK_AUTO_DELINK(chip)) | 540 | if (!CHK_AUTO_DELINK(chip)) |
491 | return 0; | 541 | return 0; |
492 | 542 | ||
@@ -547,25 +597,323 @@ static int config_autodelink_before_power_down(struct us_data *us) | |||
547 | } | 597 | } |
548 | } | 598 | } |
549 | 599 | ||
600 | US_DEBUGP("%s: --->\n", __func__); | ||
601 | |||
602 | return 0; | ||
603 | } | ||
604 | |||
605 | static void fw5895_init(struct us_data *us) | ||
606 | { | ||
607 | struct rts51x_chip *chip = (struct rts51x_chip *)(us->extra); | ||
608 | int retval; | ||
609 | u8 val; | ||
610 | |||
611 | US_DEBUGP("%s: <---\n", __func__); | ||
612 | |||
613 | if ((PRODUCT_ID(chip) != 0x0158) || (FW_VERSION(chip) != 0x5895)) { | ||
614 | US_DEBUGP("Not the specified device, return immediately!\n"); | ||
615 | } else { | ||
616 | retval = rts51x_read_mem(us, 0xFD6F, &val, 1); | ||
617 | if (retval == STATUS_SUCCESS && (val & 0x1F) == 0) { | ||
618 | val = 0x1F; | ||
619 | retval = rts51x_write_mem(us, 0xFD70, &val, 1); | ||
620 | if (retval != STATUS_SUCCESS) | ||
621 | US_DEBUGP("Write memory fail\n"); | ||
622 | } else { | ||
623 | US_DEBUGP("Read memory fail, OR (val & 0x1F) != 0\n"); | ||
624 | } | ||
625 | } | ||
626 | |||
627 | US_DEBUGP("%s: --->\n", __func__); | ||
628 | } | ||
629 | |||
630 | #ifdef CONFIG_REALTEK_AUTOPM | ||
631 | static void fw5895_set_mmc_wp(struct us_data *us) | ||
632 | { | ||
633 | struct rts51x_chip *chip = (struct rts51x_chip *)(us->extra); | ||
634 | int retval; | ||
635 | u8 buf[13]; | ||
636 | |||
637 | US_DEBUGP("%s: <---\n", __func__); | ||
638 | |||
639 | if ((PRODUCT_ID(chip) != 0x0158) || (FW_VERSION(chip) != 0x5895)) { | ||
640 | US_DEBUGP("Not the specified device, return immediately!\n"); | ||
641 | } else { | ||
642 | retval = rts51x_read_mem(us, 0xFD6F, buf, 1); | ||
643 | if (retval == STATUS_SUCCESS && (buf[0] & 0x24) == 0x24) { | ||
644 | /* SD Exist and SD WP */ | ||
645 | retval = rts51x_read_mem(us, 0xD04E, buf, 1); | ||
646 | if (retval == STATUS_SUCCESS) { | ||
647 | buf[0] |= 0x04; | ||
648 | retval = rts51x_write_mem(us, 0xFD70, buf, 1); | ||
649 | if (retval != STATUS_SUCCESS) | ||
650 | US_DEBUGP("Write memory fail\n"); | ||
651 | } else { | ||
652 | US_DEBUGP("Read memory fail\n"); | ||
653 | } | ||
654 | } else { | ||
655 | US_DEBUGP("Read memory fail, OR (buf[0]&0x24)!=0x24\n"); | ||
656 | } | ||
657 | } | ||
658 | |||
659 | US_DEBUGP("%s: --->\n", __func__); | ||
660 | } | ||
661 | |||
662 | static void rts51x_modi_suspend_timer(struct rts51x_chip *chip) | ||
663 | { | ||
664 | US_DEBUGP("%s: <---, state:%d\n", __func__, rts51x_get_stat(chip)); | ||
665 | |||
666 | chip->timer_expires = jiffies + msecs_to_jiffies(1000*ss_delay); | ||
667 | mod_timer(&chip->rts51x_suspend_timer, chip->timer_expires); | ||
668 | |||
669 | US_DEBUGP("%s: --->\n", __func__); | ||
670 | } | ||
671 | |||
672 | static void rts51x_suspend_timer_fn(unsigned long data) | ||
673 | { | ||
674 | struct rts51x_chip *chip = (struct rts51x_chip *)data; | ||
675 | struct us_data *us = chip->us; | ||
676 | |||
677 | US_DEBUGP("%s: <---\n", __func__); | ||
678 | |||
679 | switch (rts51x_get_stat(chip)) { | ||
680 | case RTS51X_STAT_INIT: | ||
681 | case RTS51X_STAT_RUN: | ||
682 | rts51x_modi_suspend_timer(chip); | ||
683 | break; | ||
684 | case RTS51X_STAT_IDLE: | ||
685 | case RTS51X_STAT_SS: | ||
686 | US_DEBUGP("%s: RTS51X_STAT_SS, intf->pm_usage_cnt:%d," | ||
687 | "power.usage:%d\n", __func__, | ||
688 | atomic_read(&us->pusb_intf->pm_usage_cnt), | ||
689 | atomic_read(&us->pusb_intf->dev.power.usage_count)); | ||
690 | |||
691 | if (atomic_read(&us->pusb_intf->pm_usage_cnt) > 0) { | ||
692 | US_DEBUGP("%s: Ready to enter SS state.\n", | ||
693 | __func__); | ||
694 | rts51x_set_stat(chip, RTS51X_STAT_SS); | ||
695 | /* ignore mass storage interface's children */ | ||
696 | pm_suspend_ignore_children(&us->pusb_intf->dev, true); | ||
697 | usb_autopm_put_interface(us->pusb_intf); | ||
698 | US_DEBUGP("%s: RTS51X_STAT_SS 01," | ||
699 | "intf->pm_usage_cnt:%d, power.usage:%d\n", | ||
700 | __func__, | ||
701 | atomic_read(&us->pusb_intf->pm_usage_cnt), | ||
702 | atomic_read( | ||
703 | &us->pusb_intf->dev.power.usage_count)); | ||
704 | } | ||
705 | break; | ||
706 | default: | ||
707 | US_DEBUGP("%s: Unknonwn state !!!\n", __func__); | ||
708 | break; | ||
709 | } | ||
710 | |||
711 | US_DEBUGP("%s: --->\n", __func__); | ||
712 | } | ||
713 | |||
714 | static inline int working_scsi(struct scsi_cmnd *srb) | ||
715 | { | ||
716 | if ((srb->cmnd[0] == TEST_UNIT_READY) || | ||
717 | (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL)) { | ||
718 | return 0; | ||
719 | } | ||
720 | |||
721 | return 1; | ||
722 | } | ||
723 | |||
724 | void rts51x_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) | ||
725 | { | ||
726 | struct rts51x_chip *chip = (struct rts51x_chip *)(us->extra); | ||
727 | static int card_first_show = 1; | ||
728 | static u8 media_not_present[] = { 0x70, 0, 0x02, 0, 0, 0, 0, | ||
729 | 10, 0, 0, 0, 0, 0x3A, 0, 0, 0, 0, 0 | ||
730 | }; | ||
731 | static u8 invalid_cmd_field[] = { 0x70, 0, 0x05, 0, 0, 0, 0, | ||
732 | 10, 0, 0, 0, 0, 0x24, 0, 0, 0, 0, 0 | ||
733 | }; | ||
734 | int ret; | ||
735 | |||
736 | US_DEBUGP("%s: <---\n", __func__); | ||
737 | |||
738 | if (working_scsi(srb)) { | ||
739 | US_DEBUGP("%s: working scsi, intf->pm_usage_cnt:%d," | ||
740 | "power.usage:%d\n", __func__, | ||
741 | atomic_read(&us->pusb_intf->pm_usage_cnt), | ||
742 | atomic_read(&us->pusb_intf->dev.power.usage_count)); | ||
743 | |||
744 | if (atomic_read(&us->pusb_intf->pm_usage_cnt) <= 0) { | ||
745 | ret = usb_autopm_get_interface(us->pusb_intf); | ||
746 | US_DEBUGP("%s: working scsi, ret=%d\n", __func__, ret); | ||
747 | } | ||
748 | if (rts51x_get_stat(chip) != RTS51X_STAT_RUN) | ||
749 | rts51x_set_stat(chip, RTS51X_STAT_RUN); | ||
750 | chip->proto_handler_backup(srb, us); | ||
751 | } else { | ||
752 | if (rts51x_get_stat(chip) == RTS51X_STAT_SS) { | ||
753 | US_DEBUGP("%s: NOT working scsi\n", __func__); | ||
754 | if ((srb->cmnd[0] == TEST_UNIT_READY) && | ||
755 | (chip->pwr_state == US_SUSPEND)) { | ||
756 | if (TST_LUN_READY(chip, srb->device->lun)) { | ||
757 | srb->result = SAM_STAT_GOOD; | ||
758 | } else { | ||
759 | srb->result = SAM_STAT_CHECK_CONDITION; | ||
760 | memcpy(srb->sense_buffer, | ||
761 | media_not_present, | ||
762 | US_SENSE_SIZE); | ||
763 | } | ||
764 | US_DEBUGP("%s: TEST_UNIT_READY--->\n", | ||
765 | __func__); | ||
766 | goto out; | ||
767 | } | ||
768 | if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) { | ||
769 | int prevent = srb->cmnd[4] & 0x1; | ||
770 | if (prevent) { | ||
771 | srb->result = SAM_STAT_CHECK_CONDITION; | ||
772 | memcpy(srb->sense_buffer, | ||
773 | invalid_cmd_field, | ||
774 | US_SENSE_SIZE); | ||
775 | } else { | ||
776 | srb->result = SAM_STAT_GOOD; | ||
777 | } | ||
778 | US_DEBUGP("%s: ALLOW_MEDIUM_REMOVAL--->\n", | ||
779 | __func__); | ||
780 | goto out; | ||
781 | } | ||
782 | } else { | ||
783 | US_DEBUGP("%s: NOT working scsi, not SS\n", __func__); | ||
784 | chip->proto_handler_backup(srb, us); | ||
785 | /* Check wether card is plugged in */ | ||
786 | if (srb->cmnd[0] == TEST_UNIT_READY) { | ||
787 | if (srb->result == SAM_STAT_GOOD) { | ||
788 | SET_LUN_READY(chip, srb->device->lun); | ||
789 | if (card_first_show) { | ||
790 | card_first_show = 0; | ||
791 | fw5895_set_mmc_wp(us); | ||
792 | } | ||
793 | } else { | ||
794 | CLR_LUN_READY(chip, srb->device->lun); | ||
795 | card_first_show = 1; | ||
796 | } | ||
797 | } | ||
798 | if (rts51x_get_stat(chip) != RTS51X_STAT_IDLE) | ||
799 | rts51x_set_stat(chip, RTS51X_STAT_IDLE); | ||
800 | } | ||
801 | } | ||
802 | out: | ||
803 | US_DEBUGP("%s: state:%d\n", __func__, rts51x_get_stat(chip)); | ||
804 | if (rts51x_get_stat(chip) == RTS51X_STAT_RUN) | ||
805 | rts51x_modi_suspend_timer(chip); | ||
806 | |||
807 | US_DEBUGP("%s: --->\n", __func__); | ||
808 | } | ||
809 | |||
810 | static int realtek_cr_autosuspend_setup(struct us_data *us) | ||
811 | { | ||
812 | struct rts51x_chip *chip; | ||
813 | struct rts51x_status *status = NULL; | ||
814 | u8 buf[16]; | ||
815 | int retval; | ||
816 | |||
817 | chip = (struct rts51x_chip *)us->extra; | ||
818 | chip->support_auto_delink = 0; | ||
819 | chip->pwr_state = US_RESUME; | ||
820 | chip->lun_ready = 0; | ||
821 | rts51x_set_stat(chip, RTS51X_STAT_INIT); | ||
822 | |||
823 | retval = rts51x_read_status(us, 0, buf, 16, &(chip->status_len)); | ||
824 | if (retval != STATUS_SUCCESS) { | ||
825 | US_DEBUGP("Read status fail\n"); | ||
826 | return -EIO; | ||
827 | } | ||
828 | status = chip->status; | ||
829 | status->vid = ((u16) buf[0] << 8) | buf[1]; | ||
830 | status->pid = ((u16) buf[2] << 8) | buf[3]; | ||
831 | status->cur_lun = buf[4]; | ||
832 | status->card_type = buf[5]; | ||
833 | status->total_lun = buf[6]; | ||
834 | status->fw_ver = ((u16) buf[7] << 8) | buf[8]; | ||
835 | status->phy_exist = buf[9]; | ||
836 | status->multi_flag = buf[10]; | ||
837 | status->multi_card = buf[11]; | ||
838 | status->log_exist = buf[12]; | ||
839 | if (chip->status_len == 16) { | ||
840 | status->detailed_type.detailed_type1 = buf[13]; | ||
841 | status->function[0] = buf[14]; | ||
842 | status->function[1] = buf[15]; | ||
843 | } | ||
844 | |||
845 | /* back up the proto_handler in us->extra */ | ||
846 | chip = (struct rts51x_chip *)(us->extra); | ||
847 | chip->proto_handler_backup = us->proto_handler; | ||
848 | /* Set the autosuspend_delay to 0 */ | ||
849 | pm_runtime_set_autosuspend_delay(&us->pusb_dev->dev, 0); | ||
850 | /* override us->proto_handler setted in get_protocol() */ | ||
851 | us->proto_handler = rts51x_invoke_transport; | ||
852 | |||
853 | chip->timer_expires = 0; | ||
854 | setup_timer(&chip->rts51x_suspend_timer, rts51x_suspend_timer_fn, | ||
855 | (unsigned long)chip); | ||
856 | fw5895_init(us); | ||
857 | |||
858 | /* enable autosuspend funciton of the usb device */ | ||
859 | usb_enable_autosuspend(us->pusb_dev); | ||
860 | |||
550 | return 0; | 861 | return 0; |
551 | } | 862 | } |
863 | #endif | ||
552 | 864 | ||
553 | static void realtek_cr_destructor(void *extra) | 865 | static void realtek_cr_destructor(void *extra) |
554 | { | 866 | { |
555 | struct rts51x_chip *chip = (struct rts51x_chip *)extra; | 867 | struct rts51x_chip *chip = (struct rts51x_chip *)extra; |
556 | 868 | ||
869 | US_DEBUGP("%s: <---\n", __func__); | ||
870 | |||
557 | if (!chip) | 871 | if (!chip) |
558 | return; | 872 | return; |
559 | 873 | #ifdef CONFIG_REALTEK_AUTOPM | |
874 | if (ss_en) { | ||
875 | del_timer(&chip->rts51x_suspend_timer); | ||
876 | chip->timer_expires = 0; | ||
877 | } | ||
878 | #endif | ||
560 | kfree(chip->status); | 879 | kfree(chip->status); |
561 | } | 880 | } |
562 | 881 | ||
563 | #ifdef CONFIG_PM | 882 | #ifdef CONFIG_PM |
564 | static void realtek_pm_hook(struct us_data *us, int pm_state) | 883 | int realtek_cr_suspend(struct usb_interface *iface, pm_message_t message) |
565 | { | 884 | { |
566 | if (pm_state == US_SUSPEND) | 885 | struct us_data *us = usb_get_intfdata(iface); |
567 | (void)config_autodelink_before_power_down(us); | 886 | |
887 | US_DEBUGP("%s: <---\n", __func__); | ||
888 | |||
889 | /* wait until no command is running */ | ||
890 | mutex_lock(&us->dev_mutex); | ||
891 | |||
892 | config_autodelink_before_power_down(us); | ||
893 | |||
894 | mutex_unlock(&us->dev_mutex); | ||
895 | |||
896 | US_DEBUGP("%s: --->\n", __func__); | ||
897 | |||
898 | return 0; | ||
568 | } | 899 | } |
900 | |||
901 | static int realtek_cr_resume(struct usb_interface *iface) | ||
902 | { | ||
903 | struct us_data *us = usb_get_intfdata(iface); | ||
904 | |||
905 | US_DEBUGP("%s: <---\n", __func__); | ||
906 | |||
907 | fw5895_init(us); | ||
908 | config_autodelink_after_power_on(us); | ||
909 | |||
910 | US_DEBUGP("%s: --->\n", __func__); | ||
911 | |||
912 | return 0; | ||
913 | } | ||
914 | #else | ||
915 | #define realtek_cr_suspend NULL | ||
916 | #define realtek_cr_resume NULL | ||
569 | #endif | 917 | #endif |
570 | 918 | ||
571 | static int init_realtek_cr(struct us_data *us) | 919 | static int init_realtek_cr(struct us_data *us) |
@@ -579,10 +927,6 @@ static int init_realtek_cr(struct us_data *us) | |||
579 | 927 | ||
580 | us->extra = chip; | 928 | us->extra = chip; |
581 | us->extra_destructor = realtek_cr_destructor; | 929 | us->extra_destructor = realtek_cr_destructor; |
582 | #ifdef CONFIG_PM | ||
583 | us->suspend_resume_hook = realtek_pm_hook; | ||
584 | #endif | ||
585 | |||
586 | us->max_lun = chip->max_lun = rts51x_get_max_lun(us); | 930 | us->max_lun = chip->max_lun = rts51x_get_max_lun(us); |
587 | 931 | ||
588 | US_DEBUGP("chip->max_lun = %d\n", chip->max_lun); | 932 | US_DEBUGP("chip->max_lun = %d\n", chip->max_lun); |
@@ -605,6 +949,12 @@ static int init_realtek_cr(struct us_data *us) | |||
605 | if (SUPPORT_AUTO_DELINK(chip)) | 949 | if (SUPPORT_AUTO_DELINK(chip)) |
606 | SET_AUTO_DELINK(chip); | 950 | SET_AUTO_DELINK(chip); |
607 | } | 951 | } |
952 | #ifdef CONFIG_REALTEK_AUTOPM | ||
953 | if (ss_en) { | ||
954 | chip->us = us; | ||
955 | realtek_cr_autosuspend_setup(us); | ||
956 | } | ||
957 | #endif | ||
608 | 958 | ||
609 | US_DEBUGP("chip->flag = 0x%x\n", chip->flag); | 959 | US_DEBUGP("chip->flag = 0x%x\n", chip->flag); |
610 | 960 | ||
@@ -645,13 +995,16 @@ static struct usb_driver realtek_cr_driver = { | |||
645 | .name = "ums-realtek", | 995 | .name = "ums-realtek", |
646 | .probe = realtek_cr_probe, | 996 | .probe = realtek_cr_probe, |
647 | .disconnect = usb_stor_disconnect, | 997 | .disconnect = usb_stor_disconnect, |
648 | .suspend = usb_stor_suspend, | 998 | /* .suspend = usb_stor_suspend, */ |
649 | .resume = usb_stor_resume, | 999 | /* .resume = usb_stor_resume, */ |
650 | .reset_resume = usb_stor_reset_resume, | 1000 | .reset_resume = usb_stor_reset_resume, |
1001 | .suspend = realtek_cr_suspend, | ||
1002 | .resume = realtek_cr_resume, | ||
651 | .pre_reset = usb_stor_pre_reset, | 1003 | .pre_reset = usb_stor_pre_reset, |
652 | .post_reset = usb_stor_post_reset, | 1004 | .post_reset = usb_stor_post_reset, |
653 | .id_table = realtek_cr_ids, | 1005 | .id_table = realtek_cr_ids, |
654 | .soft_unbind = 1, | 1006 | .soft_unbind = 1, |
1007 | .supports_autosuspend = 1, | ||
655 | }; | 1008 | }; |
656 | 1009 | ||
657 | static int __init realtek_cr_init(void) | 1010 | static int __init realtek_cr_init(void) |