summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/usb_phy.c
diff options
context:
space:
mode:
authorMarcel Ziswiler <marcel.ziswiler@toradex.com>2012-11-12 15:28:39 +0100
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2012-11-12 15:28:39 +0100
commitf987e832a9e79d2ce8009a5ea9c7b677624b3b30 (patch)
tree0dd09a5e6b4c60ee0a9916907dfc2cda83f3e496 /arch/arm/mach-tegra/usb_phy.c
parentf737b7f46a72c099cf8ac88baff02fbf61b1a47c (diff)
parentfc993d9bc48f772133d8cd156c67c296477db070 (diff)
Merge branch 'l4t/l4t-r16-r2' into colibri
Conflicts: arch/arm/mach-tegra/tegra3_usb_phy.c arch/arm/mach-tegra/usb_phy.c drivers/usb/gadget/tegra_udc.c drivers/usb/otg/Makefile drivers/video/tegra/fb.c sound/soc/tegra/tegra_pcm.c
Diffstat (limited to 'arch/arm/mach-tegra/usb_phy.c')
-rw-r--r--arch/arm/mach-tegra/usb_phy.c73
1 files changed, 46 insertions, 27 deletions
diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c
index 654976b7b1c1..b5d3dc575e0c 100644
--- a/arch/arm/mach-tegra/usb_phy.c
+++ b/arch/arm/mach-tegra/usb_phy.c
@@ -137,7 +137,7 @@ static irqreturn_t usb_phy_dev_vbus_pmu_irq_thr(int irq, void *pdata)
if (phy->vdd_reg && !phy->vdd_reg_on) {
regulator_enable(phy->vdd_reg);
- phy->vdd_reg_on = 1;
+ phy->vdd_reg_on = true;
/*
* Optimal time to get the regulator turned on
* before detecting vbus interrupt.
@@ -224,7 +224,6 @@ fail_ctrlr_clk:
clk_put(phy->pllu_clk);
fail_pll:
-
return err;
}
@@ -234,29 +233,34 @@ struct tegra_usb_phy *tegra_usb_phy_open(struct platform_device *pdev)
struct tegra_usb_platform_data *pdata;
struct resource *res;
int err;
+ int plat_data_size = sizeof(struct tegra_usb_platform_data);
DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, pdev->id);
pdata = dev_get_platdata(&pdev->dev);
if (!pdata) {
dev_err(&pdev->dev, "inst:[%d] Platform data missing\n",
pdev->id);
- return ERR_PTR(-EINVAL);
+ err = -EINVAL;
+ goto fail_inval;
}
- phy = kzalloc(sizeof(struct tegra_usb_phy), GFP_KERNEL);
+ phy = devm_kzalloc(&pdev->dev, sizeof(struct tegra_usb_phy), GFP_KERNEL);
if (!phy) {
ERR("inst:[%d] malloc usb phy failed\n", pdev->id);
- return ERR_PTR(-ENOMEM);
+ err = -ENOMEM;
+ goto fail_nomem;
}
- phy->pdata = kzalloc(sizeof(struct tegra_usb_platform_data), GFP_KERNEL);
+ phy->pdata = devm_kzalloc(&pdev->dev, plat_data_size, GFP_KERNEL);
if (!phy->pdata) {
ERR("inst:[%d] malloc usb phy pdata failed\n", pdev->id);
- kfree(phy);
- return ERR_PTR(-ENOMEM);
+ devm_kfree(&pdev->dev, phy);
+ err = -ENOMEM;
+ goto fail_nomem;
}
- memcpy(phy->pdata, pdata, sizeof(struct tegra_usb_platform_data));
+ memcpy(phy->pdata, pdata, plat_data_size);
+
phy->pdev = pdev;
phy->inst = pdev->id;
@@ -276,7 +280,7 @@ struct tegra_usb_phy *tegra_usb_phy_open(struct platform_device *pdev)
goto fail_io;
}
- phy->vdd_reg = regulator_get(NULL, "avdd_usb");
+ phy->vdd_reg = regulator_get(&pdev->dev, "avdd_usb");
if (IS_ERR_OR_NULL(phy->vdd_reg)) {
ERR("inst:[%d] couldn't get regulator avdd_usb: %ld\n",
phy->inst, PTR_ERR(phy->vdd_reg));
@@ -312,6 +316,7 @@ struct tegra_usb_phy *tegra_usb_phy_open(struct platform_device *pdev)
instance : %d\n", PTR_ERR(phy->vbus_reg),
phy->inst);
err = PTR_ERR(phy->vbus_reg);
+ phy->vbus_reg = NULL;
goto fail_init;
}
} else {
@@ -322,8 +327,6 @@ struct tegra_usb_phy *tegra_usb_phy_open(struct platform_device *pdev)
req failed\n", phy->inst);
goto fail_init;
}
- if (gpio < TEGRA_NR_GPIOS)
- tegra_gpio_enable(gpio);
if (gpio_direction_output(gpio, !phy->pdata->u_data.host.vbus_gpio_inverted) < 0) {
ERR("inst:[%d] host vbus gpio \
dir failed\n", phy->inst);
@@ -377,8 +380,11 @@ fail_clk:
regulator_put(phy->vdd_reg);
iounmap(phy->regs);
fail_io:
- kfree(phy);
+ devm_kfree(&pdev->dev, phy->pdata);
+ devm_kfree(&pdev->dev, phy);
+fail_nomem:
+fail_inval:
return ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(tegra_usb_phy_open);
@@ -418,11 +424,10 @@ void tegra_usb_phy_close(struct tegra_usb_phy *phy)
regulator_put(phy->vdd_reg);
}
-
tegra_usb_phy_release_clocks(phy);
- kfree(phy->pdata);
- kfree(phy);
+ devm_kfree(&phy->pdev->dev, phy->pdata);
+ devm_kfree(&phy->pdev->dev, phy);
}
EXPORT_SYMBOL_GPL(tegra_usb_phy_close);
@@ -435,6 +440,7 @@ irqreturn_t tegra_usb_phy_irq(struct tegra_usb_phy *phy)
return status;
}
+
int tegra_usb_phy_init(struct tegra_usb_phy *phy)
{
int status = 0;
@@ -472,25 +478,30 @@ int tegra_usb_phy_power_off(struct tegra_usb_phy *phy)
clk_disable(phy->sys_clk);
if (phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST) {
if (!phy->pdata->u_data.host.hot_plug &&
- !phy->pdata->u_data.host.remote_wakeup_supported)
+ !phy->pdata->u_data.host.remote_wakeup_supported) {
clk_disable(phy->ctrlr_clk);
+ phy->ctrl_clk_on = false;
+ if (phy->vdd_reg && phy->vdd_reg_on) {
+ regulator_disable(phy->vdd_reg);
+ phy->vdd_reg_on = false;
+ }
+ }
} else {
- /* In device mode clock is turned on by pmu irq handler
- * if pmu irq is not available clocks will not be turned off/on
+ /* In device mode clock regulator/clocks will be turned off
+ * only if pmu interrupt is present on the board and host mode
+ * support through OTG is supported on the board.
*/
- if (phy->pdata->u_data.dev.vbus_pmu_irq) {
+ if (phy->pdata->u_data.dev.vbus_pmu_irq &&
+ phy->pdata->builtin_host_disabled) {
clk_disable(phy->ctrlr_clk);
phy->ctrl_clk_on = false;
+ if (phy->vdd_reg && phy->vdd_reg_on) {
+ regulator_disable(phy->vdd_reg);
+ phy->vdd_reg_on = false;
+ }
}
}
- if (phy->vdd_reg && phy->vdd_reg_on)
- if (phy->pdata->has_hostpc ||
- phy->pdata->builtin_host_disabled) {
- regulator_disable(phy->vdd_reg);
- phy->vdd_reg_on = false;
- }
-
phy->phy_power_on = false;
return err;
@@ -552,6 +563,7 @@ int tegra_usb_phy_reset(struct tegra_usb_phy *phy)
return status;
}
+
int tegra_usb_phy_pre_suspend(struct tegra_usb_phy *phy)
{
int status = 0;
@@ -566,6 +578,7 @@ int tegra_usb_phy_pre_suspend(struct tegra_usb_phy *phy)
return status;
}
+
int tegra_usb_phy_suspend(struct tegra_usb_phy *phy)
{
int err = 0;
@@ -581,6 +594,7 @@ int tegra_usb_phy_suspend(struct tegra_usb_phy *phy)
return err;
}
+
int tegra_usb_phy_post_suspend(struct tegra_usb_phy *phy)
{
int status = 0;
@@ -595,6 +609,7 @@ int tegra_usb_phy_post_suspend(struct tegra_usb_phy *phy)
return status;
}
+
int tegra_usb_phy_pre_resume(struct tegra_usb_phy *phy, bool remote_wakeup)
{
int status = 0;
@@ -609,6 +624,7 @@ int tegra_usb_phy_pre_resume(struct tegra_usb_phy *phy, bool remote_wakeup)
return status;
}
+
int tegra_usb_phy_resume(struct tegra_usb_phy *phy)
{
int err = 0;
@@ -625,6 +641,7 @@ int tegra_usb_phy_resume(struct tegra_usb_phy *phy)
return err;
}
+
int tegra_usb_phy_post_resume(struct tegra_usb_phy *phy)
{
int status = 0;
@@ -639,6 +656,7 @@ int tegra_usb_phy_post_resume(struct tegra_usb_phy *phy)
return status;
}
+
int tegra_usb_phy_port_power(struct tegra_usb_phy *phy)
{
int status = 0;
@@ -650,6 +668,7 @@ int tegra_usb_phy_port_power(struct tegra_usb_phy *phy)
return status;
}
+
int tegra_usb_phy_bus_reset(struct tegra_usb_phy *phy)
{
int status = 0;