aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2016-05-31 11:05:23 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-06-01 17:58:59 -0400
commitb6a619a883c38e3f01749afe13dd23395c94a058 (patch)
treeb0254bf8d6cc4804eb5c9dee3ee112dc931b7899
parentaec373c1e5d87d791525a675fe726c11d64b84a8 (diff)
usb: phy: Check initial state for twl6030
We need to check the state for the PHY with delayed_work as otherwise MUSB will get confused and idles immediately. Signed-off-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Bin Liu <b-liu@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/phy/phy-twl6030-usb.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/usb/phy/phy-twl6030-usb.c b/drivers/usb/phy/phy-twl6030-usb.c
index c66a447c3dfe..a72e8d670adc 100644
--- a/drivers/usb/phy/phy-twl6030-usb.c
+++ b/drivers/usb/phy/phy-twl6030-usb.c
@@ -97,6 +97,9 @@ struct twl6030_usb {
97 97
98 struct regulator *usb3v3; 98 struct regulator *usb3v3;
99 99
100 /* used to check initial cable status after probe */
101 struct delayed_work get_status_work;
102
100 /* used to set vbus, in atomic path */ 103 /* used to set vbus, in atomic path */
101 struct work_struct set_vbus_work; 104 struct work_struct set_vbus_work;
102 105
@@ -280,6 +283,15 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl)
280 return IRQ_HANDLED; 283 return IRQ_HANDLED;
281} 284}
282 285
286static void twl6030_status_work(struct work_struct *work)
287{
288 struct twl6030_usb *twl = container_of(work, struct twl6030_usb,
289 get_status_work.work);
290
291 twl6030_usb_irq(twl->irq2, twl);
292 twl6030_usbotg_irq(twl->irq1, twl);
293}
294
283static int twl6030_enable_irq(struct twl6030_usb *twl) 295static int twl6030_enable_irq(struct twl6030_usb *twl)
284{ 296{
285 twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); 297 twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET);
@@ -290,8 +302,6 @@ static int twl6030_enable_irq(struct twl6030_usb *twl)
290 REG_INT_MSK_LINE_C); 302 REG_INT_MSK_LINE_C);
291 twl6030_interrupt_unmask(TWL6030_CHARGER_CTRL_INT_MASK, 303 twl6030_interrupt_unmask(TWL6030_CHARGER_CTRL_INT_MASK,
292 REG_INT_MSK_STS_C); 304 REG_INT_MSK_STS_C);
293 twl6030_usb_irq(twl->irq2, twl);
294 twl6030_usbotg_irq(twl->irq1, twl);
295 305
296 return 0; 306 return 0;
297} 307}
@@ -377,6 +387,7 @@ static int twl6030_usb_probe(struct platform_device *pdev)
377 dev_warn(&pdev->dev, "could not create sysfs file\n"); 387 dev_warn(&pdev->dev, "could not create sysfs file\n");
378 388
379 INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work); 389 INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work);
390 INIT_DELAYED_WORK(&twl->get_status_work, twl6030_status_work);
380 391
381 status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq, 392 status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq,
382 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, 393 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT,
@@ -401,6 +412,7 @@ static int twl6030_usb_probe(struct platform_device *pdev)
401 412
402 twl->asleep = 0; 413 twl->asleep = 0;
403 twl6030_enable_irq(twl); 414 twl6030_enable_irq(twl);
415 schedule_delayed_work(&twl->get_status_work, HZ);
404 dev_info(&pdev->dev, "Initialized TWL6030 USB module\n"); 416 dev_info(&pdev->dev, "Initialized TWL6030 USB module\n");
405 417
406 return 0; 418 return 0;
@@ -410,6 +422,7 @@ static int twl6030_usb_remove(struct platform_device *pdev)
410{ 422{
411 struct twl6030_usb *twl = platform_get_drvdata(pdev); 423 struct twl6030_usb *twl = platform_get_drvdata(pdev);
412 424
425 cancel_delayed_work(&twl->get_status_work);
413 twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK, 426 twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK,
414 REG_INT_MSK_LINE_C); 427 REG_INT_MSK_LINE_C);
415 twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK, 428 twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK,