| From 74be9c7a78fea88c2504448fff201d44e8ec0ef9 Mon Sep 17 00:00:00 2001 |
| From: Magnus Damm <damm@opensource.se> |
| Date: Thu, 30 Jan 2014 08:10:29 +0900 |
| Subject: ARM: shmobile: Lager USB0 cable detection workaround |
| |
| Add Lager board code to check the PWEN GPIO signal and refuse to |
| allow probe of the USBHS driver in case of DIP misconfiguration. |
| |
| For correct operation Lager DIP switches SW5 and SW6 shall be |
| configured in 2-3 position to enable USB Function support. |
| |
| If the DIP switch is configured incorrectly then the user can |
| simply adjust the hardware and either reboot or use the bind interface |
| to try to probe again: |
| |
| # echo renesas_usbhs > /sys/bus/platform/drivers/renesas_usbhs/bind |
| |
| Signed-off-by: Magnus Damm <damm@opensource.se> |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| (cherry picked from commit 36be7686caa05334ca8d52df157b373a41d8d9f1) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| arch/arm/mach-shmobile/board-lager.c | 25 ++++++++++++++++++++++--- |
| 1 file changed, 22 insertions(+), 3 deletions(-) |
| |
| diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c |
| index 30ebd0805a34..6a7041f9afa6 100644 |
| --- a/arch/arm/mach-shmobile/board-lager.c |
| +++ b/arch/arm/mach-shmobile/board-lager.c |
| @@ -408,13 +408,30 @@ static int usbhs_hardware_init(struct platform_device *pdev) |
| { |
| struct usbhs_private *priv = usbhs_get_priv(pdev); |
| struct usb_phy *phy; |
| + int ret; |
| + |
| + /* USB0 Function - use PWEN as GPIO input to detect DIP Switch SW5 |
| + * setting to avoid VBUS short circuit due to wrong cable. |
| + * PWEN should be pulled up high if USB Function is selected by SW5 |
| + */ |
| + gpio_request_one(RCAR_GP_PIN(5, 18), GPIOF_IN, NULL); /* USB0_PWEN */ |
| + if (!gpio_get_value(RCAR_GP_PIN(5, 18))) { |
| + pr_warn("Error: USB Function not selected - check SW5 + SW6\n"); |
| + ret = -ENOTSUPP; |
| + goto error; |
| + } |
| |
| phy = usb_get_phy_dev(&pdev->dev, 0); |
| - if (IS_ERR(phy)) |
| - return PTR_ERR(phy); |
| + if (IS_ERR(phy)) { |
| + ret = PTR_ERR(phy); |
| + goto error; |
| + } |
| |
| priv->phy = phy; |
| return 0; |
| + error: |
| + gpio_free(RCAR_GP_PIN(5, 18)); |
| + return ret; |
| } |
| |
| static int usbhs_hardware_exit(struct platform_device *pdev) |
| @@ -426,6 +443,8 @@ static int usbhs_hardware_exit(struct platform_device *pdev) |
| |
| usb_put_phy(priv->phy); |
| priv->phy = NULL; |
| + |
| + gpio_free(RCAR_GP_PIN(5, 18)); |
| return 0; |
| } |
| |
| @@ -536,7 +555,7 @@ static const struct pinctrl_map lager_pinctrl_map[] = { |
| "vin1_clk", "vin1"), |
| /* USB0 */ |
| PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs", "pfc-r8a7790", |
| - "usb0", "usb0"), |
| + "usb0_ovc_vbus", "usb0"), |
| }; |
| |
| static void __init lager_add_standard_devices(void) |
| -- |
| 2.1.2 |
| |