Skip to content

Commit

Permalink
Merge tag 'usb-3.17-rc5' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/gregkh/usb

Pull USB fixes from Greg KH:
 "Here are some USB and PHY fixes for 3.17-rc5.

  Nothing major here, just a number of tiny fixes for reported issues,
  and some new device ids as well.

  All have been tested in linux-next"

* tag 'usb-3.17-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (46 commits)
  xhci: fix oops when xhci resumes from hibernate with hw lpm capable devices
  usb: xhci: Fix OOPS in xhci error handling code
  xhci: Fix null pointer dereference if xhci initialization fails
  storage: Add single-LUN quirk for Jaz USB Adapter
  uas: Add missing le16_to_cpu calls to asm1051 / asm1053 usb-id check
  usb: chipidea: msm: Initialize PHY on reset event
  usb: chipidea: msm: Use USB PHY API to control PHY state
  usb: hub: take hub->hdev reference when processing from eventlist
  uas: Disable uas on ASM1051 devices
  usb: dwc2/gadget: avoid disabling ep0
  usb: dwc2/gadget: delay enabling irq once hardware is configured properly
  usb: dwc2/gadget: do not call disconnect method in pullup
  usb: dwc2/gadget: break infinite loop in endpoint disable code
  usb: dwc2/gadget: fix phy initialization sequence
  usb: dwc2/gadget: fix phy disable sequence
  uwb: init beacon cache entry before registering uwb device
  USB: ftdi_sio: Add support for GE Healthcare Nemo Tracker device
  USB: document the 'u' flag for usb-storage quirks parameter
  usb: host: xhci: fix compliance mode workaround
  usb: dwc3: fix TRB completion when multiple TRBs are started
  ...
  • Loading branch information
Linus Torvalds committed Sep 12, 2014
2 parents 602b536 + e2c6098 commit 90a3c48
Show file tree
Hide file tree
Showing 35 changed files with 389 additions and 138 deletions.
1 change: 1 addition & 0 deletions Documentation/devicetree/bindings/usb/mxs-phy.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Required properties:
* "fsl,imx23-usbphy" for imx23 and imx28
* "fsl,imx6q-usbphy" for imx6dq and imx6dl
* "fsl,imx6sl-usbphy" for imx6sl
* "fsl,imx6sx-usbphy" for imx6sx
"fsl,imx23-usbphy" is still a fallback for other strings
- reg: Should contain registers location and length
- interrupts: Should contain phy interrupt
Expand Down
1 change: 1 addition & 0 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3541,6 +3541,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
bogus residue values);
s = SINGLE_LUN (the device has only one
Logical Unit);
u = IGNORE_UAS (don't bind to the uas driver);
w = NO_WP_DETECT (don't test whether the
medium is write-protected).
Example: quirks=0419:aaf5:rl,0421:0433:rc
Expand Down
13 changes: 13 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -7913,6 +7913,19 @@ S: Supported
L: netdev@vger.kernel.org
F: drivers/net/ethernet/samsung/sxgbe/

SAMSUNG USB2 PHY DRIVER
M: Kamil Debski <k.debski@samsung.com>
L: linux-kernel@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/phy/samsung-phy.txt
F: Documentation/phy/samsung-usb2.txt
F: drivers/phy/phy-exynos4210-usb2.c
F: drivers/phy/phy-exynos4x12-usb2.c
F: drivers/phy/phy-exynos5250-usb2.c
F: drivers/phy/phy-s5pv210-usb2.c
F: drivers/phy/phy-samsung-usb2.c
F: drivers/phy/phy-samsung-usb2.h

SERIAL DRIVERS
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
L: linux-serial@vger.kernel.org
Expand Down
2 changes: 1 addition & 1 deletion drivers/phy/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ config PHY_MVEBU_SATA
config PHY_MIPHY365X
tristate "STMicroelectronics MIPHY365X PHY driver for STiH41x series"
depends on ARCH_STI
depends on GENERIC_PHY
depends on HAS_IOMEM
depends on OF
select GENERIC_PHY
help
Enable this to support the miphy transceiver (for SATA/PCIE)
that is part of STMicroelectronics STiH41x SoC series.
Expand Down
1 change: 1 addition & 0 deletions drivers/phy/phy-exynos5-usbdrd.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = {
},
{ },
};
MODULE_DEVICE_TABLE(of, exynos5_usbdrd_phy_of_match);

