[PATCH v4 01/26] usb: isp1760: Use the gpio descriptor API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Switching to the managed gpio descriptor API simplifies both error and
cleanup code paths (by removing the need to free the gpio) and runtime
code (by removing manual handling of the active low flag). It also
permits handling the reset gpio entirely from within the HCD code,
sharing it between the different glue layers.

Signed-off-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx>
Signed-off-by: Felipe Balbi <balbi@xxxxxx>
---
 drivers/usb/host/isp1760-hcd.c | 24 ++++++++++++------------
 drivers/usb/host/isp1760-hcd.h |  2 --
 drivers/usb/host/isp1760-if.c  | 39 +++++++--------------------------------
 3 files changed, 19 insertions(+), 46 deletions(-)

diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index 395649f..e4a9424 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -11,6 +11,7 @@
  * (c) 2011 Arvid Brodin <arvid.brodin@xxxxxxxx>
  *
  */
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -24,7 +25,6 @@
 #include <linux/timer.h>
 #include <asm/unaligned.h>
 #include <asm/cacheflush.h>
-#include <linux/gpio.h>
 
 #include "isp1760-hcd.h"
 
@@ -57,7 +57,7 @@ struct isp1760_hcd {
 	unsigned long		next_statechange;
 	unsigned int		devflags;
 
-	int			rst_gpio;
+	struct gpio_desc	*rst_gpio;
 };
 
 static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd)
@@ -444,15 +444,10 @@ static int isp1760_hc_setup(struct usb_hcd *hcd)
 	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);
+	if (priv->rst_gpio) {
+		gpiod_set_value_cansleep(priv->rst_gpio, 1);
 		mdelay(50);
-		gpio_set_value(priv->rst_gpio, !rst_lvl);
+		gpiod_set_value_cansleep(priv->rst_gpio, 0);
 	}
 
 	/* Setup HW Mode Control: This assumes a level active-low interrupt */
@@ -2215,7 +2210,6 @@ void deinit_kmem_cache(void)
 
 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)
 {
@@ -2235,7 +2229,13 @@ struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len,
 
 	priv = hcd_to_priv(hcd);
 	priv->devflags = devflags;
-	priv->rst_gpio = rst_gpio;
+
+	priv->rst_gpio = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH);
+	if (IS_ERR(priv->rst_gpio)) {
+		ret = PTR_ERR(priv->rst_gpio);
+		goto err_put;
+	}
+
 	init_memory(priv);
 	hcd->regs = ioremap(res_start, res_len);
 	if (!hcd->regs) {
diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h
index 33dc79c..fda0f2d 100644
--- a/drivers/usb/host/isp1760-hcd.h
+++ b/drivers/usb/host/isp1760-hcd.h
@@ -4,7 +4,6 @@
 /* exports for if */
 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);
 int init_kmem_once(void);
@@ -127,7 +126,6 @@ typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh,
 #define ISP1760_FLAG_ISP1761		0x00000040 /* Chip is ISP1761 */
 #define ISP1760_FLAG_INTR_POL_HIGH	0x00000080 /* Interrupt polarity active high */
 #define ISP1760_FLAG_INTR_EDGE_TRIG	0x00000100 /* Interrupt edge triggered */
-#define ISP1760_FLAG_RESET_ACTIVE_HIGH	0x80000000 /* RESET GPIO active high */
 
 /* chip memory management */
 struct memory_chunk {
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
index 09254a4..7e8e7f6 100644
--- a/drivers/usb/host/isp1760-if.c
+++ b/drivers/usb/host/isp1760-if.c
@@ -24,7 +24,6 @@
 #include <linux/of_platform.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
-#include <linux/of_gpio.h>
 #endif
 
 #ifdef CONFIG_PCI
@@ -34,7 +33,6 @@
 #if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ)
 struct isp1760 {
 	struct usb_hcd *hcd;
-	int rst_gpio;
 };
 
 static int of_isp1760_probe(struct platform_device *dev)
@@ -47,7 +45,6 @@ static int of_isp1760_probe(struct platform_device *dev)
 	resource_size_t res_len;
 	int ret;
 	unsigned int devflags = 0;
-	enum of_gpio_flags gpio_flags;
 	u32 bus_width = 0;
 
 	drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
@@ -94,36 +91,17 @@ static int of_isp1760_probe(struct platform_device *dev)
 	if (of_get_property(dp, "dreq-polarity", NULL) != NULL)
 		devflags |= ISP1760_FLAG_DREQ_POL_HIGH;
 
-	drvdata->rst_gpio = of_get_gpio_flags(dp, 0, &gpio_flags);
-	if (gpio_is_valid(drvdata->rst_gpio)) {
-		ret = gpio_request(drvdata->rst_gpio, dev_name(&dev->dev));
-		if (!ret) {
-			if (!(gpio_flags & OF_GPIO_ACTIVE_LOW)) {
-				devflags |= ISP1760_FLAG_RESET_ACTIVE_HIGH;
-				gpio_direction_output(drvdata->rst_gpio, 0);
-			} else {
-				gpio_direction_output(drvdata->rst_gpio, 1);
-			}
-		} else {
-			drvdata->rst_gpio = ret;
-		}
-	}
-
 	drvdata->hcd = isp1760_register(memory.start, res_len, virq,
-					IRQF_SHARED, drvdata->rst_gpio,
-					&dev->dev, dev_name(&dev->dev),
-					devflags);
+					IRQF_SHARED, &dev->dev,
+					dev_name(&dev->dev), devflags);
 	if (IS_ERR(drvdata->hcd)) {
 		ret = PTR_ERR(drvdata->hcd);
-		goto free_gpio;
+		goto release_reg;
 	}
 
 	platform_set_drvdata(dev, drvdata);
 	return ret;
 
-free_gpio:
-	if (gpio_is_valid(drvdata->rst_gpio))
-		gpio_free(drvdata->rst_gpio);
 release_reg:
 	release_mem_region(memory.start, res_len);
 free_data:
@@ -140,9 +118,6 @@ static int of_isp1760_remove(struct platform_device *dev)
 	release_mem_region(drvdata->hcd->rsrc_start, drvdata->hcd->rsrc_len);
 	usb_put_hcd(drvdata->hcd);
 
-	if (gpio_is_valid(drvdata->rst_gpio))
-		gpio_free(drvdata->rst_gpio);
-
 	kfree(drvdata);
 	return 0;
 }
@@ -279,8 +254,8 @@ static int isp1761_pci_probe(struct pci_dev *dev,
 
 	dev->dev.dma_mask = NULL;
 	hcd = isp1760_register(pci_mem_phy0, memlength, dev->irq,
-		IRQF_SHARED, -ENOENT, &dev->dev, dev_name(&dev->dev),
-		devflags);
+			       IRQF_SHARED, &dev->dev, dev_name(&dev->dev),
+			       devflags);
 	if (IS_ERR(hcd)) {
 		ret_status = -ENODEV;
 		goto cleanup3;
@@ -392,8 +367,8 @@ static int isp1760_plat_probe(struct platform_device *pdev)
 	}
 
 	hcd = isp1760_register(mem_res->start, mem_size, irq_res->start,
-			       irqflags, -ENOENT,
-			       &pdev->dev, dev_name(&pdev->dev), devflags);
+			       irqflags, &pdev->dev, dev_name(&pdev->dev),
+			       devflags);
 
 	platform_set_drvdata(pdev, hcd);
 
-- 
2.0.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux