linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] Move plat-mxc gpio driver into drivers/gpio
@ 2011-05-30 14:52 Shawn Guo
  2011-05-30 14:52 ` [PATCH 1/4] gpio: gpio-mxc: add gpio driver for Freescale MXC architecture Shawn Guo
                   ` (3 more replies)
  0 siblings, 4 replies; 18+ messages in thread
From: Shawn Guo @ 2011-05-30 14:52 UTC (permalink / raw)
  To: linux-arm-kernel

The patch set moves plat-mxc gpio driver into drivers/gpio.  It's
based on the following tree, plus Sascha's i.MX consolidation
patches.

    git://git.pengutronix.de/git/imx/linux-2.6.git imx-for-3.0

Shawn Guo (4):
      gpio: gpio-mxc: add gpio driver for Freescale MXC architecture
      ARM: mxc: migrate mach-mx5 gpio driver to gpio-mxc
      ARM: mxc: migrate mach-imx gpio driver to gpio-mxc
      ARM: mxc: remove plat-mxc/gpio driver

 arch/arm/mach-imx/mm-imx1.c                        |    9 -
 arch/arm/mach-imx/mm-imx21.c                       |   11 -
 arch/arm/mach-imx/mm-imx25.c                       |    9 -
 arch/arm/mach-imx/mm-imx27.c                       |   11 -
 arch/arm/mach-imx/mm-imx31.c                       |    8 -
 arch/arm/mach-imx/mm-imx35.c                       |    8 -
 arch/arm/mach-mx5/devices.c                        |   64 ------
 arch/arm/mach-mx5/mm-mx50.c                        |   11 -
 arch/arm/mach-mx5/mm.c                             |    6 -
 arch/arm/plat-mxc/Makefile                         |    2 +-
 arch/arm/plat-mxc/devices.c                        |   11 +
 arch/arm/plat-mxc/devices/Makefile                 |    1 +
 arch/arm/plat-mxc/devices/platform-gpio-mxc.c      |  113 ++++++++++
 arch/arm/plat-mxc/include/mach/devices-common.h    |    2 +
 arch/arm/plat-mxc/include/mach/gpio.h              |   27 ---
 drivers/gpio/Makefile                              |    1 +
 .../arm/plat-mxc/gpio.c => drivers/gpio/gpio-mxc.c |  218 +++++++++++++-------
 17 files changed, 275 insertions(+), 237 deletions(-)

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

* [PATCH 1/4] gpio: gpio-mxc: add gpio driver for Freescale MXC architecture
  2011-05-30 14:52 [PATCH 0/4] Move plat-mxc gpio driver into drivers/gpio Shawn Guo
@ 2011-05-30 14:52 ` Shawn Guo
  2011-05-31  0:53   ` Olof Johansson
  2011-05-31  8:44   ` Jamie Iles
  2011-05-30 14:52 ` [PATCH 2/4] ARM: mxc: migrate mach-mx5 gpio driver to gpio-mxc Shawn Guo
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 18+ messages in thread
From: Shawn Guo @ 2011-05-30 14:52 UTC (permalink / raw)
  To: linux-arm-kernel

Add gpio-mxc driver by copying arch/arm/plat-mxc/gpio.c into
drivers/gpio with the following changes.

 * Use readl/writel to replace mach-specific accessors
   __raw_readl/__raw_writel

 * Migrate to platform driver by adding .probe function

 * Add a list to save all mx2 ports references, so that
   mx2_gpio_irq_handler can walk through all interrupt status
   registers

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/plat-mxc/include/mach/gpio.h |    2 +
 drivers/gpio/Makefile                 |    1 +
 drivers/gpio/gpio-mxc.c               |  423 +++++++++++++++++++++++++++++++++
 3 files changed, 426 insertions(+), 0 deletions(-)
 create mode 100644 drivers/gpio/gpio-mxc.c

diff --git a/arch/arm/plat-mxc/include/mach/gpio.h b/arch/arm/plat-mxc/include/mach/gpio.h
index a2747f1..87bd4ef 100644
--- a/arch/arm/plat-mxc/include/mach/gpio.h
+++ b/arch/arm/plat-mxc/include/mach/gpio.h
@@ -37,7 +37,9 @@
 #define irq_to_gpio(irq)	((irq) - MXC_GPIO_IRQ_START)
 
 struct mxc_gpio_port {
+	struct list_head node;
 	void __iomem *base;
+	int id;
 	int irq;
 	int irq_high;
 	int virtual_irq_start;
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index b605f8e..060eb79 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -47,4 +47,5 @@ obj-$(CONFIG_GPIO_SX150X)	+= sx150x.o
 obj-$(CONFIG_GPIO_VX855)	+= vx855_gpio.o
 obj-$(CONFIG_GPIO_ML_IOH)	+= ml_ioh_gpio.o
 obj-$(CONFIG_AB8500_GPIO)       += ab8500-gpio.o
+obj-$(CONFIG_ARCH_MXC)		+= gpio-mxc.o
 obj-$(CONFIG_GPIO_TPS65910)	+= tps65910-gpio.o
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
new file mode 100644
index 0000000..df3df3f
--- /dev/null
+++ b/drivers/gpio/gpio-mxc.c
@@ -0,0 +1,423 @@
+/*
+ * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ *
+ * Based on code from Freescale,
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <mach/hardware.h>
+#include <asm-generic/bug.h>
+
+/*
+ * MX2 has one interrupt *for all* gpio ports. The list is used
+ * to save the references to all ports, so that mx2_gpio_irq_handler
+ * can walk through all interrupt status registers.
+ */
+static LIST_HEAD(mxc_gpio_ports);
+
+#define cpu_is_mx1_mx2()	(cpu_is_mx1() || cpu_is_mx2())
+
+#define GPIO_DR		(cpu_is_mx1_mx2() ? 0x1c : 0x00)
+#define GPIO_GDIR	(cpu_is_mx1_mx2() ? 0x00 : 0x04)
+#define GPIO_PSR	(cpu_is_mx1_mx2() ? 0x24 : 0x08)
+#define GPIO_ICR1	(cpu_is_mx1_mx2() ? 0x28 : 0x0C)
+#define GPIO_ICR2	(cpu_is_mx1_mx2() ? 0x2C : 0x10)
+#define GPIO_IMR	(cpu_is_mx1_mx2() ? 0x30 : 0x14)
+#define GPIO_ISR	(cpu_is_mx1_mx2() ? 0x34 : 0x18)
+
+#define GPIO_INT_LOW_LEV	(cpu_is_mx1_mx2() ? 0x3 : 0x0)
+#define GPIO_INT_HIGH_LEV	(cpu_is_mx1_mx2() ? 0x2 : 0x1)
+#define GPIO_INT_RISE_EDGE	(cpu_is_mx1_mx2() ? 0x0 : 0x2)
+#define GPIO_INT_FALL_EDGE	(cpu_is_mx1_mx2() ? 0x1 : 0x3)
+#define GPIO_INT_NONE		0x4
+
+/* Note: This driver assumes 32 GPIOs are handled in one register */
+
+static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index)
+{
+	writel(1 << index, port->base + GPIO_ISR);
+}
+
+static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index,
+				int enable)
+{
+	u32 l;
+
+	l = readl(port->base + GPIO_IMR);
+	l = (l & (~(1 << index))) | (!!enable << index);
+	writel(l, port->base + GPIO_IMR);
+}
+
+static void gpio_ack_irq(struct irq_data *d)
+{
+	struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d);
+	u32 gpio = irq_to_gpio(d->irq);
+	_clear_gpio_irqstatus(port, gpio & 0x1f);
+}
+
+static void gpio_mask_irq(struct irq_data *d)
+{
+	struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d);
+	u32 gpio = irq_to_gpio(d->irq);
+	_set_gpio_irqenable(port, gpio & 0x1f, 0);
+}
+
+static void gpio_unmask_irq(struct irq_data *d)
+{
+	struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d);
+	u32 gpio = irq_to_gpio(d->irq);
+	_set_gpio_irqenable(port, gpio & 0x1f, 1);
+}
+
+static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset);
+
+static int gpio_set_irq_type(struct irq_data *d, u32 type)
+{
+	u32 gpio = irq_to_gpio(d->irq);
+	struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d);
+	u32 bit, val;
+	int edge;
+	void __iomem *reg = port->base;
+
+	port->both_edges &= ~(1 << (gpio & 31));
+	switch (type) {
+	case IRQ_TYPE_EDGE_RISING:
+		edge = GPIO_INT_RISE_EDGE;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		edge = GPIO_INT_FALL_EDGE;
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		val = mxc_gpio_get(&port->chip, gpio & 31);
+		if (val) {
+			edge = GPIO_INT_LOW_LEV;
+			pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
+		} else {
+			edge = GPIO_INT_HIGH_LEV;
+			pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
+		}
+		port->both_edges |= 1 << (gpio & 31);
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		edge = GPIO_INT_LOW_LEV;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		edge = GPIO_INT_HIGH_LEV;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
+	bit = gpio & 0xf;
+	val = readl(reg) & ~(0x3 << (bit << 1));
+	writel(val | (edge << (bit << 1)), reg);
+	_clear_gpio_irqstatus(port, gpio & 0x1f);
+
+	return 0;
+}
+
+static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
+{
+	void __iomem *reg = port->base;
+	u32 bit, val;
+	int edge;
+
+	reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
+	bit = gpio & 0xf;
+	val = readl(reg);
+	edge = (val >> (bit << 1)) & 3;
+	val &= ~(0x3 << (bit << 1));
+	if (edge == GPIO_INT_HIGH_LEV) {
+		edge = GPIO_INT_LOW_LEV;
+		pr_debug("mxc: switch GPIO %d to low trigger\n", gpio);
+	} else if (edge == GPIO_INT_LOW_LEV) {
+		edge = GPIO_INT_HIGH_LEV;
+		pr_debug("mxc: switch GPIO %d to high trigger\n", gpio);
+	} else {
+		pr_err("mxc: invalid configuration for GPIO %d: %x\n",
+		       gpio, edge);
+		return;
+	}
+	writel(val | (edge << (bit << 1)), reg);
+}
+
+/* handle 32 interrupts in one status register */
+static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
+{
+	u32 gpio_irq_no_base = port->virtual_irq_start;
+
+	while (irq_stat != 0) {
+		int irqoffset = fls(irq_stat) - 1;
+
+		if (port->both_edges & (1 << irqoffset))
+			mxc_flip_edge(port, irqoffset);
+
+		generic_handle_irq(gpio_irq_no_base + irqoffset);
+
+		irq_stat &= ~(1 << irqoffset);
+	}
+}
+
+/* MX1 and MX3 has one interrupt *per* gpio port */
+static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+	u32 irq_stat;
+	struct mxc_gpio_port *port = irq_get_handler_data(irq);
+
+	irq_stat = readl(port->base + GPIO_ISR) & readl(port->base + GPIO_IMR);
+
+	mxc_gpio_irq_handler(port, irq_stat);
+}
+
+/* MX2 has one interrupt *for all* gpio ports */
+static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+	u32 irq_msk, irq_stat;
+	struct mxc_gpio_port *port;
+
+	/* walk through all interrupt status registers */
+	list_for_each_entry(port, &mxc_gpio_ports, node) {
+		irq_msk = readl(port->base + GPIO_IMR);
+		if (!irq_msk)
+			continue;
+
+		irq_stat =readl(port->base + GPIO_ISR) & irq_msk;
+		if (irq_stat)
+			mxc_gpio_irq_handler(port, irq_stat);
+	}
+}
+
+/*
+ * Set interrupt number "irq" in the GPIO as a wake-up source.
+ * While system is running, all registered GPIO interrupts need to have
+ * wake-up enabled. When system is suspended, only selected GPIO interrupts
+ * need to have wake-up enabled.
+ * @param  irq          interrupt source number
+ * @param  enable       enable as wake-up if equal to non-zero
+ * @return       This function returns 0 on success.
+ */
+static int gpio_set_wake_irq(struct irq_data *d, u32 enable)
+{
+	u32 gpio = irq_to_gpio(d->irq);
+	u32 gpio_idx = gpio & 0x1F;
+	struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d);
+
+	if (enable) {
+		if (port->irq_high && (gpio_idx >= 16))
+			enable_irq_wake(port->irq_high);
+		else
+			enable_irq_wake(port->irq);
+	} else {
+		if (port->irq_high && (gpio_idx >= 16))
+			disable_irq_wake(port->irq_high);
+		else
+			disable_irq_wake(port->irq);
+	}
+
+	return 0;
+}
+
+static struct irq_chip gpio_irq_chip = {
+	.name = "GPIO",
+	.irq_ack = gpio_ack_irq,
+	.irq_mask = gpio_mask_irq,
+	.irq_unmask = gpio_unmask_irq,
+	.irq_set_type = gpio_set_irq_type,
+	.irq_set_wake = gpio_set_wake_irq,
+};
+
+static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
+				int dir)
+{
+	struct mxc_gpio_port *port =
+		container_of(chip, struct mxc_gpio_port, chip);
+	u32 l;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	l = readl(port->base + GPIO_GDIR);
+	if (dir)
+		l |= 1 << offset;
+	else
+		l &= ~(1 << offset);
+	writel(l, port->base + GPIO_GDIR);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct mxc_gpio_port *port =
+		container_of(chip, struct mxc_gpio_port, chip);
+	void __iomem *reg = port->base + GPIO_DR;
+	u32 l;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	l = (readl(reg) & (~(1 << offset))) | (!!value << offset);
+	writel(l, reg);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct mxc_gpio_port *port =
+		container_of(chip, struct mxc_gpio_port, chip);
+
+	return (readl(port->base + GPIO_PSR) >> offset) & 1;
+}
+
+static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	_set_gpio_direction(chip, offset, 0);
+	return 0;
+}
+
+static int mxc_gpio_direction_output(struct gpio_chip *chip,
+				     unsigned offset, int value)
+{
+	mxc_gpio_set(chip, offset, value);
+	_set_gpio_direction(chip, offset, 1);
+	return 0;
+}
+
+/*
+ * This lock class tells lockdep that GPIO irqs are in a different
+ * category than their parents, so it won't report false recursion.
+ */
+static struct lock_class_key gpio_lock_class;
+
+static int __devinit mxc_gpio_probe(struct platform_device *pdev)
+{
+	struct mxc_gpio_port *port;
+	struct resource *iores;
+	int err, i;
+
+	port = kzalloc(sizeof(struct mxc_gpio_port), GFP_KERNEL);
+	if (!port)
+		return -ENOMEM;
+
+	port->id = pdev->id;
+	port->virtual_irq_start = MXC_GPIO_IRQ_START + port->id * 32;
+
+	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!iores) {
+		err = -ENODEV;
+		goto out_kfree;
+	}
+
+	if (!request_mem_region(iores->start, resource_size(iores),
+				pdev->name)) {
+		err = -EBUSY;
+		goto out_kfree;
+	}
+
+	port->base = ioremap(iores->start, resource_size(iores));
+	if (!port->base) {
+		err = -ENOMEM;
+		goto out_release_mem;
+	}
+
+	port->irq_high = platform_get_irq(pdev, 1);
+	port->irq = platform_get_irq(pdev, 0);
+	if (port->irq < 0) {
+		err = -EINVAL;
+		goto out_iounmap;
+	}
+
+	/* disable the interrupt and clear the status */
+	writel(0, port->base + GPIO_IMR);
+	writel(~0, port->base + GPIO_ISR);
+
+	for (i = port->virtual_irq_start;
+		i < port->virtual_irq_start + 32; i++) {
+		irq_set_lockdep_class(i, &gpio_lock_class);
+		irq_set_chip_and_handler(i, &gpio_irq_chip, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID);
+		irq_set_chip_data(i, port);
+	}
+
+	if (cpu_is_mx2()) {
+		/* setup one handler for all GPIO interrupts */
+		if (port->id == 0)
+			irq_set_chained_handler(port->irq,
+						mx2_gpio_irq_handler);
+	} else {
+		/* setup one handler for each entry */
+		irq_set_chained_handler(port->irq, mx3_gpio_irq_handler);
+		irq_set_handler_data(port->irq, port);
+		if (port->irq_high > 0) {
+			/* setup handler for GPIO 16 to 31 */
+			irq_set_chained_handler(port->irq_high,
+						mx3_gpio_irq_handler);
+			irq_set_handler_data(port->irq_high, port);
+		}
+	}
+
+	/* register gpio chip */
+	port->chip.direction_input = mxc_gpio_direction_input;
+	port->chip.direction_output = mxc_gpio_direction_output;
+	port->chip.get = mxc_gpio_get;
+	port->chip.set = mxc_gpio_set;
+	port->chip.base = port->id * 32;
+	port->chip.ngpio = 32;
+
+	spin_lock_init(&port->lock);
+
+	err = gpiochip_add(&port->chip);
+	if (err)
+		goto out_iounmap;
+
+	list_add_tail(&port->node, &mxc_gpio_ports);
+
+	return 0;
+
+out_iounmap:
+	iounmap(port->base);
+out_release_mem:
+	release_mem_region(iores->start, resource_size(iores));
+out_kfree:
+	kfree(port);
+	dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err);
+	return err;
+}
+
+static struct platform_driver mxc_gpio_driver = {
+	.driver		= {
+		.name	= "gpio-mxc",
+	},
+	.probe		= mxc_gpio_probe,
+};
+
+static int __init gpio_mxc_init(void)
+{
+	return platform_driver_register(&mxc_gpio_driver);
+}
+postcore_initcall(gpio_mxc_init);
+
+MODULE_AUTHOR("Freescale Semiconductor, "
+	      "Daniel Mack <danielncaiaq.de>, "
+	      "Juergen Beisert <kernel@pengutronix.de>");
+MODULE_DESCRIPTION("Freescale MXC GPIO");
+MODULE_LICENSE("GPL");
-- 
1.7.4.1

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

