diff options
Diffstat (limited to 'drivers/usb/phy')
-rw-r--r-- | drivers/usb/phy/Kconfig | 36 | ||||
-rw-r--r-- | drivers/usb/phy/phy-fsl-usb.c | 6 | ||||
-rw-r--r-- | drivers/usb/phy/phy-generic.c | 3 | ||||
-rw-r--r-- | drivers/usb/phy/phy-gpio-vbus-usb.c | 10 | ||||
-rw-r--r-- | drivers/usb/phy/phy-msm-usb.c | 4 | ||||
-rw-r--r-- | drivers/usb/phy/phy-mv-u3d-usb.c | 4 | ||||
-rw-r--r-- | drivers/usb/phy/phy-mv-usb.c | 6 | ||||
-rw-r--r-- | drivers/usb/phy/phy-mxs-usb.c | 13 | ||||
-rw-r--r-- | drivers/usb/phy/phy-omap-control.c | 3 | ||||
-rw-r--r-- | drivers/usb/phy/phy-omap-usb3.c | 87 | ||||
-rw-r--r-- | drivers/usb/phy/phy-rcar-usb.c | 9 | ||||
-rw-r--r-- | drivers/usb/phy/phy-samsung-usb2.c | 2 | ||||
-rw-r--r-- | drivers/usb/phy/phy-samsung-usb3.c | 2 | ||||
-rw-r--r-- | drivers/usb/phy/phy-tegra-usb.c | 254 | ||||
-rw-r--r-- | drivers/usb/phy/phy-twl4030-usb.c | 2 | ||||
-rw-r--r-- | drivers/usb/phy/phy-twl6030-usb.c | 2 |
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) |