usb/isp1760: Allow to optionally trigger low-level chip reset via GPIOLIB.

Properly triggering the reset wire is necessary with the ISP1761 used
on Terasic DE4 Altera-FPGA boards using a NIOS2 processor, for example.

This is an optional implementation for the OF binding only. The other
bindings just pass an invalid GPIO to the isp1760_register() routine.

Example, usage in DTS:
        gpios = <&pio_isp1761rst_0 0 1>;
to point to a GPIO controller from within the ISP1761 node: GPIO 0, active low.

Signed-off-by: Joachim Foerster <joachim.foerster@missinglinkelectronics.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index 5b08bd7..27dfab8 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -24,6 +24,7 @@
 #include <linux/timer.h>
 #include <asm/unaligned.h>
 #include <asm/cacheflush.h>
+#include <linux/gpio.h>
 
 #include "isp1760-hcd.h"
 
@@ -48,6 +49,8 @@
 	unsigned long		reset_done;
 	unsigned long		next_statechange;
 	unsigned int		devflags;
+
+	int			rst_gpio;
 };
 
 static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd)
@@ -433,6 +436,18 @@
 	int result;
 	u32 scratch, hwmode;
 
+	/* low-level chip reset */
+	if (gpio_is_valid(priv->rst_gpio)) {
+		unsigned int rst_lvl;
+
+		rst_lvl = (priv->devflags &
+			   ISP1760_FLAG_RESET_ACTIVE_HIGH) ? 1 : 0;
+
+		gpio_set_value(priv->rst_gpio, rst_lvl);
+		mdelay(50);
+		gpio_set_value(priv->rst_gpio, !rst_lvl);
+	}
+
 	/* Setup HW Mode Control: This assumes a level active-low interrupt */
 	hwmode = HW_DATA_BUS_32BIT;
 
@@ -2207,6 +2222,7 @@
 
 struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len,
 				 int irq, unsigned long irqflags,
+				 int rst_gpio,
 				 struct device *dev, const char *busname,
 				 unsigned int devflags)
 {
@@ -2226,6 +2242,7 @@
 
 	priv = hcd_to_priv(hcd);
 	priv->devflags = devflags;
+	priv->rst_gpio = rst_gpio;
 	init_memory(priv);
 	hcd->regs = ioremap(res_start, res_len);
 	if (!hcd->regs) {