* [PATCH 2/4] ARM: mxc: migrate mach-mx5 gpio driver to gpio-mxc
  2011-05-30 14:52 [PATCH 0/4] Move plat-mxc gpio driver into drivers/gpio Shawn Guo
  2011-05-30 14:52 ` [PATCH 1/4] gpio: gpio-mxc: add gpio driver for Freescale MXC architecture Shawn Guo
@ 2011-05-30 14:52 ` Shawn Guo
  2011-05-31  0:16   ` Olof Johansson
  2011-05-30 14:52 ` [PATCH 3/4] ARM: mxc: migrate mach-imx " Shawn Guo
  2011-05-30 14:52 ` [PATCH 4/4] ARM: mxc: remove plat-mxc/gpio driver Shawn Guo
  3 siblings, 1 reply; 18+ messages in thread
From: Shawn Guo @ 2011-05-30 14:52 UTC (permalink / raw)
  To: linux-arm-kernel

It adds platform device for drivers/gpio/gpio-mxc, and migrates
mx50/mx51/mx53 gpio driver to gpio-mxc.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-mx5/devices.c                     |   64 ---------------------
 arch/arm/mach-mx5/mm-mx50.c                     |   11 ----
 arch/arm/mach-mx5/mm.c                          |    6 --
 arch/arm/plat-mxc/devices.c                     |   11 ++++
 arch/arm/plat-mxc/devices/Makefile              |    1 +
 arch/arm/plat-mxc/devices/platform-gpio-mxc.c   |   69 +++++++++++++++++++++++
 arch/arm/plat-mxc/include/mach/devices-common.h |    2 +
 7 files changed, 83 insertions(+), 81 deletions(-)
 create mode 100644 arch/arm/plat-mxc/devices/platform-gpio-mxc.c

diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c
index 153ada5..371ca8c 100644
--- a/arch/arm/mach-mx5/devices.c
+++ b/arch/arm/mach-mx5/devices.c
@@ -12,7 +12,6 @@
 
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
-#include <linux/gpio.h>
 #include <mach/hardware.h>
 #include <mach/imx-uart.h>
 #include <mach/irqs.h>
@@ -119,66 +118,3 @@ struct platform_device mxc_usbh2_device = {
 		.coherent_dma_mask = DMA_BIT_MASK(32),
 	},
 };
-
-static struct mxc_gpio_port mxc_gpio_ports[] = {
-	{
-		.chip.label = "gpio-0",
-		.base = MX51_IO_ADDRESS(MX51_GPIO1_BASE_ADDR),
-		.irq = MX51_MXC_INT_GPIO1_LOW,
-		.irq_high = MX51_MXC_INT_GPIO1_HIGH,
-		.virtual_irq_start = MXC_GPIO_IRQ_START
-	},
-	{
-		.chip.label = "gpio-1",
-		.base = MX51_IO_ADDRESS(MX51_GPIO2_BASE_ADDR),
-		.irq = MX51_MXC_INT_GPIO2_LOW,
-		.irq_high = MX51_MXC_INT_GPIO2_HIGH,
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 1
-	},
-	{
-		.chip.label = "gpio-2",
-		.base = MX51_IO_ADDRESS(MX51_GPIO3_BASE_ADDR),
-		.irq = MX51_MXC_INT_GPIO3_LOW,
-		.irq_high = MX51_MXC_INT_GPIO3_HIGH,
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 2
-	},
-	{
-		.chip.label = "gpio-3",
-		.base = MX51_IO_ADDRESS(MX51_GPIO4_BASE_ADDR),
-		.irq = MX51_MXC_INT_GPIO4_LOW,
-		.irq_high = MX51_MXC_INT_GPIO4_HIGH,
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 3
-	},
-	{
-		.chip.label = "gpio-4",
-		.base = MX53_IO_ADDRESS(MX53_GPIO5_BASE_ADDR),
-		.irq = MX53_INT_GPIO5_LOW,
-		.irq_high = MX53_INT_GPIO5_HIGH,
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 4
-	},
-	{
-		.chip.label = "gpio-5",
-		.base = MX53_IO_ADDRESS(MX53_GPIO6_BASE_ADDR),
-		.irq = MX53_INT_GPIO6_LOW,
-		.irq_high = MX53_INT_GPIO6_HIGH,
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 5
-	},
-	{
-		.chip.label = "gpio-6",
-		.base = MX53_IO_ADDRESS(MX53_GPIO7_BASE_ADDR),
-		.irq = MX53_INT_GPIO7_LOW,
-		.irq_high = MX53_INT_GPIO7_HIGH,
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 6
-	},
-};
-
-int __init imx51_register_gpios(void)
-{
-	return mxc_gpio_init(mxc_gpio_ports, 4);
-}
-
-int __init imx53_register_gpios(void)
-{
-	return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports));
-}
-
diff --git a/arch/arm/mach-mx5/mm-mx50.c b/arch/arm/mach-mx5/mm-mx50.c
index b9c363b..e1377ca 100644
--- a/arch/arm/mach-mx5/mm-mx50.c
+++ b/arch/arm/mach-mx5/mm-mx50.c
@@ -26,7 +26,6 @@
 #include <mach/hardware.h>
 #include <mach/common.h>
 #include <mach/iomux-v3.h>
-#include <mach/gpio.h>
 #include <mach/irqs.h>
 
 /*
@@ -56,17 +55,7 @@ void __init imx50_init_early(void)
 	mxc_arch_reset_init(MX50_IO_ADDRESS(MX50_WDOG_BASE_ADDR));
 }
 
-static struct mxc_gpio_port imx50_gpio_ports[] = {
-	DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 0, 1, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH),
-	DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 1, 2, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH),
-	DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 2, 3, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
-	DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 3, 4, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
-	DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 4, 5, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
-	DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 5, 6, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
-};
-
 void __init mx50_init_irq(void)
 {
 	tzic_init_irq(MX50_IO_ADDRESS(MX50_TZIC_BASE_ADDR));
-	mxc_gpio_init(imx50_gpio_ports,	ARRAY_SIZE(imx50_gpio_ports));
 }
diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c
index ff55730..ccc6ceb 100644
--- a/arch/arm/mach-mx5/mm.c
+++ b/arch/arm/mach-mx5/mm.c
@@ -69,8 +69,6 @@ void __init imx53_init_early(void)
 	mxc_arch_reset_init(MX53_IO_ADDRESS(MX53_WDOG1_BASE_ADDR));
 }
 
-int imx51_register_gpios(void);
-
 void __init mx51_init_irq(void)
 {
 	unsigned long tzic_addr;
@@ -86,11 +84,8 @@ void __init mx51_init_irq(void)
 		panic("unable to map TZIC interrupt controller\n");
 
 	tzic_init_irq(tzic_virt);
-	imx51_register_gpios();
 }
 
-int imx53_register_gpios(void);
-
 void __init mx53_init_irq(void)
 {
 	unsigned long tzic_addr;
@@ -103,5 +98,4 @@ void __init mx53_init_irq(void)
 		panic("unable to map TZIC interrupt controller\n");
 
 	tzic_init_irq(tzic_virt);
-	imx53_register_gpios();
 }
diff --git a/arch/arm/plat-mxc/devices.c b/arch/arm/plat-mxc/devices.c
index eee1b60..fb166b2 100644
--- a/arch/arm/plat-mxc/devices.c
+++ b/arch/arm/plat-mxc/devices.c
@@ -89,3 +89,14 @@ err:
 
 	return pdev;
 }
+
+struct device mxc_aips_bus = {
+	.init_name	= "mxc_aips",
+	.parent		= &platform_bus,
+};
+
+static int __init mxc_device_init(void)
+{
+	return device_register(&mxc_aips_bus);
+}
+core_initcall(mxc_device_init);
diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
index ad2922a..b41bf97 100644
--- a/arch/arm/plat-mxc/devices/Makefile
+++ b/arch/arm/plat-mxc/devices/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC) += platform-fsl-usb2-udc.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS) += platform-gpio_keys.o
+obj-y += platform-gpio-mxc.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX21_HCD) += platform-imx21-hcd.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT) += platform-imx2-wdt.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_IMXDI_RTC) += platform-imxdi_rtc.o
diff --git a/arch/arm/plat-mxc/devices/platform-gpio-mxc.c b/arch/arm/plat-mxc/devices/platform-gpio-mxc.c
new file mode 100644
index 0000000..3b10da0
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-gpio-mxc.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2011 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/compiler.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+static struct platform_device *__init mxc_add_gpio(int id,
+	resource_size_t iobase, resource_size_t iosize, int irq, int irq_high)
+{
+	struct resource res[] = {
+		{
+			.start = iobase,
+			.end = iobase + iosize - 1,
+			.flags = IORESOURCE_MEM,
+		}, {
+			.start = irq,
+			.end = irq,
+			.flags = IORESOURCE_IRQ,
+		}, {
+			.start = irq_high,
+			.end = irq_high,
+			.flags = IORESOURCE_IRQ,
+		},
+	};
+
+	return platform_device_register_resndata(&mxc_aips_bus,
+			"gpio-mxc", id, res, ARRAY_SIZE(res), NULL, 0);
+}
+
+static int __init mxc_add_mxc_gpio(void)
+{
+	if (cpu_is_mx50()) {
+		mxc_add_gpio(0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH);
+		mxc_add_gpio(1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH);
+		mxc_add_gpio(2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH);
+		mxc_add_gpio(3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH);
+		mxc_add_gpio(4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH);
+		mxc_add_gpio(5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH);
+	}
+
+	if (cpu_is_mx51()) {
+		mxc_add_gpio(0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO1_LOW, MX51_MXC_INT_GPIO1_HIGH);
+		mxc_add_gpio(1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO2_LOW, MX51_MXC_INT_GPIO2_HIGH);
+		mxc_add_gpio(2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO3_LOW, MX51_MXC_INT_GPIO3_HIGH);
+		mxc_add_gpio(3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO4_LOW, MX51_MXC_INT_GPIO4_HIGH);
+	}
+
+	if (cpu_is_mx53()) {
+		mxc_add_gpio(0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH);
+		mxc_add_gpio(1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH);
+		mxc_add_gpio(2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH);
+		mxc_add_gpio(3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH);
+		mxc_add_gpio(4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH);
+		mxc_add_gpio(5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH);
+		mxc_add_gpio(6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH);
+	}
+
+	return 0;
+}
+postcore_initcall(mxc_add_mxc_gpio);
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
index fa84773..03f6266 100644
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -10,6 +10,8 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 
+extern struct device mxc_aips_bus;
+
 struct platform_device *imx_add_platform_device_dmamask(
 		const char *name, int id,
 		const struct resource *res, unsigned int num_resources,
-- 
1.7.4.1

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

* [PATCH 3/4] ARM: mxc: migrate mach-imx gpio driver to gpio-mxc
  2011-05-30 14:52 [PATCH 0/4] Move plat-mxc gpio driver into drivers/gpio Shawn Guo
  2011-05-30 14:52 ` [PATCH 1/4] gpio: gpio-mxc: add gpio driver for Freescale MXC architecture Shawn Guo
  2011-05-30 14:52 ` [PATCH 2/4] ARM: mxc: migrate mach-mx5 gpio driver to gpio-mxc Shawn Guo
@ 2011-05-30 14:52 ` Shawn Guo
  2011-05-30 14:52 ` [PATCH 4/4] ARM: mxc: remove plat-mxc/gpio driver Shawn Guo
  3 siblings, 0 replies; 18+ messages in thread
From: Shawn Guo @ 2011-05-30 14:52 UTC (permalink / raw)
  To: linux-arm-kernel

It migrates mx1/mx21/mx25/mx27/mx31/mx35 gpio driver to
drivers/gpio/gpio-mxc.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-imx/mm-imx1.c                   |    9 -----
 arch/arm/mach-imx/mm-imx21.c                  |   11 ------
 arch/arm/mach-imx/mm-imx25.c                  |    9 -----
 arch/arm/mach-imx/mm-imx27.c                  |   11 ------
 arch/arm/mach-imx/mm-imx31.c                  |    8 ----
 arch/arm/mach-imx/mm-imx35.c                  |    8 ----
 arch/arm/plat-mxc/devices/platform-gpio-mxc.c |   44 +++++++++++++++++++++++++
 7 files changed, 44 insertions(+), 56 deletions(-)

diff --git a/arch/arm/mach-imx/mm-imx1.c b/arch/arm/mach-imx/mm-imx1.c
index 2e482ba..621ee4c 100644
--- a/arch/arm/mach-imx/mm-imx1.c
+++ b/arch/arm/mach-imx/mm-imx1.c
@@ -23,7 +23,6 @@
 
 #include <mach/common.h>
 #include <mach/hardware.h>
-#include <mach/gpio.h>
 #include <mach/irqs.h>
 #include <mach/iomux-v1.h>
 
@@ -44,15 +43,7 @@ void __init imx1_init_early(void)
 			MX1_NUM_GPIO_PORT);
 }
 
-static struct mxc_gpio_port imx1_gpio_ports[] = {
-	DEFINE_IMX_GPIO_PORT_IRQ(MX1, 0, 1, MX1_GPIO_INT_PORTA),
-	DEFINE_IMX_GPIO_PORT_IRQ(MX1, 1, 2, MX1_GPIO_INT_PORTB),
-	DEFINE_IMX_GPIO_PORT_IRQ(MX1, 2, 3, MX1_GPIO_INT_PORTC),
-	DEFINE_IMX_GPIO_PORT_IRQ(MX1, 3, 4, MX1_GPIO_INT_PORTD),
-};
-
 void __init mx1_init_irq(void)
 {
 	mxc_init_irq(MX1_IO_ADDRESS(MX1_AVIC_BASE_ADDR));
-	mxc_gpio_init(imx1_gpio_ports,	ARRAY_SIZE(imx1_gpio_ports));
 }
diff --git a/arch/arm/mach-imx/mm-imx21.c b/arch/arm/mach-imx/mm-imx21.c
index 7a0c500..a00ffe1 100644
--- a/arch/arm/mach-imx/mm-imx21.c
+++ b/arch/arm/mach-imx/mm-imx21.c
@@ -24,7 +24,6 @@
 #include <mach/common.h>
 #include <asm/pgtable.h>
 #include <asm/mach/map.h>
-#include <mach/gpio.h>
 #include <mach/irqs.h>
 #include <mach/iomux-v1.h>
 
@@ -70,17 +69,7 @@ void __init imx21_init_early(void)
 			MX21_NUM_GPIO_PORT);
 }
 
-static struct mxc_gpio_port imx21_gpio_ports[] = {
-	DEFINE_IMX_GPIO_PORT_IRQ(MX21, 0, 1, MX21_INT_GPIO),
-	DEFINE_IMX_GPIO_PORT(MX21, 1, 2),
-	DEFINE_IMX_GPIO_PORT(MX21, 2, 3),
-	DEFINE_IMX_GPIO_PORT(MX21, 3, 4),
-	DEFINE_IMX_GPIO_PORT(MX21, 4, 5),
-	DEFINE_IMX_GPIO_PORT(MX21, 5, 6),
-};
-
 void __init mx21_init_irq(void)
 {
 	mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR));
-	mxc_gpio_init(imx21_gpio_ports,	ARRAY_SIZE(imx21_gpio_ports));
 }
diff --git a/arch/arm/mach-imx/mm-imx25.c b/arch/arm/mach-imx/mm-imx25.c
index 02f7b5c..3866c88 100644
--- a/arch/arm/mach-imx/mm-imx25.c
+++ b/arch/arm/mach-imx/mm-imx25.c
@@ -27,7 +27,6 @@
 #include <mach/hardware.h>
 #include <mach/mx25.h>
 #include <mach/iomux-v3.h>
-#include <mach/gpio.h>
 #include <mach/irqs.h>
 
 /*
@@ -57,16 +56,8 @@ void __init imx25_init_early(void)
 	mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR));
 }
 
-static struct mxc_gpio_port imx25_gpio_ports[] = {
-	DEFINE_IMX_GPIO_PORT_IRQ(MX25, 0, 1, MX25_INT_GPIO1),
-	DEFINE_IMX_GPIO_PORT_IRQ(MX25, 1, 2, MX25_INT_GPIO2),
-	DEFINE_IMX_GPIO_PORT_IRQ(MX25, 2, 3, MX25_INT_GPIO3),
-	DEFINE_IMX_GPIO_PORT_IRQ(MX25, 3, 4, MX25_INT_GPIO4),
-};
-
 void __init mx25_init_irq(void)
 {
 	mxc_init_irq(MX25_IO_ADDRESS(MX25_AVIC_BASE_ADDR));
-	mxc_gpio_init(imx25_gpio_ports,	ARRAY_SIZE(imx25_gpio_ports));
 }
 
diff --git a/arch/arm/mach-imx/mm-imx27.c b/arch/arm/mach-imx/mm-imx27.c
index a6761a3..b98eb7a 100644
--- a/arch/arm/mach-imx/mm-imx27.c
+++ b/arch/arm/mach-imx/mm-imx27.c
@@ -24,7 +24,6 @@
 #include <mach/common.h>
 #include <asm/pgtable.h>
 #include <asm/mach/map.h>
-#include <mach/gpio.h>
 #include <mach/irqs.h>
 #include <mach/iomux-v1.h>
 
@@ -70,17 +69,7 @@ void __init imx27_init_early(void)
 			MX27_NUM_GPIO_PORT);
 }
 
-static struct mxc_gpio_port imx27_gpio_ports[] = {
-	DEFINE_IMX_GPIO_PORT_IRQ(MX27, 0, 1, MX27_INT_GPIO),
-	DEFINE_IMX_GPIO_PORT(MX27, 1, 2),
-	DEFINE_IMX_GPIO_PORT(MX27, 2, 3),
-	DEFINE_IMX_GPIO_PORT(MX27, 3, 4),
-	DEFINE_IMX_GPIO_PORT(MX27, 4, 5),
-	DEFINE_IMX_GPIO_PORT(MX27, 5, 6),
-};
-
 void __init mx27_init_irq(void)
 {
 	mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR));
-	mxc_gpio_init(imx27_gpio_ports,	ARRAY_SIZE(imx27_gpio_ports));
 }
diff --git a/arch/arm/mach-imx/mm-imx31.c b/arch/arm/mach-imx/mm-imx31.c
index 86b9b45..afcca7b 100644
--- a/arch/arm/mach-imx/mm-imx31.c
+++ b/arch/arm/mach-imx/mm-imx31.c
@@ -26,7 +26,6 @@
 #include <mach/common.h>
 #include <mach/hardware.h>
 #include <mach/iomux-v3.h>
-#include <mach/gpio.h>
 #include <mach/irqs.h>
 
 static struct map_desc mx31_io_desc[] __initdata = {
@@ -53,14 +52,7 @@ void __init imx31_init_early(void)
 	mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
 }
 
-static struct mxc_gpio_port imx31_gpio_ports[] = {
-	DEFINE_IMX_GPIO_PORT_IRQ(MX31, 0, 1, MX31_INT_GPIO1),
-	DEFINE_IMX_GPIO_PORT_IRQ(MX31, 1, 2, MX31_INT_GPIO2),
-	DEFINE_IMX_GPIO_PORT_IRQ(MX31, 2, 3, MX31_INT_GPIO3),
-};
-
 void __init mx31_init_irq(void)
 {
 	mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR));
-	mxc_gpio_init(imx31_gpio_ports,	ARRAY_SIZE(imx31_gpio_ports));
 }
diff --git a/arch/arm/mach-imx/mm-imx35.c b/arch/arm/mach-imx/mm-imx35.c
index c880e6d..ac9d031 100644
--- a/arch/arm/mach-imx/mm-imx35.c
+++ b/arch/arm/mach-imx/mm-imx35.c
@@ -27,7 +27,6 @@
 #include <mach/common.h>
 #include <mach/hardware.h>
 #include <mach/iomux-v3.h>
-#include <mach/gpio.h>
 #include <mach/irqs.h>
 
 static struct map_desc mx35_io_desc[] __initdata = {
@@ -50,14 +49,7 @@ void __init imx35_init_early(void)
 	mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
 }
 
-static struct mxc_gpio_port imx35_gpio_ports[] = {
-	DEFINE_IMX_GPIO_PORT_IRQ(MX35, 0, 1, MX35_INT_GPIO1),
-	DEFINE_IMX_GPIO_PORT_IRQ(MX35, 1, 2, MX35_INT_GPIO2),
-	DEFINE_IMX_GPIO_PORT_IRQ(MX35, 2, 3, MX35_INT_GPIO3),
-};
-
 void __init mx35_init_irq(void)
 {
 	mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR));
-	mxc_gpio_init(imx35_gpio_ports,	ARRAY_SIZE(imx35_gpio_ports));
 }
diff --git a/arch/arm/plat-mxc/devices/platform-gpio-mxc.c b/arch/arm/plat-mxc/devices/platform-gpio-mxc.c
index 3b10da0..07fee19 100644
--- a/arch/arm/plat-mxc/devices/platform-gpio-mxc.c
+++ b/arch/arm/plat-mxc/devices/platform-gpio-mxc.c
@@ -38,6 +38,50 @@ static struct platform_device *__init mxc_add_gpio(int id,
 
 static int __init mxc_add_mxc_gpio(void)
 {
+	if (cpu_is_mx1()) {
+		mxc_add_gpio(0, MX1_GPIO1_BASE_ADDR, SZ_4K, MX1_GPIO_INT_PORTA, 0);
+		mxc_add_gpio(1, MX1_GPIO2_BASE_ADDR, SZ_4K, MX1_GPIO_INT_PORTB, 0);
+		mxc_add_gpio(2, MX1_GPIO3_BASE_ADDR, SZ_4K, MX1_GPIO_INT_PORTC, 0);
+		mxc_add_gpio(3, MX1_GPIO4_BASE_ADDR, SZ_4K, MX1_GPIO_INT_PORTD, 0);
+	}
+
+	if (cpu_is_mx21()) {
+		mxc_add_gpio(0, MX21_GPIO1_BASE_ADDR, SZ_4K, MX21_INT_GPIO, 0);
+		mxc_add_gpio(1, MX21_GPIO2_BASE_ADDR, SZ_4K, MX21_INT_GPIO, 0);
+		mxc_add_gpio(2, MX21_GPIO3_BASE_ADDR, SZ_4K, MX21_INT_GPIO, 0);
+		mxc_add_gpio(3, MX21_GPIO4_BASE_ADDR, SZ_4K, MX21_INT_GPIO, 0);
+		mxc_add_gpio(4, MX21_GPIO5_BASE_ADDR, SZ_4K, MX21_INT_GPIO, 0);
+		mxc_add_gpio(5, MX21_GPIO6_BASE_ADDR, SZ_4K, MX21_INT_GPIO, 0);
+	}
+
+	if (cpu_is_mx25()) {
+		mxc_add_gpio(0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0);
+		mxc_add_gpio(1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0);
+		mxc_add_gpio(2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0);
+		mxc_add_gpio(3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0);
+	}
+
+	if (cpu_is_mx27()) {
+		mxc_add_gpio(0, MX27_GPIO1_BASE_ADDR, SZ_4K, MX27_INT_GPIO, 0);
+		mxc_add_gpio(1, MX27_GPIO2_BASE_ADDR, SZ_4K, MX27_INT_GPIO, 0);
+		mxc_add_gpio(2, MX27_GPIO3_BASE_ADDR, SZ_4K, MX27_INT_GPIO, 0);
+		mxc_add_gpio(3, MX27_GPIO4_BASE_ADDR, SZ_4K, MX27_INT_GPIO, 0);
+		mxc_add_gpio(4, MX27_GPIO5_BASE_ADDR, SZ_4K, MX27_INT_GPIO, 0);
+		mxc_add_gpio(5, MX27_GPIO6_BASE_ADDR, SZ_4K, MX27_INT_GPIO, 0);
+	}
+
+	if (cpu_is_mx31()) {
+		mxc_add_gpio(0, MX31_GPIO1_BASE_ADDR, SZ_16K, MX31_INT_GPIO1, 0);
+		mxc_add_gpio(1, MX31_GPIO2_BASE_ADDR, SZ_16K, MX31_INT_GPIO2, 0);
+		mxc_add_gpio(2, MX31_GPIO3_BASE_ADDR, SZ_16K, MX31_INT_GPIO3, 0);
+	}
+
+	if (cpu_is_mx35()) {
+		mxc_add_gpio(0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0);
+		mxc_add_gpio(1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0);
+		mxc_add_gpio(2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0);
+	}
+
 	if (cpu_is_mx50()) {
 		mxc_add_gpio(0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH);
 		mxc_add_gpio(1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH);
-- 
1.7.4.1

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

* [PATCH 4/4] ARM: mxc: remove plat-mxc/gpio driver
  2011-05-30 14:52 [PATCH 0/4] Move plat-mxc gpio driver into drivers/gpio Shawn Guo
                   ` (2 preceding siblings ...)
  2011-05-30 14:52 ` [PATCH 3/4] ARM: mxc: migrate mach-imx " Shawn Guo
@ 2011-05-30 14:52 ` Shawn Guo
  3 siblings, 0 replies; 18+ messages in thread
