aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Konovalov <andrey.konovalov@linaro.org>2013-04-18 20:26:10 +0400
committerAndrey Konovalov <andrey.konovalov@linaro.org>2013-04-18 20:26:10 +0400
commit5a59f9681dcf273d0dbc7826d39d77ed513821f3 (patch)
tree6c7f0f3d1ca8a1ca0dba7ebf3662e8b8bb68b63d
parenta241dda2f11243b3b87aedf87a3dc9e72580a2b3 (diff)
parent3896c8e6399e6bc73ddbd63de0734b48f9b749f2 (diff)
Automatically merging tracking-panda-fix-usb into merge-linux-linaro
Conflicting files:
-rw-r--r--Documentation/devicetree/bindings/arm/omap/usb-host.txt60
-rw-r--r--Documentation/devicetree/bindings/regulator/fixed-regulator.txt6
-rw-r--r--arch/arm/boot/dts/omap4-panda.dts54
-rw-r--r--arch/arm/boot/dts/omap4.dtsi5
-rw-r--r--arch/arm/mach-omap2/board-generic.c2
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c94
-rw-r--r--arch/arm/mach-omap2/common.h2
-rw-r--r--arch/arm/mach-omap2/usb-host.c73
-rw-r--r--drivers/mfd/omap-usb-host.c44
-rw-r--r--drivers/regulator/fixed.c6
-rw-r--r--drivers/usb/host/ehci-omap.c86
-rw-r--r--include/linux/platform_data/usb-omap.h3
12 files changed, 331 insertions, 104 deletions
diff --git a/Documentation/devicetree/bindings/arm/omap/usb-host.txt b/Documentation/devicetree/bindings/arm/omap/usb-host.txt
new file mode 100644
index 00000000000..f25cfa416c8
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/omap/usb-host.txt
@@ -0,0 +1,60 @@
+* usb-host - OMAP USB Host Subsystem
+
+The OMAP USB host subsystem consists of the following modules
+1) USBTLL (Tranceiverless interface)
+2) USBHOST (Host Controller module) which includes both EHCI and OHCI controllers
+
+THe USB Host subsystem can be connected to the external world using 3 PORTs that could
+be configured in various modes like UTMI+ for external PHY, ULPI transceiverless link (TLL),
+Serial TLL, High-speed interchip (HSIC), etc.
+
+Required proprties:
+- compatible: Must be "ti,usb-host";
+- num_ports: Number of physical ports available
+
+Optional properties:
+- 1 child node for each available port. These child nodes are usually supplied by the
+ board support device tree as they are specific to how the ports are wired on the board
+
+ - mode: Integer specifying the mode in which the port is used
+ * OMAP_USBHS_PORT_MODE_UNUSED = 0,
+ * OMAP_EHCI_PORT_MODE_PHY = 1,
+ * OMAP_EHCI_PORT_MODE_TLL = 2,
+ * OMAP_EHCI_PORT_MODE_HSIC = 3,
+ * OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0 = 4,
+ * OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM = 5,
+ * OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0 = 6,
+ * OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM = 7,
+ * OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0 = 8,
+ * OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM = 9,
+ * OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0 = 10,
+ * OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM = 11,
+ * OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0 = 12,
+ * OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM = 13,
+ - clk: Name of the clock that needs to be active when using the port
+ - clkrate: Frequency at which the above clk needs to be run at
+
+
+Example:
+
+/* In the OMAP Core tree */
+usbhost: usb-host {
+ compatible = "ti,usb-host";
+ num_ports = <3>;
+};
+
+/* In the Board tree */
+&usbhost {
+ port@0 {
+ mode = <1>;
+ clk = "auxclk3_ck";
+ clkrate = <19200000>;
+ };
+ port@1 {
+ mode = <0>;
+ };
+ port@2 {
+ mode = <0>;
+ };
+};
+
diff --git a/Documentation/devicetree/bindings/regulator/fixed-regulator.txt b/Documentation/devicetree/bindings/regulator/fixed-regulator.txt
index 4fae41d5479..fe341147d1b 100644
--- a/Documentation/devicetree/bindings/regulator/fixed-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/fixed-regulator.txt
@@ -7,10 +7,10 @@ Optional properties:
- gpio: gpio to use for enable control
- startup-delay-us: startup time in microseconds
- enable-active-high: Polarity of GPIO is Active high
-If this property is missing, the default assumed is Active low.
+ If this property is missing, the default assumed is Active low.
- gpio-open-drain: GPIO is open drain type.
If this property is missing then default assumption is false.
--vin-supply: Input supply name.
+- vin-supply: Input supply name.
Any property defined as part of the core regulator
binding, defined in regulator.txt, can also be used.
@@ -30,5 +30,5 @@ Example:
enable-active-high;
regulator-boot-on;
gpio-open-drain;
- vin-supply = <&parent_reg>;
+ vin-supply = "input-supply-name";
};
diff --git a/arch/arm/boot/dts/omap4-panda.dts b/arch/arm/boot/dts/omap4-panda.dts
index 4122efe31cf..1d98284ad3b 100644
--- a/arch/arm/boot/dts/omap4-panda.dts
+++ b/arch/arm/boot/dts/omap4-panda.dts
@@ -57,6 +57,27 @@
"AFML", "Line In",
"AFMR", "Line In";
};
+
+ hubpower: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vhub0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 1 0>; /* gpio 1 : HUB Power */
+ startup-delay-us = <70000>;
+ enable-active-high;
+ };
+
+ hubreset: fixedregulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "hsusb0"; /* tag to associate with PORT 1 */
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 30 0>; /* gpio 62 : HUB & PHY Reset */
+ startup-delay-us = <70000>;
+ enable-active-high;
+ vin-supply = "vhub0"; /* Makes regulator f/w enable power before reset */
+ };
};
&omap4_pmx_core {
@@ -67,6 +88,7 @@
&mcbsp1_pins
&dss_hdmi_pins
&tpd12s015_pins
+ &usbb1_pins /* port 0 of omap usb host port pin mux configuration */
>;
twl6040_pins: pinmux_twl6040_pins {
@@ -110,6 +132,23 @@
0x58 0x10b /* hdmi_hpd.gpio_63 INPUT PULLDOWN | MODE3 */
>;
};
+
+ usbb1_pins: pinmux_usbb1_pins {
+ pinctrl-single,pins = <
+ 0x82 0x10C /* USBB1_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_clk INPUT | PULLDOWN */
+ 0x84 0x4 /* USBB1_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_stp OUTPUT */
+ 0x86 0x104 /* USBB1_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dir INPUT | PULLDOWN */
+ 0x88 0x104 /* USBB1_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_nxt INPUT | PULLDOWN */
+ 0x8a 0x104 /* USBB1_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat0 INPUT | PULLDOWN */
+ 0x8c 0x104 /* USBB1_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat1 INPUT | PULLDOWN */
+ 0x8e 0x104 /* USBB1_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat2 INPUT | PULLDOWN */
+ 0x90 0x104 /* USBB1_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat3 INPUT | PULLDOWN */
+ 0x92 0x104 /* USBB1_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat4 INPUT | PULLDOWN */
+ 0x94 0x104 /* USBB1_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat5 INPUT | PULLDOWN */
+ 0x96 0x104 /* USBB1_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat6 INPUT | PULLDOWN */
+ 0x98 0x104 /* USBB1_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat7 INPUT | PULLDOWN */
+ >;
+ };
};
&i2c1 {
@@ -136,6 +175,21 @@
};
};
+
+&usbhost {
+ port@0 {
+ mode = <1>; /* PHY mode */
+ clk = "auxclk3_ck"; /* PHY clock on FREF_CLK3_OUT */
+ clkrate = <19200000>;
+ };
+ port@1 {
+ mode = <0>;
+ };
+ port@2 {
+ mode = <0>;
+ };
+};
+
/include/ "twl6030.dtsi"
&i2c2 {
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
index 739bb79e410..0900d44388c 100644
--- a/arch/arm/boot/dts/omap4.dtsi
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -529,5 +529,10 @@
ti,hwmods = "timer11";
ti,timer-pwm;
};
+
+ usbhost: usb-host {
+ compatible = "ti,usb-host";
+ num_ports = <2>;
+ };
};
};
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index e54a4806019..65ea5e7185f 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -49,6 +49,8 @@ static void __init omap_generic_init(void)
omap4_panda_display_init_of();
else if (of_machine_is_compatible("ti,omap4-sdp"))
omap_4430sdp_display_init_of();
+
+ usbhost_init_of();
}
#ifdef CONFIG_SOC_OMAP2420
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index b02c2f00609..1dfdaeb0461 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -147,45 +147,73 @@ static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
.phy_reset = false,
.reset_gpio_port[0] = -EINVAL,
.reset_gpio_port[1] = -EINVAL,
- .reset_gpio_port[2] = -EINVAL
+ .reset_gpio_port[2] = -EINVAL,
+ .clk[0] = "auxclk3_ck", /* FREF_CLK3 provides 19.2 MHz clock to PHY */
+ .clkrate[0] = 19200000,
};
-static struct gpio panda_ehci_gpios[] __initdata = {
- { GPIO_HUB_POWER, GPIOF_OUT_INIT_LOW, "hub_power" },
- { GPIO_HUB_NRESET, GPIOF_OUT_INIT_LOW, "hub_nreset" },
+/*
+ * hub_nreset also enables the ULPI PHY
+ * ULPI PHY is always powered
+ * hub_power enables a 3.3V regulator for (hub + eth) chip
+ * however there's no point having ULPI PHY in use alone
+ * since it's only connected to the (hub + eth) chip
+ */
+
+static struct regulator_init_data panda_hub = {
+ .constraints = {
+ .name = "vhub",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
};
-static void __init omap4_ehci_init(void)
-{
- int ret;
- struct clk *phy_ref_clk;
+static struct fixed_voltage_config panda_vhub = {
+ .supply_name = "vhub",
+ .microvolts = 3300000,
+ .gpio = GPIO_HUB_POWER,
+ .startup_delay = 70000, /* 70msec */
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &panda_hub,
+};
- /* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */
- phy_ref_clk = clk_get(NULL, "auxclk3_ck");
- if (IS_ERR(phy_ref_clk)) {
- pr_err("Cannot request auxclk3\n");
- return;
- }
- clk_set_rate(phy_ref_clk, 19200000);
- clk_prepare_enable(phy_ref_clk);
-
- /* disable the power to the usb hub prior to init and reset phy+hub */
- ret = gpio_request_array(panda_ehci_gpios,
- ARRAY_SIZE(panda_ehci_gpios));
- if (ret) {
- pr_err("Unable to initialize EHCI power/reset\n");
- return;
- }
+static struct platform_device omap_vhub_device = {
+ .name = "reg-fixed-voltage",
+ .id = 2,
+ .dev = {
+ .platform_data = &panda_vhub,
+ },
+};
- gpio_export(GPIO_HUB_POWER, 0);
- gpio_export(GPIO_HUB_NRESET, 0);
- gpio_set_value(GPIO_HUB_NRESET, 1);
+static struct regulator_init_data panda_ulpireset = {
+ /*
+ * idea is that when operating ulpireset, regulator api will make
+ * sure that the hub+eth chip is powered, since it's the "parent"
+ */
+ .supply_regulator = "vhub", /* we are a child of vhub */
+ .constraints = {
+ .name = "hsusb0",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
- usbhs_init(&usbhs_bdata);
+static struct fixed_voltage_config panda_vulpireset = {
+ .supply_name = "hsusb0", /* this name is magic for hsusb driver */
+ .microvolts = 3300000,
+ .gpio = GPIO_HUB_NRESET,
+ .startup_delay = 70000, /* 70msec */
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &panda_ulpireset,
+};
- /* enable power to hub */
- gpio_set_value(GPIO_HUB_POWER, 1);
-}
+static struct platform_device omap_vulpireset_device = {
+ .name = "reg-fixed-voltage",
+ .id = 3,
+ .dev = {
+ .platform_data = &panda_vulpireset,
+ },
+};
static struct omap_musb_board_data musb_board_data = {
.interface_type = MUSB_INTERFACE_UTMI,
@@ -444,10 +472,12 @@ static void __init omap4_panda_init(void)
omap4_panda_i2c_init();
platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
platform_device_register(&omap_vwlan_device);
+ platform_device_register(&omap_vhub_device);
+ platform_device_register(&omap_vulpireset_device);
omap_serial_init();
omap_sdrc_init(NULL, NULL);
omap4_twl6030_hsmmc_init(mmc);
- omap4_ehci_init();
+ usbhs_init(&usbhs_bdata);
usb_bind_phy("musb-hdrc.0.auto", 0, "omap-usb2.1.auto");
usb_musb_init(&musb_board_data);
omap4_panda_display_init();
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index d6ba13e1c54..ce8945f104e 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -296,5 +296,7 @@ extern int omap_dss_reset(struct omap_hwmod *);
/* SoC specific clock initializer */
extern int (*omap_clk_init)(void);
+void __init usbhost_init_of(void);
+
#endif /* __ASSEMBLER__ */
#endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */
diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c
index 5706bdccf45..fb9a10d2ed6 100644
--- a/arch/arm/mach-omap2/usb-host.c
+++ b/arch/arm/mach-omap2/usb-host.c
@@ -22,6 +22,8 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
#include <asm/io.h>
@@ -526,3 +528,74 @@ void __init usbhs_init(struct usbhs_omap_platform_data *pdata)
}
#endif
+
+static struct usbhs_omap_platform_data bdata;
+
+#define USBHS_NODE "usb-host"
+
+/**
+ * usbhost_init_of - initialize USB Host subsystem from device tree
+ *
+ * Scans the device tree for required information and populates
+ * platform data for the OMAP USB High Speed Host subsystem
+ */
+void __init usbhost_init_of(void)
+{
+ int r;
+ struct device_node *node, *child;
+ int num_ports;
+ int i;
+
+ node = of_find_node_by_name(NULL, USBHS_NODE);
+ if (!node) {
+ pr_err("%s could not find OF node : %s\n",
+ __func__, USBHS_NODE);
+ return;
+ }
+
+ r = of_property_read_u32(node, "num_ports", &num_ports);
+ if (r) {
+ pr_err("%s num_ports not specified in OF node %s\n",
+ __func__, USBHS_NODE);
+ } else {
+ bdata.nports = num_ports;
+ }
+
+ r = of_property_read_bool(node, "phy_reset");
+ bdata.phy_reset = r;
+
+ i = 0;
+ for_each_child_of_node(node, child) {
+ int mode;
+ const char *clk_name;
+ u32 clk_rate;
+
+ r = of_property_read_u32(child, "mode", &mode);
+ if (r) {
+ pr_err("%s mode not specified in OF node %s port %d\n",
+ __func__, USBHS_NODE, i);
+ bdata.port_mode[i] = OMAP_USBHS_PORT_MODE_UNUSED;
+ } else {
+ bdata.port_mode[i] = mode;
+ }
+
+ r = of_get_named_gpio(child, "reset_gpio", 0);
+ if (gpio_is_valid(r))
+ bdata.reset_gpio_port[i] = r;
+ else
+ bdata.reset_gpio_port[i] = -EINVAL;
+
+ clk_name = of_get_property(child, "clk", NULL);
+ if (clk_name)
+ bdata.clk[i] = clk_name;
+
+ r = of_property_read_u32(child, "clkrate", &clk_rate);
+ if (!r)
+ bdata.clkrate[i] = clk_rate;
+
+ i++;
+ }
+
+ usbhs_init(&bdata);
+}
+
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 4febc5c7fde..21af9abf7e1 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -88,12 +88,12 @@
#define is_ehci_tll_mode(x) (x == OMAP_EHCI_PORT_MODE_TLL)
#define is_ehci_hsic_mode(x) (x == OMAP_EHCI_PORT_MODE_HSIC)
-
struct usbhs_hcd_omap {
int nports;
struct clk **utmi_clk;
struct clk **hsic60m_clk;
struct clk **hsic480m_clk;
+ struct clk **aux_clk; /* board dependent clock */
struct clk *xclk60mhsp1_ck;
struct clk *xclk60mhsp2_ck;
@@ -284,6 +284,14 @@ static int usbhs_runtime_resume(struct device *dev)
clk_enable(omap->ehci_logic_fck);
for (i = 0; i < omap->nports; i++) {
+ if (!IS_ERR(omap->aux_clk[i])) {
+ r = clk_prepare_enable(omap->aux_clk[i]);
+ if (r) {
+ dev_err(dev,
+ "Can't enable port %d aux clk %d\n", i, r);
+ }
+ }
+
switch (pdata->port_mode[i]) {
case OMAP_EHCI_PORT_MODE_HSIC:
if (!IS_ERR(omap->hsic60m_clk[i])) {
@@ -348,6 +356,9 @@ static int usbhs_runtime_suspend(struct device *dev)
default:
break;
}
+
+ if (!IS_ERR(omap->aux_clk[i]))
+ clk_disable(omap->aux_clk[i]);
}
if (!IS_ERR(omap->ehci_logic_fck))
@@ -581,11 +592,13 @@ static int usbhs_omap_probe(struct platform_device *pdev)
omap->utmi_clk = devm_kzalloc(dev, i, GFP_KERNEL);
omap->hsic480m_clk = devm_kzalloc(dev, i, GFP_KERNEL);
omap->hsic60m_clk = devm_kzalloc(dev, i, GFP_KERNEL);
+ omap->aux_clk = devm_kzalloc(dev, i, GFP_KERNEL);
- if (!omap->utmi_clk || !omap->hsic480m_clk || !omap->hsic60m_clk) {
- dev_err(dev, "Memory allocation failed\n");
- ret = -ENOMEM;
- goto err_mem;
+ if (!omap->utmi_clk || !omap->hsic480m_clk || !omap->hsic60m_clk ||
+ !omap->aux_clk) {
+ dev_err(dev, "Memory allocation failed\n");
+ ret = -ENOMEM;
+ goto err_mem;
}
need_logic_fck = false;
@@ -668,6 +681,23 @@ static int usbhs_omap_probe(struct platform_device *pdev)
if (IS_ERR(omap->hsic60m_clk[i]))
dev_dbg(dev, "Failed to get clock : %s : %ld\n",
clkname, PTR_ERR(omap->hsic60m_clk[i]));
+
+ /* get the auxiliary clock if required and set its rate */
+ if (pdata->clk[i] && pdata->clkrate[i]) {
+ omap->aux_clk[i] = clk_get(dev, pdata->clk[i]);
+ if (IS_ERR(omap->aux_clk[i])) {
+ dev_dbg(dev, "Failed to get clock %s\n",
+ pdata->clk[i]);
+ } else {
+ ret = clk_set_rate(omap->aux_clk[i],
+ pdata->clkrate[i]);
+ if (ret) {
+ dev_err(dev,
+ "Failed to set clock %s to %luHz\n",
+ pdata->clk[i], pdata->clkrate[i]);
+ }
+ }
+ }
}
if (is_ehci_phy_mode(pdata->port_mode[0])) {
@@ -718,6 +748,8 @@ err_alloc:
clk_put(omap->hsic60m_clk[i]);
if (!IS_ERR(omap->hsic480m_clk[i]))
clk_put(omap->hsic480m_clk[i]);
+ if (!IS_ERR(omap->aux_clk[i]))
+ clk_put(omap->aux_clk[i]);
}
clk_put(omap->init_60m_fclk);
@@ -764,6 +796,8 @@ static int usbhs_omap_remove(struct platform_device *pdev)
clk_put(omap->hsic60m_clk[i]);
if (!IS_ERR(omap->hsic480m_clk[i]))
clk_put(omap->hsic480m_clk[i]);
+ if (!IS_ERR(omap->aux_clk[i]))
+ clk_put(omap->aux_clk[i]);
}
clk_put(omap->init_60m_fclk);
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index e5c03b534fa..0af15854fb4 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -53,6 +53,7 @@ of_get_fixed_voltage_config(struct device *dev)
struct device_node *np = dev->of_node;
const __be32 *delay;
struct regulator_init_data *init_data;
+ const char *vin_name;
config = devm_kzalloc(dev, sizeof(struct fixed_voltage_config),
GFP_KERNEL);
@@ -102,8 +103,9 @@ of_get_fixed_voltage_config(struct device *dev)
if (of_find_property(np, "gpio-open-drain", NULL))
config->gpio_is_open_drain = true;
- if (of_find_property(np, "vin-supply", NULL))
- config->input_supply = "vin";
+ vin_name = of_get_property(np, "vin-supply", NULL);
+ if (vin_name)
+ config->input_supply = vin_name;
return config;
}
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 0555ee42d7c..82bc25cc24e 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -72,37 +72,6 @@ static inline u32 ehci_read(void __iomem *base, u32 reg)
return __raw_readl(base + reg);
}
-
-static void omap_ehci_soft_phy_reset(struct usb_hcd *hcd, u8 port)
-{
- unsigned long timeout = jiffies + msecs_to_jiffies(1000);
- unsigned reg = 0;
-
- reg = ULPI_FUNC_CTRL_RESET
- /* FUNCTION_CTRL_SET register */
- | (ULPI_SET(ULPI_FUNC_CTRL) << EHCI_INSNREG05_ULPI_REGADD_SHIFT)
- /* Write */
- | (2 << EHCI_INSNREG05_ULPI_OPSEL_SHIFT)
- /* PORTn */
- | ((port + 1) << EHCI_INSNREG05_ULPI_PORTSEL_SHIFT)
- /* start ULPI access*/
- | (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT);
-
- ehci_write(hcd->regs, EHCI_INSNREG05_ULPI, reg);
-
- /* Wait for ULPI access completion */
- while ((ehci_read(hcd->regs, EHCI_INSNREG05_ULPI)
- & (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT))) {
- cpu_relax();
-
- if (time_after(jiffies, timeout)) {
- dev_dbg(hcd->self.controller,
- "phy reset operation timed out\n");
- break;
- }
- }
-}
-
static int omap_ehci_init(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
@@ -111,42 +80,11 @@ static int omap_ehci_init(struct usb_hcd *hcd)
pdata = hcd->self.controller->platform_data;
- /* Hold PHYs in reset while initializing EHCI controller */
- if (pdata->phy_reset) {
- if (gpio_is_valid(pdata->reset_gpio_port[0]))
- gpio_set_value_cansleep(pdata->reset_gpio_port[0], 0);
-
- if (gpio_is_valid(pdata->reset_gpio_port[1]))
- gpio_set_value_cansleep(pdata->reset_gpio_port[1], 0);
-
- /* Hold the PHY in RESET for enough time till DIR is high */
- udelay(10);
- }
-
- /* Soft reset the PHY using PHY reset command over ULPI */
- if (pdata->port_mode[0] == OMAP_EHCI_PORT_MODE_PHY)
- omap_ehci_soft_phy_reset(hcd, 0);
- if (pdata->port_mode[1] == OMAP_EHCI_PORT_MODE_PHY)
- omap_ehci_soft_phy_reset(hcd, 1);
-
/* we know this is the memory we want, no need to ioremap again */
ehci->caps = hcd->regs;
rc = ehci_setup(hcd);
- if (pdata->phy_reset) {
- /* Hold the PHY in RESET for enough time till
- * PHY is settled and ready
- */
- udelay(10);
-
- if (gpio_is_valid(pdata->reset_gpio_port[0]))
- gpio_set_value_cansleep(pdata->reset_gpio_port[0], 1);
-
- if (gpio_is_valid(pdata->reset_gpio_port[1]))
- gpio_set_value_cansleep(pdata->reset_gpio_port[1], 1);
- }
-
return rc;
}
@@ -241,6 +179,18 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
}
}
+ /* Hold PHYs in reset while initializing EHCI controller */
+ if (pdata->phy_reset) {
+ if (gpio_is_valid(pdata->reset_gpio_port[0]))
+ gpio_set_value_cansleep(pdata->reset_gpio_port[0], 0);
+
+ if (gpio_is_valid(pdata->reset_gpio_port[1]))
+ gpio_set_value_cansleep(pdata->reset_gpio_port[1], 0);
+
+ /* Hold the PHY in RESET for enough time till DIR is high */
+ udelay(10);
+ }
+
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
@@ -262,6 +212,18 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
goto err_pm_runtime;
}
+ if (pdata->phy_reset) {
+ /* Hold the PHY in RESET for enough time till
+ * PHY is settled and ready
+ */
+ udelay(10);
+
+ if (gpio_is_valid(pdata->reset_gpio_port[0]))
+ gpio_set_value_cansleep(pdata->reset_gpio_port[0], 1);
+
+ if (gpio_is_valid(pdata->reset_gpio_port[1]))
+ gpio_set_value_cansleep(pdata->reset_gpio_port[1], 1);
+ }
return 0;
diff --git a/include/linux/platform_data/usb-omap.h b/include/linux/platform_data/usb-omap.h
index fa579b4c666..6b8d99958a5 100644
--- a/include/linux/platform_data/usb-omap.h
+++ b/include/linux/platform_data/usb-omap.h
@@ -63,6 +63,9 @@ struct usbhs_omap_platform_data {
struct ehci_hcd_omap_platform_data *ehci_data;
struct ohci_hcd_omap_platform_data *ohci_data;
+ const char *clk[OMAP3_HS_USB_PORTS];
+ unsigned long int clkrate[OMAP3_HS_USB_PORTS];
+
/* OMAP3 <= ES2.1 have a single ulpi bypass control bit */
unsigned single_ulpi_bypass:1;
unsigned es2_compatibility:1;