aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorWei WANG <wei_wang@realsil.com.cn>2013-01-29 02:21:37 -0500
committerSamuel Ortiz <sameo@linux.intel.com>2013-02-13 18:22:58 -0500
commit504decc0a063e6a09a1e5b203ca68bc21dfffde9 (patch)
tree9434da1da1e015bbb1d7f556dc180fd79759442b /drivers/mfd
parenteebbe2541684da99bf0b179d5182dc8025f5f5b6 (diff)
mfd: rtsx: Optimize card detect flow
1. Schedule card detect work at the end of the ISR 2. Callback function ops->cd_deglitch may delay for a period of time. It is not proper to call this callback when local irq disabled. 3. Card detect flow can't be executed in parallel with other card reader operations, so it's better to be protected by mutex. Signed-off-by: Wei WANG <wei_wang@realsil.com.cn> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/rtsx_pcr.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index 67bb34ef0ebd..9016932f0267 100644
--- a/drivers/mfd/rtsx_pcr.c
+++ b/drivers/mfd/rtsx_pcr.c
@@ -752,7 +752,7 @@ static void rtsx_pci_card_detect(struct work_struct *work)
752 struct delayed_work *dwork; 752 struct delayed_work *dwork;
753 struct rtsx_pcr *pcr; 753 struct rtsx_pcr *pcr;
754 unsigned long flags; 754 unsigned long flags;
755 unsigned int card_detect = 0; 755 unsigned int card_detect = 0, card_inserted, card_removed;
756 u32 irq_status; 756 u32 irq_status;
757 757
758 dwork = to_delayed_work(work); 758 dwork = to_delayed_work(work);
@@ -760,25 +760,32 @@ static void rtsx_pci_card_detect(struct work_struct *work)
760 760
761 dev_dbg(&(pcr->pci->dev), "--> %s\n", __func__); 761 dev_dbg(&(pcr->pci->dev), "--> %s\n", __func__);
762 762
763 mutex_lock(&pcr->pcr_mutex);
763 spin_lock_irqsave(&pcr->lock, flags); 764 spin_lock_irqsave(&pcr->lock, flags);
764 765
765 irq_status = rtsx_pci_readl(pcr, RTSX_BIPR); 766 irq_status = rtsx_pci_readl(pcr, RTSX_BIPR);
766 dev_dbg(&(pcr->pci->dev), "irq_status: 0x%08x\n", irq_status); 767 dev_dbg(&(pcr->pci->dev), "irq_status: 0x%08x\n", irq_status);
767 768
768 if (pcr->card_inserted || pcr->card_removed) { 769 irq_status &= CARD_EXIST;
770 card_inserted = pcr->card_inserted & irq_status;
771 card_removed = pcr->card_removed;
772 pcr->card_inserted = 0;
773 pcr->card_removed = 0;
774
775 spin_unlock_irqrestore(&pcr->lock, flags);
776
777 if (card_inserted || card_removed) {
769 dev_dbg(&(pcr->pci->dev), 778 dev_dbg(&(pcr->pci->dev),
770 "card_inserted: 0x%x, card_removed: 0x%x\n", 779 "card_inserted: 0x%x, card_removed: 0x%x\n",
771 pcr->card_inserted, pcr->card_removed); 780 card_inserted, card_removed);
772 781
773 if (pcr->ops->cd_deglitch) 782 if (pcr->ops->cd_deglitch)
774 pcr->card_inserted = pcr->ops->cd_deglitch(pcr); 783 card_inserted = pcr->ops->cd_deglitch(pcr);
775 784
776 card_detect = pcr->card_inserted | pcr->card_removed; 785 card_detect = card_inserted | card_removed;
777 pcr->card_inserted = 0;
778 pcr->card_removed = 0;
779 } 786 }
780 787
781 spin_unlock_irqrestore(&pcr->lock, flags); 788 mutex_unlock(&pcr->pcr_mutex);
782 789
783 if ((card_detect & SD_EXIST) && pcr->slots[RTSX_SD_CARD].card_event) 790 if ((card_detect & SD_EXIST) && pcr->slots[RTSX_SD_CARD].card_event)
784 pcr->slots[RTSX_SD_CARD].card_event( 791 pcr->slots[RTSX_SD_CARD].card_event(
@@ -830,10 +837,6 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
830 } 837 }
831 } 838 }
832 839
833 if (pcr->card_inserted || pcr->card_removed)
834 schedule_delayed_work(&pcr->carddet_work,
835 msecs_to_jiffies(200));
836
837 if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) { 840 if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) {
838 if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) { 841 if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) {
839 pcr->trans_result = TRANS_RESULT_FAIL; 842 pcr->trans_result = TRANS_RESULT_FAIL;
@@ -846,6 +849,10 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
846 } 849 }
847 } 850 }
848 851
852 if (pcr->card_inserted || pcr->card_removed)
853 schedule_delayed_work(&pcr->carddet_work,
854 msecs_to_jiffies(200));
855
849 spin_unlock(&pcr->lock); 856 spin_unlock(&pcr->lock);
850 return IRQ_HANDLED; 857 return IRQ_HANDLED;
851} 858}