From: Shawn Guo @ 2011-05-30 14:52 UTC (permalink / raw)
  To: linux-arm-kernel

With all users of plat-mxc/gpio migrated to drivers/gpio/gpio-mxc,
plat-mxc/gpio can be removed now.  And plat-mxc/include/mach/gpio.h
can also be cleaned up as below.

 * Remove the helper macros for gpio ports definition
 * Move "struct mxc_gpio_port" into drivers/gpio/gpio-mxc.c, as it's
   not needed to be public at all

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/plat-mxc/Makefile            |    2 +-
 arch/arm/plat-mxc/gpio.c              |  361 ---------------------------------
 arch/arm/plat-mxc/include/mach/gpio.h |   29 ---
 drivers/gpio/gpio-mxc.c               |   12 +
 4 files changed, 13 insertions(+), 391 deletions(-)
 delete mode 100644 arch/arm/plat-mxc/gpio.c

diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index a138787..d53c35f 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -3,7 +3,7 @@
 #
 
 # Common support
-obj-y := clock.o gpio.o time.o devices.o cpu.o system.o irq-common.o
+obj-y := clock.o time.o devices.o cpu.o system.o irq-common.o
 
 # MX51 uses the TZIC interrupt controller, older platforms use AVIC
 obj-$(CONFIG_MXC_TZIC) += tzic.o
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
deleted file mode 100644
index 6cd6d7f..0000000
--- a/arch/arm/plat-mxc/gpio.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
- * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
- *
- * Based on code from Freescale,
- * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <mach/hardware.h>
-#include <asm-generic/bug.h>
-
-static struct mxc_gpio_port *mxc_gpio_ports;
-static int gpio_table_size;
-
-#define cpu_is_mx1_mx2()	(cpu_is_mx1() || cpu_is_mx2())
-
-#define GPIO_DR		(cpu_is_mx1_mx2() ? 0x1c : 0x00)
-#define GPIO_GDIR	(cpu_is_mx1_mx2() ? 0x00 : 0x04)
-#define GPIO_PSR	(cpu_is_mx1_mx2() ? 0x24 : 0x08)
-#define GPIO_ICR1	(cpu_is_mx1_mx2() ? 0x28 : 0x0C)
-#define GPIO_ICR2	(cpu_is_mx1_mx2() ? 0x2C : 0x10)
-#define GPIO_IMR	(cpu_is_mx1_mx2() ? 0x30 : 0x14)
-#define GPIO_ISR	(cpu_is_mx1_mx2() ? 0x34 : 0x18)
-
-#define GPIO_INT_LOW_LEV	(cpu_is_mx1_mx2() ? 0x3 : 0x0)
-#define GPIO_INT_HIGH_LEV	(cpu_is_mx1_mx2() ? 0x2 : 0x1)
-#define GPIO_INT_RISE_EDGE	(cpu_is_mx1_mx2() ? 0x0 : 0x2)
-#define GPIO_INT_FALL_EDGE	(cpu_is_mx1_mx2() ? 0x1 : 0x3)
-#define GPIO_INT_NONE		0x4
-
-/* Note: This driver assumes 32 GPIOs are handled in one register */
-
-static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index)
-{
-	__raw_writel(1 << index, port->base + GPIO_ISR);
-}
-
-static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index,
-				int enable)
-{
-	u32 l;
-
-	l = __raw_readl(port->base + GPIO_IMR);
-	l = (l & (~(1 << index))) | (!!enable << index);
-	__raw_writel(l, port->base + GPIO_IMR);
-}
-
-static void gpio_ack_irq(struct irq_data *d)
-{
-	u32 gpio = irq_to_gpio(d->irq);
-	_clear_gpio_irqstatus(&mxc_gpio_ports[gpio / 32], gpio & 0x1f);
-}
-
-static void gpio_mask_irq(struct irq_data *d)
-{
-	u32 gpio = irq_to_gpio(d->irq);
-	_set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 0);
-}
-
-static void gpio_unmask_irq(struct irq_data *d)
-{
-	u32 gpio = irq_to_gpio(d->irq);
-	_set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 1);
-}
-
-static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset);
-
-static int gpio_set_irq_type(struct irq_data *d, u32 type)
-{
-	u32 gpio = irq_to_gpio(d->irq);
-	struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32];
-	u32 bit, val;
-	int edge;
-	void __iomem *reg = port->base;
-
-	port->both_edges &= ~(1 << (gpio & 31));
-	switch (type) {
-	case IRQ_TYPE_EDGE_RISING:
-		edge = GPIO_INT_RISE_EDGE;
-		break;
-	case IRQ_TYPE_EDGE_FALLING:
-		edge = GPIO_INT_FALL_EDGE;
-		break;
-	case IRQ_TYPE_EDGE_BOTH:
-		val = mxc_gpio_get(&port->chip, gpio & 31);
-		if (val) {
-			edge = GPIO_INT_LOW_LEV;
-			pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
-		} else {
-			edge = GPIO_INT_HIGH_LEV;
-			pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
-		}
-		port->both_edges |= 1 << (gpio & 31);
-		break;
-	case IRQ_TYPE_LEVEL_LOW:
-		edge = GPIO_INT_LOW_LEV;
-		break;
-	case IRQ_TYPE_LEVEL_HIGH:
-		edge = GPIO_INT_HIGH_LEV;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
-	bit = gpio & 0xf;
-	val = __raw_readl(reg) & ~(0x3 << (bit << 1));
-	__raw_writel(val | (edge << (bit << 1)), reg);
-	_clear_gpio_irqstatus(port, gpio & 0x1f);
-
-	return 0;
-}
-
-static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
-{
-	void __iomem *reg = port->base;
-	u32 bit, val;
-	int edge;
-
-	reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
-	bit = gpio & 0xf;
-	val = __raw_readl(reg);
-	edge = (val >> (bit << 1)) & 3;
-	val &= ~(0x3 << (bit << 1));
-	if (edge == GPIO_INT_HIGH_LEV) {
-		edge = GPIO_INT_LOW_LEV;
-		pr_debug("mxc: switch GPIO %d to low trigger\n", gpio);
-	} else if (edge == GPIO_INT_LOW_LEV) {
-		edge = GPIO_INT_HIGH_LEV;
-		pr_debug("mxc: switch GPIO %d to high trigger\n", gpio);
-	} else {
-		pr_err("mxc: invalid configuration for GPIO %d: %x\n",
-		       gpio, edge);
-		return;
-	}
-	__raw_writel(val | (edge << (bit << 1)), reg);
-}
-
-/* handle 32 interrupts in one status register */
-static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
-{
-	u32 gpio_irq_no_base = port->virtual_irq_start;
-
-	while (irq_stat != 0) {
-		int irqoffset = fls(irq_stat) - 1;
-
-		if (port->both_edges & (1 << irqoffset))
-			mxc_flip_edge(port, irqoffset);
-
-		generic_handle_irq(gpio_irq_no_base + irqoffset);
-
-		irq_stat &= ~(1 << irqoffset);
-	}
-}
-
-/* MX1 and MX3 has one interrupt *per* gpio port */
-static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
-{
-	u32 irq_stat;
-	struct mxc_gpio_port *port = irq_get_handler_data(irq);
-
-	irq_stat = __raw_readl(port->base + GPIO_ISR) &
-			__raw_readl(port->base + GPIO_IMR);
-
-	mxc_gpio_irq_handler(port, irq_stat);
-}
-
-/* MX2 has one interrupt *for all* gpio ports */
-static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
-{
-	int i;
-	u32 irq_msk, irq_stat;
-	struct mxc_gpio_port *port = irq_get_handler_data(irq);
-
-	/* walk through all interrupt status registers */
-	for (i = 0; i < gpio_table_size; i++) {
-		irq_msk = __raw_readl(port[i].base + GPIO_IMR);
-		if (!irq_msk)
-			continue;
-
-		irq_stat = __raw_readl(port[i].base + GPIO_ISR) & irq_msk;
-		if (irq_stat)
-			mxc_gpio_irq_handler(&port[i], irq_stat);
-	}
-}
-
-/*
- * Set interrupt number "irq" in the GPIO as a wake-up source.
- * While system is running, all registered GPIO interrupts need to have
- * wake-up enabled. When system is suspended, only selected GPIO interrupts
- * need to have wake-up enabled.
- * @param  irq          interrupt source number
- * @param  enable       enable as wake-up if equal to non-zero
- * @return       This function returns 0 on success.
- */
-static int gpio_set_wake_irq(struct irq_data *d, u32 enable)
-{
-	u32 gpio = irq_to_gpio(d->irq);
-	u32 gpio_idx = gpio & 0x1F;
-	struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32];
-
-	if (enable) {
-		if (port->irq_high && (gpio_idx >= 16))
-			enable_irq_wake(port->irq_high);
-		else
-			enable_irq_wake(port->irq);
-	} else {
-		if (port->irq_high && (gpio_idx >= 16))
-			disable_irq_wake(port->irq_high);
-		else
-			disable_irq_wake(port->irq);
-	}
-
-	return 0;
-}
-
-static struct irq_chip gpio_irq_chip = {
-	.name = "GPIO",
-	.irq_ack = gpio_ack_irq,
-	.irq_mask = gpio_mask_irq,
-	.irq_unmask = gpio_unmask_irq,
-	.irq_set_type = gpio_set_irq_type,
-	.irq_set_wake = gpio_set_wake_irq,
-};
-
-static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
-				int dir)
-{
-	struct mxc_gpio_port *port =
-		container_of(chip, struct mxc_gpio_port, chip);
-	u32 l;
-	unsigned long flags;
-
-	spin_lock_irqsave(&port->lock, flags);
-	l = __raw_readl(port->base + GPIO_GDIR);
-	if (dir)
-		l |= 1 << offset;
-	else
-		l &= ~(1 << offset);
-	__raw_writel(l, port->base + GPIO_GDIR);
-	spin_unlock_irqrestore(&port->lock, flags);
-}
-
-static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-{
-	struct mxc_gpio_port *port =
-		container_of(chip, struct mxc_gpio_port, chip);
-	void __iomem *reg = port->base + GPIO_DR;
-	u32 l;
-	unsigned long flags;
-
-	spin_lock_irqsave(&port->lock, flags);
-	l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);
-	__raw_writel(l, reg);
-	spin_unlock_irqrestore(&port->lock, flags);
-}
-
-static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
-	struct mxc_gpio_port *port =
-		container_of(chip, struct mxc_gpio_port, chip);
-
-	return (__raw_readl(port->base + GPIO_PSR) >> offset) & 1;
-}
-
-static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-{
-	_set_gpio_direction(chip, offset, 0);
-	return 0;
-}
-
-static int mxc_gpio_direction_output(struct gpio_chip *chip,
-				     unsigned offset, int value)
-{
-	mxc_gpio_set(chip, offset, value);
-	_set_gpio_direction(chip, offset, 1);
-	return 0;
-}
-
-/*
- * This lock class tells lockdep that GPIO irqs are in a different
- * category than their parents, so it won't report false recursion.
- */
-static struct lock_class_key gpio_lock_class;
-
-int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
-{
-	int i, j;
-
-	/* save for local usage */
-	mxc_gpio_ports = port;
-	gpio_table_size = cnt;
-
-	printk(KERN_INFO "MXC GPIO hardware\n");
-
-	for (i = 0; i < cnt; i++) {
-		/* disable the interrupt and clear the status */
-		__raw_writel(0, port[i].base + GPIO_IMR);
-		__raw_writel(~0, port[i].base + GPIO_ISR);
-		for (j = port[i].virtual_irq_start;
-			j < port[i].virtual_irq_start + 32; j++) {
-			irq_set_lockdep_class(j, &gpio_lock_class);
-			irq_set_chip_and_handler(j, &gpio_irq_chip,
-						 handle_level_irq);
-			set_irq_flags(j, IRQF_VALID);
-		}
-
-		/* register gpio chip */
-		port[i].chip.direction_input = mxc_gpio_direction_input;
-		port[i].chip.direction_output = mxc_gpio_direction_output;
-		port[i].chip.get = mxc_gpio_get;
-		port[i].chip.set = mxc_gpio_set;
-		port[i].chip.base = i * 32;
-		port[i].chip.ngpio = 32;
-
-		spin_lock_init(&port[i].lock);
-
-		/* its a serious configuration bug when it fails */
-		BUG_ON( gpiochip_add(&port[i].chip) < 0 );
-
-		if (cpu_is_mx1() || cpu_is_mx3() || cpu_is_mx25() || cpu_is_mx51()) {
-			/* setup one handler for each entry */
-			irq_set_chained_handler(port[i].irq,
-						mx3_gpio_irq_handler);
-			irq_set_handler_data(port[i].irq, &port[i]);
-			if (port[i].irq_high) {
-				/* setup handler for GPIO 16 to 31 */
-				irq_set_chained_handler(port[i].irq_high,
-							mx3_gpio_irq_handler);
-				irq_set_handler_data(port[i].irq_high,
-						     &port[i]);
-			}
-		}
-	}
-
-	if (cpu_is_mx2()) {
-		/* setup one handler for all GPIO interrupts */
-		irq_set_chained_handler(port[0].irq, mx2_gpio_irq_handler);
-		irq_set_handler_data(port[0].irq, port);
-	}
-
-	return 0;
-}
diff --git a/arch/arm/plat-mxc/include/mach/gpio.h b/arch/arm/plat-mxc/include/mach/gpio.h
index 87bd4ef..31c820c 100644
--- a/arch/arm/plat-mxc/include/mach/gpio.h
+++ b/arch/arm/plat-mxc/include/mach/gpio.h
@@ -36,33 +36,4 @@
 #define gpio_to_irq(gpio)	(MXC_GPIO_IRQ_START + (gpio))
 #define irq_to_gpio(irq)	((irq) - MXC_GPIO_IRQ_START)
 
