USB: chipidea: acknowledge ID change interrupt in irq handler
authorRichard Zhao <richard.zhao@freescale.com>
Wed, 12 Sep 2012 11:58:08 +0000 (14:58 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 12 Sep 2012 18:20:38 +0000 (11:20 -0700)
In order to avoid re-queueing of the role changing work, we need to clear
the ID change interrupt bit right in the irq handler.

Tested-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
Tested-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Richard Zhao <richard.zhao@freescale.com>
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/chipidea/core.c

index 3c3ed77..19ef324 100644 (file)
@@ -273,8 +273,6 @@ static void ci_role_work(struct work_struct *work)
        struct ci13xxx *ci = container_of(work, struct ci13xxx, work);
        enum ci_role role = ci_otg_role(ci);
 
-       hw_write(ci, OP_OTGSC, OTGSC_IDIS, OTGSC_IDIS);
-
        if (role != ci->role) {
                dev_dbg(ci->dev, "switching from %s to %s\n",
                        ci_role(ci)->name, ci->roles[role]->name);
@@ -325,6 +323,7 @@ static irqreturn_t ci_irq(int irq, void *data)
                u32 sts = hw_read(ci, OP_OTGSC, ~0);
 
                if (sts & OTGSC_IDIS) {
+                       hw_write(ci, OP_OTGSC, OTGSC_IDIS, OTGSC_IDIS);
                        queue_work(ci->wq, &ci->work);
                        ret = IRQ_HANDLED;
                }