summaryrefslogtreecommitdiff
path: root/drivers/usb/phy/phy-twl6030-usb.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-06-18 19:06:49 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2016-06-18 19:06:49 +0300
commite80dac114c63dd54398c3c785a6431622c320e87 (patch)
tree2a49ad6be601be3463172082bd61bdde863753e9 /drivers/usb/phy/phy-twl6030-usb.c
parenta50094a4813443a7ca605f86019061905ba697c4 (diff)
parent083d5ad1a924e79ecf92be37cce9f1efa5c1d240 (diff)
downloadlinux-e80dac114c63dd54398c3c785a6431622c320e87.tar.xz
Merge tag 'usb-4.7-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB fixes from Greg KH: "Here are a bunch (65) of USB fixes for 4.7-rc4. Sorry about the quantity, I've been slow in getting these out. The majority are the "normal" gadget, musb, and xhci fixes, that we all are used to. There are also a few other tiny fixes resolving a number of reported issues that showed up in 4.7-rc1. All of these have been in linux-next" * tag 'usb-4.7-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (65 commits) usbip: rate limit get_frame_number message usb: musb: sunxi: Remove bogus "Frees glue" comment usb: musb: sunxi: Fix NULL ptr deref when gadget is registered before musb usb: echi-hcd: Add ehci_setup check before echi_shutdown usb: host: ehci-msm: Conditionally call ehci suspend/resume MAINTAINERS: Add file patterns for usb device tree bindings usb: host: ehci-tegra: Avoid getting the same reset twice usb: host: ehci-tegra: Grab the correct UTMI pads reset USB: mos7720: delete parport USB: OHCI: Don't mark EDs as ED_OPER if scheduling fails phy: ti-pipe3: Program the DPLL even if it was already locked usb: musb: Stop bulk endpoint while queue is rotated usb: musb: Ensure rx reinit occurs for shared_fifo endpoints usb: musb: host: correct cppi dma channel for isoch transfer usb: musb: only restore devctl when session was set in backup usb: phy: Check initial state for twl6030 usb: musb: Use normal module_init for 2430 glue usb: musb: Remove pm_runtime_set_irq_safe usb: musb: Remove extra PM runtime calls from 2430 glue layer usb: musb: Return error value from musb_mailbox ...
Diffstat (limited to 'drivers/usb/phy/phy-twl6030-usb.c')
-rw-r--r--drivers/usb/phy/phy-twl6030-usb.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/drivers/usb/phy/phy-twl6030-usb.c b/drivers/usb/phy/phy-twl6030-usb.c
index 24e2b3cf1867..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 {
struct regulator *usb3v3;
+ /* used to check initial cable status after probe */
+ struct delayed_work get_status_work;
+
/* used to set vbus, in atomic path */
struct work_struct set_vbus_work;
@@ -227,12 +230,16 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl)
twl->asleep = 1;
status = MUSB_VBUS_VALID;
twl->linkstat = status;
- musb_mailbox(status);
+ ret = musb_mailbox(status);
+ if (ret)
+ twl->linkstat = MUSB_UNKNOWN;
} else {
if (twl->linkstat != MUSB_UNKNOWN) {
status = MUSB_VBUS_OFF;
twl->linkstat = status;
- musb_mailbox(status);
+ ret = musb_mailbox(status);
+ if (ret)
+ twl->linkstat = MUSB_UNKNOWN;
if (twl->asleep) {
regulator_disable(twl->usb3v3);
twl->asleep = 0;
@@ -264,7 +271,9 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl)
twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_SET);
status = MUSB_ID_GROUND;
twl->linkstat = status;
- musb_mailbox(status);
+ ret = musb_mailbox(status);
+ if (ret)
+ twl->linkstat = MUSB_UNKNOWN;
} else {
twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_CLR);
twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET);
@@ -274,6 +283,15 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl)
return IRQ_HANDLED;
}
+static void twl6030_status_work(struct work_struct *work)
+{
+ struct twl6030_usb *twl = container_of(work, struct twl6030_usb,
+ get_status_work.work);
+
+ twl6030_usb_irq(twl->irq2, twl);
+ twl6030_usbotg_irq(twl->irq1, twl);
+}
+
static int twl6030_enable_irq(struct twl6030_usb *twl)
{
twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET);
@@ -284,8 +302,6 @@ static int twl6030_enable_irq(struct twl6030_usb *twl)
REG_INT_MSK_LINE_C);
twl6030_interrupt_unmask(TWL6030_CHARGER_CTRL_INT_MASK,
REG_INT_MSK_STS_C);
- twl6030_usb_irq(twl->irq2, twl);
- twl6030_usbotg_irq(twl->irq1, twl);
return 0;
}
@@ -371,6 +387,7 @@ static int twl6030_usb_probe(struct platform_device *pdev)
dev_warn(&pdev->dev, "could not create sysfs file\n");
INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work);
+ INIT_DELAYED_WORK(&twl->get_status_work, twl6030_status_work);
status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq,
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT,
@@ -395,6 +412,7 @@ static int twl6030_usb_probe(struct platform_device *pdev)
twl->asleep = 0;
twl6030_enable_irq(twl);
+ schedule_delayed_work(&twl->get_status_work, HZ);
dev_info(&pdev->dev, "Initialized TWL6030 USB module\n");
return 0;
@@ -404,6 +422,7 @@ static int twl6030_usb_remove(struct platform_device *pdev)
{
struct twl6030_usb *twl = platform_get_drvdata(pdev);
+ cancel_delayed_work(&twl->get_status_work);
twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK,
REG_INT_MSK_LINE_C);
twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK,