]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
usb: xhci: reset gamepad after xhci reinit
authorAnkita Garg <ankitag@nvidia.com>
Tue, 7 Jul 2015 23:07:53 +0000 (16:07 -0700)
committerAshutosh Jha <ajha@nvidia.com>
Fri, 21 Aug 2015 00:18:06 +0000 (17:18 -0700)
Sometimes due to a potential bug in the loki JS firmware,
the gamepad does not respond to set address from the
USB host. This change triggers a gamepad reset
if this error happens.

Bug 1587415

Change-Id: I29bd526581359a215b1522d377c43fd5c4812870
Signed-off-by: Ankita Garg <ankitag@nvidia.com>
Reviewed-on: http://git-master/r/767293
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Ajay Gupta <ajayg@nvidia.com>
Reviewed-by: ChihMin Cheng <ccheng@nvidia.com>
Reviewed-by: Ashutosh Jha <ajha@nvidia.com>
arch/arm64/boot/dts/tegra210-platforms/tegra210-loki-e-gamepad-reset.dtsi
drivers/misc/nv_gamepad_reset.c
drivers/usb/host/xhci-tegra.c
drivers/usb/host/xhci-tegra.h

index 6ed06f00dab143b97381876ccb7baa00b58f566f..be6a282ec732a512f0154f5b72fc62d6179c5316 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * arch/arm64/boot/dts/tegra210-platforms/tegra210-loki-e-gamepad-reset.dtsi
  *
- * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -22,5 +22,6 @@
                name = "gamepad_reset";
 
                reset_gpio = <TEGRA_GPIO(H, 1)>;
+               status = "okay";
        };
 };
index 716e6cdf33833aac23f3b00a7e12684e9dfaa0df..3fdd7ea060e932a901d313fdea76be25b928d0af 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * NVIDIA Gamepad Reset Driver for NVIDIA Shield-2
  *
- * Copyright (c) 2014, NVIDIA Corporation. All Rights Reserved.
+ * Copyright (c) 2014-2015, NVIDIA Corporation. All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -85,6 +85,32 @@ static int gamepad_reset_remove(struct platform_device *pdev)
        return 0;
 }
 
+int gamepad_reset_gpio = -1;
+void gamepad_reset_war(void)
+{
+       int ret;
+
+       ret = gpio_request(gamepad_reset_gpio, "GAMEPAD_RST");
+       if (ret < 0) {
+               pr_err("%s: gpio_request failed %d\n", __func__, ret);
+               return;
+       }
+
+       ret = gpio_direction_output(gamepad_reset_gpio, 1);
+       if (ret < 0) {
+               gpio_free(gamepad_reset_gpio);
+               pr_err("%s: gpio_direction_output failed %d\n", __func__, ret);
+               return;
+       }
+
+       pr_info("%s: xusb WAR - resetting gamepad\n", __func__);
+       gpio_set_value(gamepad_reset_gpio, 0);
+       udelay(RESET_DELAY);
+       gpio_set_value(gamepad_reset_gpio, 1);
+       gpio_free(gamepad_reset_gpio);
+}
+EXPORT_SYMBOL(gamepad_reset_war);
+
 static int gamepad_reset_probe(struct platform_device *pdev)
 {
        int ret;
@@ -124,6 +150,7 @@ static int gamepad_reset_probe(struct platform_device *pdev)
        }
        data->reset_gpio = pdata->reset_gpio;
 #endif
+       gamepad_reset_gpio = data->reset_gpio;
 
        platform_set_drvdata(pdev, data);
 
index 08e2c863901a5c97b7522dc78e924f0de561a093..db2f4311078b0d17548d2ea034a3fc0f747a08ac 100644 (file)
@@ -4234,6 +4234,18 @@ static int tegra_xhci_hcd_reinit(struct usb_hcd *hcd)
        return 0;
 }
 
+#ifdef CONFIG_NV_GAMEPAD_RESET
+static void tegra_loki_gamepad_reset(void)
+{
+       struct device_node *np = of_find_node_by_name(NULL, "gamepad-reset");
+
+       if (np) {
+               if (of_device_is_available(np))
+                       gamepad_reset_war();
+       }
+}
+#endif
+
 static const struct hc_driver tegra_plat_xhci_driver = {
        .description =          "tegra-xhci",
        .product_desc =         "Nvidia xHCI Host Controller",
@@ -5858,5 +5870,9 @@ static void xhci_reinit_work(struct work_struct *work)
                tegra_xhci_unregister_plat();
                usleep_range(10, 20);
                tegra_xhci_register_plat();
+#ifdef CONFIG_NV_GAMEPAD_RESET
+               udelay(10);
+               tegra_loki_gamepad_reset();
+#endif
        }
 }
index 6d5b3ed7cd925ee09148db07e4933d74187ead78..ad67da068e2396ef02539747eff796d72c677fa8 100644 (file)
 
 #include <mach/xusb.h>
 
+#ifdef CONFIG_NV_GAMEPAD_RESET
+extern void gamepad_reset_war(void);
+#endif
+
 #ifdef CONFIG_USB_OTG_WAKELOCK
 extern void otgwl_acquire_temp_lock(void);
 #endif