From b3c575b3f1852808e4927038bd623aa8033a1640 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Tue, 8 May 2012 09:22:49 -0700 Subject: [PATCH] --- yaml --- r: 303984 b: refs/heads/master c: 1530bbc6272d9da1e39ef8e06190d42c13a02733 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/usb/host/xhci-pci.c | 1 + trunk/drivers/usb/host/xhci-ring.c | 20 ++++++++-- trunk/drivers/usb/host/xhci.h | 1 + trunk/drivers/usb/otg/gpio_vbus.c | 58 ++++++----------------------- trunk/drivers/usb/otg/twl6030-usb.c | 4 +- trunk/include/linux/usb/gpio_vbus.h | 2 - 7 files changed, 33 insertions(+), 55 deletions(-) diff --git a/[refs] b/[refs] index 593cbcd18bf7..33e6509d6320 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 7cbb062ade87b987a24aa834bbde32ad8374a4cf +refs/heads/master: 1530bbc6272d9da1e39ef8e06190d42c13a02733 diff --git a/trunk/drivers/usb/host/xhci-pci.c b/trunk/drivers/usb/host/xhci-pci.c index 7a856a767e77..19e89216436e 100644 --- a/trunk/drivers/usb/host/xhci-pci.c +++ b/trunk/drivers/usb/host/xhci-pci.c @@ -72,6 +72,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci_dbg(xhci, "QUIRK: Fresco Logic revision %u " "has broken MSI implementation\n", pdev->revision); + xhci->quirks |= XHCI_TRUST_TX_LENGTH; } if (pdev->vendor == PCI_VENDOR_ID_NEC) diff --git a/trunk/drivers/usb/host/xhci-ring.c b/trunk/drivers/usb/host/xhci-ring.c index 329fd2a98dd6..c60617bb8c2e 100644 --- a/trunk/drivers/usb/host/xhci-ring.c +++ b/trunk/drivers/usb/host/xhci-ring.c @@ -1787,8 +1787,12 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, /* handle completion code */ switch (trb_comp_code) { case COMP_SUCCESS: - frame->status = 0; - break; + if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) { + frame->status = 0; + break; + } + if ((xhci->quirks & XHCI_TRUST_TX_LENGTH)) + trb_comp_code = COMP_SHORT_TX; case COMP_SHORT_TX: frame->status = td->urb->transfer_flags & URB_SHORT_NOT_OK ? -EREMOTEIO : 0; @@ -1885,13 +1889,16 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, switch (trb_comp_code) { case COMP_SUCCESS: /* Double check that the HW transferred everything. */ - if (event_trb != td->last_trb) { + if (event_trb != td->last_trb || + TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { xhci_warn(xhci, "WARN Successful completion " "on short TX\n"); if (td->urb->transfer_flags & URB_SHORT_NOT_OK) *status = -EREMOTEIO; else *status = 0; + if ((xhci->quirks & XHCI_TRUST_TX_LENGTH)) + trb_comp_code = COMP_SHORT_TX; } else { *status = 0; } @@ -2050,6 +2057,13 @@ static int handle_tx_event(struct xhci_hcd *xhci, * transfer type */ case COMP_SUCCESS: + if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) + break; + if (xhci->quirks & XHCI_TRUST_TX_LENGTH) + trb_comp_code = COMP_SHORT_TX; + else + xhci_warn(xhci, "WARN Successful completion on short TX: " + "needs XHCI_TRUST_TX_LENGTH quirk?\n"); case COMP_SHORT_TX: break; case COMP_STOP: diff --git a/trunk/drivers/usb/host/xhci.h b/trunk/drivers/usb/host/xhci.h index ce1edd7246aa..ac142760fd3b 100644 --- a/trunk/drivers/usb/host/xhci.h +++ b/trunk/drivers/usb/host/xhci.h @@ -1481,6 +1481,7 @@ struct xhci_hcd { #define XHCI_RESET_ON_RESUME (1 << 7) #define XHCI_SW_BW_CHECKING (1 << 8) #define XHCI_AMD_0x96_HOST (1 << 9) +#define XHCI_TRUST_TX_LENGTH (1 << 10) unsigned int num_active_eps; unsigned int limit_active_eps; /* There are two roothubs to keep track of bus suspend info for */ diff --git a/trunk/drivers/usb/otg/gpio_vbus.c b/trunk/drivers/usb/otg/gpio_vbus.c index bde6298a9693..bd6e755dd3d8 100644 --- a/trunk/drivers/usb/otg/gpio_vbus.c +++ b/trunk/drivers/usb/otg/gpio_vbus.c @@ -39,7 +39,6 @@ struct gpio_vbus_data { unsigned mA; struct delayed_work work; int vbus; - int irq; }; @@ -53,7 +52,8 @@ struct gpio_vbus_data { * edges might be workable. */ #define VBUS_IRQ_FLAGS \ - (IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING) + ( IRQF_SAMPLE_RANDOM | IRQF_SHARED \ + | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING ) /* interface to regulator framework */ @@ -173,11 +173,12 @@ static int gpio_vbus_set_peripheral(struct usb_otg *otg, struct gpio_vbus_data *gpio_vbus; struct gpio_vbus_mach_info *pdata; struct platform_device *pdev; - int gpio; + int gpio, irq; gpio_vbus = container_of(otg->phy, struct gpio_vbus_data, phy); pdev = to_platform_device(gpio_vbus->dev); pdata = gpio_vbus->dev->platform_data; + irq = gpio_to_irq(pdata->gpio_vbus); gpio = pdata->gpio_pullup; if (!gadget) { @@ -202,7 +203,7 @@ static int gpio_vbus_set_peripheral(struct usb_otg *otg, /* initialize connection state */ gpio_vbus->vbus = 0; /* start with disconnected */ - gpio_vbus_irq(gpio_vbus->irq, pdev); + gpio_vbus_irq(irq, pdev); return 0; } @@ -242,7 +243,6 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) struct gpio_vbus_data *gpio_vbus; struct resource *res; int err, gpio, irq; - unsigned long irqflags; if (!pdata || !gpio_is_valid(pdata->gpio_vbus)) return -EINVAL; @@ -279,13 +279,10 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res) { irq = res->start; - irqflags = (res->flags & IRQF_TRIGGER_MASK) | IRQF_SHARED; - } else { + res->flags &= IRQF_TRIGGER_MASK; + res->flags |= IRQF_SAMPLE_RANDOM | IRQF_SHARED; + } else irq = gpio_to_irq(gpio); - irqflags = VBUS_IRQ_FLAGS; - } - - gpio_vbus->irq = irq; /* if data line pullup is in use, initialize it to "not pulling up" */ gpio = pdata->gpio_pullup; @@ -301,7 +298,8 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) gpio_direction_output(gpio, pdata->gpio_pullup_inverted); } - err = request_irq(irq, gpio_vbus_irq, irqflags, "vbus_detect", pdev); + err = request_irq(irq, gpio_vbus_irq, VBUS_IRQ_FLAGS, + "vbus_detect", pdev); if (err) { dev_err(&pdev->dev, "can't request irq %i, err: %d\n", irq, err); @@ -327,8 +325,6 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) goto err_otg; } - device_init_wakeup(&pdev->dev, pdata->wakeup); - return 0; err_otg: regulator_put(gpio_vbus->vbus_draw); @@ -350,13 +346,11 @@ static int __exit gpio_vbus_remove(struct platform_device *pdev) struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; int gpio = pdata->gpio_vbus; - device_init_wakeup(&pdev->dev, 0); - cancel_delayed_work_sync(&gpio_vbus->work); regulator_put(gpio_vbus->vbus_draw); usb_set_transceiver(NULL); - free_irq(gpio_vbus->irq, pdev); + free_irq(gpio_to_irq(gpio), pdev); if (gpio_is_valid(pdata->gpio_pullup)) gpio_free(pdata->gpio_pullup); gpio_free(gpio); @@ -367,33 +361,6 @@ static int __exit gpio_vbus_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM -static int gpio_vbus_pm_suspend(struct device *dev) -{ - struct gpio_vbus_data *gpio_vbus = dev_get_drvdata(dev); - - if (device_may_wakeup(dev)) - enable_irq_wake(gpio_vbus->irq); - - return 0; -} - -static int gpio_vbus_pm_resume(struct device *dev) -{ - struct gpio_vbus_data *gpio_vbus = dev_get_drvdata(dev); - - if (device_may_wakeup(dev)) - disable_irq_wake(gpio_vbus->irq); - - return 0; -} - -static const struct dev_pm_ops gpio_vbus_dev_pm_ops = { - .suspend = gpio_vbus_pm_suspend, - .resume = gpio_vbus_pm_resume, -}; -#endif - /* NOTE: the gpio-vbus device may *NOT* be hotplugged */ MODULE_ALIAS("platform:gpio-vbus"); @@ -402,9 +369,6 @@ static struct platform_driver gpio_vbus_driver = { .driver = { .name = "gpio-vbus", .owner = THIS_MODULE, -#ifdef CONFIG_PM - .pm = &gpio_vbus_dev_pm_ops, -#endif }, .remove = __exit_p(gpio_vbus_remove), }; diff --git a/trunk/drivers/usb/otg/twl6030-usb.c b/trunk/drivers/usb/otg/twl6030-usb.c index d2a9a8e691b9..e3fa387ca81e 100644 --- a/trunk/drivers/usb/otg/twl6030-usb.c +++ b/trunk/drivers/usb/otg/twl6030-usb.c @@ -455,7 +455,7 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) twl->irq_enabled = true; status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "twl6030_usb", twl); if (status < 0) { dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", @@ -467,7 +467,7 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) } status = request_threaded_irq(twl->irq2, NULL, twl6030_usb_irq, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "twl6030_usb", twl); if (status < 0) { dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", diff --git a/trunk/include/linux/usb/gpio_vbus.h b/trunk/include/linux/usb/gpio_vbus.h index 837bba604a0b..d9f03ccc2d60 100644 --- a/trunk/include/linux/usb/gpio_vbus.h +++ b/trunk/include/linux/usb/gpio_vbus.h @@ -17,7 +17,6 @@ * @gpio_pullup: optional D+ or D- pullup GPIO (else negative/invalid) * @gpio_vbus_inverted: true if gpio_vbus is active low * @gpio_pullup_inverted: true if gpio_pullup is active low - * @wakeup: configure gpio_vbus as a wake-up source * * The VBUS sensing GPIO should have a pulldown, which will normally be * part of a resistor ladder turning a 4.0V-5.25V level on VBUS into a @@ -28,5 +27,4 @@ struct gpio_vbus_mach_info { int gpio_pullup; bool gpio_vbus_inverted; bool gpio_pullup_inverted; - bool wakeup; };