summaryrefslogtreecommitdiffstats
path: root/drivers/usb/phy
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/phy')
-rw-r--r--drivers/usb/phy/Kconfig36
-rw-r--r--drivers/usb/phy/phy-fsl-usb.c6
-rw-r--r--drivers/usb/phy/phy-generic.c3
-rw-r--r--drivers/usb/phy/phy-gpio-vbus-usb.c10
-rw-r--r--drivers/usb/phy/phy-msm-usb.c4
-rw-r--r--drivers/usb/phy/phy-mv-u3d-usb.c4
-rw-r--r--drivers/usb/phy/phy-mv-usb.c6
-rw-r--r--drivers/usb/phy/phy-mxs-usb.c13
-rw-r--r--drivers/usb/phy/phy-omap-control.c3
-rw-r--r--drivers/usb/phy/phy-omap-usb3.c87
-rw-r--r--drivers/usb/phy/phy-rcar-usb.c9
-rw-r--r--drivers/usb/phy/phy-samsung-usb2.c2
-rw-r--r--drivers/usb/phy/phy-samsung-usb3.c2
-rw-r--r--drivers/usb/phy/phy-tegra-usb.c254
-rw-r--r--drivers/usb/phy/phy-twl4030-usb.c2
-rw-r--r--drivers/usb/phy/phy-twl6030-usb.c2
16 files changed, 255 insertions, 188 deletions
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 3622fff8b798..f5ea339ec155 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -1,22 +1,10 @@
#
# Physical Layer USB driver configuration
#
-menuconfig USB_PHY
- bool "USB Physical Layer drivers"
- help
- Most USB controllers have the physical layer signalling part
- (commonly called a PHY) built in. However, dual-role devices
- (a.k.a. USB on-the-go) which support being USB master or slave
- with the same connector often use an external PHY.
-
- The drivers in this submenu add support for such PHY devices.
- They are not needed for standard master-only (or the vast
- majority of slave-only) USB interfaces.
-
- If you're not sure if this applies to you, it probably doesn't;
- say N here.
+menu "USB Physical Layer drivers"
-if USB_PHY
+config USB_PHY
+ def_bool n
#
# USB Transceiver Drivers
@@ -24,6 +12,7 @@ if USB_PHY
config AB8500_USB
tristate "AB8500 USB Transceiver Driver"
depends on AB8500_CORE
+ select USB_PHY
help
Enable this to support the USB OTG transceiver in AB8500 chip.
This transceiver supports high and full speed devices plus,
@@ -33,12 +22,14 @@ config FSL_USB2_OTG
bool "Freescale USB OTG Transceiver Driver"
depends on USB_EHCI_FSL && USB_FSL_USB2 && PM_RUNTIME
select USB_OTG
+ select USB_PHY
help
Enable this to support Freescale USB OTG transceiver.
config ISP1301_OMAP
tristate "Philips ISP1301 with OMAP OTG"
depends on I2C && ARCH_OMAP_OTG
+ select USB_PHY
help
If you say yes here you get support for the Philips ISP1301
USB-On-The-Go transceiver working with the OMAP OTG controller.
@@ -52,12 +43,14 @@ config ISP1301_OMAP
config MV_U3D_PHY
bool "Marvell USB 3.0 PHY controller Driver"
depends on CPU_MMP3
+ select USB_PHY
help
Enable this to support Marvell USB 3.0 phy controller for Marvell
SoC.
config NOP_USB_XCEIV
tristate "NOP USB Transceiver Driver"
+ select USB_PHY
help
This driver is to be used by all the usb transceiver which are either
built-in with usb ip or which are autonomous and doesn't require any
@@ -76,6 +69,7 @@ config OMAP_USB2
tristate "OMAP USB2 PHY Driver"
depends on ARCH_OMAP2PLUS
select OMAP_CONTROL_USB
+ select USB_PHY
help
Enable this to support the transceiver that is part of SOC. This
driver takes care of all the PHY functionality apart from comparator.
@@ -85,6 +79,7 @@ config OMAP_USB2
config OMAP_USB3
tristate "OMAP USB3 PHY Driver"
select OMAP_CONTROL_USB
+ select USB_PHY
help
Enable this to support the USB3 PHY that is part of SOC. This
driver takes care of all the PHY functionality apart from comparator.
@@ -101,6 +96,7 @@ config SAMSUNG_USBPHY
config SAMSUNG_USB2PHY
tristate "Samsung USB 2.0 PHY controller Driver"
select SAMSUNG_USBPHY
+ select USB_PHY
help
Enable this to support Samsung USB 2.0 (High Speed) PHY controller
driver for Samsung SoCs.
@@ -108,6 +104,7 @@ config SAMSUNG_USB2PHY
config SAMSUNG_USB3PHY
tristate "Samsung USB 3.0 PHY controller Driver"
select SAMSUNG_USBPHY
+ select USB_PHY
help
Enable this to support Samsung USB 3.0 (Super Speed) phy controller
for samsung SoCs.
@@ -115,6 +112,7 @@ config SAMSUNG_USB3PHY
config TWL4030_USB
tristate "TWL4030 USB Transceiver Driver"
depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS
+ select USB_PHY
help
Enable this to support the USB OTG transceiver on TWL4030
family chips (including the TWL5030 and TPS659x0 devices).
@@ -135,6 +133,7 @@ config TWL6030_USB
config USB_GPIO_VBUS
tristate "GPIO based peripheral-only VBUS sensing 'transceiver'"
depends on GPIOLIB
+ select USB_PHY
help
Provides simple GPIO VBUS sensing for controllers with an
internal transceiver via the usb_phy interface, and
@@ -145,6 +144,7 @@ config USB_ISP1301
tristate "NXP ISP1301 USB transceiver support"
depends on USB || USB_GADGET
depends on I2C
+ select USB_PHY
help
Say Y here to add support for the NXP ISP1301 USB transceiver driver.
This chip is typically used as USB transceiver for USB host, gadget
@@ -156,6 +156,7 @@ config USB_ISP1301
config USB_MSM_OTG
tristate "OTG support for Qualcomm on-chip USB controller"
depends on (USB || USB_GADGET) && ARCH_MSM
+ select USB_PHY
help
Enable this to support the USB OTG transceiver on MSM chips. It
handles PHY initialization, clock management, and workarounds
@@ -169,6 +170,7 @@ config USB_MV_OTG
tristate "Marvell USB OTG support"
depends on USB_EHCI_MV && USB_MV_UDC && PM_RUNTIME
select USB_OTG
+ select USB_PHY
help
Say Y here if you want to build Marvell USB OTG transciever
driver in kernel (including PXA and MMP series). This driver
@@ -180,6 +182,7 @@ config USB_MXS_PHY
tristate "Freescale MXS USB PHY support"
depends on ARCH_MXC || ARCH_MXS
select STMP_DEVICE
+ select USB_PHY
help
Enable this to support the Freescale MXS USB PHY.
@@ -188,6 +191,7 @@ config USB_MXS_PHY
config USB_RCAR_PHY
tristate "Renesas R-Car USB PHY support"
depends on USB || USB_GADGET
+ select USB_PHY
help
Say Y here to add support for the Renesas R-Car USB common PHY driver.
This chip is typically used as USB PHY for USB host, gadget.
@@ -210,4 +214,4 @@ config USB_ULPI_VIEWPORT
Provides read/write operations to the ULPI phy register set for
controllers with a viewport register (e.g. Chipidea/ARC controllers).
-endif # USB_PHY
+endmenu
diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c
index e771bafb9f1d..e965cf65d696 100644
--- a/drivers/usb/phy/phy-fsl-usb.c
+++ b/drivers/usb/phy/phy-fsl-usb.c
@@ -834,7 +834,7 @@ int usb_otg_start(struct platform_device *pdev)
int status;
struct resource *res;
u32 temp;
- struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+ struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev);
p_otg = container_of(otg_trans, struct fsl_otg, phy);
fsm = &p_otg->fsm;
@@ -1105,7 +1105,7 @@ static int fsl_otg_probe(struct platform_device *pdev)
{
int ret;
- if (!pdev->dev.platform_data)
+ if (!dev_get_platdata(&pdev->dev))
return -ENODEV;
/* configure the OTG */
@@ -1137,7 +1137,7 @@ static int fsl_otg_probe(struct platform_device *pdev)
static int fsl_otg_remove(struct platform_device *pdev)
{
- struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+ struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev);
usb_remove_phy(&fsl_otg_dev->phy);
free_irq(fsl_otg_dev->irq, fsl_otg_dev);
diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c
index f379b7ded037..406f8e43f852 100644
--- a/drivers/usb/phy/phy-generic.c
+++ b/drivers/usb/phy/phy-generic.c
@@ -142,7 +142,8 @@ static int nop_set_host(struct usb_otg *otg, struct usb_bus *host)
static int usb_phy_gen_xceiv_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct usb_phy_gen_xceiv_platform_data *pdata = pdev->dev.platform_data;
+ struct usb_phy_gen_xceiv_platform_data *pdata =
+ dev_get_platdata(&pdev->dev);
struct usb_phy_gen_xceiv *nop;
enum usb_phy_type type = USB_PHY_TYPE_USB2;
int err;
diff --git a/drivers/usb/phy/phy-gpio-vbus-usb.c b/drivers/usb/phy/phy-gpio-vbus-usb.c
index 8443335c2ea0..b2f29c9aebbf 100644
--- a/drivers/usb/phy/phy-gpio-vbus-usb.c
+++ b/drivers/usb/phy/phy-gpio-vbus-usb.c
@@ -101,7 +101,7 @@ static void gpio_vbus_work(struct work_struct *work)
{
struct gpio_vbus_data *gpio_vbus =
container_of(work, struct gpio_vbus_data, work.work);
- struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data;
+ struct gpio_vbus_mach_info *pdata = dev_get_platdata(gpio_vbus->dev);
int gpio, status, vbus;
if (!gpio_vbus->phy.otg->gadget)
@@ -155,7 +155,7 @@ static void gpio_vbus_work(struct work_struct *work)
static irqreturn_t gpio_vbus_irq(int irq, void *data)
{
struct platform_device *pdev = data;
- struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data;
+ struct gpio_vbus_mach_info *pdata = dev_get_platdata(&pdev->dev);
struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev);
struct usb_otg *otg = gpio_vbus->phy.otg;
@@ -182,7 +182,7 @@ static int gpio_vbus_set_peripheral(struct usb_otg *otg,
gpio_vbus = container_of(otg->phy, struct gpio_vbus_data, phy);
pdev = to_platform_device(gpio_vbus->dev);
- pdata = gpio_vbus->dev->platform_data;
+ pdata = dev_get_platdata(gpio_vbus->dev);
gpio = pdata->gpio_pullup;
if (!gadget) {
@@ -243,7 +243,7 @@ static int gpio_vbus_set_suspend(struct usb_phy *phy, int suspend)
static int __init gpio_vbus_probe(struct platform_device *pdev)
{
- struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data;
+ struct gpio_vbus_mach_info *pdata = dev_get_platdata(&pdev->dev);
struct gpio_vbus_data *gpio_vbus;
struct resource *res;
int err, gpio, irq;
@@ -352,7 +352,7 @@ err_gpio:
static int __exit gpio_vbus_remove(struct platform_device *pdev)
{
struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev);
- struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data;
+ struct gpio_vbus_mach_info *pdata = dev_get_platdata(&pdev->dev);
int gpio = pdata->gpio_vbus;
device_init_wakeup(&pdev->dev, 0);
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index d08f33435e96..e9d4cd960ecd 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -1419,7 +1419,7 @@ static int __init msm_otg_probe(struct platform_device *pdev)
struct usb_phy *phy;
dev_info(&pdev->dev, "msm_otg probe\n");
- if (!pdev->dev.platform_data) {
+ if (!dev_get_platdata(&pdev->dev)) {
dev_err(&pdev->dev, "No platform data given. Bailing out\n");
return -ENODEV;
}
@@ -1436,7 +1436,7 @@ static int __init msm_otg_probe(struct platform_device *pdev)
return -ENOMEM;
}
- motg->pdata = pdev->dev.platform_data;
+ motg->pdata = dev_get_platdata(&pdev->dev);
phy = &motg->phy;
phy->dev = &pdev->dev;
diff --git a/drivers/usb/phy/phy-mv-u3d-usb.c b/drivers/usb/phy/phy-mv-u3d-usb.c
index 1568ea63e338..d317903022bf 100644
--- a/drivers/usb/phy/phy-mv-u3d-usb.c
+++ b/drivers/usb/phy/phy-mv-u3d-usb.c
@@ -82,7 +82,7 @@ static void mv_u3d_phy_write(void __iomem *base, u32 reg, u32 value)
writel_relaxed(value, data);
}
-void mv_u3d_phy_shutdown(struct usb_phy *phy)
+static void mv_u3d_phy_shutdown(struct usb_phy *phy)
{
struct mv_u3d_phy *mv_u3d_phy;
void __iomem *base;
@@ -271,7 +271,7 @@ static int mv_u3d_phy_probe(struct platform_device *pdev)
void __iomem *phy_base;
int ret;
- pdata = pdev->dev.platform_data;
+ pdata = dev_get_platdata(&pdev->dev);
if (!pdata) {
dev_err(&pdev->dev, "%s: no platform data defined\n", __func__);
return -EINVAL;
diff --git a/drivers/usb/phy/phy-mv-usb.c b/drivers/usb/phy/phy-mv-usb.c
index 4a6b03c73876..98f6ac6a78ea 100644
--- a/drivers/usb/phy/phy-mv-usb.c
+++ b/drivers/usb/phy/phy-mv-usb.c
@@ -653,7 +653,7 @@ static struct attribute_group inputs_attr_group = {
.attrs = inputs_attrs,
};
-int mv_otg_remove(struct platform_device *pdev)
+static int mv_otg_remove(struct platform_device *pdev)
{
struct mv_otg *mvotg = platform_get_drvdata(pdev);
@@ -673,7 +673,7 @@ int mv_otg_remove(struct platform_device *pdev)
static int mv_otg_probe(struct platform_device *pdev)
{
- struct mv_usb_platform_data *pdata = pdev->dev.platform_data;
+ struct mv_usb_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct mv_otg *mvotg;
struct usb_otg *otg;
struct resource *r;
@@ -893,7 +893,7 @@ static int mv_otg_resume(struct platform_device *pdev)
static struct platform_driver mv_otg_driver = {
.probe = mv_otg_probe,
- .remove = __exit_p(mv_otg_remove),
+ .remove = mv_otg_remove,
.driver = {
.owner = THIS_MODULE,
.name = driver_name,
diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c
index bd601c537c8d..fdd33b44dbd3 100644
--- a/drivers/usb/phy/phy-mxs-usb.c
+++ b/drivers/usb/phy/phy-mxs-usb.c
@@ -41,11 +41,14 @@ struct mxs_phy {
#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy)
-static void mxs_phy_hw_init(struct mxs_phy *mxs_phy)
+static int mxs_phy_hw_init(struct mxs_phy *mxs_phy)
{
+ int ret;
void __iomem *base = mxs_phy->phy.io_priv;
- stmp_reset_block(base + HW_USBPHY_CTRL);
+ ret = stmp_reset_block(base + HW_USBPHY_CTRL);
+ if (ret)
+ return ret;
/* Power up the PHY */
writel(0, base + HW_USBPHY_PWD);
@@ -54,6 +57,8 @@ static void mxs_phy_hw_init(struct mxs_phy *mxs_phy)
writel(BM_USBPHY_CTRL_ENUTMILEVEL2 |
BM_USBPHY_CTRL_ENUTMILEVEL3,
base + HW_USBPHY_CTRL_SET);
+
+ return 0;
}
static int mxs_phy_init(struct usb_phy *phy)
@@ -61,9 +66,7 @@ static int mxs_phy_init(struct usb_phy *phy)
struct mxs_phy *mxs_phy = to_mxs_phy(phy);
clk_prepare_enable(mxs_phy->clk);
- mxs_phy_hw_init(mxs_phy);
-
- return 0;
+ return mxs_phy_hw_init(mxs_phy);
}
static void mxs_phy_shutdown(struct usb_phy *phy)
diff --git a/drivers/usb/phy/phy-omap-control.c b/drivers/usb/phy/phy-omap-control.c
index 1419ceda9759..a4dda8e12562 100644
--- a/drivers/usb/phy/phy-omap-control.c
+++ b/drivers/usb/phy/phy-omap-control.c
@@ -197,7 +197,8 @@ static int omap_control_usb_probe(struct platform_device *pdev)
{
struct resource *res;
struct device_node *np = pdev->dev.of_node;
- struct omap_control_usb_platform_data *pdata = pdev->dev.platform_data;
+ struct omap_control_usb_platform_data *pdata =
+ dev_get_platdata(&pdev->dev);
control_usb = devm_kzalloc(&pdev->dev, sizeof(*control_usb),
GFP_KERNEL);
diff --git a/drivers/usb/phy/phy-omap-usb3.c b/drivers/usb/phy/phy-omap-usb3.c
index a2fb30bbb971..fc15694d3031 100644
--- a/drivers/usb/phy/phy-omap-usb3.c
+++ b/drivers/usb/phy/phy-omap-usb3.c
@@ -27,7 +27,6 @@
#include <linux/delay.h>
#include <linux/usb/omap_control_usb.h>
-#define NUM_SYS_CLKS 6
#define PLL_STATUS 0x00000004
#define PLL_GO 0x00000008
#define PLL_CONFIGURATION1 0x0000000C
@@ -57,26 +56,32 @@
*/
# define PLL_IDLE_TIME 100;
-enum sys_clk_rate {
- CLK_RATE_UNDEFINED = -1,
- CLK_RATE_12MHZ,
- CLK_RATE_16MHZ,
- CLK_RATE_19MHZ,
- CLK_RATE_20MHZ,
- CLK_RATE_26MHZ,
- CLK_RATE_38MHZ
+struct usb_dpll_map {
+ unsigned long rate;
+ struct usb_dpll_params params;
};
-static struct usb_dpll_params omap_usb3_dpll_params[NUM_SYS_CLKS] = {
- {1250, 5, 4, 20, 0}, /* 12 MHz */
- {3125, 20, 4, 20, 0}, /* 16.8 MHz */
- {1172, 8, 4, 20, 65537}, /* 19.2 MHz */
- {1000, 7, 4, 10, 0}, /* 20 MHz */
- {1250, 12, 4, 20, 0}, /* 26 MHz */
- {3125, 47, 4, 20, 92843}, /* 38.4 MHz */
-
+static struct usb_dpll_map dpll_map[] = {
+ {12000000, {1250, 5, 4, 20, 0} }, /* 12 MHz */
+ {16800000, {3125, 20, 4, 20, 0} }, /* 16.8 MHz */
+ {19200000, {1172, 8, 4, 20, 65537} }, /* 19.2 MHz */
+ {20000000, {1000, 7, 4, 10, 0} }, /* 20 MHz */
+ {26000000, {1250, 12, 4, 20, 0} }, /* 26 MHz */
+ {38400000, {3125, 47, 4, 20, 92843} }, /* 38.4 MHz */
};
+static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dpll_map); i++) {
+ if (rate == dpll_map[i].rate)
+ return &dpll_map[i].params;
+ }
+
+ return 0;
+}
+
static int omap_usb3_suspend(struct usb_phy *x, int suspend)
{
struct omap_usb *phy = phy_to_omapusb(x);
@@ -116,26 +121,6 @@ static int omap_usb3_suspend(struct usb_phy *x, int suspend)
return 0;
}
-static inline enum sys_clk_rate __get_sys_clk_index(unsigned long rate)
-{
- switch (rate) {
- case 12000000:
- return CLK_RATE_12MHZ;
- case 16800000:
- return CLK_RATE_16MHZ;
- case 19200000:
- return CLK_RATE_19MHZ;
- case 20000000:
- return CLK_RATE_20MHZ;
- case 26000000:
- return CLK_RATE_26MHZ;
- case 38400000:
- return CLK_RATE_38MHZ;
- default:
- return CLK_RATE_UNDEFINED;
- }
-}
-
static void omap_usb_dpll_relock(struct omap_usb *phy)
{
u32 val;
@@ -155,39 +140,39 @@ static int omap_usb_dpll_lock(struct omap_usb *phy)
{
u32 val;
unsigned long rate;
- enum sys_clk_rate clk_index;
-
- rate = clk_get_rate(phy->sys_clk);
- clk_index = __get_sys_clk_index(rate);
+ struct usb_dpll_params *dpll_params;
- if (clk_index == CLK_RATE_UNDEFINED) {
- pr_err("dpll cannot be locked for sys clk freq:%luHz\n", rate);
+ rate = clk_get_rate(phy->sys_clk);
+ dpll_params = omap_usb3_get_dpll_params(rate);
+ if (!dpll_params) {
+ dev_err(phy->dev,
+ "No DPLL configuration for %lu Hz SYS CLK\n", rate);
return -EINVAL;
}
val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
val &= ~PLL_REGN_MASK;
- val |= omap_usb3_dpll_params[clk_index].n << PLL_REGN_SHIFT;
+ val |= dpll_params->n << PLL_REGN_SHIFT;
omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
val &= ~PLL_SELFREQDCO_MASK;
- val |= omap_usb3_dpll_params[clk_index].freq << PLL_SELFREQDCO_SHIFT;
+ val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT;
omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
val &= ~PLL_REGM_MASK;
- val |= omap_usb3_dpll_params[clk_index].m << PLL_REGM_SHIFT;
+ val |= dpll_params->m << PLL_REGM_SHIFT;
omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
val &= ~PLL_REGM_F_MASK;
- val |= omap_usb3_dpll_params[clk_index].mf << PLL_REGM_F_SHIFT;
+ val |= dpll_params->mf << PLL_REGM_F_SHIFT;
omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);
val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
val &= ~PLL_SD_MASK;
- val |= omap_usb3_dpll_params[clk_index].sd << PLL_SD_SHIFT;
+ val |= dpll_params->sd << PLL_SD_SHIFT;
omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);
omap_usb_dpll_relock(phy);
@@ -198,8 +183,12 @@ static int omap_usb_dpll_lock(struct omap_usb *phy)
static int omap_usb3_init(struct usb_phy *x)
{
struct omap_usb *phy = phy_to_omapusb(x);
+ int ret;
+
+ ret = omap_usb_dpll_lock(phy);
+ if (ret)
+ return ret;
- omap_usb_dpll_lock(phy);
omap_control_usb3_phy_power(phy->control_dev, 1);
return 0;
diff --git a/drivers/usb/phy/phy-rcar-usb.c b/drivers/usb/phy/phy-rcar-usb.c
index ae909408958d..33265a5b2cdf 100644
--- a/drivers/usb/phy/phy-rcar-usb.c
+++ b/drivers/usb/phy/phy-rcar-usb.c
@@ -83,7 +83,7 @@ static int rcar_usb_phy_init(struct usb_phy *phy)
{
struct rcar_usb_phy_priv *priv = usb_phy_to_priv(phy);
struct device *dev = phy->dev;
- struct rcar_phy_platform_data *pdata = dev->platform_data;
+ struct rcar_phy_platform_data *pdata = dev_get_platdata(dev);
void __iomem *reg0 = priv->reg0;
void __iomem *reg1 = priv->reg1;
static const u8 ovcn_act[] = { OVC0_ACT, OVC1_ACT, OVC2_ACT };
@@ -184,17 +184,12 @@ static int rcar_usb_phy_probe(struct platform_device *pdev)
void __iomem *reg0, *reg1 = NULL;
int ret;
- if (!pdev->dev.platform_data) {
+ if (!dev_get_platdata(&pdev->dev)) {
dev_err(dev, "No platform data\n");
return -EINVAL;
}
res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res0) {
- dev_err(dev, "Not enough platform resources\n");
- return -EINVAL;
- }
-
reg0 = devm_ioremap_resource(dev, res0);
if (IS_ERR(reg0))
return PTR_ERR(reg0);
diff --git a/drivers/usb/phy/phy-samsung-usb2.c b/drivers/usb/phy/phy-samsung-usb2.c
index 758b86d0fcb3..ff70e4b19b97 100644
--- a/drivers/usb/phy/phy-samsung-usb2.c
+++ b/drivers/usb/phy/phy-samsung-usb2.c
@@ -359,7 +359,7 @@ static int samsung_usb2phy_probe(struct platform_device *pdev)
{
struct samsung_usbphy *sphy;
struct usb_otg *otg;
- struct samsung_usbphy_data *pdata = pdev->dev.platform_data;
+ struct samsung_usbphy_data *pdata = dev_get_platdata(&pdev->dev);
const struct samsung_usbphy_drvdata *drv_data;
struct device *dev = &pdev->dev;
struct resource *phy_mem;
diff --git a/drivers/usb/phy/phy-samsung-usb3.c b/drivers/usb/phy/phy-samsung-usb3.c
index 300e0cf5e31f..c6eb22213de6 100644
--- a/drivers/usb/phy/phy-samsung-usb3.c
+++ b/drivers/usb/phy/phy-samsung-usb3.c
@@ -231,7 +231,7 @@ static void samsung_usb3phy_shutdown(struct usb_phy *phy)
static int samsung_usb3phy_probe(struct platform_device *pdev)
{
struct samsung_usbphy *sphy;
- struct samsung_usbphy_data *pdata = pdev->dev.platform_data;
+ struct samsung_usbphy_data *pdata = dev_get_platdata(&pdev->dev);
struct device *dev = &pdev->dev;
struct resource *phy_mem;
void __iomem *phy_base;
diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c
index cec0855ed248..49fa2da56c4b 100644
--- a/drivers/usb/phy/phy-tegra-usb.c
+++ b/drivers/usb/phy/phy-tegra-usb.c
@@ -31,9 +31,11 @@
#include <linux/of_gpio.h>
#include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>
+#include <linux/usb/of.h>
#include <asm/mach-types.h>
#include <linux/usb/ehci_def.h>
#include <linux/usb/tegra_usb_phy.h>
+#include <linux/regulator/consumer.h>
#define ULPI_VIEWPORT 0x170
@@ -184,27 +186,6 @@ static const struct tegra_xtal_freq tegra_freq_table[] = {
},
};
-static struct tegra_utmip_config utmip_default[] = {
- [0] = {
- .hssync_start_delay = 9,
- .idle_wait_delay = 17,
- .elastic_limit = 16,
- .term_range_adj = 6,
- .xcvr_setup = 9,
- .xcvr_lsfslew = 1,
- .xcvr_lsrslew = 1,
- },
- [2] = {
- .hssync_start_delay = 9,
- .idle_wait_delay = 17,
- .elastic_limit = 16,
- .term_range_adj = 6,
- .xcvr_setup = 9,
- .xcvr_lsfslew = 2,
- .xcvr_lsrslew = 2,
- },
-};
-
static void set_pts(struct tegra_usb_phy *phy, u8 pts_val)
{
void __iomem *base = phy->regs;
@@ -231,7 +212,7 @@ static void set_phcd(struct tegra_usb_phy *phy, bool enable)
static int utmip_pad_open(struct tegra_usb_phy *phy)
{
- phy->pad_clk = devm_clk_get(phy->dev, "utmi-pads");
+ phy->pad_clk = devm_clk_get(phy->u_phy.dev, "utmi-pads");
if (IS_ERR(phy->pad_clk)) {
pr_err("%s: can't get utmip pad clock\n", __func__);
return PTR_ERR(phy->pad_clk);
@@ -396,7 +377,7 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy)
UTMIP_PLLU_ENABLE_DLY_COUNT(phy->freq->enable_delay);
writel(val, base + UTMIP_PLL_CFG1);
- if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) {
+ if (phy->mode == USB_DR_MODE_PERIPHERAL) {
val = readl(base + USB_SUSP_CTRL);
val &= ~(USB_WAKE_ON_CNNT_EN_DEV | USB_WAKE_ON_DISCON_EN_DEV);
writel(val, base + USB_SUSP_CTRL);
@@ -431,7 +412,7 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy)
if (phy->is_legacy_phy) {
val = readl(base + UTMIP_SPARE_CFG0);
- if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE)
+ if (phy->mode == USB_DR_MODE_PERIPHERAL)
val &= ~FUSE_SETUP_SEL;
else
val |= FUSE_SETUP_SEL;
@@ -472,7 +453,7 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy)
utmi_phy_clk_disable(phy);
- if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) {
+ if (phy->mode == USB_DR_MODE_PERIPHERAL) {
val = readl(base + USB_SUSP_CTRL);
val &= ~USB_WAKEUP_DEBOUNCE_COUNT(~0);
val |= USB_WAKE_ON_CNNT_EN_DEV | USB_WAKEUP_DEBOUNCE_COUNT(5);
@@ -560,13 +541,15 @@ static int ulpi_phy_power_on(struct tegra_usb_phy *phy)
ret = gpio_direction_output(phy->reset_gpio, 0);
if (ret < 0) {
- dev_err(phy->dev, "gpio %d not set to 0\n", phy->reset_gpio);
+ dev_err(phy->u_phy.dev, "gpio %d not set to 0\n",
+ phy->reset_gpio);
return ret;
}
msleep(5);
ret = gpio_direction_output(phy->reset_gpio, 1);
if (ret < 0) {
- dev_err(phy->dev, "gpio %d not set to 1\n", phy->reset_gpio);
+ dev_err(phy->u_phy.dev, "gpio %d not set to 1\n",
+ phy->reset_gpio);
return ret;
}
@@ -634,6 +617,9 @@ static void tegra_usb_phy_close(struct usb_phy *x)
{
struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy);
+ if (!IS_ERR(phy->vbus))
+ regulator_disable(phy->vbus);
+
clk_disable_unprepare(phy->pll_u);
}
@@ -666,29 +652,30 @@ static int ulpi_open(struct tegra_usb_phy *phy)
{
int err;
- phy->clk = devm_clk_get(phy->dev, "ulpi-link");
+ phy->clk = devm_clk_get(phy->u_phy.dev, "ulpi-link");
if (IS_ERR(phy->clk)) {
pr_err("%s: can't get ulpi clock\n", __func__);
return PTR_ERR(phy->clk);
}
- err = devm_gpio_request(phy->dev, phy->reset_gpio, "ulpi_phy_reset_b");
+ err = devm_gpio_request(phy->u_phy.dev, phy->reset_gpio,
+ "ulpi_phy_reset_b");
if (err < 0) {
- dev_err(phy->dev, "request failed for gpio: %d\n",
+ dev_err(phy->u_phy.dev, "request failed for gpio: %d\n",
phy->reset_gpio);
return err;
}
err = gpio_direction_output(phy->reset_gpio, 0);
if (err < 0) {
- dev_err(phy->dev, "gpio %d direction not set to output\n",
+ dev_err(phy->u_phy.dev, "gpio %d direction not set to output\n",
phy->reset_gpio);
return err;
}
phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0);
if (!phy->ulpi) {
- dev_err(phy->dev, "otg_ulpi_create returned NULL\n");
+ dev_err(phy->u_phy.dev, "otg_ulpi_create returned NULL\n");
err = -ENOMEM;
return err;
}
@@ -703,14 +690,7 @@ static int tegra_usb_phy_init(struct tegra_usb_phy *phy)
int i;
int err;
- if (!phy->is_ulpi_phy) {
- if (phy->is_legacy_phy)
- phy->config = &utmip_default[0];
- else
- phy->config = &utmip_default[2];
- }
-
- phy->pll_u = devm_clk_get(phy->dev, "pll_u");
+ phy->pll_u = devm_clk_get(phy->u_phy.dev, "pll_u");
if (IS_ERR(phy->pll_u)) {
pr_err("Can't get pll_u clock\n");
return PTR_ERR(phy->pll_u);
@@ -733,6 +713,16 @@ static int tegra_usb_phy_init(struct tegra_usb_phy *phy)
goto fail;
}
+ if (!IS_ERR(phy->vbus)) {
+ err = regulator_enable(phy->vbus);
+ if (err) {
+ dev_err(phy->u_phy.dev,
+ "failed to enable usb vbus regulator: %d\n",
+ err);
+ goto fail;
+ }
+ }
+
if (phy->is_ulpi_phy)
err = ulpi_open(phy);
else
@@ -784,11 +774,94 @@ void tegra_ehci_phy_restore_end(struct usb_phy *x)
}
EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_end);
+static int read_utmi_param(struct platform_device *pdev, const char *param,
+ u8 *dest)
+{
+ u32 value;
+ int err = of_property_read_u32(pdev->dev.of_node, param, &value);
+ *dest = (u8)value;
+ if (err < 0)
+ dev_err(&pdev->dev, "Failed to read USB UTMI parameter %s: %d\n",
+ param, err);
+ return err;
+}
+
+static int utmi_phy_probe(struct tegra_usb_phy *tegra_phy,
+ struct platform_device *pdev)
+{
+ struct resource *res;
+ int err;
+ struct tegra_utmip_config *config;
+
+ tegra_phy->is_ulpi_phy = false;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res) {
+ dev_err(&pdev->dev, "Failed to get UTMI Pad regs\n");
+ return -ENXIO;
+ }
+
+ tegra_phy->pad_regs = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!tegra_phy->regs) {
+ dev_err(&pdev->dev, "Failed to remap UTMI Pad regs\n");
+ return -ENOMEM;
+ }
+
+ tegra_phy->config = devm_kzalloc(&pdev->dev,
+ sizeof(*tegra_phy->config), GFP_KERNEL);
+ if (!tegra_phy->config) {
+ dev_err(&pdev->dev,
+ "unable to allocate memory for USB UTMIP config\n");
+ return -ENOMEM;
+ }
+
+ config = tegra_phy->config;
+
+ err = read_utmi_param(pdev, "nvidia,hssync-start-delay",
+ &config->hssync_start_delay);
+ if (err < 0)
+ return err;
+
+ err = read_utmi_param(pdev, "nvidia,elastic-limit",
+ &config->elastic_limit);
+ if (err < 0)
+ return err;
+
+ err = read_utmi_param(pdev, "nvidia,idle-wait-delay",
+ &config->idle_wait_delay);
+ if (err < 0)
+ return err;
+
+ err = read_utmi_param(pdev, "nvidia,term-range-adj",
+ &config->term_range_adj);
+ if (err < 0)
+ return err;
+
+ err = read_utmi_param(pdev, "nvidia,xcvr-setup",
+ &config->xcvr_setup);
+ if (err < 0)
+ return err;
+
+ err = read_utmi_param(pdev, "nvidia,xcvr-lsfslew",
+ &config->xcvr_lsfslew);
+ if (err < 0)
+ return err;
+
+ err = read_utmi_param(pdev, "nvidia,xcvr-lsrslew",
+ &config->xcvr_lsrslew);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
static int tegra_usb_phy_probe(struct platform_device *pdev)
{
struct resource *res;
struct tegra_usb_phy *tegra_phy = NULL;
struct device_node *np = pdev->dev.of_node;
+ enum usb_phy_interface phy_type;
int err;
tegra_phy = devm_kzalloc(&pdev->dev, sizeof(*tegra_phy), GFP_KERNEL);
@@ -813,23 +886,15 @@ static int tegra_usb_phy_probe(struct platform_device *pdev)
tegra_phy->is_legacy_phy =
of_property_read_bool(np, "nvidia,has-legacy-mode");
- err = of_property_match_string(np, "phy_type", "ulpi");
- if (err < 0) {
- tegra_phy->is_ulpi_phy = false;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (!res) {
- dev_err(&pdev->dev, "Failed to get UTMI Pad regs\n");
- return -ENXIO;
- }
+ phy_type = of_usb_get_phy_mode(np);
+ switch (phy_type) {
+ case USBPHY_INTERFACE_MODE_UTMI:
+ err = utmi_phy_probe(tegra_phy, pdev);
+ if (err < 0)
+ return err;
+ break;
- tegra_phy->pad_regs = devm_ioremap(&pdev->dev, res->start,
- resource_size(res));
- if (!tegra_phy->regs) {
- dev_err(&pdev->dev, "Failed to remap UTMI Pad regs\n");
- return -ENOMEM;
- }
- } else {
+ case USBPHY_INTERFACE_MODE_ULPI:
tegra_phy->is_ulpi_phy = true;
tegra_phy->reset_gpio =
@@ -839,19 +904,35 @@ static int tegra_usb_phy_probe(struct platform_device *pdev)
tegra_phy->reset_gpio);
return tegra_phy->reset_gpio;
}
+ tegra_phy->config = NULL;
+ break;
+
+ default:
+ dev_err(&pdev->dev, "phy_type is invalid or unsupported\n");
+ return -EINVAL;
}
- err = of_property_match_string(np, "dr_mode", "otg");
- if (err < 0) {
- err = of_property_match_string(np, "dr_mode", "peripheral");
- if (err < 0)
- tegra_phy->mode = TEGRA_USB_PHY_MODE_HOST;
- else
- tegra_phy->mode = TEGRA_USB_PHY_MODE_DEVICE;
- } else
- tegra_phy->mode = TEGRA_USB_PHY_MODE_OTG;
+ if (of_find_property(np, "dr_mode", NULL))
+ tegra_phy->mode = of_usb_get_dr_mode(np);
+ else
+ tegra_phy->mode = USB_DR_MODE_HOST;
+
+ if (tegra_phy->mode == USB_DR_MODE_UNKNOWN) {
+ dev_err(&pdev->dev, "dr_mode is invalid\n");
+ return -EINVAL;
+ }
- tegra_phy->dev = &pdev->dev;
+ /* On some boards, the VBUS regulator doesn't need to be controlled */
+ if (of_find_property(np, "vbus-supply", NULL)) {
+ tegra_phy->vbus = devm_regulator_get(&pdev->dev, "vbus");
+ if (IS_ERR(tegra_phy->vbus))
+ return PTR_ERR(tegra_phy->vbus);
+ } else {
+ dev_notice(&pdev->dev, "no vbus regulator");
+ tegra_phy->vbus = ERR_PTR(-ENODEV);
+ }
+
+ tegra_phy->u_phy.dev = &pdev->dev;
err = tegra_usb_phy_init(tegra_phy);
if (err < 0)
return err;
@@ -860,6 +941,22 @@ static int tegra_usb_phy_probe(struct platform_device *pdev)
tegra_phy->u_phy.set_suspend = tegra_usb_phy_suspend;
dev_set_drvdata(&pdev->dev, tegra_phy);
+
+ err = usb_add_phy_dev(&tegra_phy->u_phy);
+ if (err < 0) {
+ tegra_usb_phy_close(&tegra_phy->u_phy);
+ return err;
+ }
+
+ return 0;
+}
+
+static int tegra_usb_phy_remove(struct platform_device *pdev)
+{
+ struct tegra_usb_phy *tegra_phy = platform_get_drvdata(pdev);
+
+ usb_remove_phy(&tegra_phy->u_phy);
+
return 0;
}
@@ -871,6 +968,7 @@ MODULE_DEVICE_TABLE(of, tegra_usb_phy_id_table);
static struct platform_driver tegra_usb_phy_driver = {
.probe = tegra_usb_phy_probe,
+ .remove = tegra_usb_phy_remove,
.driver = {
.name = "tegra-phy",
.owner = THIS_MODULE,
@@ -879,29 +977,5 @@ static struct platform_driver tegra_usb_phy_driver = {
};
module_platform_driver(tegra_usb_phy_driver);
-static int tegra_usb_phy_match(struct device *dev, void *data)
-{
- struct tegra_usb_phy *tegra_phy = dev_get_drvdata(dev);
- struct device_node *dn = data;
-
- return (tegra_phy->dev->of_node == dn) ? 1 : 0;
-}
-
-struct usb_phy *tegra_usb_get_phy(struct device_node *dn)
-{
- struct device *dev;
- struct tegra_usb_phy *tegra_phy;
-
- dev = driver_find_device(&tegra_usb_phy_driver.driver, NULL, dn,
- tegra_usb_phy_match);
- if (!dev)
- return ERR_PTR(-EPROBE_DEFER);
-
- tegra_phy = dev_get_drvdata(dev);
-
- return &tegra_phy->u_phy;
-}
-EXPORT_SYMBOL_GPL(tegra_usb_get_phy);
-
MODULE_DESCRIPTION("Tegra USB PHY driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/phy/phy-twl4030-usb.c b/drivers/usb/phy/phy-twl4030-usb.c
index 8f78d2d40722..90730c8762b8 100644
--- a/drivers/usb/phy/phy-twl4030-usb.c
+++ b/drivers/usb/phy/phy-twl4030-usb.c
@@ -648,7 +648,7 @@ static int twl4030_set_host(struct usb_otg *otg, struct usb_bus *host)
static int twl4030_usb_probe(struct platform_device *pdev)
{
- struct twl4030_usb_data *pdata = pdev->dev.platform_data;
+ struct twl4030_usb_data *pdata = dev_get_platdata(&pdev->dev);
struct twl4030_usb *twl;
int status, err;
struct usb_otg *otg;
diff --git a/drivers/usb/phy/phy-twl6030-usb.c b/drivers/usb/phy/phy-twl6030-usb.c
index 1753bd367e0a..16dbc9382678 100644
--- a/drivers/usb/phy/phy-twl6030-usb.c
+++ b/drivers/usb/phy/phy-twl6030-usb.c
@@ -324,7 +324,7 @@ static int twl6030_usb_probe(struct platform_device *pdev)
int status, err;
struct device_node *np = pdev->dev.of_node;
struct device *dev = &pdev->dev;
- struct twl4030_usb_data *pdata = dev->platform_data;
+ struct twl4030_usb_data *pdata = dev_get_platdata(dev);
twl = devm_kzalloc(dev, sizeof *twl, GFP_KERNEL);
if (!twl)