dect
/
linux-2.6
Archived
13
0
Fork 0

usb: move phy driver from mach-tegra to drivers/usb

As part of this patch:
	1. Moved existing tegra phy driver to drivers/USB directory.
	2. Added standard USB phy driver APIs to tegra phy driver.

Signed-off-by: Venu Byravarasu <vbyravarasu@nvidia.com>
Tested-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
Venu Byravarasu 2012-09-05 18:50:23 +05:30 committed by Felipe Balbi
parent de4217d90f
commit 1ba8216f0b
7 changed files with 103 additions and 85 deletions

View File

@ -21,7 +21,6 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o
obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o
obj-$(CONFIG_TEGRA_PCI) += pcie.o
obj-$(CONFIG_USB_SUPPORT) += usb_phy.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-dt-tegra20.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o

View File

@ -27,7 +27,7 @@
#include <mach/irqs.h>
#include <mach/iomap.h>
#include <mach/dma.h>
#include <mach/usb_phy.h>
#include <linux/usb/tegra_usb_phy.h>
#include "gpio-names.h"
#include "devices.h"

View File

@ -22,7 +22,7 @@
#include <linux/platform_device.h>
#include <linux/platform_data/tegra_usb.h>
#include <mach/usb_phy.h>
#include <linux/usb/tegra_usb_phy.h>
extern struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config;

View File

@ -27,7 +27,7 @@
#include <linux/of_gpio.h>
#include <linux/pm_runtime.h>
#include <mach/usb_phy.h>
#include <linux/usb/tegra_usb_phy.h>
#include <mach/iomap.h>
#define TEGRA_USB_DMA_ALIGN 32
@ -49,7 +49,7 @@ static void tegra_ehci_power_up(struct usb_hcd *hcd)
clk_prepare_enable(tegra->emc_clk);
clk_prepare_enable(tegra->clk);
tegra_usb_phy_power_on(tegra->phy);
usb_phy_set_suspend(&tegra->phy->u_phy, 0);
tegra->host_resumed = 1;
}
@ -58,7 +58,7 @@ static void tegra_ehci_power_down(struct usb_hcd *hcd)
struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
tegra->host_resumed = 0;
tegra_usb_phy_power_off(tegra->phy);
usb_phy_set_suspend(&tegra->phy->u_phy, 1);
clk_disable_unprepare(tegra->clk);
clk_disable_unprepare(tegra->emc_clk);
}
@ -715,7 +715,9 @@ static int tegra_ehci_probe(struct platform_device *pdev)
goto fail_phy;
}
err = tegra_usb_phy_power_on(tegra->phy);
usb_phy_init(&tegra->phy->u_phy);
err = usb_phy_set_suspend(&tegra->phy->u_phy, 0);
if (err) {
dev_err(&pdev->dev, "Failed to power on the phy\n");
goto fail;
@ -762,7 +764,7 @@ fail:
usb_put_phy(tegra->transceiver);
}
#endif
tegra_usb_phy_close(tegra->phy);
usb_phy_shutdown(&tegra->phy->u_phy);
fail_phy:
iounmap(hcd->regs);
fail_io:
@ -801,7 +803,7 @@ static int tegra_ehci_remove(struct platform_device *pdev)
usb_remove_hcd(hcd);
usb_put_hcd(hcd);
tegra_usb_phy_close(tegra->phy);
usb_phy_shutdown(&tegra->phy->u_phy);
iounmap(hcd->regs);
clk_disable_unprepare(tegra->clk);

View File

@ -6,3 +6,4 @@ ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
obj-$(CONFIG_USB_ISP1301) += isp1301.o
obj-$(CONFIG_MV_U3D_PHY) += mv_u3d_phy.o
obj-$(CONFIG_USB_EHCI_TEGRA) += tegra_usb_phy.o

View File

