aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/memstick/host/rtsx_pci_ms.c7
-rw-r--r--drivers/mfd/rtsx_pcr.c30
-rw-r--r--drivers/mmc/host/rtsx_pci_sdmmc.c18
-rw-r--r--include/linux/mfd/rtsx_pci.h2
4 files changed, 57 insertions, 0 deletions
diff --git a/drivers/memstick/host/rtsx_pci_ms.c b/drivers/memstick/host/rtsx_pci_ms.c
index f5ddb82dadb7..64a779c58a74 100644
--- a/drivers/memstick/host/rtsx_pci_ms.c
+++ b/drivers/memstick/host/rtsx_pci_ms.c
@@ -426,6 +426,9 @@ static void rtsx_pci_ms_request(struct memstick_host *msh)
426 426
427 dev_dbg(ms_dev(host), "--> %s\n", __func__); 427 dev_dbg(ms_dev(host), "--> %s\n", __func__);
428 428
429 if (rtsx_pci_card_exclusive_check(host->pcr, RTSX_MS_CARD))
430 return;
431
429 schedule_work(&host->handle_req); 432 schedule_work(&host->handle_req);
430} 433}
431 434
@@ -441,6 +444,10 @@ static int rtsx_pci_ms_set_param(struct memstick_host *msh,
441 dev_dbg(ms_dev(host), "%s: param = %d, value = %d\n", 444 dev_dbg(ms_dev(host), "%s: param = %d, value = %d\n",
442 __func__, param, value); 445 __func__, param, value);
443 446
447 err = rtsx_pci_card_exclusive_check(host->pcr, RTSX_MS_CARD);
448 if (err)
449 return err;
450
444 switch (param) { 451 switch (param) {
445 case MEMSTICK_POWER: 452 case MEMSTICK_POWER:
446 if (value == MEMSTICK_POWER_ON) 453 if (value == MEMSTICK_POWER_ON)
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index 822237e322ba..481a98a10ecd 100644
--- a/drivers/mfd/rtsx_pcr.c
+++ b/drivers/mfd/rtsx_pcr.c
@@ -708,6 +708,25 @@ int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card)
708} 708}
709EXPORT_SYMBOL_GPL(rtsx_pci_card_power_off); 709EXPORT_SYMBOL_GPL(rtsx_pci_card_power_off);
710 710
711int rtsx_pci_card_exclusive_check(struct rtsx_pcr *pcr, int card)
712{
713 unsigned int cd_mask[] = {
714 [RTSX_SD_CARD] = SD_EXIST,
715 [RTSX_MS_CARD] = MS_EXIST
716 };
717
718 if (!pcr->ms_pmos) {
719 /* When using single PMOS, accessing card is not permitted
720 * if the existing card is not the designated one.
721 */
722 if (pcr->card_exist & (~cd_mask[card]))
723 return -EIO;
724 }
725
726 return 0;
727}
728EXPORT_SYMBOL_GPL(rtsx_pci_card_exclusive_check);
729
711int rtsx_pci_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) 730int rtsx_pci_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
712{ 731{
713 if (pcr->ops->switch_output_voltage) 732 if (pcr->ops->switch_output_voltage)
@@ -784,6 +803,9 @@ static void rtsx_pci_card_detect(struct work_struct *work)
784 card_inserted = pcr->ops->cd_deglitch(pcr); 803 card_inserted = pcr->ops->cd_deglitch(pcr);
785 804
786 card_detect = card_inserted | card_removed; 805 card_detect = card_inserted | card_removed;
806
807 pcr->card_exist |= card_inserted;
808 pcr->card_exist &= ~card_removed;
787 } 809 }
788 810
789 mutex_unlock(&pcr->pcr_mutex); 811 mutex_unlock(&pcr->pcr_mutex);
@@ -976,6 +998,14 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
976 return err; 998 return err;
977 } 999 }
978 1000
1001 /* No CD interrupt if probing driver with card inserted.
1002 * So we need to initialize pcr->card_exist here.
1003 */
1004 if (pcr->ops->cd_deglitch)
1005 pcr->card_exist = pcr->ops->cd_deglitch(pcr);
1006 else
1007 pcr->card_exist = rtsx_pci_readl(pcr, RTSX_BIPR) & CARD_EXIST;
1008
979 return 0; 1009 return 0;
980} 1010}
981 1011
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c
index f74b5adca642..468c92303167 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -678,12 +678,19 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
678 struct mmc_command *cmd = mrq->cmd; 678 struct mmc_command *cmd = mrq->cmd;
679 struct mmc_data *data = mrq->data; 679 struct mmc_data *data = mrq->data;
680 unsigned int data_size = 0; 680 unsigned int data_size = 0;
681 int err;
681 682
682 if (host->eject) { 683 if (host->eject) {
683 cmd->error = -ENOMEDIUM; 684 cmd->error = -ENOMEDIUM;
684 goto finish; 685 goto finish;
685 } 686 }
686 687
688 err = rtsx_pci_card_exclusive_check(host->pcr, RTSX_SD_CARD);
689 if (err) {
690 cmd->error = err;
691 goto finish;
692 }
693
687 mutex_lock(&pcr->pcr_mutex); 694 mutex_lock(&pcr->pcr_mutex);
688 695
689 rtsx_pci_start_run(pcr); 696 rtsx_pci_start_run(pcr);
@@ -901,6 +908,9 @@ static void sdmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
901 if (host->eject) 908 if (host->eject)
902 return; 909 return;
903 910
911 if (rtsx_pci_card_exclusive_check(host->pcr, RTSX_SD_CARD))
912 return;
913
904 mutex_lock(&pcr->pcr_mutex); 914 mutex_lock(&pcr->pcr_mutex);
905 915
906 rtsx_pci_start_run(pcr); 916 rtsx_pci_start_run(pcr);
@@ -1073,6 +1083,10 @@ static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
1073 if (host->eject) 1083 if (host->eject)
1074 return -ENOMEDIUM; 1084 return -ENOMEDIUM;
1075 1085
1086 err = rtsx_pci_card_exclusive_check(host->pcr, RTSX_SD_CARD);
1087 if (err)
1088 return err;
1089
1076 mutex_lock(&pcr->pcr_mutex); 1090 mutex_lock(&pcr->pcr_mutex);
1077 1091
1078 rtsx_pci_start_run(pcr); 1092 rtsx_pci_start_run(pcr);
@@ -1122,6 +1136,10 @@ static int sdmmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
1122 if (host->eject) 1136 if (host->eject)
1123 return -ENOMEDIUM; 1137 return -ENOMEDIUM;
1124 1138
1139 err = rtsx_pci_card_exclusive_check(host->pcr, RTSX_SD_CARD);
1140 if (err)
1141 return err;
1142
1125 mutex_lock(&pcr->pcr_mutex); 1143 mutex_lock(&pcr->pcr_mutex);
1126 1144
1127 rtsx_pci_start_run(pcr); 1145 rtsx_pci_start_run(pcr);
diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index 5d9b81e8aff4..26ea7f1b7caf 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -740,6 +740,7 @@ struct rtsx_pcr {
740 740
741 unsigned int card_inserted; 741 unsigned int card_inserted;
742 unsigned int card_removed; 742 unsigned int card_removed;
743 unsigned int card_exist;
743 744
744 struct delayed_work carddet_work; 745 struct delayed_work carddet_work;
745 struct delayed_work idle_work; 746 struct delayed_work idle_work;
@@ -804,6 +805,7 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
804 u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk); 805 u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk);
805int rtsx_pci_card_power_on(struct rtsx_pcr *pcr, int card); 806int rtsx_pci_card_power_on(struct rtsx_pcr *pcr, int card);
806int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card); 807int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card);
808int rtsx_pci_card_exclusive_check(struct rtsx_pcr *pcr, int card);
807int rtsx_pci_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage); 809int rtsx_pci_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage);
808unsigned int rtsx_pci_card_exist(struct rtsx_pcr *pcr); 810unsigned int rtsx_pci_card_exist(struct rtsx_pcr *pcr);
809void rtsx_pci_complete_unfinished_transfer(struct rtsx_pcr *pcr); 811void rtsx_pci_complete_unfinished_transfer(struct rtsx_pcr *pcr);