twl4030_charger: Make the driver atomic notifier safe

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 <heikki.krogerus@nokia.com>
Tested-by: Grazvydas Ignotas <notasas@gmail.com>
Signed-off-by: Anton Vorontsov <cbouatmailru@gmail.com>

authored by Heikki Krogerus and committed by Anton Vorontsov d6ccc442 6501f728

+19 -6
+19 -6
drivers/power/twl4030_charger.c
··· 71 struct power_supply usb; 72 struct otg_transceiver *transceiver; 73 struct notifier_block otg_nb; 74 int irq_chg; 75 int irq_bci; 76 }; 77 78 /* ··· 261 return IRQ_HANDLED; 262 } 263 264 - static int twl4030_bci_usb_ncb(struct notifier_block *nb, unsigned long val, 265 - void *priv) 266 { 267 - struct twl4030_bci *bci = container_of(nb, struct twl4030_bci, otg_nb); 268 269 - dev_dbg(bci->dev, "OTG notify %lu\n", val); 270 - 271 - switch (val) { 272 case USB_EVENT_VBUS: 273 case USB_EVENT_CHARGER: 274 twl4030_charger_enable_usb(bci, true); ··· 274 twl4030_charger_enable_usb(bci, false); 275 break; 276 } 277 278 return NOTIFY_OK; 279 } ··· 476 bci->irq_bci, ret); 477 goto fail_bci_irq; 478 } 479 480 bci->transceiver = otg_get_transceiver(); 481 if (bci->transceiver != NULL) {
··· 71 struct power_supply usb; 72 struct otg_transceiver *transceiver; 73 struct notifier_block otg_nb; 74 + struct work_struct work; 75 int irq_chg; 76 int irq_bci; 77 + 78 + unsigned long event; 79 }; 80 81 /* ··· 258 return IRQ_HANDLED; 259 } 260 261 + static void twl4030_bci_usb_work(struct work_struct *data) 262 { 263 + struct twl4030_bci *bci = container_of(data, struct twl4030_bci, work); 264 265 + switch (bci->event) { 266 case USB_EVENT_VBUS: 267 case USB_EVENT_CHARGER: 268 twl4030_charger_enable_usb(bci, true); ··· 274 twl4030_charger_enable_usb(bci, false); 275 break; 276 } 277 + } 278 + 279 + static int twl4030_bci_usb_ncb(struct notifier_block *nb, unsigned long val, 280 + void *priv) 281 + { 282 + struct twl4030_bci *bci = container_of(nb, struct twl4030_bci, otg_nb); 283 + 284 + dev_dbg(bci->dev, "OTG notify %lu\n", val); 285 + 286 + bci->event = val; 287 + schedule_work(&bci->work); 288 289 return NOTIFY_OK; 290 } ··· 465 bci->irq_bci, ret); 466 goto fail_bci_irq; 467 } 468 + 469 + INIT_WORK(&bci->work, twl4030_bci_usb_work); 470 471 bci->transceiver = otg_get_transceiver(); 472 if (bci->transceiver != NULL) {