|
@@ -752,7 +752,7 @@ static void rtsx_pci_card_detect(struct work_struct *work)
|
|
|
struct delayed_work *dwork;
|
|
|
struct rtsx_pcr *pcr;
|
|
|
unsigned long flags;
|
|
|
- unsigned int card_detect = 0;
|
|
|
+ unsigned int card_detect = 0, card_inserted, card_removed;
|
|
|
u32 irq_status;
|
|
|
|
|
|
dwork = to_delayed_work(work);
|
|
@@ -760,25 +760,32 @@ static void rtsx_pci_card_detect(struct work_struct *work)
|
|
|
|
|
|
dev_dbg(&(pcr->pci->dev), "--> %s\n", __func__);
|
|
|
|
|
|
+ mutex_lock(&pcr->pcr_mutex);
|
|
|
spin_lock_irqsave(&pcr->lock, flags);
|
|
|
|
|
|
irq_status = rtsx_pci_readl(pcr, RTSX_BIPR);
|
|
|
dev_dbg(&(pcr->pci->dev), "irq_status: 0x%08x\n", irq_status);
|
|
|
|
|
|
- if (pcr->card_inserted || pcr->card_removed) {
|
|
|
+ irq_status &= CARD_EXIST;
|
|
|
+ card_inserted = pcr->card_inserted & irq_status;
|
|
|
+ card_removed = pcr->card_removed;
|
|
|
+ pcr->card_inserted = 0;
|
|
|
+ pcr->card_removed = 0;
|
|
|
+
|
|
|
+ spin_unlock_irqrestore(&pcr->lock, flags);
|
|
|
+
|
|
|
+ if (card_inserted || card_removed) {
|
|
|
dev_dbg(&(pcr->pci->dev),
|
|
|
"card_inserted: 0x%x, card_removed: 0x%x\n",
|
|
|
- pcr->card_inserted, pcr->card_removed);
|
|
|
+ card_inserted, card_removed);
|
|
|
|
|
|
if (pcr->ops->cd_deglitch)
|
|
|
- pcr->card_inserted = pcr->ops->cd_deglitch(pcr);
|
|
|
+ card_inserted = pcr->ops->cd_deglitch(pcr);
|
|
|
|
|
|
- card_detect = pcr->card_inserted | pcr->card_removed;
|
|
|
- pcr->card_inserted = 0;
|
|
|
- pcr->card_removed = 0;
|
|
|
+ card_detect = card_inserted | card_removed;
|
|
|
}
|
|
|
|
|
|
- spin_unlock_irqrestore(&pcr->lock, flags);
|
|
|
+ mutex_unlock(&pcr->pcr_mutex);
|
|
|
|
|
|
if ((card_detect & SD_EXIST) && pcr->slots[RTSX_SD_CARD].card_event)
|
|
|
pcr->slots[RTSX_SD_CARD].card_event(
|
|
@@ -830,10 +837,6 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (pcr->card_inserted || pcr->card_removed)
|
|
|
- schedule_delayed_work(&pcr->carddet_work,
|
|
|
- msecs_to_jiffies(200));
|
|
|
-
|
|
|
if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) {
|
|
|
if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) {
|
|
|
pcr->trans_result = TRANS_RESULT_FAIL;
|
|
@@ -846,6 +849,10 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if (pcr->card_inserted || pcr->card_removed)
|
|
|
+ schedule_delayed_work(&pcr->carddet_work,
|
|
|
+ msecs_to_jiffies(200));
|
|
|
+
|
|
|
spin_unlock(&pcr->lock);
|
|
|
return IRQ_HANDLED;
|
|
|
}
|