-struct mxc_gpio_port {
-	struct list_head node;
-	void __iomem *base;
-	int id;
-	int irq;
-	int irq_high;
-	int virtual_irq_start;
-	struct gpio_chip chip;
-	u32 both_edges;
-	spinlock_t lock;
-};
-
-#define DEFINE_IMX_GPIO_PORT_IRQ_HIGH(soc, _id, _hwid, _irq, _irq_high)	\
-	{								\
-		.chip.label = "gpio-" #_id,				\
-		.irq = _irq,						\
-		.irq_high = _irq_high,					\
-		.base = soc ## _IO_ADDRESS(				\
-				soc ## _GPIO ## _hwid ## _BASE_ADDR),	\
-		.virtual_irq_start = MXC_GPIO_IRQ_START + (_id) * 32,	\
-	}
-
-#define DEFINE_IMX_GPIO_PORT_IRQ(soc, _id, _hwid, _irq)			\
-	DEFINE_IMX_GPIO_PORT_IRQ_HIGH(soc, _id, _hwid, _irq, 0)
-#define DEFINE_IMX_GPIO_PORT(soc, _id, _hwid)				\
-	DEFINE_IMX_GPIO_PORT_IRQ(soc, _id, _hwid, 0)
-
-int mxc_gpio_init(struct mxc_gpio_port*, int);
-
 #endif
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index df3df3f..065b5c0 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -29,6 +29,18 @@
 #include <mach/hardware.h>
 #include <asm-generic/bug.h>
 