@ -1,6 +1,4 @@
/*
* arch/arm/mach-tegra/usb_phy.c
*
* Copyright (C) 2010 Google, Inc.
*
* Author:
@ -31,7 +29,7 @@
#include <linux/usb/ulpi.h>
#include <asm/mach-types.h>
#include <mach/gpio-tegra.h>
#include <mach/usb_phy.h>
#include <linux/usb/tegra_usb_phy.h>
#include <mach/iomap.h>
#define ULPI_VIEWPORT 0x170
@ -482,7 +480,7 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy)
return 0;
}
static void utmi_phy_power_off(struct tegra_usb_phy *phy)
static int utmi_phy_power_off(struct tegra_usb_phy *phy)
{
unsigned long val;
void __iomem *base = phy->regs;
@ -514,7 +512,7 @@ static void utmi_phy_power_off(struct tegra_usb_phy *phy)
UTMIP_FORCE_PDDR_POWERDOWN;
writel(val, base + UTMIP_XCVR_CFG1);
utmip_pad_power_off(phy);
return utmip_pad_power_off(phy);
}
static void utmi_phy_preresume(struct tegra_usb_phy *phy)
@ -638,7 +636,7 @@ static int ulpi_phy_power_on(struct tegra_usb_phy *phy)
return 0;
}
static void ulpi_phy_power_off(struct tegra_usb_phy *phy)
static int ulpi_phy_power_off(struct tegra_usb_phy *phy)
{
unsigned long val;
void __iomem *base = phy->regs;
@ -651,15 +649,92 @@ static void ulpi_phy_power_off(struct tegra_usb_phy *phy)
val &= ~(USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN);
writel(val, base + USB_PORTSC1);
gpio_direction_output(config->reset_gpio, 0);
clk_disable(phy->clk);
return gpio_direction_output(config->reset_gpio, 0);
}
static int tegra_phy_init(struct usb_phy *x)
{
struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy);
struct tegra_ulpi_config *ulpi_config;
int err;
if (phy_is_ulpi(phy)) {
ulpi_config = phy->config;
phy->clk = clk_get_sys(NULL, ulpi_config->clk);
if (IS_ERR(phy->clk)) {
pr_err("%s: can't get ulpi clock\n", __func__);
err = -ENXIO;
goto err1;
}
if (!gpio_is_valid(ulpi_config->reset_gpio))
ulpi_config->reset_gpio =
of_get_named_gpio(phy->dev->of_node,
"nvidia,phy-reset-gpio", 0);
if (!gpio_is_valid(ulpi_config->reset_gpio)) {
pr_err("%s: invalid reset gpio: %d\n", __func__,
ulpi_config->reset_gpio);
err = -EINVAL;
goto err1;
}
gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b");
gpio_direction_output(ulpi_config->reset_gpio, 0);
phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0);
phy->ulpi->io_priv = phy->regs + ULPI_VIEWPORT;
} else {
err = utmip_pad_open(phy);
if (err < 0)
goto err1;
}
return 0;
err1:
clk_disable_unprepare(phy->pll_u);
clk_put(phy->pll_u);
return err;
}
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 (phy_is_ulpi(phy))
clk_put(phy->clk);
else
utmip_pad_close(phy);
clk_disable_unprepare(phy->pll_u);
clk_put(phy->pll_u);
kfree(phy);
}
static int tegra_usb_phy_power_on(struct tegra_usb_phy *phy)
{
if (phy_is_ulpi(phy))
return ulpi_phy_power_on(phy);
else
return utmi_phy_power_on(phy);
}
static int tegra_usb_phy_power_off(struct tegra_usb_phy *phy)
{
if (phy_is_ulpi(phy))
return ulpi_phy_power_off(phy);
else
return utmi_phy_power_off(phy);
}
static int tegra_usb_phy_suspend(struct usb_phy *x, int suspend)
{
struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy);
if (suspend)
return tegra_usb_phy_power_off(phy);
else
return tegra_usb_phy_power_on(phy);
}
struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance,
void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode)
{
struct tegra_usb_phy *phy;
struct tegra_ulpi_config *ulpi_config;
unsigned long parent_rate;
int i;
int err;
@ -672,6 +747,7 @@ struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance,
phy->regs = regs;
phy->config = config;
phy->mode = phy_mode;
phy->dev = dev;
if (!phy->config) {
if (phy_is_ulpi(phy)) {
@ -704,33 +780,9 @@ struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance,
goto err1;
}
if (phy_is_ulpi(phy)) {
ulpi_config = config;
phy->clk = clk_get_sys(NULL, ulpi_config->clk);
if (IS_ERR(phy->clk)) {
pr_err("%s: can't get ulpi clock\n", __func__);
err = -ENXIO;
goto err1;
}
if (!gpio_is_valid(ulpi_config->reset_gpio))
ulpi_config->reset_gpio =
of_get_named_gpio(dev->of_node,
"nvidia,phy-reset-gpio", 0);
if (!gpio_is_valid(ulpi_config->reset_gpio)) {
pr_err("%s: invalid reset gpio: %d\n", __func__,
ulpi_config->reset_gpio);
err = -EINVAL;
goto err1;
}
gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b");
gpio_direction_output(ulpi_config->reset_gpio, 0);
phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0);
phy->ulpi->io_priv = regs + ULPI_VIEWPORT;
} else {
err = utmip_pad_open(phy);
if (err < 0)
goto err1;
}
phy->u_phy.init = tegra_phy_init;
phy->u_phy.shutdown = tegra_usb_phy_close;
phy->u_phy.set_suspend = tegra_usb_phy_suspend;
return phy;
@ -743,24 +795,6 @@ err0:
}
EXPORT_SYMBOL_GPL(tegra_usb_phy_open);
int tegra_usb_phy_power_on(struct tegra_usb_phy *phy)
{
if (phy_is_ulpi(phy))
return ulpi_phy_power_on(phy);
else
return utmi_phy_power_on(phy);
}
EXPORT_SYMBOL_GPL(tegra_usb_phy_power_on);
void tegra_usb_phy_power_off(struct tegra_usb_phy *phy)
{
if (phy_is_ulpi(phy))
ulpi_phy_power_off(phy);
else
utmi_phy_power_off(phy);
}
EXPORT_SYMBOL_GPL(tegra_usb_phy_power_off);
void tegra_usb_phy_preresume(struct tegra_usb_phy *phy)
{
if (!phy_is_ulpi(phy))
@ -803,15 +837,3 @@ void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy)
utmi_phy_clk_enable(phy);
}
EXPORT_SYMBOL_GPL(tegra_usb_phy_clk_enable);
void tegra_usb_phy_close(struct tegra_usb_phy *phy)
{
if (phy_is_ulpi(phy))
clk_put(phy->clk);
else
utmip_pad_close(phy);
clk_disable_unprepare(phy->pll_u);
clk_put(phy->pll_u);
kfree(phy);
}
EXPORT_SYMBOL_GPL(tegra_usb_phy_close);

View File

@ -1,6 +1,4 @@
/*
* arch/arm/mach-tegra/include/mach/usb_phy.h
*
* Copyright (C) 2010 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
@ -14,8 +12,8 @@
*
*/
#ifndef __MACH_USB_PHY_H
#define __MACH_USB_PHY_H
#ifndef __TEGRA_USB_PHY_H
#define __TEGRA_USB_PHY_H
#include <linux/clk.h>
#include <linux/usb/otg.h>
@ -59,19 +57,17 @@ struct tegra_usb_phy {
enum tegra_usb_phy_mode mode;
void *config;
struct usb_phy *ulpi;
struct usb_phy u_phy;
struct device *dev;
};
struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance,
void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode);
int tegra_usb_phy_power_on(struct tegra_usb_phy *phy);
void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy);
void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy);
void tegra_usb_phy_power_off(struct tegra_usb_phy *phy);
void tegra_usb_phy_preresume(struct tegra_usb_phy *phy);
void tegra_usb_phy_postresume(struct tegra_usb_phy *phy);
@ -81,6 +77,4 @@ void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy,
void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy);
void tegra_usb_phy_close(struct tegra_usb_phy *phy);
#endif /* __MACH_USB_PHY_H */
#endif /* __TEGRA_USB_PHY_H */