This queues work from the otg notification where the
i2c operations can be safely made. Needed for atomic otg
notifiers.

Signed-off-by: Heikki Krogerus <[email protected]>
Cc: Grazvydas Ignotas <[email protected]>
Cc: Anton Vorontsov <[email protected]>
---
 drivers/power/twl4030_charger.c |   25 +++++++++++++++++++------
 1 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index ff1f423..92c16e1 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -71,8 +71,11 @@ struct twl4030_bci {
        struct power_supply     usb;
        struct otg_transceiver  *transceiver;
        struct notifier_block   otg_nb;
+       struct work_struct      work;
        int                     irq_chg;
        int                     irq_bci;
+
+       unsigned long           event;
 };
 
 /*
@@ -258,14 +261,11 @@ static irqreturn_t twl4030_bci_interrupt(int irq, void 
*arg)
        return IRQ_HANDLED;
 }
 
-static int twl4030_bci_usb_ncb(struct notifier_block *nb, unsigned long val,
-                              void *priv)
+static void twl4030_bci_usb_work(struct work_struct *data)
 {
-       struct twl4030_bci *bci = container_of(nb, struct twl4030_bci, otg_nb);
+       struct twl4030_bci *bci = container_of(data, struct twl4030_bci, work);
 
-       dev_dbg(bci->dev, "OTG notify %lu\n", val);
-
-       switch (val) {
+       switch (bci->event) {
        case USB_EVENT_VBUS:
        case USB_EVENT_CHARGER:
                twl4030_charger_enable_usb(bci, true);
@@ -274,6 +274,17 @@ static int twl4030_bci_usb_ncb(struct notifier_block *nb, 
unsigned long val,
                twl4030_charger_enable_usb(bci, false);
                break;
        }
+}
+
+static int twl4030_bci_usb_ncb(struct notifier_block *nb, unsigned long val,
+                              void *priv)
+{
+       struct twl4030_bci *bci = container_of(nb, struct twl4030_bci, otg_nb);
+
+       dev_dbg(bci->dev, "OTG notify %lu\n", val);
+
+       bci->event = val;
+       schedule_work(&bci->work);
 
        return NOTIFY_OK;
 }
@@ -466,6 +477,8 @@ static int __init twl4030_bci_probe(struct platform_device 
*pdev)
                goto fail_bci_irq;
        }
 
+       INIT_WORK(&bci->work, twl4030_bci_usb_work);
+
        bci->transceiver = otg_get_transceiver();
        if (bci->transceiver != NULL) {
                bci->otg_nb.notifier_call = twl4030_bci_usb_ncb;
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to