+struct mxc_gpio_port {
+	struct list_head node;
+	void __iomem *base;
+	int id;
+	int irq;
+	int irq_high;
+	int virtual_irq_start;
+	struct gpio_chip chip;
+	u32 both_edges;
+	spinlock_t lock;
+};
+
 /*
  * MX2 has one interrupt *for all* gpio ports. The list is used
  * to save the references to all ports, so that mx2_gpio_irq_handler
-- 
1.7.4.1

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

* [PATCH 2/4] ARM: mxc: migrate mach-mx5 gpio driver to gpio-mxc
  2011-05-30 14:52 ` [PATCH 2/4] ARM: mxc: migrate mach-mx5 gpio driver to gpio-mxc Shawn Guo
@ 2011-05-31  0:16   ` Olof Johansson
  2011-05-31  2:47     ` Shawn Guo
  0 siblings, 1 reply; 18+ messages in thread
From: Olof Johansson @ 2011-05-31  0:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Mon, May 30, 2011 at 10:52:17PM +0800, Shawn Guo wrote:
> It adds platform device for drivers/gpio/gpio-mxc, and migrates
> mx50/mx51/mx53 gpio driver to gpio-mxc.
> 

[...]

> diff --git a/arch/arm/plat-mxc/devices/platform-gpio-mxc.c b/arch/arm/plat-mxc/devices/platform-gpio-mxc.c
> new file mode 100644
> index 0000000..3b10da0
> --- /dev/null
> +++ b/arch/arm/plat-mxc/devices/platform-gpio-mxc.c
> @@ -0,0 +1,69 @@
> +/*
> + * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2011 Linaro Limited
> + *
> + * This program is free software; you can redistribute it and/or modify it under
> + * the terms of the GNU General Public License version 2 as published by the
> + * Free Software Foundation.
> + */
> +#include <linux/compiler.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/devices-common.h>
> +
> +static struct platform_device *__init mxc_add_gpio(int id,
> +	resource_size_t iobase, resource_size_t iosize, int irq, int irq_high)
> +{
> +	struct resource res[] = {
> +		{
> +			.start = iobase,
> +			.end = iobase + iosize - 1,
> +			.flags = IORESOURCE_MEM,
> +		}, {
> +			.start = irq,
> +			.end = irq,
> +			.flags = IORESOURCE_IRQ,
> +		}, {
> +			.start = irq_high,
> +			.end = irq_high,
> +			.flags = IORESOURCE_IRQ,
> +		},
> +	};
> +
> +	return platform_device_register_resndata(&mxc_aips_bus,
> +			"gpio-mxc", id, res, ARRAY_SIZE(res), NULL, 0);

Why bother returning the value, it's never checked below?

> +static int __init mxc_add_mxc_gpio(void)

Minor nits: Redundant mxcs? Also, 'gpios' would be more accurate naming.

> +{
> +	if (cpu_is_mx50()) {
> +		mxc_add_gpio(0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH);
> +		mxc_add_gpio(1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH);
> +		mxc_add_gpio(2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH);
> +		mxc_add_gpio(3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH);
> +		mxc_add_gpio(4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH);
> +		mxc_add_gpio(5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH);
> +	}
> +
> +	if (cpu_is_mx51()) {
> +		mxc_add_gpio(0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO1_LOW, MX51_MXC_INT_GPIO1_HIGH);
> +		mxc_add_gpio(1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO2_LOW, MX51_MXC_INT_GPIO2_HIGH);
> +		mxc_add_gpio(2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO3_LOW, MX51_MXC_INT_GPIO3_HIGH);
> +		mxc_add_gpio(3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO4_LOW, MX51_MXC_INT_GPIO4_HIGH);
> +	}
> +
> +	if (cpu_is_mx53()) {
> +		mxc_add_gpio(0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH);
> +		mxc_add_gpio(1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH);
> +		mxc_add_gpio(2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH);
> +		mxc_add_gpio(3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH);
> +		mxc_add_gpio(4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH);
> +		mxc_add_gpio(5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH);
> +		mxc_add_gpio(6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH);
> +	}

The above tables are pretty crazy, and they only get worse later in the series
when the other SoCs are added. Is it really worth it to have a common initcall
entry for the various SoCs here?

It'd seem cleaner to me to just call the registration function for the
family you're running from in per-family-init code such as where it was
removed above (irq init, which makes some sense since the gpios provide
interrupt sources as well).

It's different on OMAP since there it is data driven with a shared
registration function, but here it's really just a hardcoded table
(as code even, not as data) per SoC.


-Olof

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

* [PATCH 1/4] gpio: gpio-mxc: add gpio driver for Freescale MXC architecture
  2011-05-30 14:52 ` [PATCH 1/4] gpio: gpio-mxc: add gpio driver for Freescale MXC architecture Shawn Guo
@ 2011-05-31  0:53   ` Olof Johansson
  2011-05-31  1:35     ` Shawn Guo
  2011-05-31  8:44   ` Jamie Iles
  1 sibling, 1 reply; 18+ messages in thread
From: Olof Johansson @ 2011-05-31  0:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Mon, May 30, 2011 at 10:52:16PM +0800, Shawn Guo wrote:
> Add gpio-mxc driver by copying arch/arm/plat-mxc/gpio.c into
> drivers/gpio with the following changes.
> 
>  * Use readl/writel to replace mach-specific accessors
>    __raw_readl/__raw_writel
> 
>  * Migrate to platform driver by adding .probe function
> 
>  * Add a list to save all mx2 ports references, so that
>    mx2_gpio_irq_handler can walk through all interrupt status
>    registers
> 
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> ---
>  arch/arm/plat-mxc/include/mach/gpio.h |    2 +
>  drivers/gpio/Makefile                 |    1 +
>  drivers/gpio/gpio-mxc.c               |  423 +++++++++++++++++++++++++++++++++
>  3 files changed, 426 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/gpio/gpio-mxc.c
> 
> diff --git a/arch/arm/plat-mxc/include/mach/gpio.h b/arch/arm/plat-mxc/include/mach/gpio.h
> index a2747f1..87bd4ef 100644
> --- a/arch/arm/plat-mxc/include/mach/gpio.h
> +++ b/arch/arm/plat-mxc/include/mach/gpio.h
> @@ -37,7 +37,9 @@
>  #define irq_to_gpio(irq)	((irq) - MXC_GPIO_IRQ_START)
>  
>  struct mxc_gpio_port {
> +	struct list_head node;
>  	void __iomem *base;
> +	int id;

What's id for? You assign it based on pdev->id in the probe function but
never use it anywhere else.


-Olof

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

* [PATCH 1/4] gpio: gpio-mxc: add gpio driver for Freescale MXC architecture
  2011-05-31  0:53   ` Olof Johansson
@ 2011-05-31  1:35     ` Shawn Guo
  0 siblings, 0 replies; 18+ messages in thread
From: Shawn Guo @ 2011-05-31  1:35 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Olof,

Thanks for the review.

On Mon, May 30, 2011 at 05:53:15PM -0700, Olof Johansson wrote:
> Hi,
> 
> On Mon, May 30, 2011 at 10:52:16PM +0800, Shawn Guo wrote:
> > Add gpio-mxc driver by copying arch/arm/plat-mxc/gpio.c into
> > drivers/gpio with the following changes.
> > 
> >  * Use readl/writel to replace mach-specific accessors
> >    __raw_readl/__raw_writel
> > 
> >  * Migrate to platform driver by adding .probe function
> > 
> >  * Add a list to save all mx2 ports references, so that
> >    mx2_gpio_irq_handler can walk through all interrupt status
> >    registers
> > 
> > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> > ---
> >  arch/arm/plat-mxc/include/mach/gpio.h |    2 +
> >  drivers/gpio/Makefile                 |    1 +
> >  drivers/gpio/gpio-mxc.c               |  423 +++++++++++++++++++++++++++++++++
> >  3 files changed, 426 insertions(+), 0 deletions(-)
> >  create mode 100644 drivers/gpio/gpio-mxc.c
> > 
> > diff --git a/arch/arm/plat-mxc/include/mach/gpio.h b/arch/arm/plat-mxc/include/mach/gpio.h
> > index a2747f1..87bd4ef 100644
> > --- a/arch/arm/plat-mxc/include/mach/gpio.h
> > +++ b/arch/arm/plat-mxc/include/mach/gpio.h
> > @@ -37,7 +37,9 @@
> >  #define irq_to_gpio(irq)	((irq) - MXC_GPIO_IRQ_START)
> >  
> >  struct mxc_gpio_port {
> > +	struct list_head node;
> >  	void __iomem *base;
> > +	int id;
> 
> What's id for? You assign it based on pdev->id in the probe function but
> never use it anywhere else.
> 
Yes, it is only used in probe function right now, and can be removed.
I feel it will be needed someday when more cleanup and consolidation
works happen, but we can add it back then.  So, yes, I will remove it
for now.

-- 
Regards,
Shawn

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

* [PATCH 2/4] ARM: mxc: migrate mach-mx5 gpio driver to gpio-mxc
  2011-05-31  0:16   ` Olof Johansson
@ 2011-05-31  2:47     ` Shawn Guo
  2011-05-31  8:26       ` Arnd Bergmann
  0 siblings, 1 reply; 18+ messages in thread
From: Shawn Guo @ 2011-05-31  2:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 30, 2011 at 05:16:34PM -0700, Olof Johansson wrote:
> Hi,
> 
> On Mon, May 30, 2011 at 10:52:17PM +0800, Shawn Guo wrote:
> > It adds platform device for drivers/gpio/gpio-mxc, and migrates
> > mx50/mx51/mx53 gpio driver to gpio-mxc.
> > 
> 
> [...]
> 
> > diff --git a/arch/arm/plat-mxc/devices/platform-gpio-mxc.c b/arch/arm/plat-mxc/devices/platform-gpio-mxc.c
> > new file mode 100644
> > index 0000000..3b10da0
> > --- /dev/null
> > +++ b/arch/arm/plat-mxc/devices/platform-gpio-mxc.c
> > @@ -0,0 +1,69 @@
> > +/*
> > + * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
> > + * Copyright 2011 Linaro Limited
> > + *
> > + * This program is free software; you can redistribute it and/or modify it under
> > + * the terms of the GNU General Public License version 2 as published by the
> > + * Free Software Foundation.
> > + */
> > +#include <linux/compiler.h>
> > +#include <linux/err.h>
> > +#include <linux/init.h>
> > +
> > +#include <mach/hardware.h>
> > +#include <mach/devices-common.h>
> > +
> > +static struct platform_device *__init mxc_add_gpio(int id,
> > +	resource_size_t iobase, resource_size_t iosize, int irq, int irq_high)
> > +{
> > +	struct resource res[] = {
> > +		{
> > +			.start = iobase,
> > +			.end = iobase + iosize - 1,
> > +			.flags = IORESOURCE_MEM,
> > +		}, {
> > +			.start = irq,
> > +			.end = irq,
> > +			.flags = IORESOURCE_IRQ,
> > +		}, {
> > +			.start = irq_high,
> > +			.end = irq_high,
> > +			.flags = IORESOURCE_IRQ,
> > +		},
> > +	};
> > +
> > +	return platform_device_register_resndata(&mxc_aips_bus,
> > +			"gpio-mxc", id, res, ARRAY_SIZE(res), NULL, 0);
> 
> Why bother returning the value, it's never checked below?
> 
Please help me understand.  You are saying the return value should be
checked below?

> > +static int __init mxc_add_mxc_gpio(void)
> 
> Minor nits: Redundant mxcs? Also, 'gpios' would be more accurate naming.
> 
The first one is the namespace of plat-mxc function, and the second
one is to reflect gpio driver name 'mxc gpio'.

> > +{
> > +	if (cpu_is_mx50()) {
> > +		mxc_add_gpio(0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH);
> > +		mxc_add_gpio(1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH);
> > +		mxc_add_gpio(2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH);
> > +		mxc_add_gpio(3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH);
> > +		mxc_add_gpio(4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH);
> > +		mxc_add_gpio(5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH);
> > +	}
> > +
> > +	if (cpu_is_mx51()) {
> > +		mxc_add_gpio(0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO1_LOW, MX51_MXC_INT_GPIO1_HIGH);
> > +		mxc_add_gpio(1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO2_LOW, MX51_MXC_INT_GPIO2_HIGH);
> > +		mxc_add_gpio(2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO3_LOW, MX51_MXC_INT_GPIO3_HIGH);
> > +		mxc_add_gpio(3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO4_LOW, MX51_MXC_INT_GPIO4_HIGH);
> > +	}
> > +
> > +	if (cpu_is_mx53()) {
> > +		mxc_add_gpio(0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH);
> > +		mxc_add_gpio(1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH);
> > +		mxc_add_gpio(2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH);
> > +		mxc_add_gpio(3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH);
> > +		mxc_add_gpio(4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH);
> > +		mxc_add_gpio(5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH);
> > +		mxc_add_gpio(6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH);
> > +	}
> 
> The above tables are pretty crazy, and they only get worse later in the series
> when the other SoCs are added. Is it really worth it to have a common initcall
> entry for the various SoCs here?
> 
This common initcall seems a good place to concentrate the gpio device
registration.  It's easy to look at the common/different things among
these SoCs.  The only problem you reminded me is the scanning of the
long cpu_is_mx list.  It can be optimized a little bit by sorting the
list from the latest (most used) SoC to the oldest (least used) one,
and breaking out the scanning immediately when hitting one.

> It'd seem cleaner to me to just call the registration function for the
> family you're running from in per-family-init code such as where it was
> removed above (irq init, which makes some sense since the gpios provide
> interrupt sources as well).
> 
I just gave it a test, and it's not working at all.  (too early
to register device in irq init?)

-- 
Regards,
Shawn

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

* [PATCH 2/4] ARM: mxc: migrate mach-mx5 gpio driver to gpio-mxc
  2011-05-31  2:47     ` Shawn Guo
@ 2011-05-31  8:26       ` Arnd Bergmann
  2011-05-31 10:30         ` Shawn Guo
  0 siblings, 1 reply; 18+ messages in thread
From: Arnd Bergmann @ 2011-05-31  8:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 31 May 2011, Shawn Guo wrote:
> > The above tables are pretty crazy, and they only get worse later in the series
> > when the other SoCs are added. Is it really worth it to have a common initcall
> > entry for the various SoCs here?
> > 
> This common initcall seems a good place to concentrate the gpio device
> registration.  It's easy to look at the common/different things among
> these SoCs.  The only problem you reminded me is the scanning of the
> long cpu_is_mx list.  It can be optimized a little bit by sorting the
> list from the latest (most used) SoC to the oldest (least used) one,
> and breaking out the scanning immediately when hitting one.

No, better make them separate functions.

> > It'd seem cleaner to me to just call the registration function for the
> > family you're running from in per-family-init code such as where it was
> > removed above (irq init, which makes some sense since the gpios provide
> > interrupt sources as well).
> > 
> I just gave it a test, and it's not working at all.  (too early
> to register device in irq init?)

Just open-code the mxc_add_mxc_gpio() by moving the individual calls to
mxc_add_gpio() into the respective callers. Having a global
mxc_add_mxc_gpio() function that does something different for each
caller seems entirely pointless to me.

Best think of it from the point of view how it should look like when
everything is converted to the device tree. In that case, you would
have a function scanning the device tree that calls mxc_add_gpio
for each entry.

	Arnd

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

* [PATCH 1/4] gpio: gpio-mxc: add gpio driver for Freescale MXC architecture
  2011-05-30 14:52 ` [PATCH 1/4] gpio: gpio-mxc: add gpio driver for Freescale MXC architecture Shawn Guo
  2011-05-31  0:53   ` Olof Johansson
@ 2011-05-31  8:44   ` Jamie Iles
  2011-05-31  9:16     ` Shawn Guo
  1 sibling, 1 reply; 18+ messages in thread
From: Jamie Iles @ 2011-05-31  8:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Shawn,

On Mon, May 30, 2011 at 10:52:16PM +0800, Shawn Guo wrote:
> Add gpio-mxc driver by copying arch/arm/plat-mxc/gpio.c into
> drivers/gpio with the following changes.
> 
>  * Use readl/writel to replace mach-specific accessors
>    __raw_readl/__raw_writel
> 
>  * Migrate to platform driver by adding .probe function
> 
>  * Add a list to save all mx2 ports references, so that
>    mx2_gpio_irq_handler can walk through all interrupt status
>    registers
> 
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> ---

Could you use the stuff in drivers/gpio/basic_mmio_gpio.c for 
implementing the gpio_chip?  I had a go a little while ago [1] but since 
then we've made it possible to embed the bgpio_chip in your own 
structure which may be cleaner.

Jamie

1. http://permalink.gmane.org/gmane.linux.ports.arm.kernel/113139

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

* [PATCH 1/4] gpio: gpio-mxc: add gpio driver for Freescale MXC architecture
  2011-05-31  8:44   ` Jamie Iles
@ 2011-05-31  9:16     ` Shawn Guo
  0 siblings, 0 replies; 18+ messages in thread
From: Shawn Guo @ 2011-05-31  9:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jamie,

On Tue, May 31, 2011 at 09:44:24AM +0100, Jamie Iles wrote:
> Hi Shawn,
> 
> On Mon, May 30, 2011 at 10:52:16PM +0800, Shawn Guo wrote:
> > Add gpio-mxc driver by copying arch/arm/plat-mxc/gpio.c into
> > drivers/gpio with the following changes.
> > 
> >  * Use readl/writel to replace mach-specific accessors
> >    __raw_readl/__raw_writel
> > 
> >  * Migrate to platform driver by adding .probe function
> > 
> >  * Add a list to save all mx2 ports references, so that
> >    mx2_gpio_irq_handler can walk through all interrupt status
> >    registers
> > 
> > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> > ---
> 
> Could you use the stuff in drivers/gpio/basic_mmio_gpio.c for 
> implementing the gpio_chip?  I had a go a little while ago [1] but since 
> then we've made it possible to embed the bgpio_chip in your own 
> structure which may be cleaner.
> 
> Jamie
> 
> 1. http://permalink.gmane.org/gmane.linux.ports.arm.kernel/113139
> --

I would like to keep this series as simple as it is, straight moving
plat-mxc/gpio into drivers/gpio, and then start looking at the
possible consolidation, like generic_irq_chip and basic_mmio_gpio you
offered here.  Thanks for the patch.  I will start with it shortly. 

-- 
Regards,
Shawn

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

* [PATCH 2/4] ARM: mxc: migrate mach-mx5 gpio driver to gpio-mxc
  2011-05-31  8:26       ` Arnd Bergmann
@ 2011-05-31 10:30         ` Shawn Guo
  2011-05-31 11:28           ` Arnd Bergmann
  0 siblings, 1 reply; 18+ messages in thread
From: Shawn Guo @ 2011-05-31 10:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 31, 2011 at 10:26:11AM +0200, Arnd Bergmann wrote:
> On Tuesday 31 May 2011, Shawn Guo wrote:
> > > The above tables are pretty crazy, and they only get worse later in the series
> > > when the other SoCs are added. Is it really worth it to have a common initcall
> > > entry for the various SoCs here?
> > > 
> > This common initcall seems a good place to concentrate the gpio device
> > registration.  It's easy to look at the common/different things among
> > these SoCs.  The only problem you reminded me is the scanning of the
> > long cpu_is_mx list.  It can be optimized a little bit by sorting the
> > list from the latest (most used) SoC to the oldest (least used) one,
> > and breaking out the scanning immediately when hitting one.
> 
> No, better make them separate functions.
> 
> > > It'd seem cleaner to me to just call the registration function for the
> > > family you're running from in per-family-init code such as where it was
> > > removed above (irq init, which makes some sense since the gpios provide
> > > interrupt sources as well).
> > > 
> > I just gave it a test, and it's not working at all.  (too early
> > to register device in irq init?)
> 
> Just open-code the mxc_add_mxc_gpio() by moving the individual calls to
> mxc_add_gpio() into the respective callers. Having a global
> mxc_add_mxc_gpio() function that does something different for each
> caller seems entirely pointless to me.
> 
Right now, mxc_add_mxc_gpio() is a postcore_initcall.  Moving
individual mxc_add_gpio() call into irq_init function does not work.
And I need to find a proper caller for each SoC to call mxc_add_gpio
to register gpio devices.

-- 
Regards,
Shawn

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

* [PATCH 2/4] ARM: mxc: migrate mach-mx5 gpio driver to gpio-mxc
  2011-05-31 10:30         ` Shawn Guo
@ 2011-05-31 11:28           ` Arnd Bergmann
  2011-05-31 15:10             ` Shawn Guo
  0 siblings, 1 reply; 18+ messages in thread
From: Arnd Bergmann @ 2011-05-31 11:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 31 May 2011, Shawn Guo wrote:
> > Just open-code the mxc_add_mxc_gpio() by moving the individual calls to
> > mxc_add_gpio() into the respective callers. Having a global
> > mxc_add_mxc_gpio() function that does something different for each
> > caller seems entirely pointless to me.
> > 
> Right now, mxc_add_mxc_gpio() is a postcore_initcall.  Moving
> individual mxc_add_gpio() call into irq_init function does not work.
> And I need to find a proper caller for each SoC to call mxc_add_gpio
> to register gpio devices.
 
Why not init_machine? That is an arch_initcall(), so it's probably close
enough.

	Arnd

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

* [PATCH 2/4] ARM: mxc: migrate mach-mx5 gpio driver to gpio-mxc
  2011-05-31 11:28           ` Arnd Bergmann
@ 2011-05-31 15:10             ` Shawn Guo
  2011-05-31 15:27               ` Arnd Bergmann
  0 siblings, 1 reply; 18+ messages in thread
From: Shawn Guo @ 2011-05-31 15:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 31, 2011 at 01:28:17PM +0200, Arnd Bergmann wrote:
> On Tuesday 31 May 2011, Shawn Guo wrote:
> > > Just open-code the mxc_add_mxc_gpio() by moving the individual calls to
> > > mxc_add_gpio() into the respective callers. Having a global
> > > mxc_add_mxc_gpio() function that does something different for each
> > > caller seems entirely pointless to me.
> > > 
> > Right now, mxc_add_mxc_gpio() is a postcore_initcall.  Moving
> > individual mxc_add_gpio() call into irq_init function does not work.
> > And I need to find a proper caller for each SoC to call mxc_add_gpio
> > to register gpio devices.
>  
> Why not init_machine? That is an arch_initcall(), so it's probably close
> enough.
> 
The init_machine is mostly a board specific function than SoC specific
one.  That is to say we will call mxc_add_gpio() in every single board
init function even for the same SoC.

-- 
Regards,
Shawn

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

* [PATCH 2/4] ARM: mxc: migrate mach-mx5 gpio driver to gpio-mxc
  2011-05-31 15:10             ` Shawn Guo
@ 2011-05-31 15:27               ` Arnd Bergmann
  2011-05-31 16:08                 ` Shawn Guo
  0 siblings, 1 reply; 18+ messages in thread
From: Arnd Bergmann @ 2011-05-31 15:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 31 May 2011, Shawn Guo wrote:
> 
> On Tue, May 31, 2011 at 01:28:17PM +0200, Arnd Bergmann wrote:
> > On Tuesday 31 May 2011, Shawn Guo wrote:
> > > > Just open-code the mxc_add_mxc_gpio() by moving the individual calls to
> > > > mxc_add_gpio() into the respective callers. Having a global
> > > > mxc_add_mxc_gpio() function that does something different for each
> > > > caller seems entirely pointless to me.
> > > > 
> > > Right now, mxc_add_mxc_gpio() is a postcore_initcall.  Moving
> > > individual mxc_add_gpio() call into irq_init function does not work.
> > > And I need to find a proper caller for each SoC to call mxc_add_gpio
> > > to register gpio devices.
> >  
> > Why not init_machine? That is an arch_initcall(), so it's probably close
> > enough.
> > 
> The init_machine is mostly a board specific function than SoC specific
> one.  That is to say we will call mxc_add_gpio() in every single board
> init function even for the same SoC.

But the machine is the only place that knows what SOC is being used.
Your patch right now detects it by looking at the CPU type that is
also being set by the board file using the init_early call, which
is a bit silly.

I would leave e.g. the imx51_register_gpios() in place, but only
change the definition and the caller to

void __init imx51_register_gpios(void)
{
        mxc_add_gpio(0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO1_LOW, MX51_MXC_INT_GPIO1_HIGH);
        mxc_add_gpio(1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO2_LOW, MX51_MXC_INT_GPIO2_HIGH);
        mxc_add_gpio(2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO3_LOW, MX51_MXC_INT_GPIO3_HIGH);
        mxc_add_gpio(3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO4_LOW, MX51_MXC_INT_GPIO4_HIGH);
}

Then you can call that function from each i.mx51 based board, or
from a new imx51_soc_init() function that groups multiple such
functions.

	Arnd

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

* [PATCH 2/4] ARM: mxc: migrate mach-mx5 gpio driver to gpio-mxc
  2011-05-31 15:27               ` Arnd Bergmann
@ 2011-05-31 16:08                 ` Shawn Guo
  2011-05-31 16:52                   ` Olof Johansson
  0 siblings, 1 reply; 18+ messages in thread
From: Shawn Guo @ 2011-05-31 16:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 31, 2011 at 05:27:55PM +0200, Arnd Bergmann wrote:
> On Tuesday 31 May 2011, Shawn Guo wrote:
> > 
> > On Tue, May 31, 2011 at 01:28:17PM +0200, Arnd Bergmann wrote:
> > > On Tuesday 31 May 2011, Shawn Guo wrote:
> > > > > Just open-code the mxc_add_mxc_gpio() by moving the individual calls to
> > > > > mxc_add_gpio() into the respective callers. Having a global
> > > > > mxc_add_mxc_gpio() function that does something different for each
> > > > > caller seems entirely pointless to me.
> > > > > 
> > > > Right now, mxc_add_mxc_gpio() is a postcore_initcall.  Moving
> > > > individual mxc_add_gpio() call into irq_init function does not work.
> > > > And I need to find a proper caller for each SoC to call mxc_add_gpio
> > > > to register gpio devices.
> > >  
> > > Why not init_machine? That is an arch_initcall(), so it's probably close
> > > enough.
> > > 
> > The init_machine is mostly a board specific function than SoC specific
> > one.  That is to say we will call mxc_add_gpio() in every single board
> > init function even for the same SoC.
> 
> But the machine is the only place that knows what SOC is being used.
> Your patch right now detects it by looking at the CPU type that is
> also being set by the board file using the init_early call, which
> is a bit silly.
> 
I would say that the CPU type is being set by SoC file (e.g.
mach-mx5/mm.c) than board file.  All the things in mach-mx5/mm.c are
common to any mx51 based boards.

> I would leave e.g. the imx51_register_gpios() in place, but only
> change the definition and the caller to
> 
> void __init imx51_register_gpios(void)
> {
>         mxc_add_gpio(0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO1_LOW, MX51_MXC_INT_GPIO1_HIGH);
>         mxc_add_gpio(1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO2_LOW, MX51_MXC_INT_GPIO2_HIGH);
>         mxc_add_gpio(2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO3_LOW, MX51_MXC_INT_GPIO3_HIGH);
>         mxc_add_gpio(3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO4_LOW, MX51_MXC_INT_GPIO4_HIGH);
> }
> 
> Then you can call that function from each i.mx51 based board, or
> from a new imx51_soc_init() function that groups multiple such
> functions.
> 
It will anyway touch every single board file (a lot) to have this SoC
specific device registration plugged in.  If you still think it's
worthy to do so, I can turn around.

-- 
Regards,
Shawn

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

* [PATCH 2/4] ARM: mxc: migrate mach-mx5 gpio driver to gpio-mxc
  2011-05-31 16:08                 ` Shawn Guo
@ 2011-05-31 16:52                   ` Olof Johansson
  0 siblings, 0 replies; 18+ messages in thread
From: Olof Johansson @ 2011-05-31 16:52 UTC (permalink / raw)
  To: linux-arm-kernel

[was offline last night, apologies for the latency]

On Tue, May 31, 2011 at 9:08 AM, Shawn Guo <shawn.guo@freescale.com> wrote:
> On Tue, May 31, 2011 at 05:27:55PM +0200, Arnd Bergmann wrote:
>> On Tuesday 31 May 2011, Shawn Guo wrote:
>> >
>> > On Tue, May 31, 2011 at 01:28:17PM +0200, Arnd Bergmann wrote:
>> > > On Tuesday 31 May 2011, Shawn Guo wrote:
>> > > > > Just open-code the mxc_add_mxc_gpio() by moving the individual calls to
>> > > > > mxc_add_gpio() into the respective callers. Having a global
>> > > > > mxc_add_mxc_gpio() function that does something different for each
>> > > > > caller seems entirely pointless to me.
>> > > > >
>> > > > Right now, mxc_add_mxc_gpio() is a postcore_initcall. ?Moving
>> > > > individual mxc_add_gpio() call into irq_init function does not work.
>> > > > And I need to find a proper caller for each SoC to call mxc_add_gpio
>> > > > to register gpio devices.
>> > >
>> > > Why not init_machine? That is an arch_initcall(), so it's probably close
>> > > enough.
>> > >
>> > The init_machine is mostly a board specific function than SoC specific
>> > one. ?That is to say we will call mxc_add_gpio() in every single board
>> > init function even for the same SoC.
>>
>> But the machine is the only place that knows what SOC is being used.
>> Your patch right now detects it by looking at the CPU type that is
>> also being set by the board file using the init_early call, which
>> is a bit silly.
>>
> I would say that the CPU type is being set by SoC file (e.g.
> mach-mx5/mm.c) than board file. ?All the things in mach-mx5/mm.c are
> common to any mx51 based boards.

The thing is that all initialization today starts at the board file.
Instead of setting a variable that determines code paths in
asyncronous initcalls later, you might as well call the appropriate
initcall functions from common functions called by board files.

So, you'd just add a call to a common per-soc init in each of the
per-board machine_init functions. Over time it'll be a good place to
add code that would otherwise be duplicated per board of the same soc
family.

>> I would leave e.g. the imx51_register_gpios() in place, but only
>> change the definition and the caller to
>>
>> void __init imx51_register_gpios(void)
>> {
>> ? ? ? ? mxc_add_gpio(0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO1_LOW, MX51_MXC_INT_GPIO1_HIGH);
>> ? ? ? ? mxc_add_gpio(1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO2_LOW, MX51_MXC_INT_GPIO2_HIGH);
>> ? ? ? ? mxc_add_gpio(2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO3_LOW, MX51_MXC_INT_GPIO3_HIGH);
>> ? ? ? ? mxc_add_gpio(3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO4_LOW, MX51_MXC_INT_GPIO4_HIGH);
>> }
>>
>> Then you can call that function from each i.mx51 based board, or
>> from a new imx51_soc_init() function that groups multiple such
>> functions.
>>
> It will anyway touch every single board file (a lot) to have this SoC
> specific device registration plugged in. ?If you still think it's
> worthy to do so, I can turn around.

I personally prefer the imx51_soc_init() Arnd proposed above, since
there's a chance you will want to add more things to it over time. It
is worth adding it now, it's just a one-line change per board and it
gives you a good place to hook in other per-family setup that might be
needed later.


-Olof

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

end of thread, other threads:[~2011-05-31 16:52 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-30 14:52 [PATCH 0/4] Move plat-mxc gpio driver into drivers/gpio Shawn Guo
2011-05-30 14:52 ` [PATCH 1/4] gpio: gpio-mxc: add gpio driver for Freescale MXC architecture Shawn Guo
2011-05-31  0:53   ` Olof Johansson
2011-05-31  1:35     ` Shawn Guo
2011-05-31  8:44   ` Jamie Iles
2011-05-31  9:16     ` Shawn Guo
2011-05-30 14:52 ` [PATCH 2/4] ARM: mxc: migrate mach-mx5 gpio driver to gpio-mxc Shawn Guo
2011-05-31  0:16   ` Olof Johansson
2011-05-31  2:47     ` Shawn Guo
2011-05-31  8:26       ` Arnd Bergmann
2011-05-31 10:30         ` Shawn Guo
2011-05-31 11:28           ` Arnd Bergmann
2011-05-31 15:10             ` Shawn Guo
2011-05-31 15:27               ` Arnd Bergmann
2011-05-31 16:08                 ` Shawn Guo
2011-05-31 16:52                   ` Olof Johansson
2011-05-30 14:52 ` [PATCH 3/4] ARM: mxc: migrate mach-imx " Shawn Guo
2011-05-30 14:52 ` [PATCH 4/4] ARM: mxc: remove plat-mxc/gpio driver Shawn Guo

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).