linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/4] gpio/xilinx: Add support for PCI mapped devices and rmmod
@ 2014-12-10 15:24 Ricardo Ribalda Delgado
  2014-12-10 15:24 ` [PATCH v3 1/4] gpio/xilinx: Remove offset property Ricardo Ribalda Delgado
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Ricardo Ribalda Delgado @ 2014-12-10 15:24 UTC (permalink / raw)
  To: Linus Walleij, Alexandre Courbot, Michal Simek,
	Sören Brinkmann, linux-gpio, linux-kernel
  Cc: Ricardo Ribalda Delgado

The main purpose of this patchset is to use the driver on a PCI mapped fpga.

This patchset also converts the driver to platform device, so it will support
hot plugged devices and rmmod.

Changeset:

v3
Suggested by Michal Simek <michal.simek@xilinx.com>
-Add patch for fixing kernel-doc
-Leave the driver at subsys_initcall


v2
Suggested by Alexandre Courbot <gnurou@gmail.com>
Merge 2 and 3 (convert to platform device and implement remove)


Ricardo Ribalda Delgado (4):
  gpio/xilinx: Remove offset property
  gpio/xilinx: Convert the driver to platform device interface
  gpio/xilinx: Add support for X86 Arch
  gpio/xilinx: Fix kernel-doc

 drivers/gpio/Kconfig       |   4 +-
 drivers/gpio/gpio-xilinx.c | 148 ++++++++++++++++++++++++++++-----------------
 2 files changed, 94 insertions(+), 58 deletions(-)

-- 
2.1.3


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v3 1/4] gpio/xilinx: Remove offset property
  2014-12-10 15:24 [PATCH v3 0/4] gpio/xilinx: Add support for PCI mapped devices and rmmod Ricardo Ribalda Delgado
@ 2014-12-10 15:24 ` Ricardo Ribalda Delgado
  2014-12-10 15:24 ` [PATCH v3 2/4] gpio/xilinx: Convert the driver to platform device interface Ricardo Ribalda Delgado
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: Ricardo Ribalda Delgado @ 2014-12-10 15:24 UTC (permalink / raw)
  To: Linus Walleij, Alexandre Courbot, Michal Simek,
	Sören Brinkmann, linux-gpio, linux-kernel
  Cc: Ricardo Ribalda Delgado

Instead of calculating the register offset per call, pre-calculate it on
probe time.

Acked-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
---

v3: Remove offset from kernel-doc

 drivers/gpio/gpio-xilinx.c | 34 +++++++++++-----------------------
 1 file changed, 11 insertions(+), 23 deletions(-)

diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index ba18b06..e668ec4 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -43,14 +43,12 @@
  * struct of_mm_gpio_chip mmchip: OF GPIO chip for memory mapped banks
  * gpio_state: GPIO state shadow register
  * gpio_dir: GPIO direction shadow register
- * offset: GPIO channel offset
  * gpio_lock: Lock used for synchronization
  */
 struct xgpio_instance {
 	struct of_mm_gpio_chip mmchip;
 	u32 gpio_state;
 	u32 gpio_dir;
-	u32 offset;
 	spinlock_t gpio_lock;
 };
 
@@ -65,12 +63,8 @@ struct xgpio_instance {
 static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
 {
 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
-	struct xgpio_instance *chip =
-	    container_of(mm_gc, struct xgpio_instance, mmchip);
 
-	void __iomem *regs = mm_gc->regs + chip->offset;
-
-	return !!(xgpio_readreg(regs + XGPIO_DATA_OFFSET) & BIT(gpio));
+	return !!(xgpio_readreg(mm_gc->regs + XGPIO_DATA_OFFSET) & BIT(gpio));
 }
 
 /**
@@ -88,7 +82,6 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(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);
 
@@ -98,8 +91,7 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 	else
 		chip->gpio_state &= ~BIT(gpio);
 
-	xgpio_writereg(regs + chip->offset + XGPIO_DATA_OFFSET,
-							 chip->gpio_state);
+	xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 }
@@ -119,13 +111,12 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(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);
 
 	/* Set the GPIO bit in shadow register and set direction as input */
 	chip->gpio_dir |= BIT(gpio);
-	xgpio_writereg(regs + chip->offset + XGPIO_TRI_OFFSET, chip->gpio_dir);
+	xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 
@@ -148,7 +139,6 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(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);
 
@@ -157,12 +147,11 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 		chip->gpio_state |= BIT(gpio);
 	else
 		chip->gpio_state &= ~BIT(gpio);
-	xgpio_writereg(regs + chip->offset + XGPIO_DATA_OFFSET,
-		       chip->gpio_state);
+	xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state);
 
 	/* Clear the GPIO bit in shadow register and set direction as output */
 	chip->gpio_dir &= ~BIT(gpio);
-	xgpio_writereg(regs + chip->offset + XGPIO_TRI_OFFSET, chip->gpio_dir);
+	xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 
@@ -178,10 +167,8 @@ static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc)
 	struct xgpio_instance *chip =
 	    container_of(mm_gc, struct xgpio_instance, mmchip);
 
-	xgpio_writereg(mm_gc->regs + chip->offset + XGPIO_DATA_OFFSET,
-							chip->gpio_state);
-	xgpio_writereg(mm_gc->regs + chip->offset + XGPIO_TRI_OFFSET,
-							 chip->gpio_dir);
+	xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET,	chip->gpio_state);
+	xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir);
 }
 
 /**
@@ -247,9 +234,6 @@ static int xgpio_of_probe(struct device_node *np)
 		if (!chip)
 			return -ENOMEM;
 
-		/* Add dual channel offset */
-		chip->offset = XGPIO_CHANNEL_OFFSET;
-
 		/* Update GPIO state shadow register with default value */
 		of_property_read_u32(np, "xlnx,dout-default-2",
 				     &chip->gpio_state);
@@ -285,6 +269,10 @@ static int xgpio_of_probe(struct device_node *np)
 			np->full_name, status);
 			return status;
 		}
+
+		/* Add dual channel offset */
+		chip->mmchip.regs += XGPIO_CHANNEL_OFFSET;
+
 		pr_info("XGpio: %s: dual channel registered, base is %d\n",
 					np->full_name, chip->mmchip.gc.base);
 	}
-- 
2.1.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v3 2/4] gpio/xilinx: Convert the driver to platform device interface
  2014-12-10 15:24 [PATCH v3 0/4] gpio/xilinx: Add support for PCI mapped devices and rmmod Ricardo Ribalda Delgado
  2014-12-10 15:24 ` [PATCH v3 1/4] gpio/xilinx: Remove offset property Ricardo Ribalda Delgado
