Messages in this thread Patch in this message | | | Date | Tue, 10 Dec 2013 09:56:48 +0800 | From | micky <> | Subject | Re: 3.12: kernel panic when resuming from suspend to RAM (x86_64) |
| |
Hi Francis: On 12/10/2013 09:39 AM, wwang wrote: > which is based on Thomas' patch.
Can you help us test this patch, we disable irq while suspend here.
From 6b2bd6d85780bfd8d4fe5289aee1b09dd655d2d4 Mon Sep 17 00:00:00 2001 From: Micky Ching <micky_ching@realsil.com.cn> Date: Thu, 5 Dec 2013 16:44:19 +0800 Subject: [PATCH] mfd: rtsx: fix pci remove panic while resuming
On some special condition, when resume from suspend, the rtsx_pci will being removed. And card insert/remove interrupt triggered during removing, this will cause kernel panic, since in card detect work will read pci register but device is no longer exist.
Signed-off-by: Micky Ching <micky_ching@realsil.com.cn> --- drivers/mfd/rtsx_pcr.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c index 11e20af..efdd9b9 100644 --- a/drivers/mfd/rtsx_pcr.c +++ b/drivers/mfd/rtsx_pcr.c @@ -1228,14 +1228,14 @@ static void rtsx_pci_remove(struct pci_dev *pcidev)
pcr->remove_pci = true;
- cancel_delayed_work(&pcr->carddet_work); - cancel_delayed_work(&pcr->idle_work); + cancel_delayed_work_sync(&pcr->carddet_work); + cancel_delayed_work_sync(&pcr->idle_work);
mfd_remove_devices(&pcidev->dev);
dma_free_coherent(&(pcr->pci->dev), RTSX_RESV_BUF_LEN, pcr->rtsx_resv_buf, pcr->rtsx_resv_buf_addr); - free_irq(pcr->irq, (void *)pcr); + free_irq(pcr->irq, pcr); if (pcr->msi_en) pci_disable_msi(pcr->pci); iounmap(pcr->remap_addr); @@ -1268,8 +1268,13 @@ static int rtsx_pci_suspend(struct pci_dev *pcidev, pm_message_t state) handle = pci_get_drvdata(pcidev); pcr = handle->pcr;
- cancel_delayed_work(&pcr->carddet_work); - cancel_delayed_work(&pcr->idle_work); + spin_lock_irq(&pcr->lock); + rtsx_pci_writel(pcr, RTSX_BIER, 0); + pcr->bier = 0; + spin_unlock_irq(&pcr->lock); + cancel_delayed_work_sync(&pcr->carddet_work); + cancel_delayed_work_sync(&pcr->idle_work); + free_irq(pcr->irq, pcr);
mutex_lock(&pcr->pcr_mutex);
@@ -1295,6 +1300,12 @@ static int rtsx_pci_resume(struct pci_dev *pcidev) handle = pci_get_drvdata(pcidev); pcr = handle->pcr;
+ ret = rtsx_pci_acquire_irq(pcr); + if (ret < 0) + return ret; + synchronize_irq(pcr->irq); + rtsx_pci_enable_bus_int(pcr); + mutex_lock(&pcr->pcr_mutex);
pci_set_power_state(pcidev, PCI_D0); -- 1.7.9.5
-- Best Regards Micky.
| |