static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
{
Expand Down
121 changes: 73 additions & 48 deletions drivers/phy/phy-twl4030-usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <linux/delay.h>
#include <linux/usb/otg.h>
#include <linux/phy/phy.h>
#include <linux/pm_runtime.h>
#include <linux/usb/musb-omap.h>
#include <linux/usb/ulpi.h>
#include <linux/i2c/twl.h>
Expand Down Expand Up @@ -422,37 +423,55 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on)
}
}

static int twl4030_phy_power_off(struct phy *phy)
static int twl4030_usb_runtime_suspend(struct device *dev)
{
struct twl4030_usb *twl = phy_get_drvdata(phy);
struct twl4030_usb *twl = dev_get_drvdata(dev);

dev_dbg(twl->dev, "%s\n", __func__);
if (twl->asleep)
return 0;

twl4030_phy_power(twl, 0);
twl->asleep = 1;
dev_dbg(twl->dev, "%s\n", __func__);

return 0;
}

static void __twl4030_phy_power_on(struct twl4030_usb *twl)
static int twl4030_usb_runtime_resume(struct device *dev)
{
struct twl4030_usb *twl = dev_get_drvdata(dev);

dev_dbg(twl->dev, "%s\n", __func__);
if (!twl->asleep)
return 0;

twl4030_phy_power(twl, 1);
twl4030_i2c_access(twl, 1);
twl4030_usb_set_mode(twl, twl->usb_mode);
if (twl->usb_mode == T2_USB_MODE_ULPI)
twl4030_i2c_access(twl, 0);
twl->asleep = 0;

return 0;
}

static int twl4030_phy_power_off(struct phy *phy)
{
struct twl4030_usb *twl = phy_get_drvdata(phy);

dev_dbg(twl->dev, "%s\n", __func__);
pm_runtime_mark_last_busy(twl->dev);
pm_runtime_put_autosuspend(twl->dev);

return 0;
}

static int twl4030_phy_power_on(struct phy *phy)
{
struct twl4030_usb *twl = phy_get_drvdata(phy);

if (!twl->asleep)
return 0;
__twl4030_phy_power_on(twl);
twl->asleep = 0;
dev_dbg(twl->dev, "%s\n", __func__);
pm_runtime_get_sync(twl->dev);
twl4030_i2c_access(twl, 1);
twl4030_usb_set_mode(twl, twl->usb_mode);
if (twl->usb_mode == T2_USB_MODE_ULPI)
twl4030_i2c_access(twl, 0);

/*
* XXX When VBUS gets driven after musb goes to A mode,
Expand Down Expand Up @@ -558,9 +577,27 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
* USB_LINK_VBUS state. musb_hdrc won't care until it
* starts to handle softconnect right.
*/
if ((status == OMAP_MUSB_VBUS_VALID) ||
(status == OMAP_MUSB_ID_GROUND)) {
if (twl->asleep)
pm_runtime_get_sync(twl->dev);
} else {
if (!twl->asleep) {
pm_runtime_mark_last_busy(twl->dev);
pm_runtime_put_autosuspend(twl->dev);
}
}
omap_musb_mailbox(status);
}
sysfs_notify(&twl->dev->kobj, NULL, "vbus");

/* don't schedule during sleep - irq works right then */
if (status == OMAP_MUSB_ID_GROUND && !twl->asleep) {
cancel_delayed_work(&twl->id_workaround_work);
schedule_delayed_work(&twl->id_workaround_work, HZ);
}

if (irq)
sysfs_notify(&twl->dev->kobj, NULL, "vbus");

return IRQ_HANDLED;
}
Expand All @@ -569,52 +606,26 @@ static void twl4030_id_workaround_work(struct work_struct *work)
{
struct twl4030_usb *twl = container_of(work, struct twl4030_usb,
id_workaround_work.work);
enum omap_musb_vbus_id_status status;
bool status_changed = false;

status = twl4030_usb_linkstat(twl);

spin_lock_irq(&twl->lock);
if (status >= 0 && status != twl->linkstat) {
twl->linkstat = status;
status_changed = true;
}
spin_unlock_irq(&twl->lock);

if (status_changed) {
dev_dbg(twl->dev, "handle missing status change to %d\n",
status);
omap_musb_mailbox(status);
}

/* don't schedule during sleep - irq works right then */
if (status == OMAP_MUSB_ID_GROUND && !twl->asleep) {
cancel_delayed_work(&twl->id_workaround_work);
schedule_delayed_work(&twl->id_workaround_work, HZ);
}
twl4030_usb_irq(0, twl);
}