@ 2014-12-10 15:24 ` Ricardo Ribalda Delgado
  2014-12-10 15:29   ` Michal Simek
  2014-12-10 15:24 ` [PATCH v3 3/4] gpio/xilinx: Add support for X86 Arch Ricardo Ribalda Delgado
  2014-12-10 15:25 ` [PATCH v3 4/4] gpio/xilinx: Fix kernel-doc Ricardo Ribalda Delgado
  3 siblings, 1 reply; 8+ messages in thread
From: Ricardo Ribalda Delgado @ 2014-12-10 15:24 UTC (permalink / raw)
  To: Linus Walleij, Alexandre Courbot, Michal Simek,
	Sören Brinkmann, linux-gpio, linux-kernel
  Cc: Ricardo Ribalda Delgado

This way we do not need to transverse the device tree manually and we
support hot plugged devices.

Also Implement remove callback so the driver can be unloaded

Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
---

v3:
Add inited to kernel-doc
Keep the driver in susbys_initcall


 drivers/gpio/gpio-xilinx.c | 77 ++++++++++++++++++++++++++++++++++++----------
 1 file changed, 60 insertions(+), 17 deletions(-)

diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index e668ec4..9a81c82 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -44,12 +44,18 @@
  * gpio_state: GPIO state shadow register
  * gpio_dir: GPIO direction shadow register
  * gpio_lock: Lock used for synchronization
+ * inited: True if the port has been inited
  */
 struct xgpio_instance {
 	struct of_mm_gpio_chip mmchip;
 	u32 gpio_state;
 	u32 gpio_dir;
 	spinlock_t gpio_lock;
+	bool inited;
+};
+
+struct xgpio {
+	struct xgpio_instance port[2];
 };
 
 /**
@@ -172,24 +178,56 @@ static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc)
 }
 
 /**
+ * xgpio_remove - Remove method for the GPIO device.
+ * @pdev: pointer to the platform device
+ *
+ * This function remove gpiochips and frees all the allocated resources.
+ */
+static int xgpio_remove(struct platform_device *pdev)
+{
+	struct xgpio *xgpio = platform_get_drvdata(pdev);
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		if (!xgpio->port[i].inited)
+			continue;
+		gpiochip_remove(&xgpio->port[i].mmchip.gc);
+
+		if (i == 1)
+			xgpio->port[i].mmchip.regs -= XGPIO_CHANNEL_OFFSET;
+
+		iounmap(xgpio->port[i].mmchip.regs);
+		kfree(xgpio->port[i].mmchip.gc.label);
+	}
+
+	return 0;
+}
+
+/**
  * xgpio_of_probe - Probe method for the GPIO device.
- * @np: pointer to device tree node
+ * @pdev: pointer to the platform device
  *
  * This function probes the GPIO device in the device tree. It initializes the
  * driver data structure. It returns 0, if the driver is bound to the GPIO
  * device, or a negative value if there is an error.
  */
