diff mbox series

[20/22] gpio: xilinx: defer the probe if clock is not found

Message ID 5D23E7CAADD3BE4A97642792FFC691C561C7A5E6@MBX215.d.ethz.ch
State New
Headers show
Series None | expand

Commit Message

Hedges Alexander July 21, 2018, 2:38 p.m. UTC
From: Venkatesh Yadav Abbarapu <vabbarap@xilinx.com>
Date: Wed, 24 Jan 2018 18:20:19 +0530

It's not always the case that clock is already available when gpio
driver get probed at the first time, e.g. the clock is provided by
clock wizard which may be probed after gpio driver. So let's defer
the probe when devm_clk_get() call fails and give it chance to
try later.

Signed-off-by: Venkatesh Yadav Abbarapu <vabbarap@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Signed-off-by: Alexander Hedges <ahedges@ethz.ch>
(cherry picked from commit 3bbc2fda8018d067910eac153c1f30caa509828a)
---
 .../devicetree/bindings/gpio/gpio-xilinx.txt  |  4 ++
 drivers/gpio/gpio-xilinx.c                    | 69 +++++++++----------
 2 files changed, 38 insertions(+), 35 deletions(-)
diff mbox series

Patch

diff --git a/Documentation/devicetree/bindings/gpio/gpio-xilinx.txt b/Documentation/devicetree/bindings/gpio/gpio-xilinx.txt
index 7efb3395c6fa..60ab01786019 100644
--- a/Documentation/devicetree/bindings/gpio/gpio-xilinx.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio-xilinx.txt
@@ -15,6 +15,8 @@  Required properties:
 - gpio-controller : Marks the device node as a GPIO controller.
 
 Optional properties:
+- clock-names : Should be "s_axi_aclk"
+- clocks: Input clock specifier. Refer to common clock bindings.
 - interrupts : Interrupt mapping for GPIO IRQ.
 - interrupt-parent : Phandle for the interrupt controller that
   services interrupts for this device.
@@ -34,6 +36,8 @@  gpio: gpio@40000000 {
 	#gpio-cells = <2>;
 	compatible = "xlnx,xps-gpio-1.00.a";
 	gpio-controller ;
+	clock-names = "s_axi_aclk";
+	clocks = <&clkc 71>;
 	interrupt-parent = <&microblaze_0_intc>;
 	interrupts = < 6 2 >;
 	reg = < 0x40000000 0x10000 >;
diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index 92fdb5c92203..9256ad296082 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -64,8 +64,8 @@ 
  */
 struct xgpio_instance {
 	struct of_mm_gpio_chip mmchip;
-	u32 gpio_state;		/* GPIO state shadow register */
-	u32 gpio_dir;		/* GPIO direction shadow register */
+	u32 gpio_state;
+	u32 gpio_dir;
 	u32 offset;
 	int irq_base;
 	u32 irq_enable;
@@ -93,7 +93,7 @@  static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
 
 	void __iomem *regs = mm_gc->regs + chip->offset;
 
-	return (xgpio_readreg(regs + XGPIO_DATA_OFFSET) >> gpio) & 1;
+	return !!(xgpio_readreg(regs + XGPIO_DATA_OFFSET) & BIT(gpio));
 }
 
 /**
@@ -134,7 +134,6 @@  static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
  * @bits:   Value to be wrote on each GPIO
  *
  * This function writes the specified values into the specified signals of the
-IO at once
  * GPIO devices.
  */
 static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
@@ -189,7 +188,7 @@  static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
 	spin_lock_irqsave(&chip->gpio_lock, flags);
 
 	/* Set the GPIO bit in shadow register and set direction as input */
-	chip->gpio_dir |= (1 << gpio);
+	chip->gpio_dir |= BIT(gpio);
 	xgpio_writereg(regs + chip->offset + XGPIO_TRI_OFFSET, chip->gpio_dir);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
@@ -213,7 +212,8 @@  static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 {
 	unsigned long flags;
 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
-	struct xgpio_instance *chip = gpiochip_get_data(gc);
+	struct xgpio_instance *chip =
+	    container_of(mm_gc, struct xgpio_instance, mmchip);
 	void __iomem *regs = mm_gc->regs;
 
 	spin_lock_irqsave(&chip->gpio_lock, flags);
@@ -222,11 +222,12 @@  static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 	if (val)
 		chip->gpio_state |= BIT(gpio);
 	else
-		chip->gpio_state &= ~(1 << gpio);
-	xgpio_writereg(regs + chip->offset + XGPIO_DATA_OFFSET, chip->gpio_state);
+		chip->gpio_state &= ~BIT(gpio);
+	xgpio_writereg(regs + chip->offset + XGPIO_DATA_OFFSET,
+		       chip->gpio_state);
 
 	/* Clear the GPIO bit in shadow register and set direction as output */
-	chip->gpio_dir &= (~(1 << gpio));
+	chip->gpio_dir &= ~BIT(gpio);
 	xgpio_writereg(regs + chip->offset + XGPIO_TRI_OFFSET, chip->gpio_dir);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
@@ -241,7 +242,7 @@  static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc)
 {
 	struct xgpio_instance *chip =
-		container_of(mm_gc, struct xgpio_instance, mmchip);
+	    container_of(mm_gc, struct xgpio_instance, mmchip);
 
 	xgpio_writereg(mm_gc->regs + chip->offset + XGPIO_DATA_OFFSET,
 							chip->gpio_state);
@@ -592,6 +593,8 @@  static int xgpio_of_probe(struct platform_device *pdev)
 
 	/* Update GPIO state shadow register with default value */
 	of_property_read_u32(np, "xlnx,dout-default", &chip->gpio_state);
+
+	/* By default, all pins are inputs */
 	chip->gpio_dir = 0xFFFFFFFF;
 
 	/* Update GPIO direction shadow register with default value */
@@ -603,7 +606,7 @@  static int xgpio_of_probe(struct platform_device *pdev)
 	 */
 	if (of_property_read_u32(np, "xlnx,gpio-width", &ngpio))
 		ngpio = 32;
-	chip->mmchip.gc.ngpio = (u16)ngpio;;
+	chip->mmchip.gc.ngpio = (u16)ngpio;
 
 	spin_lock_init(&chip->gpio_lock);
 
@@ -623,9 +626,10 @@  static int xgpio_of_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, chip);
 
-	chip->clk = devm_clk_get(&pdev->dev, "axi_clk");
+	chip->clk = devm_clk_get(&pdev->dev, "s_axi_aclk");
 	if (IS_ERR(chip->clk)) {
-		if (PTR_ERR(chip->clk) != -ENOENT) {
+		if ((PTR_ERR(chip->clk) != -ENOENT) ||
+				(PTR_ERR(chip->clk) != -EPROBE_DEFER)) {
 			dev_err(&pdev->dev, "Input clock not found\n");
 			return PTR_ERR(chip->clk);
 		}
@@ -637,7 +641,7 @@  static int xgpio_of_probe(struct platform_device *pdev)
 		chip->clk = NULL;
 	}
 
-	status = clk_prepare(chip->clk);
+	status = clk_prepare_enable(chip->clk);
 	if (status < 0) {
 		dev_err(&pdev->dev, "Failed to prepare clk\n");
 		return status;
@@ -651,13 +655,12 @@  static int xgpio_of_probe(struct platform_device *pdev)
 	/* Call the OF gpio helper to setup and register the GPIO device */
 	status = of_mm_gpiochip_add(np, &chip->mmchip);
 	if (status) {
-		pr_err("%s: error in probe function with status %d\n",
-		       np->full_name, status);
+		pr_err("%pOF: error in probe function with status %d\n",
+		       np, status);
 		goto err_pm_put;
 	}
 
 	status = xgpio_irq_setup(np, chip);
-
 	if (status) {
 		pr_err("%s: GPIO IRQ initialization failed %d\n",
 		       np->full_name, status);
@@ -677,26 +680,22 @@  static int xgpio_of_probe(struct platform_device *pdev)
 		chip->offset = XGPIO_CHANNEL_OFFSET;
 
 		/* Update GPIO state shadow register with default value */
-		tree_info = of_get_property(np, "xlnx,dout-default-2", NULL);
-		if (tree_info)
-			chip->gpio_state = be32_to_cpup(tree_info);
+		of_property_read_u32(np, "xlnx,dout-default-2",
+				     &chip->gpio_state);
 
-		/* Update GPIO direction shadow register with default value */
 		/* By default, all pins are inputs */
 		chip->gpio_dir = 0xFFFFFFFF;
-		tree_info = of_get_property(np, "xlnx,tri-default-2", NULL);
-		if (tree_info)
-			chip->gpio_dir = be32_to_cpup(tree_info);
-
-		/* Check device node and parent device node for device width */
-		/* By default assume full GPIO controller */
-		chip->mmchip.gc.ngpio = 32;
-		tree_info = of_get_property(np, "xlnx,gpio2-width", NULL);
-		if (!tree_info)
-			tree_info = of_get_property(np->parent,
-						"xlnx,gpio2-width", NULL);
-		if (tree_info)
-			chip->mmchip.gc.ngpio = be32_to_cpup(tree_info);
+
+		/* Update GPIO direction shadow register with default value */
+		of_property_read_u32(np, "xlnx,tri-default-2", &chip->gpio_dir);
+
+		/*
+		 * Check device node and parent device node for device width
+		 * and assume default width of 32
+		 */
+		if (of_property_read_u32(np, "xlnx,gpio2-width", &ngpio))
+			ngpio = 32;
+		chip->mmchip.gc.ngpio = (u16)ngpio;
 
 		spin_lock_init(&chip->gpio_lock);
 
@@ -739,7 +738,7 @@  static int xgpio_of_probe(struct platform_device *pdev)
 	pm_runtime_put(&pdev->dev);
 err_unprepare_clk:
 	pm_runtime_disable(&pdev->dev);
-	clk_unprepare(chip->clk);
+	clk_disable_unprepare(chip->clk);
 	return status;
 }