static int twl4030_phy_init(struct phy *phy)
{
struct twl4030_usb *twl = phy_get_drvdata(phy);
enum omap_musb_vbus_id_status status;

/*
* Start in sleep state, we'll get called through set_suspend()
* callback when musb is runtime resumed and it's time to start.
*/
__twl4030_phy_power(twl, 0);
twl->asleep = 1;

pm_runtime_get_sync(twl->dev);
status = twl4030_usb_linkstat(twl);
twl->linkstat = status;

if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID) {
if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID)
omap_musb_mailbox(twl->linkstat);
twl4030_phy_power_on(phy);
}

sysfs_notify(&twl->dev->kobj, NULL, "vbus");
pm_runtime_mark_last_busy(twl->dev);
pm_runtime_put_autosuspend(twl->dev);

return 0;
}

Expand Down Expand Up @@ -650,6 +661,11 @@ static const struct phy_ops ops = {
.owner = THIS_MODULE,
};

static const struct dev_pm_ops twl4030_usb_pm_ops = {
SET_RUNTIME_PM_OPS(twl4030_usb_runtime_suspend,
twl4030_usb_runtime_resume, NULL)
};

static int twl4030_usb_probe(struct platform_device *pdev)
{
struct twl4030_usb_data *pdata = dev_get_platdata(&pdev->dev);
Expand Down Expand Up @@ -726,6 +742,11 @@ static int twl4030_usb_probe(struct platform_device *pdev)

ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier);

pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);

/* Our job is to use irqs and status from the power module
* to keep the transceiver disabled when nothing's connected.
*
Expand All @@ -744,6 +765,9 @@ static int twl4030_usb_probe(struct platform_device *pdev)
return status;
}

pm_runtime_mark_last_busy(&pdev->dev);
pm_runtime_put_autosuspend(twl->dev);

dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");
return 0;
}
Expand All @@ -753,6 +777,7 @@ static int twl4030_usb_remove(struct platform_device *pdev)
struct twl4030_usb *twl = platform_get_drvdata(pdev);
int val;

pm_runtime_get_sync(twl->dev);
cancel_delayed_work(&twl->id_workaround_work);
device_remove_file(twl->dev, &dev_attr_vbus);

Expand All @@ -772,9 +797,8 @@ static int twl4030_usb_remove(struct platform_device *pdev)

/* disable complete OTG block */
twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);

if (!twl->asleep)
twl4030_phy_power(twl, 0);
pm_runtime_mark_last_busy(twl->dev);
pm_runtime_put(twl->dev);

return 0;
}
Expand All @@ -792,6 +816,7 @@ static struct platform_driver twl4030_usb_driver = {
.remove = twl4030_usb_remove,
.driver = {
.name = "twl4030_usb",
.pm = &twl4030_usb_pm_ops,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(twl4030_usb_id_table),
},
Expand Down
7 changes: 2 additions & 5 deletions drivers/usb/chipidea/ci_hdrc_msm.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,21 @@
static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
{
struct device *dev = ci->gadget.dev.parent;
int val;

switch (event) {
case CI_HDRC_CONTROLLER_RESET_EVENT:
dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
writel(0, USB_AHBBURST);
writel(0, USB_AHBMODE);
usb_phy_init(ci->transceiver);
break;
case CI_HDRC_CONTROLLER_STOPPED_EVENT:
dev_dbg(dev, "CI_HDRC_CONTROLLER_STOPPED_EVENT received\n");
/*
* Put the transceiver in non-driving mode. Otherwise host
* may not detect soft-disconnection.
*/
val = usb_phy_io_read(ci->transceiver, ULPI_FUNC_CTRL);
val &= ~ULPI_FUNC_CTRL_OPMODE_MASK;
val |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING;
usb_phy_io_write(ci->transceiver, val, ULPI_FUNC_CTRL);
usb_phy_notify_disconnect(ci->transceiver, USB_SPEED_UNKNOWN);
break;
default:
dev_dbg(dev, "unknown ci_hdrc event\n");
Expand Down
4 changes: 3 additions & 1 deletion drivers/usb/core/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -5024,9 +5024,10 @@ static void hub_events(void)

hub = list_entry(tmp, struct usb_hub, event_list);
kref_get(&hub->kref);
hdev = hub->hdev;
usb_get_dev(hdev);
spin_unlock_irq(&hub_event_lock);

hdev = hub->hdev;
hub_dev = hub->intfdev;
intf = to_usb_interface(hub_dev);
dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n",
Expand Down Expand Up @@ -5139,6 +5140,7 @@ static void hub_events(void)
usb_autopm_put_interface(intf);
loop_disconnected:
usb_unlock_device(hdev);
usb_put_dev(hdev);
kref_put(&hub->kref, hub_release);

} /* end while (1) */
Expand Down
Loading

0 comments on commit 90a3c48

Please sign in to comment.