All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] msm: Install the Google-Android gpio driver.
@ 2010-08-31  0:18 ` Gregory Bean
  0 siblings, 0 replies; 17+ messages in thread
From: Gregory Bean @ 2010-08-31  0:18 UTC (permalink / raw)
  To: dwalker
  Cc: linux-arm-msm, linux-arm-kernel, linux-kernel,
	Arve Hjønnevåg, Gregory Bean

From: Arve Hjønnevåg <arve@android.com>

As part of the ongoing effort to converge on a common code base,
adopt the Google-Android msmgpio driver, as it has a stronger pedigree
than the previous submission from codeaurora.

Cc: Arve Hjønnevåg <arve@android.com>
Signed-off-by: Gregory Bean <gbean@codeaurora.org>
---
 arch/arm/mach-msm/Makefile  |    3 +
 arch/arm/mach-msm/gpio.c    |  627 +++++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-msm/gpio_hw.h |  277 +++++++++++++++++++
 3 files changed, 907 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-msm/gpio.c
 create mode 100644 arch/arm/mach-msm/gpio_hw.h

diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 2263b8f..c95d19a 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -22,3 +22,6 @@ obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
 obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-7x30.o gpiomux-v1.o gpiomux.o
 obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o gpiomux-v1.o gpiomux.o
 obj-$(CONFIG_ARCH_MSM8X60) += gpiomux-8x60.o gpiomux-v2.o gpiomux.o
+ifndef CONFIG_MSM_V2_TLMM
+obj-y	+= gpio.o
+endif
diff --git a/arch/arm/mach-msm/gpio.c b/arch/arm/mach-msm/gpio.c
new file mode 100644
index 0000000..fd899a1
--- /dev/null
+++ b/arch/arm/mach-msm/gpio.c
@@ -0,0 +1,627 @@
+/* linux/arch/arm/mach-msm/gpio.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include "gpio_hw.h"
+#include "proc_comm.h"
+#include "smd_private.h"
+
+#define FIRST_GPIO_IRQ MSM_GPIO_TO_INT(0)
+
+enum {
+	GPIO_DEBUG_SLEEP = 1U << 0,
+};
+static int msm_gpio_debug_mask;
+module_param_named(debug_mask, msm_gpio_debug_mask, int,
+		   S_IRUGO | S_IWUSR | S_IWGRP);
+
+#define MSM_GPIO_BROKEN_INT_CLEAR 1
+
+struct msm_gpio_regs {
+	void __iomem *out;
+	void __iomem *in;
+	void __iomem *int_status;
+	void __iomem *int_clear;
+	void __iomem *int_en;
+	void __iomem *int_edge;
+	void __iomem *int_pos;
+	void __iomem *oe;
+};
+
+struct msm_gpio_chip {
+	spinlock_t		lock;
+	struct gpio_chip	chip;
+	struct msm_gpio_regs	regs;
+#if MSM_GPIO_BROKEN_INT_CLEAR
+	unsigned                int_status_copy;
+#endif
+	unsigned int            both_edge_detect;
+	unsigned int            int_enable[2]; /* 0: awake, 1: sleep */
+};
+
+static int msm_gpio_write(struct msm_gpio_chip *msm_chip,
+			  unsigned offset, unsigned on)
+{
+	unsigned b = 1U << offset;
+	unsigned v;
+
+	v = readl(msm_chip->regs.out);
+	if (on)
+		writel(v | b, msm_chip->regs.out);
+	else
+		writel(v & (~b), msm_chip->regs.out);
+	return 0;
+}
+
+static void msm_gpio_update_both_edge_detect(struct msm_gpio_chip *msm_chip)
+{
+	int loop_limit = 100;
+	unsigned pol, val, val2, intstat;
+	do {
+		val = readl(msm_chip->regs.in);
+		pol = readl(msm_chip->regs.int_pos);
+		pol = (pol & ~msm_chip->both_edge_detect) |
+		      (~val & msm_chip->both_edge_detect);
+		writel(pol, msm_chip->regs.int_pos);
+		intstat = readl(msm_chip->regs.int_status);
+		val2 = readl(msm_chip->regs.in);
+		if (((val ^ val2) & msm_chip->both_edge_detect & ~intstat) == 0)
+			return;
+	} while (loop_limit-- > 0);
+	printk(KERN_ERR "msm_gpio_update_both_edge_detect, "
+	       "failed to reach stable state %x != %x\n", val, val2);
+}
+
+static int msm_gpio_clear_detect_status(struct msm_gpio_chip *msm_chip,
+					unsigned offset)
+{
+	unsigned b = BIT(offset);
+
+#if MSM_GPIO_BROKEN_INT_CLEAR
+	/* Save interrupts that already triggered before we loose them. */
+	/* Any interrupt that triggers between the read of int_status */
+	/* and the write to int_clear will still be lost though. */
+	msm_chip->int_status_copy |= readl(msm_chip->regs.int_status);
+	msm_chip->int_status_copy &= ~b;
+#endif
+	writel(b, msm_chip->regs.int_clear);
+	msm_gpio_update_both_edge_detect(msm_chip);
+	return 0;
+}
+
+static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct msm_gpio_chip *msm_chip;
+	unsigned long irq_flags;
+
+	msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+	spin_lock_irqsave(&msm_chip->lock, irq_flags);
+	writel(readl(msm_chip->regs.oe) & ~BIT(offset), msm_chip->regs.oe);
+	spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+	return 0;
+}
+
+static int
+msm_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct msm_gpio_chip *msm_chip;
+	unsigned long irq_flags;
+
+	msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+	spin_lock_irqsave(&msm_chip->lock, irq_flags);
+	msm_gpio_write(msm_chip, offset, value);
+	writel(readl(msm_chip->regs.oe) | BIT(offset), msm_chip->regs.oe);
+	spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+	return 0;
+}
+
+static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct msm_gpio_chip *msm_chip;
+
+	msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+	return (readl(msm_chip->regs.in) & (1U << offset)) ? 1 : 0;
+}
+
+static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct msm_gpio_chip *msm_chip;
+	unsigned long irq_flags;
+
+	msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+	spin_lock_irqsave(&msm_chip->lock, irq_flags);
+	msm_gpio_write(msm_chip, offset, value);
+	spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	return MSM_GPIO_TO_INT(chip->base + offset);
+}
+
+struct msm_gpio_chip msm_gpio_chips[] = {
+	{
+		.regs = {
+			.out =         GPIO_OUT_0,
+			.in =          GPIO_IN_0,
+			.int_status =  GPIO_INT_STATUS_0,
+			.int_clear =   GPIO_INT_CLEAR_0,
+			.int_en =      GPIO_INT_EN_0,
+			.int_edge =    GPIO_INT_EDGE_0,
+			.int_pos =     GPIO_INT_POS_0,
+			.oe =          GPIO_OE_0,
+		},
+		.chip = {
+			.base = 0,
+			.ngpio = 16,
+			.get = msm_gpio_get,
+			.set = msm_gpio_set,
+			.direction_input = msm_gpio_direction_input,
+			.direction_output = msm_gpio_direction_output,
+			.to_irq = msm_gpio_to_irq,
+		}
+	},
+	{
+		.regs = {
+			.out =         GPIO_OUT_1,
+			.in =          GPIO_IN_1,
+			.int_status =  GPIO_INT_STATUS_1,
+			.int_clear =   GPIO_INT_CLEAR_1,
+			.int_en =      GPIO_INT_EN_1,
+			.int_edge =    GPIO_INT_EDGE_1,
+			.int_pos =     GPIO_INT_POS_1,
+			.oe =          GPIO_OE_1,
+		},
+		.chip = {
+			.base = 16,
+#if defined(CONFIG_ARCH_MSM7X30)
+			.ngpio = 28,
+#else
+			.ngpio = 27,
+#endif
+			.get = msm_gpio_get,
+			.set = msm_gpio_set,
+			.direction_input = msm_gpio_direction_input,
+			.direction_output = msm_gpio_direction_output,
+			.to_irq = msm_gpio_to_irq,
+		}
+	},
+	{
+		.regs = {
+			.out =         GPIO_OUT_2,
+			.in =          GPIO_IN_2,
+			.int_status =  GPIO_INT_STATUS_2,
+			.int_clear =   GPIO_INT_CLEAR_2,
+			.int_en =      GPIO_INT_EN_2,
+			.int_edge =    GPIO_INT_EDGE_2,
+			.int_pos =     GPIO_INT_POS_2,
+			.oe =          GPIO_OE_2,
+		},
+		.chip = {
+#if defined(CONFIG_ARCH_MSM7X30)
+			.base = 44,
+			.ngpio = 24,
+#else
+			.base = 43,
+			.ngpio = 25,
+#endif
+			.get = msm_gpio_get,
+			.set = msm_gpio_set,
+			.direction_input = msm_gpio_direction_input,
+			.direction_output = msm_gpio_direction_output,
+			.to_irq = msm_gpio_to_irq,
+		}
+	},
+	{
+		.regs = {
+			.out =         GPIO_OUT_3,
+			.in =          GPIO_IN_3,
+			.int_status =  GPIO_INT_STATUS_3,
+			.int_clear =   GPIO_INT_CLEAR_3,
+			.int_en =      GPIO_INT_EN_3,
+			.int_edge =    GPIO_INT_EDGE_3,
+			.int_pos =     GPIO_INT_POS_3,
+			.oe =          GPIO_OE_3,
+		},
+		.chip = {
+			.base = 68,
+			.ngpio = 27,
+			.get = msm_gpio_get,
+			.set = msm_gpio_set,
+			.direction_input = msm_gpio_direction_input,
+			.direction_output = msm_gpio_direction_output,
+			.to_irq = msm_gpio_to_irq,
+		}
+	},
+	{
+		.regs = {
+			.out =         GPIO_OUT_4,
+			.in =          GPIO_IN_4,
+			.int_status =  GPIO_INT_STATUS_4,
+			.int_clear =   GPIO_INT_CLEAR_4,
+			.int_en =      GPIO_INT_EN_4,
+			.int_edge =    GPIO_INT_EDGE_4,
+			.int_pos =     GPIO_INT_POS_4,
+			.oe =          GPIO_OE_4,
+		},
+		.chip = {
+			.base = 95,
+#if defined(CONFIG_ARCH_QSD8X50)
+			.ngpio = 9,
+#else
+			.ngpio = 12,
+#endif
+			.get = msm_gpio_get,
+			.set = msm_gpio_set,
+			.direction_input = msm_gpio_direction_input,
+			.direction_output = msm_gpio_direction_output,
+			.to_irq = msm_gpio_to_irq,
+		}
+	},
+	{
+		.regs = {
+			.out =         GPIO_OUT_5,
+			.in =          GPIO_IN_5,
+			.int_status =  GPIO_INT_STATUS_5,
+			.int_clear =   GPIO_INT_CLEAR_5,
+			.int_en =      GPIO_INT_EN_5,
+			.int_edge =    GPIO_INT_EDGE_5,
+			.int_pos =     GPIO_INT_POS_5,
+			.oe =          GPIO_OE_5,
+		},
+		.chip = {
+#if defined(CONFIG_ARCH_QSD8X50)
+			.base = 104,
+			.ngpio = 18,
+#elif defined(CONFIG_ARCH_MSM7X30)
+			.base = 107,
+			.ngpio = 27,
+#elif defined(CONFIG_ARCH_MSM7X27)
+			.base = 107,
+			.ngpio = 26,
+#else
+			.base = 107,
+			.ngpio = 15,
+#endif
+			.get = msm_gpio_get,
+			.set = msm_gpio_set,
+			.direction_input = msm_gpio_direction_input,
+			.direction_output = msm_gpio_direction_output,
+			.to_irq = msm_gpio_to_irq,
+		}
+	},
+#if defined(CONFIG_ARCH_QSD8X50) || defined(CONFIG_ARCH_MSM7X30)
+	{
+		.regs = {
+			.out =         GPIO_OUT_6,
+			.in =          GPIO_IN_6,
+			.int_status =  GPIO_INT_STATUS_6,
+			.int_clear =   GPIO_INT_CLEAR_6,
+			.int_en =      GPIO_INT_EN_6,
+			.int_edge =    GPIO_INT_EDGE_6,
+			.int_pos =     GPIO_INT_POS_6,
+			.oe =          GPIO_OE_6,
+		},
+		.chip = {
+#if defined(CONFIG_ARCH_MSM7X30)
+			.base = 134,
+			.ngpio = 17,
+#else
+			.base = 122,
+			.ngpio = 31,
+#endif
+			.get = msm_gpio_get,
+			.set = msm_gpio_set,
+			.direction_input = msm_gpio_direction_input,
+			.direction_output = msm_gpio_direction_output,
+			.to_irq = msm_gpio_to_irq,
+		}
+	},
+	{
+		.regs = {
+			.out =         GPIO_OUT_7,
+			.in =          GPIO_IN_7,
+			.int_status =  GPIO_INT_STATUS_7,
+			.int_clear =   GPIO_INT_CLEAR_7,
+			.int_en =      GPIO_INT_EN_7,
+			.int_edge =    GPIO_INT_EDGE_7,
+			.int_pos =     GPIO_INT_POS_7,
+			.oe =          GPIO_OE_7,
+		},
+		.chip = {
+#if defined(CONFIG_ARCH_MSM7X30)
+			.base = 151,
+			.ngpio = 31,
+#else
+			.base = 153,
+			.ngpio = 12,
+#endif
+			.get = msm_gpio_get,
+			.set = msm_gpio_set,
+			.direction_input = msm_gpio_direction_input,
+			.direction_output = msm_gpio_direction_output,
+			.to_irq = msm_gpio_to_irq,
+		}
+	},
+#endif
+};
+
+static void msm_gpio_irq_ack(unsigned int irq)
+{
+	unsigned long irq_flags;
+	struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+	spin_lock_irqsave(&msm_chip->lock, irq_flags);
+	msm_gpio_clear_detect_status(msm_chip,
+				     irq - gpio_to_irq(msm_chip->chip.base));
+	spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static void msm_gpio_irq_mask(unsigned int irq)
+{
+	unsigned long irq_flags;
+	struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+	unsigned offset = irq - gpio_to_irq(msm_chip->chip.base);
+
+	spin_lock_irqsave(&msm_chip->lock, irq_flags);
+	/* level triggered interrupts are also latched */
+	if (!(readl(msm_chip->regs.int_edge) & BIT(offset)))
+		msm_gpio_clear_detect_status(msm_chip, offset);
+	msm_chip->int_enable[0] &= ~BIT(offset);
+	writel(msm_chip->int_enable[0], msm_chip->regs.int_en);
+	spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static void msm_gpio_irq_unmask(unsigned int irq)
+{
+	unsigned long irq_flags;
+	struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+	unsigned offset = irq - gpio_to_irq(msm_chip->chip.base);
+
+	spin_lock_irqsave(&msm_chip->lock, irq_flags);
+	/* level triggered interrupts are also latched */
+	if (!(readl(msm_chip->regs.int_edge) & BIT(offset)))
+		msm_gpio_clear_detect_status(msm_chip, offset);
+	msm_chip->int_enable[0] |= BIT(offset);
+	writel(msm_chip->int_enable[0], msm_chip->regs.int_en);
+	spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static int msm_gpio_irq_set_wake(unsigned int irq, unsigned int on)
+{
+	unsigned long irq_flags;
+	struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+	unsigned offset = irq - gpio_to_irq(msm_chip->chip.base);
+
+	spin_lock_irqsave(&msm_chip->lock, irq_flags);
+
+	if (on)
+		msm_chip->int_enable[1] |= BIT(offset);
+	else
+		msm_chip->int_enable[1] &= ~BIT(offset);
+
+	spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+	return 0;
+}
+
+static int msm_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
+{
+	unsigned long irq_flags;
+	struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+	unsigned offset = irq - gpio_to_irq(msm_chip->chip.base);
+	unsigned v, b = BIT(offset);
+
+	spin_lock_irqsave(&msm_chip->lock, irq_flags);
+	v = readl(msm_chip->regs.int_edge);
+	if (flow_type & IRQ_TYPE_EDGE_BOTH) {
+		writel(v | b, msm_chip->regs.int_edge);
+		irq_desc[irq].handle_irq = handle_edge_irq;
+	} else {
+		writel(v & ~b, msm_chip->regs.int_edge);
+		irq_desc[irq].handle_irq = handle_level_irq;
+	}
+	if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
+		msm_chip->both_edge_detect |= b;
+		msm_gpio_update_both_edge_detect(msm_chip);
+	} else {
+		msm_chip->both_edge_detect &= ~b;
+		v = readl(msm_chip->regs.int_pos);
+		if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH))
+			writel(v | b, msm_chip->regs.int_pos);
+		else
+			writel(v & ~b, msm_chip->regs.int_pos);
+	}
+	spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+	return 0;
+}
+
+static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	int i, j, m;
+	unsigned v;
+
+	for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) {
+		struct msm_gpio_chip *msm_chip = &msm_gpio_chips[i];
+		v = readl(msm_chip->regs.int_status);
+		v &= msm_chip->int_enable[0];
+		while (v) {
+			m = v & -v;
+			j = fls(m) - 1;
+			/* printk("%s %08x %08x bit %d gpio %d irq %d\n",
+				__func__, v, m, j, msm_chip->chip.start + j,
+				FIRST_GPIO_IRQ + msm_chip->chip.start + j); */
+			v &= ~m;
+			generic_handle_irq(FIRST_GPIO_IRQ +
+					   msm_chip->chip.base + j);
+		}
+	}
+	desc->chip->ack(irq);
+}
+
+static struct irq_chip msm_gpio_irq_chip = {
+	.name      = "msmgpio",
+	.ack       = msm_gpio_irq_ack,
+	.mask      = msm_gpio_irq_mask,
+	.unmask    = msm_gpio_irq_unmask,
+	.set_wake  = msm_gpio_irq_set_wake,
+	.set_type  = msm_gpio_irq_set_type,
+};
+
+#define NUM_GPIO_SMEM_BANKS 6
+#define GPIO_SMEM_NUM_GROUPS 2
+#define GPIO_SMEM_MAX_PC_INTERRUPTS 8
+struct tramp_gpio_smem {
+	uint16_t num_fired[GPIO_SMEM_NUM_GROUPS];
+	uint16_t fired[GPIO_SMEM_NUM_GROUPS][GPIO_SMEM_MAX_PC_INTERRUPTS];
+	uint32_t enabled[NUM_GPIO_SMEM_BANKS];
+	uint32_t detection[NUM_GPIO_SMEM_BANKS];
+	uint32_t polarity[NUM_GPIO_SMEM_BANKS];
+};
+
+static void msm_gpio_sleep_int(unsigned long arg)
+{
+	int i, j;
+	struct tramp_gpio_smem *smem_gpio;
+
+	BUILD_BUG_ON(NR_GPIO_IRQS > NUM_GPIO_SMEM_BANKS * 32);
+
+	smem_gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*smem_gpio));
+	if (smem_gpio == NULL)
+		return;
+
+	local_irq_disable();
+	for (i = 0; i < GPIO_SMEM_NUM_GROUPS; i++) {
+		int count = smem_gpio->num_fired[i];
+		for (j = 0; j < count; j++) {
+			/* TODO: Check mask */
+			generic_handle_irq(
+				MSM_GPIO_TO_INT(smem_gpio->fired[i][j]));
+		}
+	}
+	local_irq_enable();
+}
+
+static DECLARE_TASKLET(msm_gpio_sleep_int_tasklet, msm_gpio_sleep_int, 0);
+
+void msm_gpio_enter_sleep(int from_idle)
+{
+	int i;
+	struct tramp_gpio_smem *smem_gpio;
+
+	smem_gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*smem_gpio));
+
+	if (smem_gpio) {
+		for (i = 0; i < ARRAY_SIZE(smem_gpio->enabled); i++) {
+			smem_gpio->enabled[i] = 0;
+			smem_gpio->detection[i] = 0;
+			smem_gpio->polarity[i] = 0;
+		}
+	}
+
+	for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) {
+		writel(msm_gpio_chips[i].int_enable[!from_idle],
+		       msm_gpio_chips[i].regs.int_en);
+		if (smem_gpio) {
+			uint32_t tmp;
+			int start, index, shiftl, shiftr;
+			start = msm_gpio_chips[i].chip.base;
+			index = start / 32;
+			shiftl = start % 32;
+			shiftr = 32 - shiftl;
+			tmp = msm_gpio_chips[i].int_enable[!from_idle];
+			smem_gpio->enabled[index] |= tmp << shiftl;
+			smem_gpio->enabled[index+1] |= tmp >> shiftr;
+			smem_gpio->detection[index] |=
+				readl(msm_gpio_chips[i].regs.int_edge) <<
+				shiftl;
+			smem_gpio->detection[index+1] |=
+				readl(msm_gpio_chips[i].regs.int_edge) >>
+				shiftr;
+			smem_gpio->polarity[index] |=
+				readl(msm_gpio_chips[i].regs.int_pos) << shiftl;
+			smem_gpio->polarity[index+1] |=
+				readl(msm_gpio_chips[i].regs.int_pos) >> shiftr;
+		}
+	}
+
+	if (smem_gpio) {
+		if (msm_gpio_debug_mask & GPIO_DEBUG_SLEEP)
+			for (i = 0; i < ARRAY_SIZE(smem_gpio->enabled); i++) {
+				printk("msm_gpio_enter_sleep gpio %d-%d: enable"
+				       " %08x, edge %08x, polarity %08x\n",
+				       i * 32, i * 32 + 31,
+				       smem_gpio->enabled[i],
+				       smem_gpio->detection[i],
+				       smem_gpio->polarity[i]);
+			}
+		for (i = 0; i < GPIO_SMEM_NUM_GROUPS; i++)
+			smem_gpio->num_fired[i] = 0;
+	}
+}
+
+void msm_gpio_exit_sleep(void)
+{
+	int i;
+	struct tramp_gpio_smem *smem_gpio;
+
+	smem_gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*smem_gpio));
+
+	for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) {
+		writel(msm_gpio_chips[i].int_enable[0],
+		       msm_gpio_chips[i].regs.int_en);
+	}
+
+	if (smem_gpio && (smem_gpio->num_fired[0] || smem_gpio->num_fired[1])) {
+		if (msm_gpio_debug_mask & GPIO_DEBUG_SLEEP)
+			printk(KERN_INFO "gpio: fired %x %x\n",
+			      smem_gpio->num_fired[0], smem_gpio->num_fired[1]);
+		tasklet_schedule(&msm_gpio_sleep_int_tasklet);
+	}
+}
+
+static int __init msm_init_gpio(void)
+{
+	int i, j = 0;
+
+	for (i = FIRST_GPIO_IRQ; i < FIRST_GPIO_IRQ + NR_GPIO_IRQS; i++) {
+		if (i - FIRST_GPIO_IRQ >=
+			msm_gpio_chips[j].chip.base +
+			msm_gpio_chips[j].chip.ngpio)
+			j++;
+		set_irq_chip_data(i, &msm_gpio_chips[j]);
+		set_irq_chip(i, &msm_gpio_irq_chip);
+		set_irq_handler(i, handle_edge_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) {
+		spin_lock_init(&msm_gpio_chips[i].lock);
+		writel(0, msm_gpio_chips[i].regs.int_en);
+		gpiochip_add(&msm_gpio_chips[i].chip);
+	}
+
+	set_irq_chained_handler(INT_GPIO_GROUP1, msm_gpio_irq_handler);
+	set_irq_chained_handler(INT_GPIO_GROUP2, msm_gpio_irq_handler);
+	set_irq_wake(INT_GPIO_GROUP1, 1);
+	set_irq_wake(INT_GPIO_GROUP2, 2);
+	return 0;
+}
+
+postcore_initcall(msm_init_gpio);
diff --git a/arch/arm/mach-msm/gpio_hw.h b/arch/arm/mach-msm/gpio_hw.h
new file mode 100644
index 0000000..74c22cf
--- /dev/null
+++ b/arch/arm/mach-msm/gpio_hw.h
@@ -0,0 +1,277 @@
+/* arch/arm/mach-msm/gpio_hw.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_GPIO_HW_H
+#define __ARCH_ARM_MACH_MSM_GPIO_HW_H
+
+#include <mach/msm_iomap.h>
+
+/* see 80-VA736-2 Rev C pp 695-751
+**
+** These are actually the *shadow* gpio registers, since the
+** real ones (which allow full access) are only available to the
+** ARM9 side of the world.
+**
+** Since the _BASE need to be page-aligned when we're mapping them
+** to virtual addresses, adjust for the additional offset in these
+** macros.
+*/
+
+#if defined(CONFIG_ARCH_MSM7X30)
+#define GPIO1_REG(off) (MSM_GPIO1_BASE + (off))
+#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off))
+#else
+#define GPIO1_REG(off) (MSM_GPIO1_BASE + 0x800 + (off))
+#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0xC00 + (off))
+#endif
+
+#if defined(CONFIG_ARCH_MSM7X00A) || defined(CONFIG_ARCH_MSM7X27)
+
+/* output value */
+#define GPIO_OUT_0         GPIO1_REG(0x00)  /* gpio  15-0  */
+#define GPIO_OUT_1         GPIO2_REG(0x00)  /* gpio  42-16 */
+#define GPIO_OUT_2         GPIO1_REG(0x04)  /* gpio  67-43 */
+#define GPIO_OUT_3         GPIO1_REG(0x08)  /* gpio  94-68 */
+#define GPIO_OUT_4         GPIO1_REG(0x0C)  /* gpio 106-95 */
+#define GPIO_OUT_5         GPIO1_REG(0x50)  /* gpio 107-121 */
+
+/* same pin map as above, output enable */
+#define GPIO_OE_0          GPIO1_REG(0x10)
+#define GPIO_OE_1          GPIO2_REG(0x08)
+#define GPIO_OE_2          GPIO1_REG(0x14)
+#define GPIO_OE_3          GPIO1_REG(0x18)
+#define GPIO_OE_4          GPIO1_REG(0x1C)
+#define GPIO_OE_5          GPIO1_REG(0x54)
+
+/* same pin map as above, input read */
+#define GPIO_IN_0          GPIO1_REG(0x34)
+#define GPIO_IN_1          GPIO2_REG(0x20)
+#define GPIO_IN_2          GPIO1_REG(0x38)
+#define GPIO_IN_3          GPIO1_REG(0x3C)
+#define GPIO_IN_4          GPIO1_REG(0x40)
+#define GPIO_IN_5          GPIO1_REG(0x44)
+
+/* same pin map as above, 1=edge 0=level interrup */
+#define GPIO_INT_EDGE_0    GPIO1_REG(0x60)
+#define GPIO_INT_EDGE_1    GPIO2_REG(0x50)
+#define GPIO_INT_EDGE_2    GPIO1_REG(0x64)
+#define GPIO_INT_EDGE_3    GPIO1_REG(0x68)
+#define GPIO_INT_EDGE_4    GPIO1_REG(0x6C)
+#define GPIO_INT_EDGE_5    GPIO1_REG(0xC0)
+
+/* same pin map as above, 1=positive 0=negative */
+#define GPIO_INT_POS_0     GPIO1_REG(0x70)
+#define GPIO_INT_POS_1     GPIO2_REG(0x58)
+#define GPIO_INT_POS_2     GPIO1_REG(0x74)
+#define GPIO_INT_POS_3     GPIO1_REG(0x78)
+#define GPIO_INT_POS_4     GPIO1_REG(0x7C)
+#define GPIO_INT_POS_5     GPIO1_REG(0xBC)
+
+/* same pin map as above, interrupt enable */
+#define GPIO_INT_EN_0      GPIO1_REG(0x80)
+#define GPIO_INT_EN_1      GPIO2_REG(0x60)
+#define GPIO_INT_EN_2      GPIO1_REG(0x84)
+#define GPIO_INT_EN_3      GPIO1_REG(0x88)
+#define GPIO_INT_EN_4      GPIO1_REG(0x8C)
+#define GPIO_INT_EN_5      GPIO1_REG(0xB8)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define GPIO_INT_CLEAR_0   GPIO1_REG(0x90)
+#define GPIO_INT_CLEAR_1   GPIO2_REG(0x68)
+#define GPIO_INT_CLEAR_2   GPIO1_REG(0x94)
+#define GPIO_INT_CLEAR_3   GPIO1_REG(0x98)
+#define GPIO_INT_CLEAR_4   GPIO1_REG(0x9C)
+#define GPIO_INT_CLEAR_5   GPIO1_REG(0xB4)
+
+/* same pin map as above, 1=interrupt pending */
+#define GPIO_INT_STATUS_0  GPIO1_REG(0xA0)
+#define GPIO_INT_STATUS_1  GPIO2_REG(0x70)
+#define GPIO_INT_STATUS_2  GPIO1_REG(0xA4)
+#define GPIO_INT_STATUS_3  GPIO1_REG(0xA8)
+#define GPIO_INT_STATUS_4  GPIO1_REG(0xAC)
+#define GPIO_INT_STATUS_5  GPIO1_REG(0xB0)
+
+#endif
+
+#if defined(CONFIG_ARCH_QSD8X50)
+/* output value */
+#define GPIO_OUT_0         GPIO1_REG(0x00)  /* gpio  15-0   */
+#define GPIO_OUT_1         GPIO2_REG(0x00)  /* gpio  42-16  */
+#define GPIO_OUT_2         GPIO1_REG(0x04)  /* gpio  67-43  */
+#define GPIO_OUT_3         GPIO1_REG(0x08)  /* gpio  94-68  */
+#define GPIO_OUT_4         GPIO1_REG(0x0C)  /* gpio 103-95  */
+#define GPIO_OUT_5         GPIO1_REG(0x10)  /* gpio 121-104 */
+#define GPIO_OUT_6         GPIO1_REG(0x14)  /* gpio 152-122 */
+#define GPIO_OUT_7         GPIO1_REG(0x18)  /* gpio 164-153 */
+
+/* same pin map as above, output enable */
+#define GPIO_OE_0          GPIO1_REG(0x20)
+#define GPIO_OE_1          GPIO2_REG(0x08)
+#define GPIO_OE_2          GPIO1_REG(0x24)
+#define GPIO_OE_3          GPIO1_REG(0x28)
+#define GPIO_OE_4          GPIO1_REG(0x2C)
+#define GPIO_OE_5          GPIO1_REG(0x30)
+#define GPIO_OE_6          GPIO1_REG(0x34)
+#define GPIO_OE_7          GPIO1_REG(0x38)
+
+/* same pin map as above, input read */
+#define GPIO_IN_0          GPIO1_REG(0x50)
+#define GPIO_IN_1          GPIO2_REG(0x20)
+#define GPIO_IN_2          GPIO1_REG(0x54)
+#define GPIO_IN_3          GPIO1_REG(0x58)
+#define GPIO_IN_4          GPIO1_REG(0x5C)
+#define GPIO_IN_5          GPIO1_REG(0x60)
+#define GPIO_IN_6          GPIO1_REG(0x64)
+#define GPIO_IN_7          GPIO1_REG(0x68)
+
+/* same pin map as above, 1=edge 0=level interrup */
+#define GPIO_INT_EDGE_0    GPIO1_REG(0x70)
+#define GPIO_INT_EDGE_1    GPIO2_REG(0x50)
+#define GPIO_INT_EDGE_2    GPIO1_REG(0x74)
+#define GPIO_INT_EDGE_3    GPIO1_REG(0x78)
+#define GPIO_INT_EDGE_4    GPIO1_REG(0x7C)
+#define GPIO_INT_EDGE_5    GPIO1_REG(0x80)
+#define GPIO_INT_EDGE_6    GPIO1_REG(0x84)
+#define GPIO_INT_EDGE_7    GPIO1_REG(0x88)
+
+/* same pin map as above, 1=positive 0=negative */
+#define GPIO_INT_POS_0     GPIO1_REG(0x90)
+#define GPIO_INT_POS_1     GPIO2_REG(0x58)
+#define GPIO_INT_POS_2     GPIO1_REG(0x94)
+#define GPIO_INT_POS_3     GPIO1_REG(0x98)
+#define GPIO_INT_POS_4     GPIO1_REG(0x9C)
+#define GPIO_INT_POS_5     GPIO1_REG(0xA0)
+#define GPIO_INT_POS_6     GPIO1_REG(0xA4)
+#define GPIO_INT_POS_7     GPIO1_REG(0xA8)
+
+/* same pin map as above, interrupt enable */
+#define GPIO_INT_EN_0      GPIO1_REG(0xB0)
+#define GPIO_INT_EN_1      GPIO2_REG(0x60)
+#define GPIO_INT_EN_2      GPIO1_REG(0xB4)
+#define GPIO_INT_EN_3      GPIO1_REG(0xB8)
+#define GPIO_INT_EN_4      GPIO1_REG(0xBC)
+#define GPIO_INT_EN_5      GPIO1_REG(0xC0)
+#define GPIO_INT_EN_6      GPIO1_REG(0xC4)
+#define GPIO_INT_EN_7      GPIO1_REG(0xC8)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define GPIO_INT_CLEAR_0   GPIO1_REG(0xD0)
+#define GPIO_INT_CLEAR_1   GPIO2_REG(0x68)
+#define GPIO_INT_CLEAR_2   GPIO1_REG(0xD4)
+#define GPIO_INT_CLEAR_3   GPIO1_REG(0xD8)
+#define GPIO_INT_CLEAR_4   GPIO1_REG(0xDC)
+#define GPIO_INT_CLEAR_5   GPIO1_REG(0xE0)
+#define GPIO_INT_CLEAR_6   GPIO1_REG(0xE4)
+#define GPIO_INT_CLEAR_7   GPIO1_REG(0xE8)
+
+/* same pin map as above, 1=interrupt pending */
+#define GPIO_INT_STATUS_0  GPIO1_REG(0xF0)
+#define GPIO_INT_STATUS_1  GPIO2_REG(0x70)
+#define GPIO_INT_STATUS_2  GPIO1_REG(0xF4)
+#define GPIO_INT_STATUS_3  GPIO1_REG(0xF8)
+#define GPIO_INT_STATUS_4  GPIO1_REG(0xFC)
+#define GPIO_INT_STATUS_5  GPIO1_REG(0x100)
+#define GPIO_INT_STATUS_6  GPIO1_REG(0x104)
+#define GPIO_INT_STATUS_7  GPIO1_REG(0x108)
+
+#endif
+
+#if defined(CONFIG_ARCH_MSM7X30)
+
+/* output value */
+#define GPIO_OUT_0         GPIO1_REG(0x00)   /* gpio  15-0   */
+#define GPIO_OUT_1         GPIO2_REG(0x00)   /* gpio  43-16  */
+#define GPIO_OUT_2         GPIO1_REG(0x04)   /* gpio  67-44  */
+#define GPIO_OUT_3         GPIO1_REG(0x08)   /* gpio  94-68  */
+#define GPIO_OUT_4         GPIO1_REG(0x0C)   /* gpio 106-95  */
+#define GPIO_OUT_5         GPIO1_REG(0x50)   /* gpio 133-107 */
+#define GPIO_OUT_6         GPIO1_REG(0xC4)   /* gpio 150-134 */
+#define GPIO_OUT_7         GPIO1_REG(0x214)  /* gpio 181-151 */
+
+/* same pin map as above, output enable */
+#define GPIO_OE_0          GPIO1_REG(0x10)
+#define GPIO_OE_1          GPIO2_REG(0x08)
+#define GPIO_OE_2          GPIO1_REG(0x14)
+#define GPIO_OE_3          GPIO1_REG(0x18)
+#define GPIO_OE_4          GPIO1_REG(0x1C)
+#define GPIO_OE_5          GPIO1_REG(0x54)
+#define GPIO_OE_6          GPIO1_REG(0xC8)
+#define GPIO_OE_7          GPIO1_REG(0x218)
+
+/* same pin map as above, input read */
+#define GPIO_IN_0          GPIO1_REG(0x34)
+#define GPIO_IN_1          GPIO2_REG(0x20)
+#define GPIO_IN_2          GPIO1_REG(0x38)
+#define GPIO_IN_3          GPIO1_REG(0x3C)
+#define GPIO_IN_4          GPIO1_REG(0x40)
+#define GPIO_IN_5          GPIO1_REG(0x44)
+#define GPIO_IN_6          GPIO1_REG(0xCC)
+#define GPIO_IN_7          GPIO1_REG(0x21C)
+
+/* same pin map as above, 1=edge 0=level interrup */
+#define GPIO_INT_EDGE_0    GPIO1_REG(0x60)
+#define GPIO_INT_EDGE_1    GPIO2_REG(0x50)
+#define GPIO_INT_EDGE_2    GPIO1_REG(0x64)
+#define GPIO_INT_EDGE_3    GPIO1_REG(0x68)
+#define GPIO_INT_EDGE_4    GPIO1_REG(0x6C)
+#define GPIO_INT_EDGE_5    GPIO1_REG(0xC0)
+#define GPIO_INT_EDGE_6    GPIO1_REG(0xD0)
+#define GPIO_INT_EDGE_7    GPIO1_REG(0x240)
+
+/* same pin map as above, 1=positive 0=negative */
+#define GPIO_INT_POS_0     GPIO1_REG(0x70)
+#define GPIO_INT_POS_1     GPIO2_REG(0x58)
+#define GPIO_INT_POS_2     GPIO1_REG(0x74)
+#define GPIO_INT_POS_3     GPIO1_REG(0x78)
+#define GPIO_INT_POS_4     GPIO1_REG(0x7C)
+#define GPIO_INT_POS_5     GPIO1_REG(0xBC)
+#define GPIO_INT_POS_6     GPIO1_REG(0xD4)
+#define GPIO_INT_POS_7     GPIO1_REG(0x228)
+
+/* same pin map as above, interrupt enable */
+#define GPIO_INT_EN_0      GPIO1_REG(0x80)
+#define GPIO_INT_EN_1      GPIO2_REG(0x60)
+#define GPIO_INT_EN_2      GPIO1_REG(0x84)
+#define GPIO_INT_EN_3      GPIO1_REG(0x88)
+#define GPIO_INT_EN_4      GPIO1_REG(0x8C)
+#define GPIO_INT_EN_5      GPIO1_REG(0xB8)
+#define GPIO_INT_EN_6      GPIO1_REG(0xD8)
+#define GPIO_INT_EN_7      GPIO1_REG(0x22C)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define GPIO_INT_CLEAR_0   GPIO1_REG(0x90)
+#define GPIO_INT_CLEAR_1   GPIO2_REG(0x68)
+#define GPIO_INT_CLEAR_2   GPIO1_REG(0x94)
+#define GPIO_INT_CLEAR_3   GPIO1_REG(0x98)
+#define GPIO_INT_CLEAR_4   GPIO1_REG(0x9C)
+#define GPIO_INT_CLEAR_5   GPIO1_REG(0xB4)
+#define GPIO_INT_CLEAR_6   GPIO1_REG(0xDC)
+#define GPIO_INT_CLEAR_7   GPIO1_REG(0x230)
+
+/* same pin map as above, 1=interrupt pending */
+#define GPIO_INT_STATUS_0  GPIO1_REG(0xA0)
+#define GPIO_INT_STATUS_1  GPIO2_REG(0x70)
+#define GPIO_INT_STATUS_2  GPIO1_REG(0xA4)
+#define GPIO_INT_STATUS_3  GPIO1_REG(0xA8)
+#define GPIO_INT_STATUS_4  GPIO1_REG(0xAC)
+#define GPIO_INT_STATUS_5  GPIO1_REG(0xB0)
+#define GPIO_INT_STATUS_6  GPIO1_REG(0xE0)
+#define GPIO_INT_STATUS_7  GPIO1_REG(0x234)
+
+#endif
+
+#endif
-- 
1.7.0.4

--
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

* [PATCH 1/2] msm: Install the Google-Android gpio driver.
@ 2010-08-31  0:18 ` Gregory Bean
  0 siblings, 0 replies; 17+ messages in thread
From: Gregory Bean @ 2010-08-31  0:18 UTC (permalink / raw)
  To: linux-arm-kernel

From: Arve Hj?nnev?g <arve@android.com>

As part of the ongoing effort to converge on a common code base,
adopt the Google-Android msmgpio driver, as it has a stronger pedigree
than the previous submission from codeaurora.

Cc: Arve Hj?nnev?g <arve@android.com>
Signed-off-by: Gregory Bean <gbean@codeaurora.org>
---
 arch/arm/mach-msm/Makefile  |    3 +
 arch/arm/mach-msm/gpio.c    |  627 +++++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-msm/gpio_hw.h |  277 +++++++++++++++++++
 3 files changed, 907 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-msm/gpio.c
 create mode 100644 arch/arm/mach-msm/gpio_hw.h

diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 2263b8f..c95d19a 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -22,3 +22,6 @@ obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
 obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-7x30.o gpiomux-v1.o gpiomux.o
 obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o gpiomux-v1.o gpiomux.o
 obj-$(CONFIG_ARCH_MSM8X60) += gpiomux-8x60.o gpiomux-v2.o gpiomux.o
+ifndef CONFIG_MSM_V2_TLMM
+obj-y	+= gpio.o
+endif
diff --git a/arch/arm/mach-msm/gpio.c b/arch/arm/mach-msm/gpio.c
new file mode 100644
index 0000000..fd899a1
--- /dev/null
+++ b/arch/arm/mach-msm/gpio.c
@@ -0,0 +1,627 @@
+/* linux/arch/arm/mach-msm/gpio.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include "gpio_hw.h"
+#include "proc_comm.h"
+#include "smd_private.h"
+
+#define FIRST_GPIO_IRQ MSM_GPIO_TO_INT(0)
+
+enum {
+	GPIO_DEBUG_SLEEP = 1U << 0,
+};
+static int msm_gpio_debug_mask;
+module_param_named(debug_mask, msm_gpio_debug_mask, int,
+		   S_IRUGO | S_IWUSR | S_IWGRP);
+
+#define MSM_GPIO_BROKEN_INT_CLEAR 1
+
+struct msm_gpio_regs {
+	void __iomem *out;
+	void __iomem *in;
+	void __iomem *int_status;
+	void __iomem *int_clear;
+	void __iomem *int_en;
+	void __iomem *int_edge;
+	void __iomem *int_pos;
+	void __iomem *oe;
+};
+
+struct msm_gpio_chip {
+	spinlock_t		lock;
+	struct gpio_chip	chip;
+	struct msm_gpio_regs	regs;
+#if MSM_GPIO_BROKEN_INT_CLEAR
+	unsigned                int_status_copy;
+#endif
+	unsigned int            both_edge_detect;
+	unsigned int            int_enable[2]; /* 0: awake, 1: sleep */
+};
+
+static int msm_gpio_write(struct msm_gpio_chip *msm_chip,
+			  unsigned offset, unsigned on)
+{
+	unsigned b = 1U << offset;
+	unsigned v;
+
+	v = readl(msm_chip->regs.out);
+	if (on)
+		writel(v | b, msm_chip->regs.out);
+	else
+		writel(v & (~b), msm_chip->regs.out);
+	return 0;
+}
+
+static void msm_gpio_update_both_edge_detect(struct msm_gpio_chip *msm_chip)
+{
+	int loop_limit = 100;
+	unsigned pol, val, val2, intstat;
+	do {
+		val = readl(msm_chip->regs.in);
+		pol = readl(msm_chip->regs.int_pos);
+		pol = (pol & ~msm_chip->both_edge_detect) |
+		      (~val & msm_chip->both_edge_detect);
+		writel(pol, msm_chip->regs.int_pos);
+		intstat = readl(msm_chip->regs.int_status);
+		val2 = readl(msm_chip->regs.in);
+		if (((val ^ val2) & msm_chip->both_edge_detect & ~intstat) == 0)
+			return;
+	} while (loop_limit-- > 0);
+	printk(KERN_ERR "msm_gpio_update_both_edge_detect, "
+	       "failed to reach stable state %x != %x\n", val, val2);
+}
+
+static int msm_gpio_clear_detect_status(struct msm_gpio_chip *msm_chip,
+					unsigned offset)
+{
+	unsigned b = BIT(offset);
+
+#if MSM_GPIO_BROKEN_INT_CLEAR
+	/* Save interrupts that already triggered before we loose them. */
+	/* Any interrupt that triggers between the read of int_status */
+	/* and the write to int_clear will still be lost though. */
+	msm_chip->int_status_copy |= readl(msm_chip->regs.int_status);
+	msm_chip->int_status_copy &= ~b;
+#endif
+	writel(b, msm_chip->regs.int_clear);
+	msm_gpio_update_both_edge_detect(msm_chip);
+	return 0;
+}
+
+static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct msm_gpio_chip *msm_chip;
+	unsigned long irq_flags;
+
+	msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+	spin_lock_irqsave(&msm_chip->lock, irq_flags);
+	writel(readl(msm_chip->regs.oe) & ~BIT(offset), msm_chip->regs.oe);
+	spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+	return 0;
+}
+
+static int
+msm_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct msm_gpio_chip *msm_chip;
+	unsigned long irq_flags;
+
+	msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+	spin_lock_irqsave(&msm_chip->lock, irq_flags);
+	msm_gpio_write(msm_chip, offset, value);
+	writel(readl(msm_chip->regs.oe) | BIT(offset), msm_chip->regs.oe);
+	spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+	return 0;
+}
+
+static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct msm_gpio_chip *msm_chip;
+
+	msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+	return (readl(msm_chip->regs.in) & (1U << offset)) ? 1 : 0;
+}
+
+static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct msm_gpio_chip *msm_chip;
+	unsigned long irq_flags;
+
+	msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+	spin_lock_irqsave(&msm_chip->lock, irq_flags);
+	msm_gpio_write(msm_chip, offset, value);
+	spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	return MSM_GPIO_TO_INT(chip->base + offset);
+}
+
+struct msm_gpio_chip msm_gpio_chips[] = {
+	{
+		.regs = {
+			.out =         GPIO_OUT_0,
+			.in =          GPIO_IN_0,
+			.int_status =  GPIO_INT_STATUS_0,
+			.int_clear =   GPIO_INT_CLEAR_0,
+			.int_en =      GPIO_INT_EN_0,
+			.int_edge =    GPIO_INT_EDGE_0,
+			.int_pos =     GPIO_INT_POS_0,
+			.oe =          GPIO_OE_0,
+		},
+		.chip = {
+			.base = 0,
+			.ngpio = 16,
+			.get = msm_gpio_get,
+			.set = msm_gpio_set,
+			.direction_input = msm_gpio_direction_input,
+			.direction_output = msm_gpio_direction_output,
+			.to_irq = msm_gpio_to_irq,
+		}
+	},
+	{
+		.regs = {
+			.out =         GPIO_OUT_1,
+			.in =          GPIO_IN_1,
+			.int_status =  GPIO_INT_STATUS_1,
+			.int_clear =   GPIO_INT_CLEAR_1,
+			.int_en =      GPIO_INT_EN_1,
+			.int_edge =    GPIO_INT_EDGE_1,
+			.int_pos =     GPIO_INT_POS_1,
+			.oe =          GPIO_OE_1,
+		},
+		.chip = {
+			.base = 16,
+#if defined(CONFIG_ARCH_MSM7X30)
+			.ngpio = 28,
+#else
+			.ngpio = 27,
+#endif
+			.get = msm_gpio_get,
+			.set = msm_gpio_set,
+			.direction_input = msm_gpio_direction_input,
+			.direction_output = msm_gpio_direction_output,
+			.to_irq = msm_gpio_to_irq,
+		}
+	},
+	{
+		.regs = {
+			.out =         GPIO_OUT_2,
+			.in =          GPIO_IN_2,
+			.int_status =  GPIO_INT_STATUS_2,
+			.int_clear =   GPIO_INT_CLEAR_2,
+			.int_en =      GPIO_INT_EN_2,
+			.int_edge =    GPIO_INT_EDGE_2,
+			.int_pos =     GPIO_INT_POS_2,
+			.oe =          GPIO_OE_2,
+		},
+		.chip = {
+#if defined(CONFIG_ARCH_MSM7X30)
+			.base = 44,
+			.ngpio = 24,
+#else
+			.base = 43,
+			.ngpio = 25,
+#endif
+			.get = msm_gpio_get,
+			.set = msm_gpio_set,
+			.direction_input = msm_gpio_direction_input,
+			.direction_output = msm_gpio_direction_output,
+			.to_irq = msm_gpio_to_irq,
+		}
+	},
+	{
+		.regs = {
+			.out =         GPIO_OUT_3,
+			.in =          GPIO_IN_3,
+			.int_status =  GPIO_INT_STATUS_3,
+			.int_clear =   GPIO_INT_CLEAR_3,
+			.int_en =      GPIO_INT_EN_3,
+			.int_edge =    GPIO_INT_EDGE_3,
+			.int_pos =     GPIO_INT_POS_3,
+			.oe =          GPIO_OE_3,
+		},
+		.chip = {
+			.base = 68,
+			.ngpio = 27,
+			.get = msm_gpio_get,
+			.set = msm_gpio_set,
+			.direction_input = msm_gpio_direction_input,
+			.direction_output = msm_gpio_direction_output,
+			.to_irq = msm_gpio_to_irq,
+		}
+	},
+	{
+		.regs = {
+			.out =         GPIO_OUT_4,
+			.in =          GPIO_IN_4,
+			.int_status =  GPIO_INT_STATUS_4,
+			.int_clear =   GPIO_INT_CLEAR_4,
+			.int_en =      GPIO_INT_EN_4,
+			.int_edge =    GPIO_INT_EDGE_4,
+			.int_pos =     GPIO_INT_POS_4,
+			.oe =          GPIO_OE_4,
+		},
+		.chip = {
+			.base = 95,
+#if defined(CONFIG_ARCH_QSD8X50)
+			.ngpio = 9,
+#else
+			.ngpio = 12,
+#endif
+			.get = msm_gpio_get,
+			.set = msm_gpio_set,
+			.direction_input = msm_gpio_direction_input,
+			.direction_output = msm_gpio_direction_output,
+			.to_irq = msm_gpio_to_irq,
+		}
+	},
+	{
+		.regs = {
+			.out =         GPIO_OUT_5,
+			.in =          GPIO_IN_5,
+			.int_status =  GPIO_INT_STATUS_5,
+			.int_clear =   GPIO_INT_CLEAR_5,
+			.int_en =      GPIO_INT_EN_5,
+			.int_edge =    GPIO_INT_EDGE_5,
+			.int_pos =     GPIO_INT_POS_5,
+			.oe =          GPIO_OE_5,
+		},
+		.chip = {
+#if defined(CONFIG_ARCH_QSD8X50)
+			.base = 104,
+			.ngpio = 18,
+#elif defined(CONFIG_ARCH_MSM7X30)
+			.base = 107,
+			.ngpio = 27,
+#elif defined(CONFIG_ARCH_MSM7X27)
+			.base = 107,
+			.ngpio = 26,
+#else
+			.base = 107,
+			.ngpio = 15,
+#endif
+			.get = msm_gpio_get,
+			.set = msm_gpio_set,
+			.direction_input = msm_gpio_direction_input,
+			.direction_output = msm_gpio_direction_output,
+			.to_irq = msm_gpio_to_irq,
+		}
+	},
+#if defined(CONFIG_ARCH_QSD8X50) || defined(CONFIG_ARCH_MSM7X30)
+	{
+		.regs = {
+			.out =         GPIO_OUT_6,
+			.in =          GPIO_IN_6,
+			.int_status =  GPIO_INT_STATUS_6,
+			.int_clear =   GPIO_INT_CLEAR_6,
+			.int_en =      GPIO_INT_EN_6,
+			.int_edge =    GPIO_INT_EDGE_6,
+			.int_pos =     GPIO_INT_POS_6,
+			.oe =          GPIO_OE_6,
+		},
+		.chip = {
+#if defined(CONFIG_ARCH_MSM7X30)
+			.base = 134,
+			.ngpio = 17,
+#else
+			.base = 122,
+			.ngpio = 31,
+#endif
+			.get = msm_gpio_get,
+			.set = msm_gpio_set,
+			.direction_input = msm_gpio_direction_input,
+			.direction_output = msm_gpio_direction_output,
+			.to_irq = msm_gpio_to_irq,
+		}
+	},
+	{
+		.regs = {
+			.out =         GPIO_OUT_7,
+			.in =          GPIO_IN_7,
+			.int_status =  GPIO_INT_STATUS_7,
+			.int_clear =   GPIO_INT_CLEAR_7,
+			.int_en =      GPIO_INT_EN_7,
+			.int_edge =    GPIO_INT_EDGE_7,
+			.int_pos =     GPIO_INT_POS_7,
+			.oe =          GPIO_OE_7,
+		},
+		.chip = {
+#if defined(CONFIG_ARCH_MSM7X30)
+			.base = 151,
+			.ngpio = 31,
+#else
+			.base = 153,
+			.ngpio = 12,
+#endif
+			.get = msm_gpio_get,
+			.set = msm_gpio_set,
+			.direction_input = msm_gpio_direction_input,
+			.direction_output = msm_gpio_direction_output,
+			.to_irq = msm_gpio_to_irq,
+		}
+	},
+#endif
+};
+
+static void msm_gpio_irq_ack(unsigned int irq)
+{
+	unsigned long irq_flags;
+	struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+	spin_lock_irqsave(&msm_chip->lock, irq_flags);
+	msm_gpio_clear_detect_status(msm_chip,
+				     irq - gpio_to_irq(msm_chip->chip.base));
+	spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static void msm_gpio_irq_mask(unsigned int irq)
+{
+	unsigned long irq_flags;
+	struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+	unsigned offset = irq - gpio_to_irq(msm_chip->chip.base);
+
+	spin_lock_irqsave(&msm_chip->lock, irq_flags);
+	/* level triggered interrupts are also latched */
+	if (!(readl(msm_chip->regs.int_edge) & BIT(offset)))
+		msm_gpio_clear_detect_status(msm_chip, offset);
+	msm_chip->int_enable[0] &= ~BIT(offset);
+	writel(msm_chip->int_enable[0], msm_chip->regs.int_en);
+	spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static void msm_gpio_irq_unmask(unsigned int irq)
+{
+	unsigned long irq_flags;
+	struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+	unsigned offset = irq - gpio_to_irq(msm_chip->chip.base);
+
+	spin_lock_irqsave(&msm_chip->lock, irq_flags);
+	/* level triggered interrupts are also latched */
+	if (!(readl(msm_chip->regs.int_edge) & BIT(offset)))
+		msm_gpio_clear_detect_status(msm_chip, offset);
+	msm_chip->int_enable[0] |= BIT(offset);
+	writel(msm_chip->int_enable[0], msm_chip->regs.int_en);
+	spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static int msm_gpio_irq_set_wake(unsigned int irq, unsigned int on)
+{
+	unsigned long irq_flags;
+	struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+	unsigned offset = irq - gpio_to_irq(msm_chip->chip.base);
+
+	spin_lock_irqsave(&msm_chip->lock, irq_flags);
+
+	if (on)
+		msm_chip->int_enable[1] |= BIT(offset);
+	else
+		msm_chip->int_enable[1] &= ~BIT(offset);
+
+	spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+	return 0;
+}
+
+static int msm_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
+{
+	unsigned long irq_flags;
+	struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+	unsigned offset = irq - gpio_to_irq(msm_chip->chip.base);
+	unsigned v, b = BIT(offset);
+
+	spin_lock_irqsave(&msm_chip->lock, irq_flags);
+	v = readl(msm_chip->regs.int_edge);
+	if (flow_type & IRQ_TYPE_EDGE_BOTH) {
+		writel(v | b, msm_chip->regs.int_edge);
+		irq_desc[irq].handle_irq = handle_edge_irq;
+	} else {
+		writel(v & ~b, msm_chip->regs.int_edge);
+		irq_desc[irq].handle_irq = handle_level_irq;
+	}
+	if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
+		msm_chip->both_edge_detect |= b;
+		msm_gpio_update_both_edge_detect(msm_chip);
+	} else {
+		msm_chip->both_edge_detect &= ~b;
+		v = readl(msm_chip->regs.int_pos);
+		if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH))
+			writel(v | b, msm_chip->regs.int_pos);
+		else
+			writel(v & ~b, msm_chip->regs.int_pos);
+	}
+	spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+	return 0;
+}
+
+static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	int i, j, m;
+	unsigned v;
+
+	for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) {
+		struct msm_gpio_chip *msm_chip = &msm_gpio_chips[i];
+		v = readl(msm_chip->regs.int_status);
+		v &= msm_chip->int_enable[0];
+		while (v) {
+			m = v & -v;
+			j = fls(m) - 1;
+			/* printk("%s %08x %08x bit %d gpio %d irq %d\n",
+				__func__, v, m, j, msm_chip->chip.start + j,
+				FIRST_GPIO_IRQ + msm_chip->chip.start + j); */
+			v &= ~m;
+			generic_handle_irq(FIRST_GPIO_IRQ +
+					   msm_chip->chip.base + j);
+		}
+	}
+	desc->chip->ack(irq);
+}
+
+static struct irq_chip msm_gpio_irq_chip = {
+	.name      = "msmgpio",
+	.ack       = msm_gpio_irq_ack,
+	.mask      = msm_gpio_irq_mask,
+	.unmask    = msm_gpio_irq_unmask,
+	.set_wake  = msm_gpio_irq_set_wake,
+	.set_type  = msm_gpio_irq_set_type,
+};
+
+#define NUM_GPIO_SMEM_BANKS 6
+#define GPIO_SMEM_NUM_GROUPS 2
+#define GPIO_SMEM_MAX_PC_INTERRUPTS 8
+struct tramp_gpio_smem {
+	uint16_t num_fired[GPIO_SMEM_NUM_GROUPS];
+	uint16_t fired[GPIO_SMEM_NUM_GROUPS][GPIO_SMEM_MAX_PC_INTERRUPTS];
+	uint32_t enabled[NUM_GPIO_SMEM_BANKS];
+	uint32_t detection[NUM_GPIO_SMEM_BANKS];
+	uint32_t polarity[NUM_GPIO_SMEM_BANKS];
+};
+
+static void msm_gpio_sleep_int(unsigned long arg)
+{
+	int i, j;
+	struct tramp_gpio_smem *smem_gpio;
+
+	BUILD_BUG_ON(NR_GPIO_IRQS > NUM_GPIO_SMEM_BANKS * 32);
+
+	smem_gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*smem_gpio));
+	if (smem_gpio == NULL)
+		return;
+
+	local_irq_disable();
+	for (i = 0; i < GPIO_SMEM_NUM_GROUPS; i++) {
+		int count = smem_gpio->num_fired[i];
+		for (j = 0; j < count; j++) {
+			/* TODO: Check mask */
+			generic_handle_irq(
+				MSM_GPIO_TO_INT(smem_gpio->fired[i][j]));
+		}
+	}
+	local_irq_enable();
+}
+
+static DECLARE_TASKLET(msm_gpio_sleep_int_tasklet, msm_gpio_sleep_int, 0);
+
+void msm_gpio_enter_sleep(int from_idle)
+{
+	int i;
+	struct tramp_gpio_smem *smem_gpio;
+
+	smem_gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*smem_gpio));
+
+	if (smem_gpio) {
+		for (i = 0; i < ARRAY_SIZE(smem_gpio->enabled); i++) {
+			smem_gpio->enabled[i] = 0;
+			smem_gpio->detection[i] = 0;
+			smem_gpio->polarity[i] = 0;
+		}
+	}
+
+	for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) {
+		writel(msm_gpio_chips[i].int_enable[!from_idle],
+		       msm_gpio_chips[i].regs.int_en);
+		if (smem_gpio) {
+			uint32_t tmp;
+			int start, index, shiftl, shiftr;
+			start = msm_gpio_chips[i].chip.base;
+			index = start / 32;
+			shiftl = start % 32;
+			shiftr = 32 - shiftl;
+			tmp = msm_gpio_chips[i].int_enable[!from_idle];
+			smem_gpio->enabled[index] |= tmp << shiftl;
+			smem_gpio->enabled[index+1] |= tmp >> shiftr;
+			smem_gpio->detection[index] |=
+				readl(msm_gpio_chips[i].regs.int_edge) <<
+				shiftl;
+			smem_gpio->detection[index+1] |=
+				readl(msm_gpio_chips[i].regs.int_edge) >>
+				shiftr;
+			smem_gpio->polarity[index] |=
+				readl(msm_gpio_chips[i].regs.int_pos) << shiftl;
+			smem_gpio->polarity[index+1] |=
+				readl(msm_gpio_chips[i].regs.int_pos) >> shiftr;
+		}
+	}
+
+	if (smem_gpio) {
+		if (msm_gpio_debug_mask & GPIO_DEBUG_SLEEP)
+			for (i = 0; i < ARRAY_SIZE(smem_gpio->enabled); i++) {
+				printk("msm_gpio_enter_sleep gpio %d-%d: enable"
+				       " %08x, edge %08x, polarity %08x\n",
+				       i * 32, i * 32 + 31,
+				       smem_gpio->enabled[i],
+				       smem_gpio->detection[i],
+				       smem_gpio->polarity[i]);
+			}
+		for (i = 0; i < GPIO_SMEM_NUM_GROUPS; i++)
+			smem_gpio->num_fired[i] = 0;
+	}
+}
+
+void msm_gpio_exit_sleep(void)
+{
+	int i;
+	struct tramp_gpio_smem *smem_gpio;
+
+	smem_gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*smem_gpio));
+
+	for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) {
+		writel(msm_gpio_chips[i].int_enable[0],
+		       msm_gpio_chips[i].regs.int_en);
+	}
+
+	if (smem_gpio && (smem_gpio->num_fired[0] || smem_gpio->num_fired[1])) {
+		if (msm_gpio_debug_mask & GPIO_DEBUG_SLEEP)
+			printk(KERN_INFO "gpio: fired %x %x\n",
+			      smem_gpio->num_fired[0], smem_gpio->num_fired[1]);
+		tasklet_schedule(&msm_gpio_sleep_int_tasklet);
+	}
+}
+
+static int __init msm_init_gpio(void)
+{
+	int i, j = 0;
+
+	for (i = FIRST_GPIO_IRQ; i < FIRST_GPIO_IRQ + NR_GPIO_IRQS; i++) {
+		if (i - FIRST_GPIO_IRQ >=
+			msm_gpio_chips[j].chip.base +
+			msm_gpio_chips[j].chip.ngpio)
+			j++;
+		set_irq_chip_data(i, &msm_gpio_chips[j]);
+		set_irq_chip(i, &msm_gpio_irq_chip);
+		set_irq_handler(i, handle_edge_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) {
+		spin_lock_init(&msm_gpio_chips[i].lock);
+		writel(0, msm_gpio_chips[i].regs.int_en);
+		gpiochip_add(&msm_gpio_chips[i].chip);
+	}
+
+	set_irq_chained_handler(INT_GPIO_GROUP1, msm_gpio_irq_handler);
+	set_irq_chained_handler(INT_GPIO_GROUP2, msm_gpio_irq_handler);
+	set_irq_wake(INT_GPIO_GROUP1, 1);
+	set_irq_wake(INT_GPIO_GROUP2, 2);
+	return 0;
+}
+
+postcore_initcall(msm_init_gpio);
diff --git a/arch/arm/mach-msm/gpio_hw.h b/arch/arm/mach-msm/gpio_hw.h
new file mode 100644
index 0000000..74c22cf
--- /dev/null
+++ b/arch/arm/mach-msm/gpio_hw.h
@@ -0,0 +1,277 @@
+/* arch/arm/mach-msm/gpio_hw.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_GPIO_HW_H
+#define __ARCH_ARM_MACH_MSM_GPIO_HW_H
+
+#include <mach/msm_iomap.h>
+
+/* see 80-VA736-2 Rev C pp 695-751
+**
+** These are actually the *shadow* gpio registers, since the
+** real ones (which allow full access) are only available to the
+** ARM9 side of the world.
+**
+** Since the _BASE need to be page-aligned when we're mapping them
+** to virtual addresses, adjust for the additional offset in these
+** macros.
+*/
+
+#if defined(CONFIG_ARCH_MSM7X30)
+#define GPIO1_REG(off) (MSM_GPIO1_BASE + (off))
+#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off))
+#else
+#define GPIO1_REG(off) (MSM_GPIO1_BASE + 0x800 + (off))
+#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0xC00 + (off))
+#endif
+
+#if defined(CONFIG_ARCH_MSM7X00A) || defined(CONFIG_ARCH_MSM7X27)
+
+/* output value */
+#define GPIO_OUT_0         GPIO1_REG(0x00)  /* gpio  15-0  */
+#define GPIO_OUT_1         GPIO2_REG(0x00)  /* gpio  42-16 */
+#define GPIO_OUT_2         GPIO1_REG(0x04)  /* gpio  67-43 */
+#define GPIO_OUT_3         GPIO1_REG(0x08)  /* gpio  94-68 */
+#define GPIO_OUT_4         GPIO1_REG(0x0C)  /* gpio 106-95 */
+#define GPIO_OUT_5         GPIO1_REG(0x50)  /* gpio 107-121 */
+
+/* same pin map as above, output enable */
+#define GPIO_OE_0          GPIO1_REG(0x10)
+#define GPIO_OE_1          GPIO2_REG(0x08)
+#define GPIO_OE_2          GPIO1_REG(0x14)
+#define GPIO_OE_3          GPIO1_REG(0x18)
+#define GPIO_OE_4          GPIO1_REG(0x1C)
+#define GPIO_OE_5          GPIO1_REG(0x54)
+
+/* same pin map as above, input read */
+#define GPIO_IN_0          GPIO1_REG(0x34)
+#define GPIO_IN_1          GPIO2_REG(0x20)
+#define GPIO_IN_2          GPIO1_REG(0x38)
+#define GPIO_IN_3          GPIO1_REG(0x3C)
+#define GPIO_IN_4          GPIO1_REG(0x40)
+#define GPIO_IN_5          GPIO1_REG(0x44)
+
+/* same pin map as above, 1=edge 0=level interrup */
+#define GPIO_INT_EDGE_0    GPIO1_REG(0x60)
+#define GPIO_INT_EDGE_1    GPIO2_REG(0x50)
+#define GPIO_INT_EDGE_2    GPIO1_REG(0x64)
+#define GPIO_INT_EDGE_3    GPIO1_REG(0x68)
+#define GPIO_INT_EDGE_4    GPIO1_REG(0x6C)
+#define GPIO_INT_EDGE_5    GPIO1_REG(0xC0)
+
+/* same pin map as above, 1=positive 0=negative */
+#define GPIO_INT_POS_0     GPIO1_REG(0x70)
+#define GPIO_INT_POS_1     GPIO2_REG(0x58)
+#define GPIO_INT_POS_2     GPIO1_REG(0x74)
+#define GPIO_INT_POS_3     GPIO1_REG(0x78)
+#define GPIO_INT_POS_4     GPIO1_REG(0x7C)
+#define GPIO_INT_POS_5     GPIO1_REG(0xBC)
+
+/* same pin map as above, interrupt enable */
+#define GPIO_INT_EN_0      GPIO1_REG(0x80)
+#define GPIO_INT_EN_1      GPIO2_REG(0x60)
+#define GPIO_INT_EN_2      GPIO1_REG(0x84)
+#define GPIO_INT_EN_3      GPIO1_REG(0x88)
+#define GPIO_INT_EN_4      GPIO1_REG(0x8C)
+#define GPIO_INT_EN_5      GPIO1_REG(0xB8)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define GPIO_INT_CLEAR_0   GPIO1_REG(0x90)
+#define GPIO_INT_CLEAR_1   GPIO2_REG(0x68)
+#define GPIO_INT_CLEAR_2   GPIO1_REG(0x94)
+#define GPIO_INT_CLEAR_3   GPIO1_REG(0x98)
+#define GPIO_INT_CLEAR_4   GPIO1_REG(0x9C)
+#define GPIO_INT_CLEAR_5   GPIO1_REG(0xB4)
+
+/* same pin map as above, 1=interrupt pending */
+#define GPIO_INT_STATUS_0  GPIO1_REG(0xA0)
+#define GPIO_INT_STATUS_1  GPIO2_REG(0x70)
+#define GPIO_INT_STATUS_2  GPIO1_REG(0xA4)
+#define GPIO_INT_STATUS_3  GPIO1_REG(0xA8)
+#define GPIO_INT_STATUS_4  GPIO1_REG(0xAC)
+#define GPIO_INT_STATUS_5  GPIO1_REG(0xB0)
+
+#endif
+
+#if defined(CONFIG_ARCH_QSD8X50)
+/* output value */
+#define GPIO_OUT_0         GPIO1_REG(0x00)  /* gpio  15-0   */
+#define GPIO_OUT_1         GPIO2_REG(0x00)  /* gpio  42-16  */
+#define GPIO_OUT_2         GPIO1_REG(0x04)  /* gpio  67-43  */
+#define GPIO_OUT_3         GPIO1_REG(0x08)  /* gpio  94-68  */
+#define GPIO_OUT_4         GPIO1_REG(0x0C)  /* gpio 103-95  */
+#define GPIO_OUT_5         GPIO1_REG(0x10)  /* gpio 121-104 */
+#define GPIO_OUT_6         GPIO1_REG(0x14)  /* gpio 152-122 */
+#define GPIO_OUT_7         GPIO1_REG(0x18)  /* gpio 164-153 */
+
+/* same pin map as above, output enable */
+#define GPIO_OE_0          GPIO1_REG(0x20)
+#define GPIO_OE_1          GPIO2_REG(0x08)
+#define GPIO_OE_2          GPIO1_REG(0x24)
+#define GPIO_OE_3          GPIO1_REG(0x28)
+#define GPIO_OE_4          GPIO1_REG(0x2C)
+#define GPIO_OE_5          GPIO1_REG(0x30)
+#define GPIO_OE_6          GPIO1_REG(0x34)
+#define GPIO_OE_7          GPIO1_REG(0x38)
+
+/* same pin map as above, input read */
+#define GPIO_IN_0          GPIO1_REG(0x50)
+#define GPIO_IN_1          GPIO2_REG(0x20)
+#define GPIO_IN_2          GPIO1_REG(0x54)
+#define GPIO_IN_3          GPIO1_REG(0x58)
+#define GPIO_IN_4          GPIO1_REG(0x5C)
+#define GPIO_IN_5          GPIO1_REG(0x60)
+#define GPIO_IN_6          GPIO1_REG(0x64)
+#define GPIO_IN_7          GPIO1_REG(0x68)
+
+/* same pin map as above, 1=edge 0=level interrup */
+#define GPIO_INT_EDGE_0    GPIO1_REG(0x70)
+#define GPIO_INT_EDGE_1    GPIO2_REG(0x50)
+#define GPIO_INT_EDGE_2    GPIO1_REG(0x74)
+#define GPIO_INT_EDGE_3    GPIO1_REG(0x78)
+#define GPIO_INT_EDGE_4    GPIO1_REG(0x7C)
+#define GPIO_INT_EDGE_5    GPIO1_REG(0x80)
+#define GPIO_INT_EDGE_6    GPIO1_REG(0x84)
+#define GPIO_INT_EDGE_7    GPIO1_REG(0x88)
+
+/* same pin map as above, 1=positive 0=negative */
+#define GPIO_INT_POS_0     GPIO1_REG(0x90)
+#define GPIO_INT_POS_1     GPIO2_REG(0x58)
+#define GPIO_INT_POS_2     GPIO1_REG(0x94)
+#define GPIO_INT_POS_3     GPIO1_REG(0x98)
+#define GPIO_INT_POS_4     GPIO1_REG(0x9C)
+#define GPIO_INT_POS_5     GPIO1_REG(0xA0)
+#define GPIO_INT_POS_6     GPIO1_REG(0xA4)
+#define GPIO_INT_POS_7     GPIO1_REG(0xA8)
+
+/* same pin map as above, interrupt enable */
+#define GPIO_INT_EN_0      GPIO1_REG(0xB0)
+#define GPIO_INT_EN_1      GPIO2_REG(0x60)
+#define GPIO_INT_EN_2      GPIO1_REG(0xB4)
+#define GPIO_INT_EN_3      GPIO1_REG(0xB8)
+#define GPIO_INT_EN_4      GPIO1_REG(0xBC)
+#define GPIO_INT_EN_5      GPIO1_REG(0xC0)
+#define GPIO_INT_EN_6      GPIO1_REG(0xC4)
+#define GPIO_INT_EN_7      GPIO1_REG(0xC8)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define GPIO_INT_CLEAR_0   GPIO1_REG(0xD0)
+#define GPIO_INT_CLEAR_1   GPIO2_REG(0x68)
+#define GPIO_INT_CLEAR_2   GPIO1_REG(0xD4)
+#define GPIO_INT_CLEAR_3   GPIO1_REG(0xD8)
+#define GPIO_INT_CLEAR_4   GPIO1_REG(0xDC)
+#define GPIO_INT_CLEAR_5   GPIO1_REG(0xE0)
+#define GPIO_INT_CLEAR_6   GPIO1_REG(0xE4)
+#define GPIO_INT_CLEAR_7   GPIO1_REG(0xE8)
+
+/* same pin map as above, 1=interrupt pending */
+#define GPIO_INT_STATUS_0  GPIO1_REG(0xF0)
+#define GPIO_INT_STATUS_1  GPIO2_REG(0x70)
+#define GPIO_INT_STATUS_2  GPIO1_REG(0xF4)
+#define GPIO_INT_STATUS_3  GPIO1_REG(0xF8)
+#define GPIO_INT_STATUS_4  GPIO1_REG(0xFC)
+#define GPIO_INT_STATUS_5  GPIO1_REG(0x100)
+#define GPIO_INT_STATUS_6  GPIO1_REG(0x104)
+#define GPIO_INT_STATUS_7  GPIO1_REG(0x108)
+
+#endif
+
+#if defined(CONFIG_ARCH_MSM7X30)
+
+/* output value */
+#define GPIO_OUT_0         GPIO1_REG(0x00)   /* gpio  15-0   */
+#define GPIO_OUT_1         GPIO2_REG(0x00)   /* gpio  43-16  */
+#define GPIO_OUT_2         GPIO1_REG(0x04)   /* gpio  67-44  */
+#define GPIO_OUT_3         GPIO1_REG(0x08)   /* gpio  94-68  */
+#define GPIO_OUT_4         GPIO1_REG(0x0C)   /* gpio 106-95  */
+#define GPIO_OUT_5         GPIO1_REG(0x50)   /* gpio 133-107 */
+#define GPIO_OUT_6         GPIO1_REG(0xC4)   /* gpio 150-134 */
+#define GPIO_OUT_7         GPIO1_REG(0x214)  /* gpio 181-151 */
+
+/* same pin map as above, output enable */
+#define GPIO_OE_0          GPIO1_REG(0x10)
+#define GPIO_OE_1          GPIO2_REG(0x08)
+#define GPIO_OE_2          GPIO1_REG(0x14)
+#define GPIO_OE_3          GPIO1_REG(0x18)
+#define GPIO_OE_4          GPIO1_REG(0x1C)
+#define GPIO_OE_5          GPIO1_REG(0x54)
+#define GPIO_OE_6          GPIO1_REG(0xC8)
+#define GPIO_OE_7          GPIO1_REG(0x218)
+
+/* same pin map as above, input read */
+#define GPIO_IN_0          GPIO1_REG(0x34)
+#define GPIO_IN_1          GPIO2_REG(0x20)
+#define GPIO_IN_2          GPIO1_REG(0x38)
+#define GPIO_IN_3          GPIO1_REG(0x3C)
+#define GPIO_IN_4          GPIO1_REG(0x40)
+#define GPIO_IN_5          GPIO1_REG(0x44)
+#define GPIO_IN_6          GPIO1_REG(0xCC)
+#define GPIO_IN_7          GPIO1_REG(0x21C)
+
+/* same pin map as above, 1=edge 0=level interrup */
+#define GPIO_INT_EDGE_0    GPIO1_REG(0x60)
+#define GPIO_INT_EDGE_1    GPIO2_REG(0x50)
+#define GPIO_INT_EDGE_2    GPIO1_REG(0x64)
+#define GPIO_INT_EDGE_3    GPIO1_REG(0x68)
+#define GPIO_INT_EDGE_4    GPIO1_REG(0x6C)
+#define GPIO_INT_EDGE_5    GPIO1_REG(0xC0)
+#define GPIO_INT_EDGE_6    GPIO1_REG(0xD0)
+#define GPIO_INT_EDGE_7    GPIO1_REG(0x240)
+
+/* same pin map as above, 1=positive 0=negative */
+#define GPIO_INT_POS_0     GPIO1_REG(0x70)
+#define GPIO_INT_POS_1     GPIO2_REG(0x58)
+#define GPIO_INT_POS_2     GPIO1_REG(0x74)
+#define GPIO_INT_POS_3     GPIO1_REG(0x78)
+#define GPIO_INT_POS_4     GPIO1_REG(0x7C)
+#define GPIO_INT_POS_5     GPIO1_REG(0xBC)
+#define GPIO_INT_POS_6     GPIO1_REG(0xD4)
+#define GPIO_INT_POS_7     GPIO1_REG(0x228)
+
+/* same pin map as above, interrupt enable */
+#define GPIO_INT_EN_0      GPIO1_REG(0x80)
+#define GPIO_INT_EN_1      GPIO2_REG(0x60)
+#define GPIO_INT_EN_2      GPIO1_REG(0x84)
+#define GPIO_INT_EN_3      GPIO1_REG(0x88)
+#define GPIO_INT_EN_4      GPIO1_REG(0x8C)
+#define GPIO_INT_EN_5      GPIO1_REG(0xB8)
+#define GPIO_INT_EN_6      GPIO1_REG(0xD8)
+#define GPIO_INT_EN_7      GPIO1_REG(0x22C)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define GPIO_INT_CLEAR_0   GPIO1_REG(0x90)
+#define GPIO_INT_CLEAR_1   GPIO2_REG(0x68)
+#define GPIO_INT_CLEAR_2   GPIO1_REG(0x94)
+#define GPIO_INT_CLEAR_3   GPIO1_REG(0x98)
+#define GPIO_INT_CLEAR_4   GPIO1_REG(0x9C)
+#define GPIO_INT_CLEAR_5   GPIO1_REG(0xB4)
+#define GPIO_INT_CLEAR_6   GPIO1_REG(0xDC)
+#define GPIO_INT_CLEAR_7   GPIO1_REG(0x230)
+
+/* same pin map as above, 1=interrupt pending */
+#define GPIO_INT_STATUS_0  GPIO1_REG(0xA0)
+#define GPIO_INT_STATUS_1  GPIO2_REG(0x70)
+#define GPIO_INT_STATUS_2  GPIO1_REG(0xA4)
+#define GPIO_INT_STATUS_3  GPIO1_REG(0xA8)
+#define GPIO_INT_STATUS_4  GPIO1_REG(0xAC)
+#define GPIO_INT_STATUS_5  GPIO1_REG(0xB0)
+#define GPIO_INT_STATUS_6  GPIO1_REG(0xE0)
+#define GPIO_INT_STATUS_7  GPIO1_REG(0x234)
+
+#endif
+
+#endif
-- 
1.7.0.4

--
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

* [PATCH 2/2] msm: gpio: Add gpiomux calls to request and free.
  2010-08-31  0:18 ` Gregory Bean
@ 2010-08-31  0:18   ` Gregory Bean
  -1 siblings, 0 replies; 17+ messages in thread
From: Gregory Bean @ 2010-08-31  0:18 UTC (permalink / raw)
  To: dwalker; +Cc: linux-arm-msm, linux-arm-kernel, linux-kernel, Gregory Bean

Add gpiomux get and put calls to msmgpio request and free,
in order to allow gpio lines to be properly reference-counted
and power-managed.

Signed-off-by: Gregory Bean <gbean@codeaurora.org>
---
 arch/arm/mach-msm/gpio.c |   27 +++++++++++++++++++++++++++
 1 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-msm/gpio.c b/arch/arm/mach-msm/gpio.c
index fd899a1..ea93ecb 100644
--- a/arch/arm/mach-msm/gpio.c
+++ b/arch/arm/mach-msm/gpio.c
@@ -21,6 +21,7 @@
 #include <linux/irq.h>
 #include <linux/module.h>
 #include "gpio_hw.h"
+#include "gpiomux.h"
 #include "proc_comm.h"
 #include "smd_private.h"
 
@@ -157,6 +158,16 @@ static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 	return MSM_GPIO_TO_INT(chip->base + offset);
 }
 
+static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+        return msm_gpiomux_get(chip->base + offset);
+}
+
+static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+        msm_gpiomux_put(chip->base + offset);
+}
+
 struct msm_gpio_chip msm_gpio_chips[] = {
 	{
 		.regs = {
@@ -177,6 +188,8 @@ struct msm_gpio_chip msm_gpio_chips[] = {
 			.direction_input = msm_gpio_direction_input,
 			.direction_output = msm_gpio_direction_output,
 			.to_irq = msm_gpio_to_irq,
+			.request = msm_gpio_request,
+			.free = msm_gpio_free,
 		}
 	},
 	{
@@ -202,6 +215,8 @@ struct msm_gpio_chip msm_gpio_chips[] = {
 			.direction_input = msm_gpio_direction_input,
 			.direction_output = msm_gpio_direction_output,
 			.to_irq = msm_gpio_to_irq,
+			.request = msm_gpio_request,
+			.free = msm_gpio_free,
 		}
 	},
 	{
@@ -228,6 +243,8 @@ struct msm_gpio_chip msm_gpio_chips[] = {
 			.direction_input = msm_gpio_direction_input,
 			.direction_output = msm_gpio_direction_output,
 			.to_irq = msm_gpio_to_irq,
+			.request = msm_gpio_request,
+			.free = msm_gpio_free,
 		}
 	},
 	{
@@ -249,6 +266,8 @@ struct msm_gpio_chip msm_gpio_chips[] = {
 			.direction_input = msm_gpio_direction_input,
 			.direction_output = msm_gpio_direction_output,
 			.to_irq = msm_gpio_to_irq,
+			.request = msm_gpio_request,
+			.free = msm_gpio_free,
 		}
 	},
 	{
@@ -274,6 +293,8 @@ struct msm_gpio_chip msm_gpio_chips[] = {
 			.direction_input = msm_gpio_direction_input,
 			.direction_output = msm_gpio_direction_output,
 			.to_irq = msm_gpio_to_irq,
+			.request = msm_gpio_request,
+			.free = msm_gpio_free,
 		}
 	},
 	{
@@ -306,6 +327,8 @@ struct msm_gpio_chip msm_gpio_chips[] = {
 			.direction_input = msm_gpio_direction_input,
 			.direction_output = msm_gpio_direction_output,
 			.to_irq = msm_gpio_to_irq,
+			.request = msm_gpio_request,
+			.free = msm_gpio_free,
 		}
 	},
 #if defined(CONFIG_ARCH_QSD8X50) || defined(CONFIG_ARCH_MSM7X30)
@@ -333,6 +356,8 @@ struct msm_gpio_chip msm_gpio_chips[] = {
 			.direction_input = msm_gpio_direction_input,
 			.direction_output = msm_gpio_direction_output,
 			.to_irq = msm_gpio_to_irq,
+			.request = msm_gpio_request,
+			.free = msm_gpio_free,
 		}
 	},
 	{
@@ -359,6 +384,8 @@ struct msm_gpio_chip msm_gpio_chips[] = {
 			.direction_input = msm_gpio_direction_input,
 			.direction_output = msm_gpio_direction_output,
 			.to_irq = msm_gpio_to_irq,
+			.request = msm_gpio_request,
+			.free = msm_gpio_free,
 		}
 	},
 #endif
-- 
1.7.0.4

--
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

* [PATCH 2/2] msm: gpio: Add gpiomux calls to request and free.
@ 2010-08-31  0:18   ` Gregory Bean
  0 siblings, 0 replies; 17+ messages in thread
From: Gregory Bean @ 2010-08-31  0:18 UTC (permalink / raw)
  To: linux-arm-kernel

Add gpiomux get and put calls to msmgpio request and free,
in order to allow gpio lines to be properly reference-counted
and power-managed.

Signed-off-by: Gregory Bean <gbean@codeaurora.org>
---
 arch/arm/mach-msm/gpio.c |   27 +++++++++++++++++++++++++++
 1 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-msm/gpio.c b/arch/arm/mach-msm/gpio.c
index fd899a1..ea93ecb 100644
--- a/arch/arm/mach-msm/gpio.c
+++ b/arch/arm/mach-msm/gpio.c
@@ -21,6 +21,7 @@
 #include <linux/irq.h>
 #include <linux/module.h>
 #include "gpio_hw.h"
+#include "gpiomux.h"
 #include "proc_comm.h"
 #include "smd_private.h"
 
@@ -157,6 +158,16 @@ static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 	return MSM_GPIO_TO_INT(chip->base + offset);
 }
 
+static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+        return msm_gpiomux_get(chip->base + offset);
+}
+
+static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+        msm_gpiomux_put(chip->base + offset);
+}
+
 struct msm_gpio_chip msm_gpio_chips[] = {
 	{
 		.regs = {
@@ -177,6 +188,8 @@ struct msm_gpio_chip msm_gpio_chips[] = {
 			.direction_input = msm_gpio_direction_input,
 			.direction_output = msm_gpio_direction_output,
 			.to_irq = msm_gpio_to_irq,
+			.request = msm_gpio_request,
+			.free = msm_gpio_free,
 		}
 	},
 	{
@@ -202,6 +215,8 @@ struct msm_gpio_chip msm_gpio_chips[] = {
 			.direction_input = msm_gpio_direction_input,
 			.direction_output = msm_gpio_direction_output,
 			.to_irq = msm_gpio_to_irq,
+			.request = msm_gpio_request,
+			.free = msm_gpio_free,
 		}
 	},
 	{
@@ -228,6 +243,8 @@ struct msm_gpio_chip msm_gpio_chips[] = {
 			.direction_input = msm_gpio_direction_input,
 			.direction_output = msm_gpio_direction_output,
 			.to_irq = msm_gpio_to_irq,
+			.request = msm_gpio_request,
+			.free = msm_gpio_free,
 		}
 	},
 	{
@@ -249,6 +266,8 @@ struct msm_gpio_chip msm_gpio_chips[] = {
 			.direction_input = msm_gpio_direction_input,
 			.direction_output = msm_gpio_direction_output,
 			.to_irq = msm_gpio_to_irq,
+			.request = msm_gpio_request,
+			.free = msm_gpio_free,
 		}
 	},
 	{
@@ -274,6 +293,8 @@ struct msm_gpio_chip msm_gpio_chips[] = {
 			.direction_input = msm_gpio_direction_input,
 			.direction_output = msm_gpio_direction_output,
 			.to_irq = msm_gpio_to_irq,
+			.request = msm_gpio_request,
+			.free = msm_gpio_free,
 		}
 	},
 	{
@@ -306,6 +327,8 @@ struct msm_gpio_chip msm_gpio_chips[] = {
 			.direction_input = msm_gpio_direction_input,
 			.direction_output = msm_gpio_direction_output,
 			.to_irq = msm_gpio_to_irq,
+			.request = msm_gpio_request,
+			.free = msm_gpio_free,
 		}
 	},
 #if defined(CONFIG_ARCH_QSD8X50) || defined(CONFIG_ARCH_MSM7X30)
@@ -333,6 +356,8 @@ struct msm_gpio_chip msm_gpio_chips[] = {
 			.direction_input = msm_gpio_direction_input,
 			.direction_output = msm_gpio_direction_output,
 			.to_irq = msm_gpio_to_irq,
+			.request = msm_gpio_request,
+			.free = msm_gpio_free,
 		}
 	},
 	{
@@ -359,6 +384,8 @@ struct msm_gpio_chip msm_gpio_chips[] = {
 			.direction_input = msm_gpio_direction_input,
 			.direction_output = msm_gpio_direction_output,
 			.to_irq = msm_gpio_to_irq,
+			.request = msm_gpio_request,
+			.free = msm_gpio_free,
 		}
 	},
 #endif
-- 
1.7.0.4

--
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

* Re: [PATCH 1/2] msm: Install the Google-Android gpio driver.
  2010-08-31  0:18 ` Gregory Bean
@ 2010-08-31 16:46   ` Daniel Walker
  -1 siblings, 0 replies; 17+ messages in thread
From: Daniel Walker @ 2010-08-31 16:46 UTC (permalink / raw)
  To: Gregory Bean
  Cc: linux-arm-msm, linux-arm-kernel, linux-kernel, Arve Hjønnevåg

On Mon, 2010-08-30 at 17:18 -0700, Gregory Bean wrote:
> struct msm_gpio_chip msm_gpio_chips[] = {
> +       {
> +               .regs = {
> +                       .out =         GPIO_OUT_0,
> +                       .in =          GPIO_IN_0,
> +                       .int_status =  GPIO_INT_STATUS_0,
> +                       .int_clear =   GPIO_INT_CLEAR_0,
> +                       .int_en =      GPIO_INT_EN_0,
> +                       .int_edge =    GPIO_INT_EDGE_0,
> +                       .int_pos =     GPIO_INT_POS_0,
> +                       .oe =          GPIO_OE_0,
> +               }, 

Macro please.

Daniel

-- 

Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


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

* [PATCH 1/2] msm: Install the Google-Android gpio driver.
@ 2010-08-31 16:46   ` Daniel Walker
  0 siblings, 0 replies; 17+ messages in thread
From: Daniel Walker @ 2010-08-31 16:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2010-08-30 at 17:18 -0700, Gregory Bean wrote:
> struct msm_gpio_chip msm_gpio_chips[] = {
> +       {
> +               .regs = {
> +                       .out =         GPIO_OUT_0,
> +                       .in =          GPIO_IN_0,
> +                       .int_status =  GPIO_INT_STATUS_0,
> +                       .int_clear =   GPIO_INT_CLEAR_0,
> +                       .int_en =      GPIO_INT_EN_0,
> +                       .int_edge =    GPIO_INT_EDGE_0,
> +                       .int_pos =     GPIO_INT_POS_0,
> +                       .oe =          GPIO_OE_0,
> +               }, 

Macro please.

Daniel

-- 

Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

* Re: [PATCH 1/2] msm: Install the Google-Android gpio driver.
  2010-08-31  0:18 ` Gregory Bean
@ 2010-08-31 16:50   ` Daniel Walker
  -1 siblings, 0 replies; 17+ messages in thread
From: Daniel Walker @ 2010-08-31 16:50 UTC (permalink / raw)
  To: Gregory Bean
  Cc: linux-arm-msm, linux-arm-kernel, linux-kernel, Arve Hjønnevåg

On Mon, 2010-08-30 at 17:18 -0700, Gregory Bean wrote:
> +                       /* printk("%s %08x %08x bit %d gpio %d irq %d\n",
> +                               __func__, v, m, j, msm_chip->chip.start + j,
> +                               FIRST_GPIO_IRQ + msm_chip->chip.start + j); */
> 

Can you drop everything that's un-used .. There's also the enter/exit
sleep functions, which I'm pretty sure aren't used. Also break this into
two patches one for gpio and another for the interrupt component ..

Daniel

-- 

Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


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

* [PATCH 1/2] msm: Install the Google-Android gpio driver.
@ 2010-08-31 16:50   ` Daniel Walker
  0 siblings, 0 replies; 17+ messages in thread
From: Daniel Walker @ 2010-08-31 16:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2010-08-30 at 17:18 -0700, Gregory Bean wrote:
> +                       /* printk("%s %08x %08x bit %d gpio %d irq %d\n",
> +                               __func__, v, m, j, msm_chip->chip.start + j,
> +                               FIRST_GPIO_IRQ + msm_chip->chip.start + j); */
> 

Can you drop everything that's un-used .. There's also the enter/exit
sleep functions, which I'm pretty sure aren't used. Also break this into
two patches one for gpio and another for the interrupt component ..

Daniel

-- 

Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

* Re: [PATCH 1/2] msm: Install the Google-Android gpio driver.
  2010-08-31  0:18 ` Gregory Bean
@ 2010-08-31 21:50   ` Daniel Walker
  -1 siblings, 0 replies; 17+ messages in thread
From: Daniel Walker @ 2010-08-31 21:50 UTC (permalink / raw)
  To: Arve Hjønnevåg
  Cc: linux-arm-msm, linux-arm-kernel, linux-kernel, Gregory Bean

On Mon, 2010-08-30 at 17:18 -0700, Gregory Bean wrote:
> From: Arve Hjønnevåg <arve@android.com>
> 
> As part of the ongoing effort to converge on a common code base,
> adopt the Google-Android msmgpio driver, as it has a stronger pedigree
> than the previous submission from codeaurora.
> 
> Cc: Arve Hjønnevåg <arve@android.com>

Arve, Are you planning to move this forward or is Greg going to? I've
asked Greg (or you) for some changes to this.. If you have a problem
with the changes please speak up ..

The signed-off is wrong on this commit also, You need to sign off on the
commit (and Greg if needed).

Daniel


-- 

Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


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

* [PATCH 1/2] msm: Install the Google-Android gpio driver.
@ 2010-08-31 21:50   ` Daniel Walker
  0 siblings, 0 replies; 17+ messages in thread
From: Daniel Walker @ 2010-08-31 21:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2010-08-30 at 17:18 -0700, Gregory Bean wrote:
> From: Arve Hj?nnev?g <arve@android.com>
> 
> As part of the ongoing effort to converge on a common code base,
> adopt the Google-Android msmgpio driver, as it has a stronger pedigree
> than the previous submission from codeaurora.
> 
> Cc: Arve Hj?nnev?g <arve@android.com>

Arve, Are you planning to move this forward or is Greg going to? I've
asked Greg (or you) for some changes to this.. If you have a problem
with the changes please speak up ..

The signed-off is wrong on this commit also, You need to sign off on the
commit (and Greg if needed).

Daniel


-- 

Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

* RE: [PATCH 1/2] msm: Install the Google-Android gpio driver.
  2010-08-31  0:18 ` Gregory Bean
  (?)
@ 2010-09-01 18:59   ` H Hartley Sweeten
  -1 siblings, 0 replies; 17+ messages in thread
From: H Hartley Sweeten @ 2010-09-01 18:59 UTC (permalink / raw)
  To: Gregory Bean, dwalker
  Cc: linux-arm-msm, Arve Hjønnevåg, linux-kernel, linux-arm-kernel

On Monday, August 30, 2010 5:18 PM, Gregory Bean wrote:
> Subject: [PATCH 1/2] msm: Install the Google-Android gpio driver.
> 
> From: Arve Hjønnevåg <arve@android.com>
> 
> As part of the ongoing effort to converge on a common code base,
> adopt the Google-Android msmgpio driver, as it has a stronger pedigree
> than the previous submission from codeaurora.
> 
> Cc: Arve Hjønnevåg <arve@android.com>
> Signed-off-by: Gregory Bean <gbean@codeaurora.org>

Hello Greg,

A couple comments on this.

> +struct msm_gpio_chip msm_gpio_chips[] = {
> +	{
> +		.regs = {
> +			.out =         GPIO_OUT_0,
> +			.in =          GPIO_IN_0,
> +			.int_status =  GPIO_INT_STATUS_0,
> +			.int_clear =   GPIO_INT_CLEAR_0,
> +			.int_en =      GPIO_INT_EN_0,
> +			.int_edge =    GPIO_INT_EDGE_0,
> +			.int_pos =     GPIO_INT_POS_0,
> +			.oe =          GPIO_OE_0,
> +		},
> +		.chip = {
> +			.base = 0,
> +			.ngpio = 16,
> +			.get = msm_gpio_get,
> +			.set = msm_gpio_set,
> +			.direction_input = msm_gpio_direction_input,
> +			.direction_output = msm_gpio_direction_output,
> +			.to_irq = msm_gpio_to_irq,
> +		}
> +	},

This is a bit ugly... A 204 line struct definition is a bit hard to follow,
especially the way it's broken up with all the #if defined stuff.

Each gpio "bank" is code duplication other than the .base and .ngpio.  The
whole thing can be reduced using a helper macro.  Something like this:

#define MSM_GPIO_BANK(bank, base_gpio, num_gpio)			\
	{										\
		.regs = {								\
			.out			= GPIO_OUT_##bank,		\
			.in			= GPIO_IN_##bank,			\
			.int_status		= GPIO_INT_STATUS_##bank,	\
			.int_clear		= GPIO_INT_CLEAR_##bank,	\
			.int_en		= GPIO_INT_EN_##bank,		\
			.int_edge		= GPIO_INT_EDGE_##bank,		\
			.int_pos		= GPIO_INT_POS_##bank,		\
			.oe			= GPIO_OE_##bank,			\
		},									\
		.chip = {								\
			.direction_input	= msm_gpio_direction_input,	\
			.direction_output	= msm_gpio_direction_output,	\
			.get			= msm_gpio_get,			\
			.set			= msm_gpio_set,			\
			.to_irq		= msm_gpio_to_irq,		\
			.base			= base_gpio,			\
			.ngpio		= num_gpio,				\
		},									\
	}

Then the struct definition can be reduced to this:

struct msm_gpio_chip msm_gpio_chips[] = {
#if defined(CONFIG_ARCH_MSM7X30)
	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
	MSM_GPIO_BANK(1, 16, 28),	/* gpio 16-43 */
	MSM_GPIO_BANK(2, 44, 24),	/* gpio 44-67 */
	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
	MSM_GPIO_BANK(4, 95, 12),	/* gpio 95-106 */
	MSM_GPIO_BANK(5, 107, 27),	/* gpio 107-133 */
	MSM_GPIO_BANK(6, 134, 17),	/* gpio 134-150 */
	MSM_GPIO_BANK(7, 151, 31),	/* gpio 151-181 */
#elif defined(CONFIG_ARCH_QSD8X50)
	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
	MSM_GPIO_BANK(1, 16, 27),	/* gpio 16-42 */
	MSM_GPIO_BANK(2, 43, 25),	/* gpio 43-67 */
	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
	MSM_GPIO_BANK(4, 95, 9),	/* gpio 95-103 */
	MSM_GPIO_BANK(5, 104, 18),	/* gpio 104-121 */
	MSM_GPIO_BANK(6, 122, 31),	/* gpio 122-152 */
	MSM_GPIO_BANK(7, 153, 12),	/* gpio 153-164 */
#else
	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
	MSM_GPIO_BANK(1, 16, 27),	/* gpio 16-42 */
	MSM_GPIO_BANK(2, 43, 25),	/* gpio 43-67 */
	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
	MSM_GPIO_BANK(4, 95, 12),	/* gpio 95-106 */
	MSM_GPIO_BANK(5, 107, 15),	/* gpio 107-121 */
#endif
};

I'm not sure if that macro will actually work correctly.  But you should
get the idea.

> +#if defined(CONFIG_ARCH_MSM7X30)
> +#define GPIO1_REG(off) (MSM_GPIO1_BASE + (off))
> +#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off))
> +#else
> +#define GPIO1_REG(off) (MSM_GPIO1_BASE + 0x800 + (off))
> +#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0xC00 + (off))
> +#endif
> +
> +#if defined(CONFIG_ARCH_MSM7X00A) || defined(CONFIG_ARCH_MSM7X27)
> +
> +/* output value */
> +#define GPIO_OUT_0         GPIO1_REG(0x00)  /* gpio  15-0  */
> +#define GPIO_OUT_1         GPIO2_REG(0x00)  /* gpio  42-16 */
> +#define GPIO_OUT_2         GPIO1_REG(0x04)  /* gpio  67-43 */
> +#define GPIO_OUT_3         GPIO1_REG(0x08)  /* gpio  94-68 */
> +#define GPIO_OUT_4         GPIO1_REG(0x0C)  /* gpio 106-95 */
> +#define GPIO_OUT_5         GPIO1_REG(0x50)  /* gpio 107-121 */

I realize this header is private (i.e. in the mach-msm directory) but
you should probably prefix all of these GPIO_* defines with something
to prevent any namespace clashes.

Regards,
Hartley

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

* RE: [PATCH 1/2] msm: Install the Google-Android gpio driver.
@ 2010-09-01 18:59   ` H Hartley Sweeten
  0 siblings, 0 replies; 17+ messages in thread
From: H Hartley Sweeten @ 2010-09-01 18:59 UTC (permalink / raw)
  To: Gregory Bean, dwalker
  Cc: linux-arm-msm, Arve Hjønnevåg, linux-kernel, linux-arm-kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 4479 bytes --]

On Monday, August 30, 2010 5:18 PM, Gregory Bean wrote:
> Subject: [PATCH 1/2] msm: Install the Google-Android gpio driver.
> 
> From: Arve Hjønnevåg <arve@android.com>
> 
> As part of the ongoing effort to converge on a common code base,
> adopt the Google-Android msmgpio driver, as it has a stronger pedigree
> than the previous submission from codeaurora.
> 
> Cc: Arve Hjønnevåg <arve@android.com>
> Signed-off-by: Gregory Bean <gbean@codeaurora.org>

Hello Greg,

A couple comments on this.

> +struct msm_gpio_chip msm_gpio_chips[] = {
> +	{
> +		.regs = {
> +			.out =         GPIO_OUT_0,
> +			.in =          GPIO_IN_0,
> +			.int_status =  GPIO_INT_STATUS_0,
> +			.int_clear =   GPIO_INT_CLEAR_0,
> +			.int_en =      GPIO_INT_EN_0,
> +			.int_edge =    GPIO_INT_EDGE_0,
> +			.int_pos =     GPIO_INT_POS_0,
> +			.oe =          GPIO_OE_0,
> +		},
> +		.chip = {
> +			.base = 0,
> +			.ngpio = 16,
> +			.get = msm_gpio_get,
> +			.set = msm_gpio_set,
> +			.direction_input = msm_gpio_direction_input,
> +			.direction_output = msm_gpio_direction_output,
> +			.to_irq = msm_gpio_to_irq,
> +		}
> +	},

This is a bit ugly... A 204 line struct definition is a bit hard to follow,
especially the way it's broken up with all the #if defined stuff.

Each gpio "bank" is code duplication other than the .base and .ngpio.  The
whole thing can be reduced using a helper macro.  Something like this:

#define MSM_GPIO_BANK(bank, base_gpio, num_gpio)			\
	{										\
		.regs = {								\
			.out			= GPIO_OUT_##bank,		\
			.in			= GPIO_IN_##bank,			\
			.int_status		= GPIO_INT_STATUS_##bank,	\
			.int_clear		= GPIO_INT_CLEAR_##bank,	\
			.int_en		= GPIO_INT_EN_##bank,		\
			.int_edge		= GPIO_INT_EDGE_##bank,		\
			.int_pos		= GPIO_INT_POS_##bank,		\
			.oe			= GPIO_OE_##bank,			\
		},									\
		.chip = {								\
			.direction_input	= msm_gpio_direction_input,	\
			.direction_output	= msm_gpio_direction_output,	\
			.get			= msm_gpio_get,			\
			.set			= msm_gpio_set,			\
			.to_irq		= msm_gpio_to_irq,		\
			.base			= base_gpio,			\
			.ngpio		= num_gpio,				\
		},									\
	}

Then the struct definition can be reduced to this:

struct msm_gpio_chip msm_gpio_chips[] = {
#if defined(CONFIG_ARCH_MSM7X30)
	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
	MSM_GPIO_BANK(1, 16, 28),	/* gpio 16-43 */
	MSM_GPIO_BANK(2, 44, 24),	/* gpio 44-67 */
	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
	MSM_GPIO_BANK(4, 95, 12),	/* gpio 95-106 */
	MSM_GPIO_BANK(5, 107, 27),	/* gpio 107-133 */
	MSM_GPIO_BANK(6, 134, 17),	/* gpio 134-150 */
	MSM_GPIO_BANK(7, 151, 31),	/* gpio 151-181 */
#elif defined(CONFIG_ARCH_QSD8X50)
	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
	MSM_GPIO_BANK(1, 16, 27),	/* gpio 16-42 */
	MSM_GPIO_BANK(2, 43, 25),	/* gpio 43-67 */
	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
	MSM_GPIO_BANK(4, 95, 9),	/* gpio 95-103 */
	MSM_GPIO_BANK(5, 104, 18),	/* gpio 104-121 */
	MSM_GPIO_BANK(6, 122, 31),	/* gpio 122-152 */
	MSM_GPIO_BANK(7, 153, 12),	/* gpio 153-164 */
#else
	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
	MSM_GPIO_BANK(1, 16, 27),	/* gpio 16-42 */
	MSM_GPIO_BANK(2, 43, 25),	/* gpio 43-67 */
	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
	MSM_GPIO_BANK(4, 95, 12),	/* gpio 95-106 */
	MSM_GPIO_BANK(5, 107, 15),	/* gpio 107-121 */
#endif
};

I'm not sure if that macro will actually work correctly.  But you should
get the idea.

> +#if defined(CONFIG_ARCH_MSM7X30)
> +#define GPIO1_REG(off) (MSM_GPIO1_BASE + (off))
> +#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off))
> +#else
> +#define GPIO1_REG(off) (MSM_GPIO1_BASE + 0x800 + (off))
> +#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0xC00 + (off))
> +#endif
> +
> +#if defined(CONFIG_ARCH_MSM7X00A) || defined(CONFIG_ARCH_MSM7X27)
> +
> +/* output value */
> +#define GPIO_OUT_0         GPIO1_REG(0x00)  /* gpio  15-0  */
> +#define GPIO_OUT_1         GPIO2_REG(0x00)  /* gpio  42-16 */
> +#define GPIO_OUT_2         GPIO1_REG(0x04)  /* gpio  67-43 */
> +#define GPIO_OUT_3         GPIO1_REG(0x08)  /* gpio  94-68 */
> +#define GPIO_OUT_4         GPIO1_REG(0x0C)  /* gpio 106-95 */
> +#define GPIO_OUT_5         GPIO1_REG(0x50)  /* gpio 107-121 */

I realize this header is private (i.e. in the mach-msm directory) but
you should probably prefix all of these GPIO_* defines with something
to prevent any namespace clashes.

Regards,
Hartleyÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* [PATCH 1/2] msm: Install the Google-Android gpio driver.
@ 2010-09-01 18:59   ` H Hartley Sweeten
  0 siblings, 0 replies; 17+ messages in thread
From: H Hartley Sweeten @ 2010-09-01 18:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday, August 30, 2010 5:18 PM, Gregory Bean wrote:
> Subject: [PATCH 1/2] msm: Install the Google-Android gpio driver.
> 
> From: Arve Hj?nnev?g <arve@android.com>
> 
> As part of the ongoing effort to converge on a common code base,
> adopt the Google-Android msmgpio driver, as it has a stronger pedigree
> than the previous submission from codeaurora.
> 
> Cc: Arve Hj?nnev?g <arve@android.com>
> Signed-off-by: Gregory Bean <gbean@codeaurora.org>

Hello Greg,

A couple comments on this.

> +struct msm_gpio_chip msm_gpio_chips[] = {
> +	{
> +		.regs = {
> +			.out =         GPIO_OUT_0,
> +			.in =          GPIO_IN_0,
> +			.int_status =  GPIO_INT_STATUS_0,
> +			.int_clear =   GPIO_INT_CLEAR_0,
> +			.int_en =      GPIO_INT_EN_0,
> +			.int_edge =    GPIO_INT_EDGE_0,
> +			.int_pos =     GPIO_INT_POS_0,
> +			.oe =          GPIO_OE_0,
> +		},
> +		.chip = {
> +			.base = 0,
> +			.ngpio = 16,
> +			.get = msm_gpio_get,
> +			.set = msm_gpio_set,
> +			.direction_input = msm_gpio_direction_input,
> +			.direction_output = msm_gpio_direction_output,
> +			.to_irq = msm_gpio_to_irq,
> +		}
> +	},

This is a bit ugly... A 204 line struct definition is a bit hard to follow,
especially the way it's broken up with all the #if defined stuff.

Each gpio "bank" is code duplication other than the .base and .ngpio.  The
whole thing can be reduced using a helper macro.  Something like this:

#define MSM_GPIO_BANK(bank, base_gpio, num_gpio)			\
	{										\
		.regs = {								\
			.out			= GPIO_OUT_##bank,		\
			.in			= GPIO_IN_##bank,			\
			.int_status		= GPIO_INT_STATUS_##bank,	\
			.int_clear		= GPIO_INT_CLEAR_##bank,	\
			.int_en		= GPIO_INT_EN_##bank,		\
			.int_edge		= GPIO_INT_EDGE_##bank,		\
			.int_pos		= GPIO_INT_POS_##bank,		\
			.oe			= GPIO_OE_##bank,			\
		},									\
		.chip = {								\
			.direction_input	= msm_gpio_direction_input,	\
			.direction_output	= msm_gpio_direction_output,	\
			.get			= msm_gpio_get,			\
			.set			= msm_gpio_set,			\
			.to_irq		= msm_gpio_to_irq,		\
			.base			= base_gpio,			\
			.ngpio		= num_gpio,				\
		},									\
	}

Then the struct definition can be reduced to this:

struct msm_gpio_chip msm_gpio_chips[] = {
#if defined(CONFIG_ARCH_MSM7X30)
	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
	MSM_GPIO_BANK(1, 16, 28),	/* gpio 16-43 */
	MSM_GPIO_BANK(2, 44, 24),	/* gpio 44-67 */
	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
	MSM_GPIO_BANK(4, 95, 12),	/* gpio 95-106 */
	MSM_GPIO_BANK(5, 107, 27),	/* gpio 107-133 */
	MSM_GPIO_BANK(6, 134, 17),	/* gpio 134-150 */
	MSM_GPIO_BANK(7, 151, 31),	/* gpio 151-181 */
#elif defined(CONFIG_ARCH_QSD8X50)
	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
	MSM_GPIO_BANK(1, 16, 27),	/* gpio 16-42 */
	MSM_GPIO_BANK(2, 43, 25),	/* gpio 43-67 */
	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
	MSM_GPIO_BANK(4, 95, 9),	/* gpio 95-103 */
	MSM_GPIO_BANK(5, 104, 18),	/* gpio 104-121 */
	MSM_GPIO_BANK(6, 122, 31),	/* gpio 122-152 */
	MSM_GPIO_BANK(7, 153, 12),	/* gpio 153-164 */
#else
	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
	MSM_GPIO_BANK(1, 16, 27),	/* gpio 16-42 */
	MSM_GPIO_BANK(2, 43, 25),	/* gpio 43-67 */
	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
	MSM_GPIO_BANK(4, 95, 12),	/* gpio 95-106 */
	MSM_GPIO_BANK(5, 107, 15),	/* gpio 107-121 */
#endif
};

I'm not sure if that macro will actually work correctly.  But you should
get the idea.

> +#if defined(CONFIG_ARCH_MSM7X30)
> +#define GPIO1_REG(off) (MSM_GPIO1_BASE + (off))
> +#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off))
> +#else
> +#define GPIO1_REG(off) (MSM_GPIO1_BASE + 0x800 + (off))
> +#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0xC00 + (off))
> +#endif
> +
> +#if defined(CONFIG_ARCH_MSM7X00A) || defined(CONFIG_ARCH_MSM7X27)
> +
> +/* output value */
> +#define GPIO_OUT_0         GPIO1_REG(0x00)  /* gpio  15-0  */
> +#define GPIO_OUT_1         GPIO2_REG(0x00)  /* gpio  42-16 */
> +#define GPIO_OUT_2         GPIO1_REG(0x04)  /* gpio  67-43 */
> +#define GPIO_OUT_3         GPIO1_REG(0x08)  /* gpio  94-68 */
> +#define GPIO_OUT_4         GPIO1_REG(0x0C)  /* gpio 106-95 */
> +#define GPIO_OUT_5         GPIO1_REG(0x50)  /* gpio 107-121 */

I realize this header is private (i.e. in the mach-msm directory) but
you should probably prefix all of these GPIO_* defines with something
to prevent any namespace clashes.

Regards,
Hartley

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

* RE: [PATCH 1/2] msm: Install the Google-Android gpio driver.
  2010-09-01 18:59   ` H Hartley Sweeten
@ 2010-09-01 21:13     ` Daniel Walker
  -1 siblings, 0 replies; 17+ messages in thread
From: Daniel Walker @ 2010-09-01 21:13 UTC (permalink / raw)
  To: H Hartley Sweeten
  Cc: Gregory Bean, linux-arm-msm, Arve Hjønnevåg,
	linux-kernel, linux-arm-kernel

On Wed, 2010-09-01 at 13:59 -0500, H Hartley Sweeten wrote:
> On Monday, August 30, 2010 5:18 PM, Gregory Bean wrote:
> > Subject: [PATCH 1/2] msm: Install the Google-Android gpio driver.
> > 
> > From: Arve Hjønnevåg <arve@android.com>
> > 
> > As part of the ongoing effort to converge on a common code base,
> > adopt the Google-Android msmgpio driver, as it has a stronger pedigree
> > than the previous submission from codeaurora.
> > 
> > Cc: Arve Hjønnevåg <arve@android.com>
> > Signed-off-by: Gregory Bean <gbean@codeaurora.org>
> 
> Hello Greg,
> 
> A couple comments on this.
> 
> > +struct msm_gpio_chip msm_gpio_chips[] = {
> > +	{
> > +		.regs = {
> > +			.out =         GPIO_OUT_0,
> > +			.in =          GPIO_IN_0,
> > +			.int_status =  GPIO_INT_STATUS_0,
> > +			.int_clear =   GPIO_INT_CLEAR_0,
> > +			.int_en =      GPIO_INT_EN_0,
> > +			.int_edge =    GPIO_INT_EDGE_0,
> > +			.int_pos =     GPIO_INT_POS_0,
> > +			.oe =          GPIO_OE_0,
> > +		},
> > +		.chip = {
> > +			.base = 0,
> > +			.ngpio = 16,
> > +			.get = msm_gpio_get,
> > +			.set = msm_gpio_set,
> > +			.direction_input = msm_gpio_direction_input,
> > +			.direction_output = msm_gpio_direction_output,
> > +			.to_irq = msm_gpio_to_irq,
> > +		}
> > +	},
> 
> This is a bit ugly... A 204 line struct definition is a bit hard to follow,
> especially the way it's broken up with all the #if defined stuff.
> 
> Each gpio "bank" is code duplication other than the .base and .ngpio.  The
> whole thing can be reduced using a helper macro.  Something like this:
> 
> #define MSM_GPIO_BANK(bank, base_gpio, num_gpio)			\
> 	{										\
> 		.regs = {								\
> 			.out			= GPIO_OUT_##bank,		\
> 			.in			= GPIO_IN_##bank,			\
> 			.int_status		= GPIO_INT_STATUS_##bank,	\
> 			.int_clear		= GPIO_INT_CLEAR_##bank,	\
> 			.int_en		= GPIO_INT_EN_##bank,		\
> 			.int_edge		= GPIO_INT_EDGE_##bank,		\
> 			.int_pos		= GPIO_INT_POS_##bank,		\
> 			.oe			= GPIO_OE_##bank,			\
> 		},									\
> 		.chip = {								\
> 			.direction_input	= msm_gpio_direction_input,	\
> 			.direction_output	= msm_gpio_direction_output,	\
> 			.get			= msm_gpio_get,			\
> 			.set			= msm_gpio_set,			\
> 			.to_irq		= msm_gpio_to_irq,		\
> 			.base			= base_gpio,			\
> 			.ngpio		= num_gpio,				\
> 		},									\
> 	}
> 
> Then the struct definition can be reduced to this:
> 
> struct msm_gpio_chip msm_gpio_chips[] = {
> #if defined(CONFIG_ARCH_MSM7X30)
> 	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
> 	MSM_GPIO_BANK(1, 16, 28),	/* gpio 16-43 */
> 	MSM_GPIO_BANK(2, 44, 24),	/* gpio 44-67 */
> 	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
> 	MSM_GPIO_BANK(4, 95, 12),	/* gpio 95-106 */
> 	MSM_GPIO_BANK(5, 107, 27),	/* gpio 107-133 */
> 	MSM_GPIO_BANK(6, 134, 17),	/* gpio 134-150 */
> 	MSM_GPIO_BANK(7, 151, 31),	/* gpio 151-181 */
> #elif defined(CONFIG_ARCH_QSD8X50)
> 	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
> 	MSM_GPIO_BANK(1, 16, 27),	/* gpio 16-42 */
> 	MSM_GPIO_BANK(2, 43, 25),	/* gpio 43-67 */
> 	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
> 	MSM_GPIO_BANK(4, 95, 9),	/* gpio 95-103 */
> 	MSM_GPIO_BANK(5, 104, 18),	/* gpio 104-121 */
> 	MSM_GPIO_BANK(6, 122, 31),	/* gpio 122-152 */
> 	MSM_GPIO_BANK(7, 153, 12),	/* gpio 153-164 */
> #else
> 	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
> 	MSM_GPIO_BANK(1, 16, 27),	/* gpio 16-42 */
> 	MSM_GPIO_BANK(2, 43, 25),	/* gpio 43-67 */
> 	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
> 	MSM_GPIO_BANK(4, 95, 12),	/* gpio 95-106 */
> 	MSM_GPIO_BANK(5, 107, 15),	/* gpio 107-121 */
> #endif
> };
> 

Yeah, this macro method is much nicer. It drops 204 lines down to less
than half that.. Less duplication and less lines to maintain.

Thanks for the review Hartley.

Daniel

-- 

Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


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

* [PATCH 1/2] msm: Install the Google-Android gpio driver.
@ 2010-09-01 21:13     ` Daniel Walker
  0 siblings, 0 replies; 17+ messages in thread
From: Daniel Walker @ 2010-09-01 21:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 2010-09-01 at 13:59 -0500, H Hartley Sweeten wrote:
> On Monday, August 30, 2010 5:18 PM, Gregory Bean wrote:
> > Subject: [PATCH 1/2] msm: Install the Google-Android gpio driver.
> > 
> > From: Arve Hj?nnev?g <arve@android.com>
> > 
> > As part of the ongoing effort to converge on a common code base,
> > adopt the Google-Android msmgpio driver, as it has a stronger pedigree
> > than the previous submission from codeaurora.
> > 
> > Cc: Arve Hj?nnev?g <arve@android.com>
> > Signed-off-by: Gregory Bean <gbean@codeaurora.org>
> 
> Hello Greg,
> 
> A couple comments on this.
> 
> > +struct msm_gpio_chip msm_gpio_chips[] = {
> > +	{
> > +		.regs = {
> > +			.out =         GPIO_OUT_0,
> > +			.in =          GPIO_IN_0,
> > +			.int_status =  GPIO_INT_STATUS_0,
> > +			.int_clear =   GPIO_INT_CLEAR_0,
> > +			.int_en =      GPIO_INT_EN_0,
> > +			.int_edge =    GPIO_INT_EDGE_0,
> > +			.int_pos =     GPIO_INT_POS_0,
> > +			.oe =          GPIO_OE_0,
> > +		},
> > +		.chip = {
> > +			.base = 0,
> > +			.ngpio = 16,
> > +			.get = msm_gpio_get,
> > +			.set = msm_gpio_set,
> > +			.direction_input = msm_gpio_direction_input,
> > +			.direction_output = msm_gpio_direction_output,
> > +			.to_irq = msm_gpio_to_irq,
> > +		}
> > +	},
> 
> This is a bit ugly... A 204 line struct definition is a bit hard to follow,
> especially the way it's broken up with all the #if defined stuff.
> 
> Each gpio "bank" is code duplication other than the .base and .ngpio.  The
> whole thing can be reduced using a helper macro.  Something like this:
> 
> #define MSM_GPIO_BANK(bank, base_gpio, num_gpio)			\
> 	{										\
> 		.regs = {								\
> 			.out			= GPIO_OUT_##bank,		\
> 			.in			= GPIO_IN_##bank,			\
> 			.int_status		= GPIO_INT_STATUS_##bank,	\
> 			.int_clear		= GPIO_INT_CLEAR_##bank,	\
> 			.int_en		= GPIO_INT_EN_##bank,		\
> 			.int_edge		= GPIO_INT_EDGE_##bank,		\
> 			.int_pos		= GPIO_INT_POS_##bank,		\
> 			.oe			= GPIO_OE_##bank,			\
> 		},									\
> 		.chip = {								\
> 			.direction_input	= msm_gpio_direction_input,	\
> 			.direction_output	= msm_gpio_direction_output,	\
> 			.get			= msm_gpio_get,			\
> 			.set			= msm_gpio_set,			\
> 			.to_irq		= msm_gpio_to_irq,		\
> 			.base			= base_gpio,			\
> 			.ngpio		= num_gpio,				\
> 		},									\
> 	}
> 
> Then the struct definition can be reduced to this:
> 
> struct msm_gpio_chip msm_gpio_chips[] = {
> #if defined(CONFIG_ARCH_MSM7X30)
> 	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
> 	MSM_GPIO_BANK(1, 16, 28),	/* gpio 16-43 */
> 	MSM_GPIO_BANK(2, 44, 24),	/* gpio 44-67 */
> 	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
> 	MSM_GPIO_BANK(4, 95, 12),	/* gpio 95-106 */
> 	MSM_GPIO_BANK(5, 107, 27),	/* gpio 107-133 */
> 	MSM_GPIO_BANK(6, 134, 17),	/* gpio 134-150 */
> 	MSM_GPIO_BANK(7, 151, 31),	/* gpio 151-181 */
> #elif defined(CONFIG_ARCH_QSD8X50)
> 	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
> 	MSM_GPIO_BANK(1, 16, 27),	/* gpio 16-42 */
> 	MSM_GPIO_BANK(2, 43, 25),	/* gpio 43-67 */
> 	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
> 	MSM_GPIO_BANK(4, 95, 9),	/* gpio 95-103 */
> 	MSM_GPIO_BANK(5, 104, 18),	/* gpio 104-121 */
> 	MSM_GPIO_BANK(6, 122, 31),	/* gpio 122-152 */
> 	MSM_GPIO_BANK(7, 153, 12),	/* gpio 153-164 */
> #else
> 	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
> 	MSM_GPIO_BANK(1, 16, 27),	/* gpio 16-42 */
> 	MSM_GPIO_BANK(2, 43, 25),	/* gpio 43-67 */
> 	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
> 	MSM_GPIO_BANK(4, 95, 12),	/* gpio 95-106 */
> 	MSM_GPIO_BANK(5, 107, 15),	/* gpio 107-121 */
> #endif
> };
> 

Yeah, this macro method is much nicer. It drops 204 lines down to less
than half that.. Less duplication and less lines to maintain.

Thanks for the review Hartley.

Daniel

-- 

Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

* Re: [PATCH 1/2] msm: Install the Google-Android gpio driver.
  2010-09-01 21:13     ` Daniel Walker
@ 2010-09-01 21:30       ` Ryan Mallon
  -1 siblings, 0 replies; 17+ messages in thread
From: Ryan Mallon @ 2010-09-01 21:30 UTC (permalink / raw)
  To: Daniel Walker
  Cc: H Hartley Sweeten, linux-arm-msm, Arve Hjønnevåg,
	Gregory Bean, linux-kernel, linux-arm-kernel

On 09/02/2010 09:13 AM, Daniel Walker wrote:
> On Wed, 2010-09-01 at 13:59 -0500, H Hartley Sweeten wrote:
>> On Monday, August 30, 2010 5:18 PM, Gregory Bean wrote:
>>> Subject: [PATCH 1/2] msm: Install the Google-Android gpio driver.
>>>
>>> From: Arve Hjønnevåg <arve@android.com>
>>>
>>> As part of the ongoing effort to converge on a common code base,
>>> adopt the Google-Android msmgpio driver, as it has a stronger pedigree
>>> than the previous submission from codeaurora.
>>>
>>> Cc: Arve Hjønnevåg <arve@android.com>
>>> Signed-off-by: Gregory Bean <gbean@codeaurora.org>
>>
>> Hello Greg,
>>
>> A couple comments on this.
>>
>>> +struct msm_gpio_chip msm_gpio_chips[] = {
>>> +	{
>>> +		.regs = {
>>> +			.out =         GPIO_OUT_0,
>>> +			.in =          GPIO_IN_0,
>>> +			.int_status =  GPIO_INT_STATUS_0,
>>> +			.int_clear =   GPIO_INT_CLEAR_0,
>>> +			.int_en =      GPIO_INT_EN_0,
>>> +			.int_edge =    GPIO_INT_EDGE_0,
>>> +			.int_pos =     GPIO_INT_POS_0,
>>> +			.oe =          GPIO_OE_0,
>>> +		},
>>> +		.chip = {
>>> +			.base = 0,
>>> +			.ngpio = 16,
>>> +			.get = msm_gpio_get,
>>> +			.set = msm_gpio_set,
>>> +			.direction_input = msm_gpio_direction_input,
>>> +			.direction_output = msm_gpio_direction_output,
>>> +			.to_irq = msm_gpio_to_irq,
>>> +		}
>>> +	},
>>
>> This is a bit ugly... A 204 line struct definition is a bit hard to follow,
>> especially the way it's broken up with all the #if defined stuff.
>>
>> Each gpio "bank" is code duplication other than the .base and .ngpio.  The
>> whole thing can be reduced using a helper macro.  Something like this:
>>
>> #define MSM_GPIO_BANK(bank, base_gpio, num_gpio)			\
>> 	{										\
>> 		.regs = {								\
>> 			.out			= GPIO_OUT_##bank,		\
>> 			.in			= GPIO_IN_##bank,			\
>> 			.int_status		= GPIO_INT_STATUS_##bank,	\
>> 			.int_clear		= GPIO_INT_CLEAR_##bank,	\
>> 			.int_en		= GPIO_INT_EN_##bank,		\
>> 			.int_edge		= GPIO_INT_EDGE_##bank,		\
>> 			.int_pos		= GPIO_INT_POS_##bank,		\
>> 			.oe			= GPIO_OE_##bank,			\
>> 		},									\
>> 		.chip = {								\
>> 			.direction_input	= msm_gpio_direction_input,	\
>> 			.direction_output	= msm_gpio_direction_output,	\
>> 			.get			= msm_gpio_get,			\
>> 			.set			= msm_gpio_set,			\
>> 			.to_irq		= msm_gpio_to_irq,		\
>> 			.base			= base_gpio,			\
>> 			.ngpio		= num_gpio,				\
>> 		},									\
>> 	}
>>
>> Then the struct definition can be reduced to this:
>>
>> struct msm_gpio_chip msm_gpio_chips[] = {
>> #if defined(CONFIG_ARCH_MSM7X30)
>> 	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
>> 	MSM_GPIO_BANK(1, 16, 28),	/* gpio 16-43 */
>> 	MSM_GPIO_BANK(2, 44, 24),	/* gpio 44-67 */
>> 	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
>> 	MSM_GPIO_BANK(4, 95, 12),	/* gpio 95-106 */
>> 	MSM_GPIO_BANK(5, 107, 27),	/* gpio 107-133 */
>> 	MSM_GPIO_BANK(6, 134, 17),	/* gpio 134-150 */
>> 	MSM_GPIO_BANK(7, 151, 31),	/* gpio 151-181 */
>> #elif defined(CONFIG_ARCH_QSD8X50)
>> 	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
>> 	MSM_GPIO_BANK(1, 16, 27),	/* gpio 16-42 */
>> 	MSM_GPIO_BANK(2, 43, 25),	/* gpio 43-67 */
>> 	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
>> 	MSM_GPIO_BANK(4, 95, 9),	/* gpio 95-103 */
>> 	MSM_GPIO_BANK(5, 104, 18),	/* gpio 104-121 */
>> 	MSM_GPIO_BANK(6, 122, 31),	/* gpio 122-152 */
>> 	MSM_GPIO_BANK(7, 153, 12),	/* gpio 153-164 */
>> #else
>> 	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
>> 	MSM_GPIO_BANK(1, 16, 27),	/* gpio 16-42 */
>> 	MSM_GPIO_BANK(2, 43, 25),	/* gpio 43-67 */
>> 	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
>> 	MSM_GPIO_BANK(4, 95, 12),	/* gpio 95-106 */
>> 	MSM_GPIO_BANK(5, 107, 15),	/* gpio 107-121 */
>> #endif
>> };

Which could also be further reduced to:

struct msm_gpio_chip msm_gpio_chips[] = {
	MSM_GPIO_BANK(0,   0, 16),	/* gpio 0-15 */
#if defined(CONFIG_ARCH_MSM7X30)
	MSM_GPIO_BANK(1,  16, 28),	/* gpio 16-43 */
 	MSM_GPIO_BANK(2,  44, 24),	/* gpio 44-67 */
 	MSM_GPIO_BANK(3,  68, 27),	/* gpio 68-94 */
 	MSM_GPIO_BANK(4,  95, 12),	/* gpio 95-106 */
 	MSM_GPIO_BANK(5, 107, 27),	/* gpio 107-133 */
 	MSM_GPIO_BANK(6, 134, 17),	/* gpio 134-150 */
 	MSM_GPIO_BANK(7, 151, 31),	/* gpio 151-181 */
#else
	MSM_GPIO_BANK(1,  16, 27),	/* gpio 16-42 */
	MSM_GPIO_BANK(2,  43, 25),	/* gpio 43-67 */
 	MSM_GPIO_BANK(3,  68, 27),	/* gpio 68-94 */
#if defined(CONFIG_ARCH_QSD8X50)
	MSM_GPIO_BANK(4,  95,  9),	/* gpio 95-103 */
 	MSM_GPIO_BANK(5, 104, 18),	/* gpio 104-121 */
 	MSM_GPIO_BANK(6, 122, 31),	/* gpio 122-152 */
 	MSM_GPIO_BANK(7, 153, 12),	/* gpio 153-164 */	
#else
	MSM_GPIO_BANK(4,  95, 12),	/* gpio 95-106 */
 	MSM_GPIO_BANK(5, 107, 15),	/* gpio 107-121 */
#endif
#endif

~Ryan

-- 
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
ryan@bluewatersys.com         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934

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

* [PATCH 1/2] msm: Install the Google-Android gpio driver.
@ 2010-09-01 21:30       ` Ryan Mallon
  0 siblings, 0 replies; 17+ messages in thread
From: Ryan Mallon @ 2010-09-01 21:30 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/02/2010 09:13 AM, Daniel Walker wrote:
> On Wed, 2010-09-01 at 13:59 -0500, H Hartley Sweeten wrote:
>> On Monday, August 30, 2010 5:18 PM, Gregory Bean wrote:
>>> Subject: [PATCH 1/2] msm: Install the Google-Android gpio driver.
>>>
>>> From: Arve Hj?nnev?g <arve@android.com>
>>>
>>> As part of the ongoing effort to converge on a common code base,
>>> adopt the Google-Android msmgpio driver, as it has a stronger pedigree
>>> than the previous submission from codeaurora.
>>>
>>> Cc: Arve Hj?nnev?g <arve@android.com>
>>> Signed-off-by: Gregory Bean <gbean@codeaurora.org>
>>
>> Hello Greg,
>>
>> A couple comments on this.
>>
>>> +struct msm_gpio_chip msm_gpio_chips[] = {
>>> +	{
>>> +		.regs = {
>>> +			.out =         GPIO_OUT_0,
>>> +			.in =          GPIO_IN_0,
>>> +			.int_status =  GPIO_INT_STATUS_0,
>>> +			.int_clear =   GPIO_INT_CLEAR_0,
>>> +			.int_en =      GPIO_INT_EN_0,
>>> +			.int_edge =    GPIO_INT_EDGE_0,
>>> +			.int_pos =     GPIO_INT_POS_0,
>>> +			.oe =          GPIO_OE_0,
>>> +		},
>>> +		.chip = {
>>> +			.base = 0,
>>> +			.ngpio = 16,
>>> +			.get = msm_gpio_get,
>>> +			.set = msm_gpio_set,
>>> +			.direction_input = msm_gpio_direction_input,
>>> +			.direction_output = msm_gpio_direction_output,
>>> +			.to_irq = msm_gpio_to_irq,
>>> +		}
>>> +	},
>>
>> This is a bit ugly... A 204 line struct definition is a bit hard to follow,
>> especially the way it's broken up with all the #if defined stuff.
>>
>> Each gpio "bank" is code duplication other than the .base and .ngpio.  The
>> whole thing can be reduced using a helper macro.  Something like this:
>>
>> #define MSM_GPIO_BANK(bank, base_gpio, num_gpio)			\
>> 	{										\
>> 		.regs = {								\
>> 			.out			= GPIO_OUT_##bank,		\
>> 			.in			= GPIO_IN_##bank,			\
>> 			.int_status		= GPIO_INT_STATUS_##bank,	\
>> 			.int_clear		= GPIO_INT_CLEAR_##bank,	\
>> 			.int_en		= GPIO_INT_EN_##bank,		\
>> 			.int_edge		= GPIO_INT_EDGE_##bank,		\
>> 			.int_pos		= GPIO_INT_POS_##bank,		\
>> 			.oe			= GPIO_OE_##bank,			\
>> 		},									\
>> 		.chip = {								\
>> 			.direction_input	= msm_gpio_direction_input,	\
>> 			.direction_output	= msm_gpio_direction_output,	\
>> 			.get			= msm_gpio_get,			\
>> 			.set			= msm_gpio_set,			\
>> 			.to_irq		= msm_gpio_to_irq,		\
>> 			.base			= base_gpio,			\
>> 			.ngpio		= num_gpio,				\
>> 		},									\
>> 	}
>>
>> Then the struct definition can be reduced to this:
>>
>> struct msm_gpio_chip msm_gpio_chips[] = {
>> #if defined(CONFIG_ARCH_MSM7X30)
>> 	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
>> 	MSM_GPIO_BANK(1, 16, 28),	/* gpio 16-43 */
>> 	MSM_GPIO_BANK(2, 44, 24),	/* gpio 44-67 */
>> 	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
>> 	MSM_GPIO_BANK(4, 95, 12),	/* gpio 95-106 */
>> 	MSM_GPIO_BANK(5, 107, 27),	/* gpio 107-133 */
>> 	MSM_GPIO_BANK(6, 134, 17),	/* gpio 134-150 */
>> 	MSM_GPIO_BANK(7, 151, 31),	/* gpio 151-181 */
>> #elif defined(CONFIG_ARCH_QSD8X50)
>> 	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
>> 	MSM_GPIO_BANK(1, 16, 27),	/* gpio 16-42 */
>> 	MSM_GPIO_BANK(2, 43, 25),	/* gpio 43-67 */
>> 	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
>> 	MSM_GPIO_BANK(4, 95, 9),	/* gpio 95-103 */
>> 	MSM_GPIO_BANK(5, 104, 18),	/* gpio 104-121 */
>> 	MSM_GPIO_BANK(6, 122, 31),	/* gpio 122-152 */
>> 	MSM_GPIO_BANK(7, 153, 12),	/* gpio 153-164 */
>> #else
>> 	MSM_GPIO_BANK(0, 0, 16),	/* gpio 0-15 */
>> 	MSM_GPIO_BANK(1, 16, 27),	/* gpio 16-42 */
>> 	MSM_GPIO_BANK(2, 43, 25),	/* gpio 43-67 */
>> 	MSM_GPIO_BANK(3, 68, 27),	/* gpio 68-94 */
>> 	MSM_GPIO_BANK(4, 95, 12),	/* gpio 95-106 */
>> 	MSM_GPIO_BANK(5, 107, 15),	/* gpio 107-121 */
>> #endif
>> };

Which could also be further reduced to:

struct msm_gpio_chip msm_gpio_chips[] = {
	MSM_GPIO_BANK(0,   0, 16),	/* gpio 0-15 */
#if defined(CONFIG_ARCH_MSM7X30)
	MSM_GPIO_BANK(1,  16, 28),	/* gpio 16-43 */
 	MSM_GPIO_BANK(2,  44, 24),	/* gpio 44-67 */
 	MSM_GPIO_BANK(3,  68, 27),	/* gpio 68-94 */
 	MSM_GPIO_BANK(4,  95, 12),	/* gpio 95-106 */
 	MSM_GPIO_BANK(5, 107, 27),	/* gpio 107-133 */
 	MSM_GPIO_BANK(6, 134, 17),	/* gpio 134-150 */
 	MSM_GPIO_BANK(7, 151, 31),	/* gpio 151-181 */
#else
	MSM_GPIO_BANK(1,  16, 27),	/* gpio 16-42 */
	MSM_GPIO_BANK(2,  43, 25),	/* gpio 43-67 */
 	MSM_GPIO_BANK(3,  68, 27),	/* gpio 68-94 */
#if defined(CONFIG_ARCH_QSD8X50)
	MSM_GPIO_BANK(4,  95,  9),	/* gpio 95-103 */
 	MSM_GPIO_BANK(5, 104, 18),	/* gpio 104-121 */
 	MSM_GPIO_BANK(6, 122, 31),	/* gpio 122-152 */
 	MSM_GPIO_BANK(7, 153, 12),	/* gpio 153-164 */	
#else
	MSM_GPIO_BANK(4,  95, 12),	/* gpio 95-106 */
 	MSM_GPIO_BANK(5, 107, 15),	/* gpio 107-121 */
#endif
#endif

~Ryan

-- 
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
ryan at bluewatersys.com         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934

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

end of thread, other threads:[~2010-09-01 21:30 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-31  0:18 [PATCH 1/2] msm: Install the Google-Android gpio driver Gregory Bean
2010-08-31  0:18 ` Gregory Bean
2010-08-31  0:18 ` [PATCH 2/2] msm: gpio: Add gpiomux calls to request and free Gregory Bean
2010-08-31  0:18   ` Gregory Bean
2010-08-31 16:46 ` [PATCH 1/2] msm: Install the Google-Android gpio driver Daniel Walker
2010-08-31 16:46   ` Daniel Walker
2010-08-31 16:50 ` Daniel Walker
2010-08-31 16:50   ` Daniel Walker
2010-08-31 21:50 ` Daniel Walker
2010-08-31 21:50   ` Daniel Walker
2010-09-01 18:59 ` H Hartley Sweeten
2010-09-01 18:59   ` H Hartley Sweeten
2010-09-01 18:59   ` H Hartley Sweeten
2010-09-01 21:13   ` Daniel Walker
2010-09-01 21:13     ` Daniel Walker
2010-09-01 21:30     ` Ryan Mallon
2010-09-01 21:30       ` Ryan Mallon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.