-static int xgpio_of_probe(struct device_node *np)
+static int xgpio_probe(struct platform_device *pdev)
 {
+	struct xgpio *xgpio;
 	struct xgpio_instance *chip;
 	int status = 0;
+	struct device_node *np = pdev->dev.of_node;
 	const u32 *tree_info;
 	u32 ngpio;
 
-	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-	if (!chip)
+	xgpio = devm_kzalloc(&pdev->dev, sizeof(*xgpio), GFP_KERNEL);
+	if (!xgpio)
 		return -ENOMEM;
 
+	platform_set_drvdata(pdev, xgpio);
+
+	chip = &xgpio->port[0];
+
 	/* Update GPIO state shadow register with default value */
 	of_property_read_u32(np, "xlnx,dout-default", &chip->gpio_state);
 
@@ -209,6 +247,7 @@ static int xgpio_of_probe(struct device_node *np)
 
 	spin_lock_init(&chip->gpio_lock);
 
+	chip->mmchip.gc.dev = &pdev->dev;
 	chip->mmchip.gc.direction_input = xgpio_dir_in;
 	chip->mmchip.gc.direction_output = xgpio_dir_out;
 	chip->mmchip.gc.get = xgpio_get;
@@ -219,20 +258,18 @@ static int xgpio_of_probe(struct device_node *np)
 	/* Call the OF gpio helper to setup and register the GPIO device */
 	status = of_mm_gpiochip_add(np, &chip->mmchip);
 	if (status) {
-		kfree(chip);
 		pr_err("%s: error in probe function with status %d\n",
 		       np->full_name, status);
 		return status;
 	}
+	chip->inited = true;
 
 	pr_info("XGpio: %s: registered, base is %d\n", np->full_name,
 							chip->mmchip.gc.base);
 
 	tree_info = of_get_property(np, "xlnx,is-dual", NULL);
 	if (tree_info && be32_to_cpup(tree_info)) {
-		chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-		if (!chip)
-			return -ENOMEM;
+		chip = &xgpio->port[1];
 
 		/* Update GPIO state shadow register with default value */
 		of_property_read_u32(np, "xlnx,dout-default-2",
@@ -254,6 +291,7 @@ static int xgpio_of_probe(struct device_node *np)
 
 		spin_lock_init(&chip->gpio_lock);
 
+		chip->mmchip.gc.dev = &pdev->dev;
 		chip->mmchip.gc.direction_input = xgpio_dir_in;
 		chip->mmchip.gc.direction_output = xgpio_dir_out;
 		chip->mmchip.gc.get = xgpio_get;
@@ -264,7 +302,7 @@ static int xgpio_of_probe(struct device_node *np)
 		/* Call the OF gpio helper to setup and register the GPIO dev */
 		status = of_mm_gpiochip_add(np, &chip->mmchip);
 		if (status) {
-			kfree(chip);
+			xgpio_remove(pdev);
 			pr_err("%s: error in probe function with status %d\n",
 			np->full_name, status);
 			return status;
@@ -272,6 +310,7 @@ static int xgpio_of_probe(struct device_node *np)
 
 		/* Add dual channel offset */
 		chip->mmchip.regs += XGPIO_CHANNEL_OFFSET;
+		chip->inited = true;
 
 		pr_info("XGpio: %s: dual channel registered, base is %d\n",
 					np->full_name, chip->mmchip.gc.base);
@@ -285,19 +324,23 @@ static const struct of_device_id xgpio_of_match[] = {
 	{ /* end of list */ },
 };
 
-static int __init xgpio_init(void)
-{
-	struct device_node *np;
+MODULE_DEVICE_TABLE(of, xgpio_of_match);
 
-	for_each_matching_node(np, xgpio_of_match)
-		xgpio_of_probe(np);
+static struct platform_driver xgpio_plat_driver = {
+	.probe		= xgpio_probe,
+	.remove		= xgpio_remove,
+	.driver		= {
+			.name = "gpio-xilinx",
+			.of_match_table	= xgpio_of_match,
+	},
+};
 
-	return 0;
+static int __init xgpio_init(void)
+{
+	return platform_driver_register(&xgpio_plat_driver);
 }
 
-/* Make sure we get initialized before anyone else tries to use us */
 subsys_initcall(xgpio_init);
-/* No exit call at the moment as we cannot unregister of GPIO chips */
 
 MODULE_AUTHOR("Xilinx, Inc.");
 MODULE_DESCRIPTION("Xilinx GPIO driver");
-- 
2.1.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v3 3/4] gpio/xilinx: Add support for X86 Arch
  2014-12-10 15:24 [PATCH v3 0/4] gpio/xilinx: Add support for PCI mapped devices and rmmod Ricardo Ribalda Delgado
  2014-12-10 15:24 ` [PATCH v3 1/4] gpio/xilinx: Remove offset property Ricardo Ribalda Delgado
  2014-12-10 15:24 ` [PATCH v3 2/4] gpio/xilinx: Convert the driver to platform device interface Ricardo Ribalda Delgado
@ 2014-12-10 15:24 ` Ricardo Ribalda Delgado
  2014-12-10 15:25 ` [PATCH v3 4/4] gpio/xilinx: Fix kernel-doc Ricardo Ribalda Delgado
  3 siblings, 0 replies; 8+ messages in thread
From: Ricardo Ribalda Delgado @ 2014-12-10 15:24 UTC (permalink / raw)
  To: Linus Walleij, Alexandre Courbot, Michal Simek,
	Sören Brinkmann, linux-gpio, linux-kernel
  Cc: Ricardo Ribalda Delgado

Core can be accessed via PCIe on X86 platform.
This patch also allows the driver to be used as module.

Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
---
v3: Fix log message

 drivers/gpio/Kconfig       | 4 ++--
 drivers/gpio/gpio-xilinx.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 0959ca9..7f8ba83 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -343,8 +343,8 @@ config GPIO_XGENE
 	  here to enable the GFC GPIO functionality.
 
 config GPIO_XILINX
-	bool "Xilinx GPIO support"
-	depends on PPC_OF || MICROBLAZE || ARCH_ZYNQ
+	tristate "Xilinx GPIO support"
+	depends on OF_GPIO && (PPC_OF || MICROBLAZE || ARCH_ZYNQ || ARCH_X86)
 	help
 	  Say yes here to support the Xilinx FPGA GPIO device
 
diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index 9a81c82..0607d97 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -30,7 +30,7 @@
 #define XGPIO_CHANNEL_OFFSET	0x8
 
 /* Read/Write access to the GPIO registers */
-#ifdef CONFIG_ARCH_ZYNQ
+#if defined(CONFIG_ARCH_ZYNQ) || defined(CONFIG_X86)
 # define xgpio_readreg(offset)		readl(offset)
 # define xgpio_writereg(offset, val)	writel(val, offset)
 #else
-- 
2.1.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v3 4/4] gpio/xilinx: Fix kernel-doc
  2014-12-10 15:24 [PATCH v3 0/4] gpio/xilinx: Add support for PCI mapped devices and rmmod Ricardo Ribalda Delgado
                   ` (2 preceding siblings ...)
  2014-12-10 15:24 ` [PATCH v3 3/4] gpio/xilinx: Add support for X86 Arch Ricardo Ribalda Delgado
@ 2014-12-10 15:25 ` Ricardo Ribalda Delgado
  2014-12-17  7:35   ` Alexandre Courbot
  3 siblings, 1 reply; 8+ messages in thread
From: Ricardo Ribalda Delgado @ 2014-12-10 15:25 UTC (permalink / raw)
  To: Linus Walleij, Alexandre Courbot, Michal Simek,
	Sören Brinkmann, linux-gpio, linux-kernel
  Cc: Ricardo Ribalda Delgado

Some documentation were not following the kernel-doc format.
Backporting patch from Xilinx git repository.

Suggested-by: Michal Simek <michal.simek@xilinx.com>
Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
---

v4: New patch

 drivers/gpio/gpio-xilinx.c | 37 +++++++++++++++++++++----------------
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index 0607d97..0297003 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -40,11 +40,11 @@
 
 /**
  * struct xgpio_instance - Stores information about GPIO device
- * struct of_mm_gpio_chip mmchip: OF GPIO chip for memory mapped banks
- * gpio_state: GPIO state shadow register
- * gpio_dir: GPIO direction shadow register
- * gpio_lock: Lock used for synchronization
- * inited: True if the port has been inited
+ * @mmchip: OF GPIO chip for memory mapped banks
+ * @gpio_state: GPIO state shadow register
+ * @gpio_dir: GPIO direction shadow register
+ * @gpio_lock: Lock used for synchronization
+ * @inited: True if the port has been inited
  */
 struct xgpio_instance {
 	struct of_mm_gpio_chip mmchip;
@@ -63,8 +63,11 @@ struct xgpio {
  * @gc:     Pointer to gpio_chip device structure.
  * @gpio:   GPIO signal number.
  *
- * This function reads the specified signal of the GPIO device. It returns 0 if
- * the signal clear, 1 if signal is set or negative value on error.
+ * This function reads the specified signal of the GPIO device.
+ *
+ * Return:
+ * 0 if direction of GPIO signals is set as input otherwise it
+ * returns negative error value.
  */
 static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
 {
@@ -107,9 +110,9 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
  * @gc:     Pointer to gpio_chip device structure.
  * @gpio:   GPIO signal number.
  *
- * This function sets the direction of specified GPIO signal as input.
- * It returns 0 if direction of GPIO signals is set as input otherwise it
- * returns negative error value.
+ * Return:
+ * 0 - if direction of GPIO signals is set as input
+ * otherwise it returns negative error value.
  */
 static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
 {
@@ -135,8 +138,10 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
  * @gpio:   GPIO signal number.
  * @val:    Value to be written to specified signal.
  *
- * This function sets the direction of specified GPIO signal as output. If all
- * GPIO signals of GPIO chip is configured as input then it returns
+ * This function sets the direction of specified GPIO signal as output.
+ *
+ * Return:
+ * If all GPIO signals of GPIO chip is configured as input then it returns
  * error otherwise it returns 0.
  */
 static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
@@ -166,7 +171,7 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 
 /**
  * xgpio_save_regs - Set initial values of GPIO pins
- * @mm_gc: pointer to memory mapped GPIO chip structure
+ * @mm_gc: Pointer to memory mapped GPIO chip structure
  */
 static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc)
 {
@@ -207,9 +212,9 @@ static int xgpio_remove(struct platform_device *pdev)
  * xgpio_of_probe - Probe method for the GPIO device.
  * @pdev: pointer to the platform device
  *
- * This function probes the GPIO device in the device tree. It initializes the
- * driver data structure. It returns 0, if the driver is bound to the GPIO
- * device, or a negative value if there is an error.
+ * Return:
+ * It returns 0, if the driver is bound to the GPIO device, or
+ * a negative value if there is an error.
  */
 static int xgpio_probe(struct platform_device *pdev)
 {
-- 
2.1.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 2/4] gpio/xilinx: Convert the driver to platform device interface
  2014-12-10 15:24 ` [PATCH v3 2/4] gpio/xilinx: Convert the driver to platform device interface Ricardo Ribalda Delgado
@ 2014-12-10 15:29   ` Michal Simek
  2014-12-10 15:54     ` Ricardo Ribalda Delgado
  0 siblings, 1 reply; 8+ messages in thread
From: Michal Simek @ 2014-12-10 15:29 UTC (permalink / raw)
  To: Ricardo Ribalda Delgado, Linus Walleij, Alexandre Courbot,
	Michal Simek, Sören Brinkmann, linux-gpio, linux-kernel

On 12/10/2014 04:24 PM, Ricardo Ribalda Delgado wrote:
> This way we do not need to transverse the device tree manually and we
> support hot plugged devices.
> 
> Also Implement remove callback so the driver can be unloaded
> 
> Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
> ---
> 
> v3:
> Add inited to kernel-doc
> Keep the driver in susbys_initcall
> 
> 
>  drivers/gpio/gpio-xilinx.c | 77 ++++++++++++++++++++++++++++++++++++----------
>  1 file changed, 60 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
> index e668ec4..9a81c82 100644
> --- a/drivers/gpio/gpio-xilinx.c
> +++ b/drivers/gpio/gpio-xilinx.c
> @@ -44,12 +44,18 @@
>   * gpio_state: GPIO state shadow register
>   * gpio_dir: GPIO direction shadow register
>   * gpio_lock: Lock used for synchronization
> + * inited: True if the port has been inited
>   */
>  struct xgpio_instance {
>  	struct of_mm_gpio_chip mmchip;
>  	u32 gpio_state;
>  	u32 gpio_dir;
>  	spinlock_t gpio_lock;
> +	bool inited;
> +};
> +
> +struct xgpio {
> +	struct xgpio_instance port[2];
>  };
>  
>  /**
> @@ -172,24 +178,56 @@ static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc)
>  }
>  
>  /**
> + * xgpio_remove - Remove method for the GPIO device.
> + * @pdev: pointer to the platform device
> + *
> + * This function remove gpiochips and frees all the allocated resources.
> + */
> +static int xgpio_remove(struct platform_device *pdev)
> +{
> +	struct xgpio *xgpio = platform_get_drvdata(pdev);
> +	int i;
> +
> +	for (i = 0; i < 2; i++) {
> +		if (!xgpio->port[i].inited)
> +			continue;
> +		gpiochip_remove(&xgpio->port[i].mmchip.gc);
> +
> +		if (i == 1)
> +			xgpio->port[i].mmchip.regs -= XGPIO_CHANNEL_OFFSET;
> +
> +		iounmap(xgpio->port[i].mmchip.regs);
> +		kfree(xgpio->port[i].mmchip.gc.label);
> +	}
> +
> +	return 0;
> +}
> +
> +/**
>   * xgpio_of_probe - Probe method for the GPIO device.
> - * @np: pointer to device tree node
> + * @pdev: pointer to the platform device
>   *
>   * This function probes the GPIO device in the device tree. It initializes the
>   * driver data structure. It returns 0, if the driver is bound to the GPIO
>   * device, or a negative value if there is an error.
>   */
> -static int xgpio_of_probe(struct device_node *np)
> +static int xgpio_probe(struct platform_device *pdev)
>  {
> +	struct xgpio *xgpio;
>  	struct xgpio_instance *chip;
>  	int status = 0;
> +	struct device_node *np = pdev->dev.of_node;
>  	const u32 *tree_info;
>  	u32 ngpio;
>  
> -	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
> -	if (!chip)
> +	xgpio = devm_kzalloc(&pdev->dev, sizeof(*xgpio), GFP_KERNEL);
> +	if (!xgpio)
>  		return -ENOMEM;
>  
> +	platform_set_drvdata(pdev, xgpio);
> +
> +	chip = &xgpio->port[0];
> +
>  	/* Update GPIO state shadow register with default value */
>  	of_property_read_u32(np, "xlnx,dout-default", &chip->gpio_state);
>  
> @@ -209,6 +247,7 @@ static int xgpio_of_probe(struct device_node *np)
>  
>  	spin_lock_init(&chip->gpio_lock);
>  
> +	chip->mmchip.gc.dev = &pdev->dev;
>  	chip->mmchip.gc.direction_input = xgpio_dir_in;
>  	chip->mmchip.gc.direction_output = xgpio_dir_out;
>  	chip->mmchip.gc.get = xgpio_get;
> @@ -219,20 +258,18 @@ static int xgpio_of_probe(struct device_node *np)
>  	/* Call the OF gpio helper to setup and register the GPIO device */
>  	status = of_mm_gpiochip_add(np, &chip->mmchip);
>  	if (status) {
> -		kfree(chip);
>  		pr_err("%s: error in probe function with status %d\n",
>  		       np->full_name, status);
>  		return status;
>  	}
> +	chip->inited = true;
>  
>  	pr_info("XGpio: %s: registered, base is %d\n", np->full_name,
>  							chip->mmchip.gc.base);
>  
>  	tree_info = of_get_property(np, "xlnx,is-dual", NULL);
>  	if (tree_info && be32_to_cpup(tree_info)) {
> -		chip = kzalloc(sizeof(*chip), GFP_KERNEL);
> -		if (!chip)
> -			return -ENOMEM;
> +		chip = &xgpio->port[1];
>  
>  		/* Update GPIO state shadow register with default value */
>  		of_property_read_u32(np, "xlnx,dout-default-2",
> @@ -254,6 +291,7 @@ static int xgpio_of_probe(struct device_node *np)
>  
>  		spin_lock_init(&chip->gpio_lock);
>  
> +		chip->mmchip.gc.dev = &pdev->dev;
>  		chip->mmchip.gc.direction_input = xgpio_dir_in;
>  		chip->mmchip.gc.direction_output = xgpio_dir_out;
>  		chip->mmchip.gc.get = xgpio_get;
> @@ -264,7 +302,7 @@ static int xgpio_of_probe(struct device_node *np)
>  		/* Call the OF gpio helper to setup and register the GPIO dev */
>  		status = of_mm_gpiochip_add(np, &chip->mmchip);
>  		if (status) {
> -			kfree(chip);
> +			xgpio_remove(pdev);
>  			pr_err("%s: error in probe function with status %d\n",
>  			np->full_name, status);
>  			return status;
> @@ -272,6 +310,7 @@ static int xgpio_of_probe(struct device_node *np)
>  
>  		/* Add dual channel offset */
>  		chip->mmchip.regs += XGPIO_CHANNEL_OFFSET;
> +		chip->inited = true;
>  
>  		pr_info("XGpio: %s: dual channel registered, base is %d\n",
>  					np->full_name, chip->mmchip.gc.base);
> @@ -285,19 +324,23 @@ static const struct of_device_id xgpio_of_match[] = {
>  	{ /* end of list */ },
>  };
>  
> -static int __init xgpio_init(void)
> -{
> -	struct device_node *np;
> +MODULE_DEVICE_TABLE(of, xgpio_of_match);
>  
> -	for_each_matching_node(np, xgpio_of_match)
> -		xgpio_of_probe(np);
> +static struct platform_driver xgpio_plat_driver = {
> +	.probe		= xgpio_probe,
> +	.remove		= xgpio_remove,
> +	.driver		= {
> +			.name = "gpio-xilinx",
> +			.of_match_table	= xgpio_of_match,
> +	},
> +};
>  
> -	return 0;
> +static int __init xgpio_init(void)
> +{
> +	return platform_driver_register(&xgpio_plat_driver);
>  }
>  
> -/* Make sure we get initialized before anyone else tries to use us */
>  subsys_initcall(xgpio_init);
> -/* No exit call at the moment as we cannot unregister of GPIO chips */
>  

Still not correct.
Here should be module_exit if you want to use as module.
I expect that you haven't tested it.

Thanks,
Michal



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 2/4] gpio/xilinx: Convert the driver to platform device interface
  2014-12-10 15:29   ` Michal Simek
@ 2014-12-10 15:54     ` Ricardo Ribalda Delgado
  0 siblings, 0 replies; 8+ messages in thread
From: Ricardo Ribalda Delgado @ 2014-12-10 15:54 UTC (permalink / raw)
  To: Michal Simek
  Cc: Linus Walleij, Alexandre Courbot, Sören Brinkmann,
	linux-gpio@vger.kernel.org, LKML

>
> Still not correct.
Not my day.

> Here should be module_exit if you want to use as module.
> I expect that you haven't tested it.


No, I only tried the original patchset, I assumed this was just
cosmetic changes ;)

Right now I have tested it  :P

 to attach helpers instead.
[  199.175954] XGpio: /axi1/gpio_0: registered, base is 509
[  242.362202] gpio-xilinx 80040000.gpio_0: REMOVING GPIOCHIP WITH
GPIOS STILL REQUESTED
[  242.362218] gpio-xilinx 80040000.gpio_0: REMOVING GPIOCHIP WITH
GPIOS STILL REQUESTED
[  242.362222] gpio-xilinx 80040000.gpio_0: REMOVING GPIOCHIP WITH
GPIOS STILL REQUESTED


I am resending only this patch to avoid spamming the list


>
> Thanks,

Thank you!


> Michal
>
>



-- 
Ricardo Ribalda

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 4/4] gpio/xilinx: Fix kernel-doc
  2014-12-10 15:25 ` [PATCH v3 4/4] gpio/xilinx: Fix kernel-doc Ricardo Ribalda Delgado
@ 2014-12-17  7:35   ` Alexandre Courbot
  0 siblings, 0 replies; 8+ messages in thread
From: Alexandre Courbot @ 2014-12-17  7:35 UTC (permalink / raw)
  To: Ricardo Ribalda Delgado
  Cc: Linus Walleij, Michal Simek, Sören Brinkmann,
	linux-gpio@vger.kernel.org, Linux Kernel Mailing List

On Thu, Dec 11, 2014 at 12:25 AM, Ricardo Ribalda Delgado
<ricardo.ribalda@gmail.com> wrote:
> Some documentation were not following the kernel-doc format.
> Backporting patch from Xilinx git repository.
>
> Suggested-by: Michal Simek <michal.simek@xilinx.com>
> Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>

Acked-by: Alexandre Courbot <acourbot@nvidia.com>

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-12-17  7:35 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-10 15:24 [PATCH v3 0/4] gpio/xilinx: Add support for PCI mapped devices and rmmod Ricardo Ribalda Delgado
2014-12-10 15:24 ` [PATCH v3 1/4] gpio/xilinx: Remove offset property Ricardo Ribalda Delgado
2014-12-10 15:24 ` [PATCH v3 2/4] gpio/xilinx: Convert the driver to platform device interface Ricardo Ribalda Delgado
2014-12-10 15:29   ` Michal Simek
2014-12-10 15:54     ` Ricardo Ribalda Delgado
2014-12-10 15:24 ` [PATCH v3 3/4] gpio/xilinx: Add support for X86 Arch Ricardo Ribalda Delgado
2014-12-10 15:25 ` [PATCH v3 4/4] gpio/xilinx: Fix kernel-doc Ricardo Ribalda Delgado
2014-12-17  7:35   ` Alexandre Courbot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).