Skip to content

Commit

Permalink
mfd: rtsx: Optimize card detect flow
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Wei WANG authored and Samuel Ortiz committed Feb 13, 2013
1 parent eebbe25 commit 504decc
Showing 1 changed file with 19 additions and 12 deletions.
31 changes: 19 additions & 12 deletions drivers/mfd/rtsx_pcr.c
Original file line number Diff line number Diff line change
Expand Up @@ -752,33 +752,40 @@ 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);
pcr = container_of(dwork, struct rtsx_pcr, carddet_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(
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down

0 comments on commit 504decc

Please sign in to comment.