The OTG device can receive device interrupts while suspended (such as for a hot add or remove). So we need to resume the hardware in the interrupt handler before touching it. Because this needs to be done synchronously, we need to switch the irq handler to a threaded one.
Signed-off-by: Kristen Carlson Accardi <kris...@linux.intel.com> Index: linux-2.6.37/drivers/usb/otg/langwell_otg.c =================================================================== --- linux-2.6.37.orig/drivers/usb/otg/langwell_otg.c +++ linux-2.6.37/drivers/usb/otg/langwell_otg.c @@ -785,11 +785,15 @@ static irqreturn_t otg_irq(int irq, void u32 int_mask = 0; int flag = 0; + pm_runtime_get_sync(lnw->dev); + int_sts = readl(lnw->iotg.base + CI_OTGSC); int_en = (int_sts & OTGSC_INTEN_MASK) >> 8; int_mask = int_sts & int_en; - if (int_mask == 0) + if (int_mask == 0) { + pm_runtime_put(lnw->dev); return IRQ_NONE; + } if (int_mask & OTGSC_IDIS) { dev_dbg(lnw->dev, "%s: id change int\n", __func__); @@ -839,6 +843,8 @@ static irqreturn_t otg_irq(int irq, void if (flag) langwell_update_transceiver(); + pm_runtime_put(lnw->dev); + return IRQ_HANDLED; } @@ -2094,7 +2100,7 @@ static int langwell_otg_probe(struct pci goto err; } - if (request_irq(pdev->irq, otg_irq, IRQF_SHARED, + if (request_threaded_irq(pdev->irq, NULL, &otg_irq, IRQF_SHARED, driver_name, lnw) != 0) { dev_dbg(lnw->dev, "request interrupt %d failed\n", pdev->irq); retval = -EBUSY; @@ -2338,7 +2344,7 @@ static int langwell_otg_resume(struct pc goto error; } - if (request_irq(pdev->irq, otg_irq, IRQF_SHARED, + if (request_threaded_irq(pdev->irq, NULL, otg_irq, IRQF_SHARED, driver_name, lnw) != 0) { dev_dbg(&pdev->dev, "request interrupt %d failed\n", pdev->irq); ret = -EBUSY; _______________________________________________ MeeGo-kernel mailing list MeeGo-kernel@lists.meego.com http://lists.meego.com/listinfo/meego-kernel