Merge tag 'xceiv-for-v3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next

Felipe writes:
	usb: xceiv: patches for v3.9 merge window

	Two new PHY drivers coming here: one for Samsung,
	one for OMAP. Both architectures are adding USB3
	support to mainline kernel.

	The PHY layer now allows us to have mulitple PHYs
	of the same type, which is necessary for platforms
	which provide more than one USB peripheral port.

	There's also a few cleanups here: removal of __dev*
	annotations, conversion of a cast to to_delayed_work(),
	and mxs-phy learns about ->set_suspend.
This commit is contained in:
Greg Kroah-Hartman
2013-01-25 09:09:46 -08:00
26 changed files with 2449 additions and 158 deletions

View File

@@ -15,14 +15,39 @@
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/platform_data/usb-exynos.h>
#include <linux/usb/phy.h>
#include <linux/usb/samsung_usb_phy.h>
#include <plat/usb-phy.h>
struct exynos_ohci_hcd {
struct device *dev;
struct usb_hcd *hcd;
struct clk *clk;
struct usb_phy *phy;
struct usb_otg *otg;
struct exynos4_ohci_platdata *pdata;
};
static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
{
struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
if (exynos_ohci->phy)
usb_phy_init(exynos_ohci->phy);
else if (exynos_ohci->pdata->phy_init)
exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
}
static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
{
struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
if (exynos_ohci->phy)
usb_phy_shutdown(exynos_ohci->phy);
else if (exynos_ohci->pdata->phy_exit)
exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
}
static int ohci_exynos_reset(struct usb_hcd *hcd)
{
return ohci_init(hcd_to_ohci(hcd));
@@ -78,20 +103,15 @@ static u64 ohci_exynos_dma_mask = DMA_BIT_MASK(32);
static int exynos_ohci_probe(struct platform_device *pdev)
{
struct exynos4_ohci_platdata *pdata;
struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
struct exynos_ohci_hcd *exynos_ohci;
struct usb_hcd *hcd;
struct ohci_hcd *ohci;
struct resource *res;
struct usb_phy *phy;
int irq;
int err;
pdata = pdev->dev.platform_data;
if (!pdata) {
dev_err(&pdev->dev, "No platform data defined\n");
return -EINVAL;
}
/*
* Right now device-tree probed devices don't get dma_mask set.
* Since shared usb code relies on it, set it here for now.
@@ -107,6 +127,20 @@ static int exynos_ohci_probe(struct platform_device *pdev)
if (!exynos_ohci)
return -ENOMEM;
phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
if (IS_ERR_OR_NULL(phy)) {
/* Fallback to pdata */
if (!pdata) {
dev_warn(&pdev->dev, "no platform data or transceiver defined\n");
return -EPROBE_DEFER;
} else {
exynos_ohci->pdata = pdata;
}
} else {
exynos_ohci->phy = phy;
exynos_ohci->otg = phy->otg;
}
exynos_ohci->dev = &pdev->dev;
hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev,
@@ -152,8 +186,11 @@ static int exynos_ohci_probe(struct platform_device *pdev)
goto fail_io;
}
if (pdata->phy_init)
pdata->phy_init(pdev, S5P_USB_PHY_HOST);
if (exynos_ohci->otg)
exynos_ohci->otg->set_host(exynos_ohci->otg,
&exynos_ohci->hcd->self);
exynos_ohci_phy_enable(exynos_ohci);
ohci = hcd_to_ohci(hcd);
ohci_hcd_init(ohci);
@@ -161,13 +198,15 @@ static int exynos_ohci_probe(struct platform_device *pdev)
err = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (err) {
dev_err(&pdev->dev, "Failed to add USB HCD\n");
goto fail_io;
goto fail_add_hcd;
}
platform_set_drvdata(pdev, exynos_ohci);
return 0;
fail_add_hcd:
exynos_ohci_phy_disable(exynos_ohci);
fail_io:
clk_disable_unprepare(exynos_ohci->clk);
fail_clk:
@@ -177,14 +216,16 @@ fail_clk:
static int exynos_ohci_remove(struct platform_device *pdev)
{
struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
struct usb_hcd *hcd = exynos_ohci->hcd;
usb_remove_hcd(hcd);
if (pdata && pdata->phy_exit)
pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
if (exynos_ohci->otg)
exynos_ohci->otg->set_host(exynos_ohci->otg,
&exynos_ohci->hcd->self);
exynos_ohci_phy_disable(exynos_ohci);
clk_disable_unprepare(exynos_ohci->clk);
@@ -208,8 +249,6 @@ static int exynos_ohci_suspend(struct device *dev)
struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
struct usb_hcd *hcd = exynos_ohci->hcd;
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
struct platform_device *pdev = to_platform_device(dev);
struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
unsigned long flags;
int rc = 0;
@@ -228,8 +267,11 @@ static int exynos_ohci_suspend(struct device *dev)
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
if (pdata && pdata->phy_exit)
pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
if (exynos_ohci->otg)
exynos_ohci->otg->set_host(exynos_ohci->otg,
&exynos_ohci->hcd->self);
exynos_ohci_phy_disable(exynos_ohci);
clk_disable_unprepare(exynos_ohci->clk);
@@ -243,13 +285,14 @@ static int exynos_ohci_resume(struct device *dev)
{
struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
struct usb_hcd *hcd = exynos_ohci->hcd;
struct platform_device *pdev = to_platform_device(dev);
struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
clk_prepare_enable(exynos_ohci->clk);
if (pdata && pdata->phy_init)
pdata->phy_init(pdev, S5P_USB_PHY_HOST);
if (exynos_ohci->otg)
exynos_ohci->otg->set_host(exynos_ohci->otg,
&exynos_ohci->hcd->self);
exynos_ohci_phy_enable(exynos_ohci);
ohci_resume(hcd, false);