From f14d3cb36bd756cf5ec2d5a2b6b93644225cfcb3 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Wed, 20 Oct 2010 19:22:29 +0200 Subject: add html doc for ux500 gpio Signed-off-by: Mian Yousaf Kaukab --- Documentation/DocBook/gpio.tmpl | 112 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 Documentation/DocBook/gpio.tmpl diff --git a/Documentation/DocBook/gpio.tmpl b/Documentation/DocBook/gpio.tmpl new file mode 100644 index 00000000000..b69c2770210 --- /dev/null +++ b/Documentation/DocBook/gpio.tmpl @@ -0,0 +1,112 @@ + + + + + + GPIO1B + + + + Alessandro + Rubini + +
+ rubini@unipv.it +
+
+
+ + Prafulla + WADASKAR + +
+ prafulla.wadaskar@st.com +
+
+
+
+ + + 2008-2010 + ST-Ericsson + + + + + Linux standard functions + + + + + + + + This documentation is free software; you can redistribute + it and/or modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later + version. + + + + This program is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, + MA 02111-1307 USA + + + + For more details see the file COPYING in the source + distribution of Linux. + + +
+ + + + Introduction + + This Documentation describes the API's provided by the GPIO controller Driver. + + + Only the API specific to the Ux500 platform is listed here. For the generic GPIO + API, see Documentation/gpio.txt in the kernel source tree. + + + + + Known Bugs And Assumptions + + + + None + + + None. + + + + + + + + + Public Interface + + This Section lists the API's provided by the GPIO controller driver to client drivers. + + + Only the API specific to the Ux500 platform is listed here. For the generic GPIO + API, see Documentation/gpio.txt in the kernel source tree. + +!Earch/arm/plat-nomadik/gpio.c + +
-- cgit v1.2.3 From e2be2d679b0c61000b3bd0011e74b18b03b6128e Mon Sep 17 00:00:00 2001 From: Philippe Langlais Date: Thu, 13 Oct 2011 16:24:46 +0200 Subject: mach-ux500: gpio: Moved the NOMADIK_NR_GPIO Move the NOMADIK_NR_GPIO to the right location. Fix warnings generated by this change. ST-Ericsson Linux next: ER 340134 ST-Ericsson ID: 340139 ST-Ericsson FOSS-OUT ID: Trivial Signed-off-by: Robert Marklund Change-Id: I5b69d4a4662b707d815a867b2b5be19e4675d010 Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/24082 Reviewed-by: Philippe LANGLAIS --- arch/arm/mach-ux500/include/mach/gpio.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/mach-ux500/include/mach/gpio.h b/arch/arm/mach-ux500/include/mach/gpio.h index c01ef66537f..8571446b09b 100644 --- a/arch/arm/mach-ux500/include/mach/gpio.h +++ b/arch/arm/mach-ux500/include/mach/gpio.h @@ -1,5 +1,17 @@ #ifndef __ASM_ARCH_GPIO_H #define __ASM_ARCH_GPIO_H +/* + * 288 (#267 is the highest one actually hooked up) onchip GPIOs, plus enough + * room for a couple of GPIO expanders. + */ + +#if CONFIG_ARCH_NR_GPIO > 0 +#define ARCH_NR_GPIOS CONFIG_ARCH_NR_GPIO +#else +#define ARCH_NR_GPIOS 355 +#endif + +#define NOMADIK_NR_GPIO 288 #endif /* __ASM_ARCH_GPIO_H */ -- cgit v1.2.3 From 7863c4fa623c320df13db9ab1290fefd2f0536bc Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Tue, 27 Sep 2011 16:14:49 +0200 Subject: ux500: gpio: move gpio base numbers to platform header Gpio numbers starts with DB gpios followed by gpio-expander gpios and then AB gpios. Change-Id: Iba0d0c24d36278afeeaaffb509650b60084985b2 Signed-off-by: Mian Yousaf Kaukab Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/32346 Reviewed-by: Jonas ABERG Tested-by: Jonas ABERG --- arch/arm/mach-ux500/include/mach/gpio.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/mach-ux500/include/mach/gpio.h b/arch/arm/mach-ux500/include/mach/gpio.h index 8571446b09b..6a9463dfd9c 100644 --- a/arch/arm/mach-ux500/include/mach/gpio.h +++ b/arch/arm/mach-ux500/include/mach/gpio.h @@ -14,4 +14,8 @@ #define NOMADIK_NR_GPIO 288 +#define MOP500_EGPIO(x) (NOMADIK_NR_GPIO + (x)) +#define MOP500_EGPIO_END MOP500_EGPIO(24) +#define AB8500_GPIO_BASE MOP500_EGPIO_END + #endif /* __ASM_ARCH_GPIO_H */ -- cgit v1.2.3 From 0ccd16ca7b9e647cdc848b933ff7d5603e09b3e0 Mon Sep 17 00:00:00 2001 From: Philippe Langlais Date: Tue, 25 Oct 2011 13:46:39 +0200 Subject: gpio/nomadik: move the Nomadik GPIO header This takes the Nomadik GPIO header out of the plat-nomadik directory and pushes it down into where it belongs. Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/include/mach/gpio.h | 8 +++ arch/arm/plat-nomadik/include/plat/gpio-nomadik.h | 88 ----------------------- drivers/gpio/gpio-nomadik.c | 2 +- include/linux/gpio/nomadik.h | 88 +++++++++++++++++++++++ 4 files changed, 97 insertions(+), 89 deletions(-) delete mode 100644 arch/arm/plat-nomadik/include/plat/gpio-nomadik.h create mode 100644 include/linux/gpio/nomadik.h diff --git a/arch/arm/mach-ux500/include/mach/gpio.h b/arch/arm/mach-ux500/include/mach/gpio.h index 6a9463dfd9c..2d3bb8f47ce 100644 --- a/arch/arm/mach-ux500/include/mach/gpio.h +++ b/arch/arm/mach-ux500/include/mach/gpio.h @@ -14,6 +14,14 @@ #define NOMADIK_NR_GPIO 288 +#include + +/* Invoke gpiolibs gpio_chip abstraction */ +#define gpio_get_value __gpio_get_value +#define gpio_set_value __gpio_set_value +#define gpio_cansleep __gpio_cansleep +#define gpio_to_irq __gpio_to_irq + #define MOP500_EGPIO(x) (NOMADIK_NR_GPIO + (x)) #define MOP500_EGPIO_END MOP500_EGPIO(24) #define AB8500_GPIO_BASE MOP500_EGPIO_END diff --git a/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h b/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h deleted file mode 100644 index 9605bf227df..00000000000 --- a/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Structures and registers for GPIO access in the Nomadik SoC - * - * Copyright (C) 2008 STMicroelectronics - * Author: Prafulla WADASKAR - * Copyright (C) 2009 Alessandro Rubini - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __PLAT_NOMADIK_GPIO -#define __PLAT_NOMADIK_GPIO - -/* - * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving - * the "gpio" namespace for generic and cross-machine functions - */ - -/* Register in the logic block */ -#define NMK_GPIO_DAT 0x00 -#define NMK_GPIO_DATS 0x04 -#define NMK_GPIO_DATC 0x08 -#define NMK_GPIO_PDIS 0x0c -#define NMK_GPIO_DIR 0x10 -#define NMK_GPIO_DIRS 0x14 -#define NMK_GPIO_DIRC 0x18 -#define NMK_GPIO_SLPC 0x1c -#define NMK_GPIO_AFSLA 0x20 -#define NMK_GPIO_AFSLB 0x24 - -#define NMK_GPIO_RIMSC 0x40 -#define NMK_GPIO_FIMSC 0x44 -#define NMK_GPIO_IS 0x48 -#define NMK_GPIO_IC 0x4c -#define NMK_GPIO_RWIMSC 0x50 -#define NMK_GPIO_FWIMSC 0x54 -#define NMK_GPIO_WKS 0x58 - -/* Alternate functions: function C is set in hw by setting both A and B */ -#define NMK_GPIO_ALT_GPIO 0 -#define NMK_GPIO_ALT_A 1 -#define NMK_GPIO_ALT_B 2 -#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B) - -/* Pull up/down values */ -enum nmk_gpio_pull { - NMK_GPIO_PULL_NONE, - NMK_GPIO_PULL_UP, - NMK_GPIO_PULL_DOWN, -}; - -/* Sleep mode */ -enum nmk_gpio_slpm { - NMK_GPIO_SLPM_INPUT, - NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT, - NMK_GPIO_SLPM_NOCHANGE, - NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE, -}; - -extern int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode); -extern int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull); -extern int nmk_gpio_set_mode(int gpio, int gpio_mode); -extern int nmk_gpio_get_mode(int gpio); - -extern void nmk_gpio_wakeups_suspend(void); -extern void nmk_gpio_wakeups_resume(void); - -extern void nmk_gpio_clocks_enable(void); -extern void nmk_gpio_clocks_disable(void); - -extern void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up); - -/* - * Platform data to register a block: only the initial gpio/irq number. - */ -struct nmk_gpio_platform_data { - char *name; - int first_gpio; - int first_irq; - int num_gpio; - u32 (*get_secondary_status)(unsigned int bank); - void (*set_ioforce)(bool enable); - bool supports_sleepmode; -}; - -#endif /* __PLAT_NOMADIK_GPIO */ diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c index 839624f9fe6..37052348724 100644 --- a/drivers/gpio/gpio-nomadik.c +++ b/drivers/gpio/gpio-nomadik.c @@ -23,11 +23,11 @@ #include #include #include +#include #include #include -#include #include #include diff --git a/include/linux/gpio/nomadik.h b/include/linux/gpio/nomadik.h new file mode 100644 index 00000000000..9605bf227df --- /dev/null +++ b/include/linux/gpio/nomadik.h @@ -0,0 +1,88 @@ +/* + * Structures and registers for GPIO access in the Nomadik SoC + * + * Copyright (C) 2008 STMicroelectronics + * Author: Prafulla WADASKAR + * Copyright (C) 2009 Alessandro Rubini + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __PLAT_NOMADIK_GPIO +#define __PLAT_NOMADIK_GPIO + +/* + * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving + * the "gpio" namespace for generic and cross-machine functions + */ + +/* Register in the logic block */ +#define NMK_GPIO_DAT 0x00 +#define NMK_GPIO_DATS 0x04 +#define NMK_GPIO_DATC 0x08 +#define NMK_GPIO_PDIS 0x0c +#define NMK_GPIO_DIR 0x10 +#define NMK_GPIO_DIRS 0x14 +#define NMK_GPIO_DIRC 0x18 +#define NMK_GPIO_SLPC 0x1c +#define NMK_GPIO_AFSLA 0x20 +#define NMK_GPIO_AFSLB 0x24 + +#define NMK_GPIO_RIMSC 0x40 +#define NMK_GPIO_FIMSC 0x44 +#define NMK_GPIO_IS 0x48 +#define NMK_GPIO_IC 0x4c +#define NMK_GPIO_RWIMSC 0x50 +#define NMK_GPIO_FWIMSC 0x54 +#define NMK_GPIO_WKS 0x58 + +/* Alternate functions: function C is set in hw by setting both A and B */ +#define NMK_GPIO_ALT_GPIO 0 +#define NMK_GPIO_ALT_A 1 +#define NMK_GPIO_ALT_B 2 +#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B) + +/* Pull up/down values */ +enum nmk_gpio_pull { + NMK_GPIO_PULL_NONE, + NMK_GPIO_PULL_UP, + NMK_GPIO_PULL_DOWN, +}; + +/* Sleep mode */ +enum nmk_gpio_slpm { + NMK_GPIO_SLPM_INPUT, + NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT, + NMK_GPIO_SLPM_NOCHANGE, + NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE, +}; + +extern int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode); +extern int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull); +extern int nmk_gpio_set_mode(int gpio, int gpio_mode); +extern int nmk_gpio_get_mode(int gpio); + +extern void nmk_gpio_wakeups_suspend(void); +extern void nmk_gpio_wakeups_resume(void); + +extern void nmk_gpio_clocks_enable(void); +extern void nmk_gpio_clocks_disable(void); + +extern void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up); + +/* + * Platform data to register a block: only the initial gpio/irq number. + */ +struct nmk_gpio_platform_data { + char *name; + int first_gpio; + int first_irq; + int num_gpio; + u32 (*get_secondary_status)(unsigned int bank); + void (*set_ioforce)(bool enable); + bool supports_sleepmode; +}; + +#endif /* __PLAT_NOMADIK_GPIO */ -- cgit v1.2.3 From 460d69bd6d40d49ec2d7aa2ec3ac1a8cb8b36a1d Mon Sep 17 00:00:00 2001 From: Philippe Langlais Date: Tue, 5 Jul 2011 12:49:38 +0100 Subject: gpio: ux500: Activate and port ab8500 GPIO driver onto 3.x Signed-off-by: Lee Jones Signed-off-by: Philippe Langlais --- drivers/gpio/Kconfig | 2 +- drivers/gpio/gpio-ab8500.c | 60 ++++++++++++++++++++++++---------------------- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index d0c41188d4e..5e073f74baa 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -479,7 +479,7 @@ config GPIO_JANZ_TTL config GPIO_AB8500 bool "ST-Ericsson AB8500 Mixed Signal Circuit gpio functions" - depends on AB8500_CORE && BROKEN + depends on AB8500_CORE help Select this to enable the AB8500 IC GPIO driver diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c index 050c05d9189..db40acb9c3e 100644 --- a/drivers/gpio/gpio-ab8500.c +++ b/drivers/gpio/gpio-ab8500.c @@ -207,7 +207,7 @@ static struct gpio_chip ab8500gpio_chip = { static unsigned int irq_to_rising(unsigned int irq) { - struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq); + struct ab8500_gpio *ab8500_gpio = irq_get_chip_data(irq); int offset = irq - ab8500_gpio->irq_base; int new_irq = offset + AB8500_INT_GPIO6R + ab8500_gpio->parent->irq_base; @@ -216,7 +216,7 @@ static unsigned int irq_to_rising(unsigned int irq) static unsigned int irq_to_falling(unsigned int irq) { - struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq); + struct ab8500_gpio *ab8500_gpio = irq_get_chip_data(irq); int offset = irq - ab8500_gpio->irq_base; int new_irq = offset + AB8500_INT_GPIO6F + ab8500_gpio->parent->irq_base; @@ -261,15 +261,16 @@ static irqreturn_t handle_falling(int irq, void *dev) return IRQ_HANDLED; } -static void ab8500_gpio_irq_lock(unsigned int irq) +static void ab8500_gpio_irq_lock(struct irq_data *data) { - struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq); + struct ab8500_gpio *ab8500_gpio = irq_data_get_irq_chip_data(data); mutex_lock(&ab8500_gpio->lock); } -static void ab8500_gpio_irq_sync_unlock(unsigned int irq) +static void ab8500_gpio_irq_sync_unlock(struct irq_data *data) { - struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq); + struct ab8500_gpio *ab8500_gpio = irq_data_get_irq_chip_data(data); + unsigned int irq = data->irq; int offset = irq - ab8500_gpio->irq_base; bool rising = ab8500_gpio->rising & BIT(offset); bool falling = ab8500_gpio->falling & BIT(offset); @@ -316,21 +317,22 @@ static void ab8500_gpio_irq_sync_unlock(unsigned int irq) } -static void ab8500_gpio_irq_mask(unsigned int irq) +static void ab8500_gpio_irq_mask(struct irq_data *data) { - struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq); + struct ab8500_gpio *ab8500_gpio = irq_data_get_irq_chip_data(data); ab8500_gpio->irq_action = MASK; } -static void ab8500_gpio_irq_unmask(unsigned int irq) +static void ab8500_gpio_irq_unmask(struct irq_data *data) { - struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq); + struct ab8500_gpio *ab8500_gpio = irq_data_get_irq_chip_data(data); ab8500_gpio->irq_action = UNMASK; } -static int ab8500_gpio_irq_set_type(unsigned int irq, unsigned int type) +static int ab8500_gpio_irq_set_type(struct irq_data *data, unsigned int type) { - struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq); + struct ab8500_gpio *ab8500_gpio = irq_data_get_irq_chip_data(data); + unsigned int irq = data->irq; int offset = irq - ab8500_gpio->irq_base; if (type == IRQ_TYPE_EDGE_BOTH) { @@ -344,28 +346,28 @@ static int ab8500_gpio_irq_set_type(unsigned int irq, unsigned int type) return 0; } -unsigned int ab8500_gpio_irq_startup(unsigned int irq) +unsigned int ab8500_gpio_irq_startup(struct irq_data *data) { - struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq); + struct ab8500_gpio *ab8500_gpio = irq_data_get_irq_chip_data(data); ab8500_gpio->irq_action = STARTUP; return 0; } -void ab8500_gpio_irq_shutdown(unsigned int irq) +void ab8500_gpio_irq_shutdown(struct irq_data *data) { - struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq); + struct ab8500_gpio *ab8500_gpio = irq_data_get_irq_chip_data(data); ab8500_gpio->irq_action = SHUTDOWN; } static struct irq_chip ab8500_gpio_irq_chip = { .name = "ab8500-gpio", - .startup = ab8500_gpio_irq_startup, - .shutdown = ab8500_gpio_irq_shutdown, - .bus_lock = ab8500_gpio_irq_lock, - .bus_sync_unlock = ab8500_gpio_irq_sync_unlock, - .mask = ab8500_gpio_irq_mask, - .unmask = ab8500_gpio_irq_unmask, - .set_type = ab8500_gpio_irq_set_type, + .irq_startup = ab8500_gpio_irq_startup, + .irq_shutdown = ab8500_gpio_irq_shutdown, + .irq_bus_lock = ab8500_gpio_irq_lock, + .irq_bus_sync_unlock = ab8500_gpio_irq_sync_unlock, + .irq_mask = ab8500_gpio_irq_mask, + .irq_unmask = ab8500_gpio_irq_unmask, + .irq_set_type = ab8500_gpio_irq_set_type, }; static int ab8500_gpio_irq_init(struct ab8500_gpio *ab8500_gpio) @@ -374,14 +376,14 @@ static int ab8500_gpio_irq_init(struct ab8500_gpio *ab8500_gpio) int irq; for (irq = base; irq < base + AB8500_NUM_VIR_GPIO_IRQ ; irq++) { - set_irq_chip_data(irq, ab8500_gpio); - set_irq_chip_and_handler(irq, &ab8500_gpio_irq_chip, + irq_set_chip_data(irq, ab8500_gpio); + irq_set_chip_and_handler(irq, &ab8500_gpio_irq_chip, handle_simple_irq); - set_irq_nested_thread(irq, 1); + irq_set_nested_thread(irq, 1); #ifdef CONFIG_ARM set_irq_flags(irq, IRQF_VALID); #else - set_irq_noprobe(irq); + irq_set_noprobe(irq); #endif } @@ -397,8 +399,8 @@ static void ab8500_gpio_irq_remove(struct ab8500_gpio *ab8500_gpio) #ifdef CONFIG_ARM set_irq_flags(irq, 0); #endif - set_irq_chip_and_handler(irq, NULL, NULL); - set_irq_chip_data(irq, NULL); + irq_set_chip_and_handler(irq, NULL, NULL); + irq_set_chip_data(irq, NULL); } } -- cgit v1.2.3 From c3d3756c066cedeab68ea4990d0c4b979251cc67 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 23 May 2011 07:43:33 +0100 Subject: nmk-gpio: cache [rf]w?imsc ST-Ericsson Linux next: - ST-Ericsson ID: ER335433 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I21df49d0f45a3d096eb37d6de10514988b0de44f Signed-off-by: Rabin Vincent Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/23928 Reviewed-by: QATEST Reviewed-by: Srinidhi KASAGAR Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/29310 Conflicts: drivers/gpio/gpio-nomadik.c --- drivers/gpio/gpio-nomadik.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c index 37052348724..1cdfd9894a9 100644 --- a/drivers/gpio/gpio-nomadik.c +++ b/drivers/gpio/gpio-nomadik.c @@ -58,6 +58,8 @@ struct nmk_gpio_chip { u32 real_wake; u32 rwimsc; u32 fwimsc; + u32 rimsc; + u32 fimsc; u32 slpm; u32 pull_up; }; @@ -150,8 +152,8 @@ static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip, unsigned offset, int gpio_mode, bool glitch) { - u32 rwimsc = readl(nmk_chip->addr + NMK_GPIO_RWIMSC); - u32 fwimsc = readl(nmk_chip->addr + NMK_GPIO_FWIMSC); + u32 rwimsc = nmk_chip->rwimsc; + u32 fwimsc = nmk_chip->fwimsc; if (glitch && nmk_chip->set_ioforce) { u32 bit = BIT(offset); @@ -556,27 +558,38 @@ static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip, int gpio, enum nmk_gpio_irq_type which, bool enable) { - u32 rimsc = which == WAKE ? NMK_GPIO_RWIMSC : NMK_GPIO_RIMSC; - u32 fimsc = which == WAKE ? NMK_GPIO_FWIMSC : NMK_GPIO_FIMSC; u32 bitmask = nmk_gpio_get_bitmask(gpio); - u32 reg; + u32 *rimscval; + u32 *fimscval; + u32 rimscreg; + u32 fimscreg; + + if (which == NORMAL) { + rimscreg = NMK_GPIO_RIMSC; + fimscreg = NMK_GPIO_FIMSC; + rimscval = &nmk_chip->rimsc; + fimscval = &nmk_chip->fimsc; + } else { + rimscreg = NMK_GPIO_RWIMSC; + fimscreg = NMK_GPIO_FWIMSC; + rimscval = &nmk_chip->rwimsc; + fimscval = &nmk_chip->fwimsc; + } /* we must individually set/clear the two edges */ if (nmk_chip->edge_rising & bitmask) { - reg = readl(nmk_chip->addr + rimsc); if (enable) - reg |= bitmask; + *rimscval |= bitmask; else - reg &= ~bitmask; - writel(reg, nmk_chip->addr + rimsc); + *rimscval &= ~bitmask; + writel(*rimscval, nmk_chip->addr + rimscreg); } if (nmk_chip->edge_falling & bitmask) { - reg = readl(nmk_chip->addr + fimsc); if (enable) - reg |= bitmask; + *fimscval |= bitmask; else - reg &= ~bitmask; - writel(reg, nmk_chip->addr + fimsc); + *fimscval &= ~bitmask; + writel(*fimscval, nmk_chip->addr + fimscreg); } } @@ -1008,9 +1021,6 @@ void nmk_gpio_wakeups_suspend(void) clk_enable(chip->clk); - chip->rwimsc = readl(chip->addr + NMK_GPIO_RWIMSC); - chip->fwimsc = readl(chip->addr + NMK_GPIO_FWIMSC); - writel(chip->rwimsc & chip->real_wake, chip->addr + NMK_GPIO_RWIMSC); writel(chip->fwimsc & chip->real_wake, -- cgit v1.2.3 From b090db7b7d09ee6375ef811ac144fdc8bac656e0 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 23 May 2011 12:22:18 +0530 Subject: nmk-gpio: fix spurious interrupts with SKE If the pin is switching to altfunc, and there was an interrupt installed on it which has been lazy disabled, actually mask the interrupt to prevent spurious interrupts that would occur while the pin is under control of the peripheral. Only SKE does this. ST-Ericsson Linux next: - ST-Ericsson ID: ER335433 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I28ff286ecac7f187da9dd838d5be7c2d7d77aae2 Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/23929 Reviewed-by: QATEST Tested-by: Rabin VINCENT Reviewed-by: Srinidhi KASAGAR Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/29311 Reviewed-by: Rabin VINCENT --- drivers/gpio/gpio-nomadik.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c index 1cdfd9894a9..86b6841ac4f 100644 --- a/drivers/gpio/gpio-nomadik.c +++ b/drivers/gpio/gpio-nomadik.c @@ -175,6 +175,36 @@ static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip, } } +static void +nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset) +{ + u32 falling = nmk_chip->fimsc & BIT(offset); + u32 rising = nmk_chip->rimsc & BIT(offset); + int gpio = nmk_chip->chip.base + offset; + int irq = NOMADIK_GPIO_TO_IRQ(gpio); + struct irq_data *d = irq_get_irq_data(irq); + + if (!rising && !falling) + return; + + if (!d || !irqd_irq_disabled(d)) + return; + + if (rising) { + nmk_chip->rimsc &= ~BIT(offset); + writel_relaxed(nmk_chip->rimsc, + nmk_chip->addr + NMK_GPIO_RIMSC); + } + + if (falling) { + nmk_chip->fimsc &= ~BIT(offset); + writel_relaxed(nmk_chip->fimsc, + nmk_chip->addr + NMK_GPIO_FIMSC); + } + + dev_dbg(nmk_chip->chip.dev, "%d: clearing interrupt mask\n", gpio); +} + static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, pin_cfg_t cfg, bool sleep, unsigned int *slpmregs) { @@ -240,6 +270,15 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, __nmk_gpio_set_pull(nmk_chip, offset, pull); } + /* + * If the pin is switching to altfunc, and there was an interrupt + * installed on it which has been lazy disabled, actually mask the + * interrupt to prevent spurious interrupts that would occur while the + * pin is under control of the peripheral. Only SKE does this. + */ + if (af != NMK_GPIO_ALT_GPIO) + nmk_gpio_disable_lazy_irq(nmk_chip, offset); + /* * If we've backed up the SLPM registers (glitch workaround), modify * the backups since they will be restored. -- cgit v1.2.3 From c7d71d636dcea6f897e169b40ba6a3af40cb13ff Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Thu, 15 Sep 2011 15:51:15 +0200 Subject: gpio: ab8500: make pins configurable Make it possible to set the pin configuration either as gpio or specific functionality. Change-Id: I884dc5f17d17b3d5352d6035648417cd83d50a62 Signed-off-by: Bengt Jonsson Signed-off-by: Mian Yousaf Kaukab Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/32098 Tested-by: Jonas ABERG --- drivers/gpio/gpio-ab8500.c | 63 ++++++++++++++++++++++++++++++++++ include/linux/mfd/abx500/ab8500-gpio.h | 51 +++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c index db40acb9c3e..c3c7c5a86ba 100644 --- a/drivers/gpio/gpio-ab8500.c +++ b/drivers/gpio/gpio-ab8500.c @@ -495,6 +495,69 @@ static int __devexit ab8500_gpio_remove(struct platform_device *pdev) return 0; } +/* + * ab8500_gpio_config_select() + * + * Configure functionality of pin, either specific use or GPIO. + * @dev: device pointer + * @gpio: gpio number + * @gpio_select: true if the pin should be used as GPIO + */ +int ab8500_gpio_config_select(struct device *dev, + enum ab8500_pin gpio, bool gpio_select) +{ + u8 offset = gpio - AB8500_PIN_GPIO1; + u8 reg = AB8500_GPIO_SEL1_REG + (offset / 8); + u8 pos = offset % 8; + u8 val = gpio_select ? 1 : 0; + int ret; + + ret = abx500_mask_and_set_register_interruptible(dev, + AB8500_MISC, reg, 1 << pos, val << pos); + if (ret < 0) + dev_err(dev, "%s write failed\n", __func__); + + dev_vdbg(dev, "%s (bank, addr, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n", + __func__, AB8500_MISC, reg, 1 << pos, val << pos); + + return ret; +} + +/* + * ab8500_gpio_config_get_select() + * + * Read currently configured functionality, either specific use or GPIO. + * @dev: device pointer + * @gpio: gpio number + * @gpio_select: pointer to pin selection status + */ +int ab8500_gpio_config_get_select(struct device *dev, + enum ab8500_pin gpio, bool *gpio_select) +{ + u8 offset = gpio - AB8500_PIN_GPIO1; + u8 reg = AB8500_GPIO_SEL1_REG + (offset / 8); + u8 pos = offset % 8; + u8 val; + int ret; + + ret = abx500_get_register_interruptible(dev, + AB8500_MISC, reg, &val); + if (ret < 0) { + dev_err(dev, "%s read failed\n", __func__); + return ret; + } + + if (val & (1 << pos)) + *gpio_select = true; + else + *gpio_select = false; + + dev_vdbg(dev, "%s (bank, addr, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n", + __func__, AB8500_MISC, reg, 1 << pos, val); + + return 0; +} + static struct platform_driver ab8500_gpio_driver = { .driver = { .name = "ab8500-gpio", diff --git a/include/linux/mfd/abx500/ab8500-gpio.h b/include/linux/mfd/abx500/ab8500-gpio.h index 488a8c920a2..df49f2d6036 100644 --- a/include/linux/mfd/abx500/ab8500-gpio.h +++ b/include/linux/mfd/abx500/ab8500-gpio.h @@ -18,4 +18,55 @@ struct ab8500_gpio_platform_data { u8 config_reg[7]; }; +enum ab8500_pin { + AB8500_PIN_GPIO1 = 0, + AB8500_PIN_GPIO2, + AB8500_PIN_GPIO3, + AB8500_PIN_GPIO4, + AB8500_PIN_GPIO5, + AB8500_PIN_GPIO6, + AB8500_PIN_GPIO7, + AB8500_PIN_GPIO8, + AB8500_PIN_GPIO9, + AB8500_PIN_GPIO10, + AB8500_PIN_GPIO11, + AB8500_PIN_GPIO12, + AB8500_PIN_GPIO13, + AB8500_PIN_GPIO14, + AB8500_PIN_GPIO15, + AB8500_PIN_GPIO16, + AB8500_PIN_GPIO17, + AB8500_PIN_GPIO18, + AB8500_PIN_GPIO19, + AB8500_PIN_GPIO20, + AB8500_PIN_GPIO21, + AB8500_PIN_GPIO22, + AB8500_PIN_GPIO23, + AB8500_PIN_GPIO24, + AB8500_PIN_GPIO25, + AB8500_PIN_GPIO26, + AB8500_PIN_GPIO27, + AB8500_PIN_GPIO28, + AB8500_PIN_GPIO29, + AB8500_PIN_GPIO30, + AB8500_PIN_GPIO31, + AB8500_PIN_GPIO32, + AB8500_PIN_GPIO33, + AB8500_PIN_GPIO34, + AB8500_PIN_GPIO35, + AB8500_PIN_GPIO36, + AB8500_PIN_GPIO37, + AB8500_PIN_GPIO38, + AB8500_PIN_GPIO39, + AB8500_PIN_GPIO40, + AB8500_PIN_GPIO41, + AB8500_PIN_GPIO42, +}; + +int ab8500_gpio_config_select(struct device *dev, + enum ab8500_pin gpio, bool gpio_select); + +int ab8500_gpio_config_get_select(struct device *dev, + enum ab8500_pin gpio, bool *gpio_select); + #endif /* _AB8500_GPIO_H */ -- cgit v1.2.3 From 73047333828b6444cf751b3cbd7b64a398dc038b Mon Sep 17 00:00:00 2001 From: Bibek Basu Date: Fri, 8 Apr 2011 08:42:16 +0530 Subject: gpio: ab8500: fix alternate function register address Alternate function register address is actually 0x50 and thus changed accordingly Change-Id: I172fc5fab1653267873efdfc6fc7e0ed5c27e7a1 Signed-off-by: Bibek Basu Signed-off-by: Mian Yousaf Kaukab Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/32111 Reviewed-by: Jonas ABERG Tested-by: Jonas ABERG --- drivers/gpio/gpio-ab8500.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c index c3c7c5a86ba..b7d44165339 100644 --- a/drivers/gpio/gpio-ab8500.c +++ b/drivers/gpio/gpio-ab8500.c @@ -60,7 +60,7 @@ #define AB8500_GPIO_IN4_REG 0x43 #define AB8500_GPIO_IN5_REG 0x44 #define AB8500_GPIO_IN6_REG 0x45 -#define AB8500_GPIO_ALTFUN_REG 0x45 +#define AB8500_GPIO_ALTFUN_REG 0x50 #define ALTFUN_REG_INDEX 6 #define AB8500_NUM_GPIO 42 #define AB8500_NUM_VIR_GPIO_IRQ 16 -- cgit v1.2.3 From d7ef70569c88a8f0b071865292b94ae2d983e252 Mon Sep 17 00:00:00 2001 From: Bibek Basu Date: Thu, 7 Apr 2011 11:38:06 +0530 Subject: gpio: ab8500: read register corrected in get_value api Read register is corrected from "AB8500_GPIO_OUT1_REG" to "AB8500_GPIO_IN1_REG" in get_value api Change-Id: I3eaed0b3e63eac08cbe2d1219e3603920aa8cadb Signed-off-by: Bibek Basu Signed-off-by: Mian Yousaf Kaukab Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/32112 Reviewed-by: Jonas ABERG Tested-by: Jonas ABERG --- drivers/gpio/gpio-ab8500.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c index b7d44165339..77fe1d765ef 100644 --- a/drivers/gpio/gpio-ab8500.c +++ b/drivers/gpio/gpio-ab8500.c @@ -115,7 +115,7 @@ static int ab8500_gpio_get(struct gpio_chip *chip, unsigned offset) { struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip); u8 mask = 1 << (offset % 8); - u8 reg = AB8500_GPIO_OUT1_REG + (offset / 8); + u8 reg = AB8500_GPIO_IN1_REG + (offset / 8); int ret; u8 data; ret = abx500_get_register_interruptible(ab8500_gpio->dev, AB8500_MISC, -- cgit v1.2.3 From f92022237ea0cba1c6b4cb755c2c2f494a0e69d8 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Mon, 19 Sep 2011 15:38:51 +0200 Subject: gpio: ab8500: allow direction and pullups configuration This patch extends the the platform data to include gpio direction and pullups configurations. These configurations are applied during probe(). Change-Id: I0c742615cb31ff83671489cce5fb742bc0e10902 Signed-off-by: Bibek Basu Signed-off-by: Mian Yousaf Kaukab Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/32113 Reviewed-by: Jonas ABERG Tested-by: Jonas ABERG --- drivers/gpio/gpio-ab8500.c | 12 ++++++++++++ include/linux/mfd/abx500/ab8500-gpio.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c index 77fe1d765ef..dd95cb3c32d 100644 --- a/drivers/gpio/gpio-ab8500.c +++ b/drivers/gpio/gpio-ab8500.c @@ -445,6 +445,18 @@ static int __devinit ab8500_gpio_probe(struct platform_device *pdev) pdata->config_reg[i]); if (ret < 0) goto out_free; + + ret = abx500_set_register_interruptible(ab8500_gpio->dev, + AB8500_MISC, i + AB8500_GPIO_DIR1_REG, + pdata->config_direction[i]); + if (ret < 0) + goto out_free; + + ret = abx500_set_register_interruptible(ab8500_gpio->dev, + AB8500_MISC, i + AB8500_GPIO_PUD1_REG, + pdata->config_pullups[i]); + if (ret < 0) + goto out_free; } ret = abx500_set_register_interruptible(ab8500_gpio->dev, AB8500_MISC, AB8500_GPIO_ALTFUN_REG, diff --git a/include/linux/mfd/abx500/ab8500-gpio.h b/include/linux/mfd/abx500/ab8500-gpio.h index df49f2d6036..20b841ab81e 100644 --- a/include/linux/mfd/abx500/ab8500-gpio.h +++ b/include/linux/mfd/abx500/ab8500-gpio.h @@ -16,6 +16,8 @@ struct ab8500_gpio_platform_data { int gpio_base; u32 irq_base; u8 config_reg[7]; + u8 config_direction[6]; + u8 config_pullups[6]; }; enum ab8500_pin { -- cgit v1.2.3 From 3556adca57126af38f85e82b408394fb5a05ffcc Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Mon, 19 Sep 2011 16:15:11 +0200 Subject: gpio: ab8500: add api to enable pulldown Change-Id: Ia8c31da2cbfef4f8cb5f6e0ccd5b70dcf0bbd9de Signed-off-by: Bibek Basu Signed-off-by: Mian Yousaf Kaukab Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/32114 Reviewed-by: Jonas ABERG Tested-by: Jonas ABERG --- drivers/gpio/gpio-ab8500.c | 17 +++++++++++++++++ include/linux/mfd/abx500/ab8500-gpio.h | 3 +++ 2 files changed, 20 insertions(+) diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c index dd95cb3c32d..b71bb723c0e 100644 --- a/drivers/gpio/gpio-ab8500.c +++ b/drivers/gpio/gpio-ab8500.c @@ -507,6 +507,23 @@ static int __devexit ab8500_gpio_remove(struct platform_device *pdev) return 0; } +int ab8500_config_pulldown(struct device *dev, + enum ab8500_pin gpio, bool enable) +{ + u8 offset = gpio - AB8500_PIN_GPIO1; + u8 pos = offset % 8; + u8 val = enable ? 0 : 1; + u8 reg = AB8500_GPIO_PUD1_REG + (offset / 8); + int ret; + + ret = abx500_mask_and_set_register_interruptible(dev, + AB8500_MISC, reg, 1 << pos, val << pos); + if (ret < 0) + dev_err(dev, "%s write failed\n", __func__); + return ret; +} +EXPORT_SYMBOL(ab8500_config_pulldown); + /* * ab8500_gpio_config_select() * diff --git a/include/linux/mfd/abx500/ab8500-gpio.h b/include/linux/mfd/abx500/ab8500-gpio.h index 20b841ab81e..e5779b7418e 100644 --- a/include/linux/mfd/abx500/ab8500-gpio.h +++ b/include/linux/mfd/abx500/ab8500-gpio.h @@ -65,6 +65,9 @@ enum ab8500_pin { AB8500_PIN_GPIO42, }; +int ab8500_config_pulldown(struct device *dev, + enum ab8500_pin gpio, bool enable); + int ab8500_gpio_config_select(struct device *dev, enum ab8500_pin gpio, bool gpio_select); -- cgit v1.2.3 From 92917f627290e265668c13712396f09cda46716f Mon Sep 17 00:00:00 2001 From: Marcel Tunnissen Date: Fri, 25 Feb 2011 12:25:46 +0100 Subject: gpio: ab8500: write argument value instead of hardwired 1 This fixes a bug in gpio_set_value(xxx, 0) for ab8500 GPIOs. Change-Id: I9c50d527813b8817f0374e45d243e7bb6400b5c9 Signed-off-by: Marcel Tunnissen Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/32115 Reviewed-by: Jonas ABERG Tested-by: Jonas ABERG --- drivers/gpio/gpio-ab8500.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c index b71bb723c0e..d3bbcce1551 100644 --- a/drivers/gpio/gpio-ab8500.c +++ b/drivers/gpio/gpio-ab8500.c @@ -132,7 +132,7 @@ static void ab8500_gpio_set(struct gpio_chip *chip, unsigned offset, int val) struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip); int ret; /* Write the data */ - ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, 1); + ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, val); if (ret < 0) dev_err(ab8500_gpio->dev, "%s write failed\n", __func__); } -- cgit v1.2.3 From e83a04975da273d14e14b41123d9ec24b30dcb65 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Tue, 27 Sep 2011 18:00:35 +0200 Subject: gpio: ab8500: use gpio base number defined for the platform Change-Id: I84da2cbc3a482d0c54ec489874fc040d8c79eda8 Signed-off-by: Mian Yousaf Kaukab Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/32347 Reviewed-by: Jonas ABERG Tested-by: Jonas ABERG --- include/linux/mfd/abx500/ab8500-gpio.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/mfd/abx500/ab8500-gpio.h b/include/linux/mfd/abx500/ab8500-gpio.h index e5779b7418e..d88e3025317 100644 --- a/include/linux/mfd/abx500/ab8500-gpio.h +++ b/include/linux/mfd/abx500/ab8500-gpio.h @@ -8,6 +8,8 @@ #ifndef _AB8500_GPIO_H #define _AB8500_GPIO_H +#include + /* * Platform data to register a block: only the initial gpio/irq number. */ @@ -21,7 +23,7 @@ struct ab8500_gpio_platform_data { }; enum ab8500_pin { - AB8500_PIN_GPIO1 = 0, + AB8500_PIN_GPIO1 = AB8500_GPIO_BASE, AB8500_PIN_GPIO2, AB8500_PIN_GPIO3, AB8500_PIN_GPIO4, -- cgit v1.2.3 From 9c081c9391fc054a967dce54178722009fae6c0d Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Tue, 27 Sep 2011 18:02:43 +0200 Subject: gpio: ab8500: fix gpio offset bounds for irq mapping AB8500 gpio numbers start from 1 and not 0 so the offset 0 represents gpio 1. Fixing cluster bounds accordingly for irq mappings. Change-Id: Ib1dc72c782011afad61481bb61f8653ed75431d5 Signed-off-by: Mian Yousaf Kaukab Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/32348 Reviewed-by: Jonas ABERG Tested-by: Jonas ABERG --- drivers/gpio/gpio-ab8500.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c index d3bbcce1551..a0253ad14df 100644 --- a/drivers/gpio/gpio-ab8500.c +++ b/drivers/gpio/gpio-ab8500.c @@ -174,9 +174,9 @@ static int ab8500_gpio_to_irq(struct gpio_chip *chip, unsigned offset) int start; int end; } clusters[] = { - {.start = 6, .end = 13}, - {.start = 24, .end = 25}, - {.start = 36, .end = 41}, + {.start = 5, .end = 12}, /* GPIO numbers start from 1 */ + {.start = 23, .end = 24}, + {.start = 35, .end = 40}, }; struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip); int base = ab8500_gpio->irq_base; -- cgit v1.2.3 From 25d989fcf615266fccc7fcb6cc98b5ebb92c5872 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Wed, 28 Sep 2011 15:49:11 +0530 Subject: gpio: nomadik: support low EMI mode ST-Ericsson ID: 345488 ST-Ericsson Linux next: NA ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I88f6c92f199e52186acf6899e14ed399aba657ac Signed-off-by: Rabin Vincent Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/32354 Reviewed-by: Srinidhi KASAGAR --- drivers/gpio/gpio-nomadik.c | 25 +++++++++++++++++++++++++ include/linux/gpio/nomadik.h | 1 + 2 files changed, 26 insertions(+) diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c index 86b6841ac4f..50693a46d1b 100644 --- a/drivers/gpio/gpio-nomadik.c +++ b/drivers/gpio/gpio-nomadik.c @@ -62,6 +62,7 @@ struct nmk_gpio_chip { u32 fimsc; u32 slpm; u32 pull_up; + u32 lowemi; }; static struct nmk_gpio_chip * @@ -126,6 +127,24 @@ static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip, } } +static void __nmk_gpio_set_lowemi(struct nmk_gpio_chip *nmk_chip, + unsigned offset, bool lowemi) +{ + u32 bit = BIT(offset); + bool enabled = nmk_chip->lowemi & bit; + + if (lowemi == enabled) + return; + + if (lowemi) + nmk_chip->lowemi |= bit; + else + nmk_chip->lowemi &= ~bit; + + writel_relaxed(nmk_chip->lowemi, + nmk_chip->addr + NMK_GPIO_LOWEMI); +} + static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip, unsigned offset) { @@ -270,6 +289,8 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, __nmk_gpio_set_pull(nmk_chip, offset, pull); } + __nmk_gpio_set_lowemi(nmk_chip, offset, PIN_LOWEMI(cfg)); + /* * If the pin is switching to altfunc, and there was an interrupt * installed on it which has been lazy disabled, actually mask the @@ -1188,6 +1209,10 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) chip->dev = &dev->dev; chip->owner = THIS_MODULE; + clk_enable(nmk_chip->clk); + nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI); + clk_disable(nmk_chip->clk); + ret = gpiochip_add(&nmk_chip->chip); if (ret) goto out_free; diff --git a/include/linux/gpio/nomadik.h b/include/linux/gpio/nomadik.h index 9605bf227df..3e8b7f16fb7 100644 --- a/include/linux/gpio/nomadik.h +++ b/include/linux/gpio/nomadik.h @@ -29,6 +29,7 @@ #define NMK_GPIO_SLPC 0x1c #define NMK_GPIO_AFSLA 0x20 #define NMK_GPIO_AFSLB 0x24 +#define NMK_GPIO_LOWEMI 0x28 #define NMK_GPIO_RIMSC 0x40 #define NMK_GPIO_FIMSC 0x44 -- cgit v1.2.3 From 3a3545aee1ec912ee3527987a7cbadd84538b141 Mon Sep 17 00:00:00 2001 From: Jonas Aaberg Date: Thu, 24 Nov 2011 11:02:46 +0100 Subject: gpio: nomadik: Use __io and IO_ADDRESS Use __io and IO_ADDRESS instead of home-made io_p2v. ST-Ericsson Linux next: - ST-Ericsson ID: 370799 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I61af9251ee4d7db4e03a58e870c7fdb537b21ab9 Signed-off-by: Jonas Aaberg Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/39651 Reviewed-by: QABUILD --- drivers/gpio/gpio-nomadik.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c index 50693a46d1b..51b8819fd56 100644 --- a/drivers/gpio/gpio-nomadik.c +++ b/drivers/gpio/gpio-nomadik.c @@ -1193,7 +1193,7 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) */ nmk_chip->bank = dev->id; nmk_chip->clk = clk; - nmk_chip->addr = io_p2v(res->start); + nmk_chip->addr = __io(IO_ADDRESS(res->start)); nmk_chip->chip = nmk_gpio_template; nmk_chip->parent_irq = irq; nmk_chip->secondary_parent_irq = secondary_irq; -- cgit v1.2.3 From e0b399ab4555b9c6358d0bc7cd44938c3db7c163 Mon Sep 17 00:00:00 2001 From: Philippe Langlais Date: Sun, 29 Jan 2012 11:22:38 +0100 Subject: gpio: ab8500: Fix bad include name after renaming Needed after "mfd: Unify abx500 headers in mfd/abx500" Signed-off-by: Philippe Langlais --- drivers/gpio/gpio-ab8500.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c index a0253ad14df..273f7caba22 100644 --- a/drivers/gpio/gpio-ab8500.c +++ b/drivers/gpio/gpio-ab8500.c @@ -18,9 +18,9 @@ #include #include #include -#include #include -#include +#include + /* * GPIO registers offset -- cgit v1.2.3 From 98056b46da63e89adea7723f98c7732259d0afef Mon Sep 17 00:00:00 2001 From: Chris Blair Date: Tue, 6 Dec 2011 15:05:33 +0000 Subject: gpio/gpio-stmpe: Add support for no-interrupt cfg Adds support for boards which have an STMPE GPIO device without the interrupt pin connected. This means that no interrupt can be received but the GPIO pins can still be driven and read. ST-Ericsson ID: 399362 ST-Ericsson FOSS-OUT ID: Trivial ST-Ericsson Linux next: NA Signed-off-by: Chris Blair Change-Id: Iefc2c3385e2df76ee1899ea68add8b881e6641a7 Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/46241 Reviewed-by: QATOOLS Reviewed-by: Michel JAOUEN Tested-by: Michel JAOUEN Reviewed-by: QATEST Reviewed-by: Srinidhi KASAGAR --- drivers/gpio/gpio-stmpe.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index 87a68a896ab..0c228458b8b 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c @@ -307,13 +307,15 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev) struct stmpe_gpio_platform_data *pdata; struct stmpe_gpio *stmpe_gpio; int ret; - int irq; + int irq = 0; pdata = stmpe->pdata->gpio; - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; + if (!stmpe->pdata->no_irq) { + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + } stmpe_gpio = kzalloc(sizeof(struct stmpe_gpio), GFP_KERNEL); if (!stmpe_gpio) @@ -336,15 +338,17 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev) if (ret) goto out_free; - ret = stmpe_gpio_irq_init(stmpe_gpio); - if (ret) - goto out_disable; + if (!stmpe->pdata->no_irq) { + ret = stmpe_gpio_irq_init(stmpe_gpio); + if (ret) + goto out_disable; - ret = request_threaded_irq(irq, NULL, stmpe_gpio_irq, IRQF_ONESHOT, - "stmpe-gpio", stmpe_gpio); - if (ret) { - dev_err(&pdev->dev, "unable to get irq: %d\n", ret); - goto out_removeirq; + ret = request_threaded_irq(irq, NULL, stmpe_gpio_irq, + IRQF_ONESHOT, "stmpe-gpio", stmpe_gpio); + if (ret) { + dev_err(&pdev->dev, "unable to get irq: %d\n", ret); + goto out_removeirq; + } } ret = gpiochip_add(&stmpe_gpio->chip); -- cgit v1.2.3 From e86f82d8121024479e3ef348a604ab425efb8e39 Mon Sep 17 00:00:00 2001 From: Chris Blair Date: Tue, 24 Jan 2012 13:10:42 +0000 Subject: gpio/gpio-stmpe: Correct cleanup for no-irq mode Corrects error condition and driver removal cleanup for the no-irq configuration. ST-Ericsson ID: 399362 ST-Ericsson FOSS-OUT ID: Trivial ST-Ericsson Linux next: NA Change-Id: Ie4d7e49a3f56d6c7f9914d1b28b23cba68a4b750 Signed-off-by: Chris Blair Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/46380 Reviewed-by: QATOOLS Reviewed-by: Linus WALLEIJ --- drivers/gpio/gpio-stmpe.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index 0c228458b8b..c7479292eb2 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c @@ -365,9 +365,11 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev) return 0; out_freeirq: - free_irq(irq, stmpe_gpio); + if (!stmpe->pdata->no_irq) + free_irq(irq, stmpe_gpio); out_removeirq: - stmpe_gpio_irq_remove(stmpe_gpio); + if (!stmpe->pdata->no_irq) + stmpe_gpio_irq_remove(stmpe_gpio); out_disable: stmpe_disable(stmpe, STMPE_BLOCK_GPIO); out_free: @@ -395,8 +397,10 @@ static int __devexit stmpe_gpio_remove(struct platform_device *pdev) stmpe_disable(stmpe, STMPE_BLOCK_GPIO); - free_irq(irq, stmpe_gpio); - stmpe_gpio_irq_remove(stmpe_gpio); + if (!stmpe->pdata->no_irq) { + free_irq(irq, stmpe_gpio); + stmpe_gpio_irq_remove(stmpe_gpio); + } platform_set_drvdata(pdev, NULL); kfree(stmpe_gpio); -- cgit v1.2.3 From 4b076b0bc5c2cbc2a12821826b005295ba5a6726 Mon Sep 17 00:00:00 2001 From: Chris Blair Date: Thu, 26 Jan 2012 08:57:32 +0000 Subject: gpio/stmpe: Change implementation of noirq mode Removes the use of the new no_irq platform data member and instead uses the value obtained for the cell irq to know if irqs are supported or not. If irqs are not supported, the device will not have been given an irq resource and the irq value will be invalid. ST-Ericsson ID: 399362 ST-Ericsson FOSS-OUT ID: Trivial ST-Ericsson Linux next: NA Change-Id: Ib7e88229b58178952405074295c70471ea1a0681 Signed-off-by: Chris Blair Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/46690 Reviewed-by: QATOOLS Reviewed-by: Linus WALLEIJ --- drivers/gpio/gpio-stmpe.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index c7479292eb2..094c5c4fd7f 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c @@ -311,11 +311,7 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev) pdata = stmpe->pdata->gpio; - if (!stmpe->pdata->no_irq) { - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; - } + irq = platform_get_irq(pdev, 0); stmpe_gpio = kzalloc(sizeof(struct stmpe_gpio), GFP_KERNEL); if (!stmpe_gpio) @@ -332,13 +328,18 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev) stmpe_gpio->chip.dev = &pdev->dev; stmpe_gpio->chip.base = pdata ? pdata->gpio_base : -1; - stmpe_gpio->irq_base = stmpe->irq_base + STMPE_INT_GPIO(0); + if (irq >= 0) + stmpe_gpio->irq_base = stmpe->irq_base + STMPE_INT_GPIO(0); + else + dev_info(&pdev->dev, + "device configured in no-irq mode; " + "irqs are not available\n"); ret = stmpe_enable(stmpe, STMPE_BLOCK_GPIO); if (ret) goto out_free; - if (!stmpe->pdata->no_irq) { + if (irq >= 0) { ret = stmpe_gpio_irq_init(stmpe_gpio); if (ret) goto out_disable; @@ -365,10 +366,10 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev) return 0; out_freeirq: - if (!stmpe->pdata->no_irq) + if (irq >= 0) free_irq(irq, stmpe_gpio); out_removeirq: - if (!stmpe->pdata->no_irq) + if (irq >= 0) stmpe_gpio_irq_remove(stmpe_gpio); out_disable: stmpe_disable(stmpe, STMPE_BLOCK_GPIO); @@ -397,7 +398,7 @@ static int __devexit stmpe_gpio_remove(struct platform_device *pdev) stmpe_disable(stmpe, STMPE_BLOCK_GPIO); - if (!stmpe->pdata->no_irq) { + if (irq >= 0) { free_irq(irq, stmpe_gpio); stmpe_gpio_irq_remove(stmpe_gpio); } -- cgit v1.2.3 From 7e4da9c6f56228dca029c1d25ee73074793a0270 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 1 Feb 2012 14:50:02 +0100 Subject: mfd/ab8500: gpio: support AB9540 variant The AB9540 variant of the AB8500 is basically close enough to use the same driver. This adds the new registers and deviations for this new chip variant. Signed-off-by: Maxime Coquelin Signed-off-by: Alex Macro Signed-off-by: Michel Jaouen Signed-off-by: Linus Walleij --- include/linux/mfd/abx500/ab8500-gpio.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/mfd/abx500/ab8500-gpio.h b/include/linux/mfd/abx500/ab8500-gpio.h index d88e3025317..c362b805104 100644 --- a/include/linux/mfd/abx500/ab8500-gpio.h +++ b/include/linux/mfd/abx500/ab8500-gpio.h @@ -12,12 +12,14 @@ /* * Platform data to register a block: only the initial gpio/irq number. + * Array sizes are large enough to contain all AB8500 and AB9540 GPIO + * registers. */ struct ab8500_gpio_platform_data { int gpio_base; u32 irq_base; - u8 config_reg[7]; + u8 config_reg[8]; u8 config_direction[6]; u8 config_pullups[6]; }; -- cgit v1.2.3 From fc8544a93978146c0125c129d0c9d19a9b0db2cd Mon Sep 17 00:00:00 2001 From: Philippe Langlais Date: Wed, 29 Feb 2012 14:56:10 +0100 Subject: mfd/ab8500: gpio: remaining mainline differences This collects the AB9540 changes that could not be included in the mainline patch set due to differences in the internal code (esp re GPIO driver). Signed-off-by: Linus Walleij --- include/linux/mfd/abx500/ab8500-gpio.h | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/include/linux/mfd/abx500/ab8500-gpio.h b/include/linux/mfd/abx500/ab8500-gpio.h index c362b805104..67ac32c1dcb 100644 --- a/include/linux/mfd/abx500/ab8500-gpio.h +++ b/include/linux/mfd/abx500/ab8500-gpio.h @@ -20,8 +20,8 @@ struct ab8500_gpio_platform_data { int gpio_base; u32 irq_base; u8 config_reg[8]; - u8 config_direction[6]; - u8 config_pullups[6]; + u8 config_direction[7]; + u8 config_pullups[7]; }; enum ab8500_pin { @@ -67,6 +67,26 @@ enum ab8500_pin { AB8500_PIN_GPIO40, AB8500_PIN_GPIO41, AB8500_PIN_GPIO42, + /* AB9540 GPIO extends support provided by AB8500 */ + AB9540_PIN_GPIO43, + AB9540_PIN_GPIO44, + AB9540_PIN_GPIO45, + AB9540_PIN_GPIO46, + AB9540_PIN_GPIO47, + AB9540_PIN_GPIO48, + AB9540_PIN_GPIO49, + AB9540_PIN_GPIO50, + AB9540_PIN_GPIO51, + AB9540_PIN_GPIO52, + AB9540_PIN_GPIO53, + /* + * AB9540_PIN_GPIO60 is configured, in the AB9540 GPIO registers, where + * AB9540_PIN_GPIO54 would be expected. AB9540_PIN_GPIO54 to + * AB9540_PIN_GPIO59 do not exist and no reserved space has been left + * for them in the registers. Therefore the enum goes directly from + * AB9540_PIN_GPIO53 to AB9540_PIN_GPIO60. + */ + AB9540_PIN_GPIO60, }; int ab8500_config_pulldown(struct device *dev, -- cgit v1.2.3 From 6fb5704ecd4b7763edebc5a2bc0f1bbb7e2ee29e Mon Sep 17 00:00:00 2001 From: Michel JAOUEN Date: Wed, 25 Jan 2012 09:29:39 +0100 Subject: drivers: gpio ab9540 ST-Ericsson ID: 409625 ST-Ericsson FOSS-OUT ID: trivial ST-Ericsson Linux next: NA Change-Id: I1daa8fb12ee70c558a17aa187c5985ddfbbd2ccd Signed-off-by: Maxime Coquelin Signed-off-by: Alex MACRO Signed-off-by: Michel JAOUEN Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/46633 Reviewed-by: QATOOLS Reviewed-by: QABUILD Reviewed-by: Jonas ABERG Reviewed-by: Bengt JONSSON Reviewed-by: Bibek BASU --- drivers/gpio/gpio-ab8500.c | 92 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 70 insertions(+), 22 deletions(-) diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c index 273f7caba22..b78cf2f9530 100644 --- a/drivers/gpio/gpio-ab8500.c +++ b/drivers/gpio/gpio-ab8500.c @@ -22,6 +22,13 @@ #include +/* + * The AB9540 GPIO support is an extended version of the + * AB8500 GPIO support. The AB9540 supports an additional + * (7th) register so that more GPIO may be configured and + * used. + */ + /* * GPIO registers offset * Bank: 0x10 @@ -32,6 +39,7 @@ #define AB8500_GPIO_SEL4_REG 0x03 #define AB8500_GPIO_SEL5_REG 0x04 #define AB8500_GPIO_SEL6_REG 0x05 +#define AB9540_GPIO_SEL7_REG 0x06 #define AB8500_GPIO_DIR1_REG 0x10 #define AB8500_GPIO_DIR2_REG 0x11 @@ -39,6 +47,7 @@ #define AB8500_GPIO_DIR4_REG 0x13 #define AB8500_GPIO_DIR5_REG 0x14 #define AB8500_GPIO_DIR6_REG 0x15 +#define AB9540_GPIO_DIR7_REG 0x16 #define AB8500_GPIO_OUT1_REG 0x20 #define AB8500_GPIO_OUT2_REG 0x21 @@ -46,6 +55,7 @@ #define AB8500_GPIO_OUT4_REG 0x23 #define AB8500_GPIO_OUT5_REG 0x24 #define AB8500_GPIO_OUT6_REG 0x25 +#define AB9540_GPIO_OUT7_REG 0x26 #define AB8500_GPIO_PUD1_REG 0x30 #define AB8500_GPIO_PUD2_REG 0x31 @@ -53,6 +63,7 @@ #define AB8500_GPIO_PUD4_REG 0x33 #define AB8500_GPIO_PUD5_REG 0x34 #define AB8500_GPIO_PUD6_REG 0x35 +#define AB9540_GPIO_PUD7_REG 0x36 #define AB8500_GPIO_IN1_REG 0x40 #define AB8500_GPIO_IN2_REG 0x41 @@ -60,9 +71,12 @@ #define AB8500_GPIO_IN4_REG 0x43 #define AB8500_GPIO_IN5_REG 0x44 #define AB8500_GPIO_IN6_REG 0x45 +#define AB9540_GPIO_IN7_REG 0x46 #define AB8500_GPIO_ALTFUN_REG 0x50 -#define ALTFUN_REG_INDEX 6 +#define AB8500_ALTFUN_REG_INDEX 6 +#define AB9540_ALTFUN_REG_INDEX 7 #define AB8500_NUM_GPIO 42 +#define AB9540_NUM_GPIO 54 #define AB8500_NUM_VIR_GPIO_IRQ 16 enum ab8500_gpio_action { @@ -73,6 +87,11 @@ enum ab8500_gpio_action { UNMASK }; +struct ab8500_gpio_irq_cluster { + int start; + int end; +}; + struct ab8500_gpio { struct gpio_chip chip; struct ab8500 *parent; @@ -82,7 +101,32 @@ struct ab8500_gpio { enum ab8500_gpio_action irq_action; u16 rising; u16 falling; + struct ab8500_gpio_irq_cluster *irq_cluster; + int irq_cluster_size; +}; + +/* + * Only some GPIOs are interrupt capable, and they are + * organized in discontiguous clusters: + * + * GPIO6 to GPIO13 + * GPIO24 and GPIO25 + * GPIO36 to GPIO41 + * GPIO50 to GPIO54 (AB9540 only) + */ +static struct ab8500_gpio_irq_cluster ab8500_irq_clusters[] = { + {.start = 5, .end = 12}, /* GPIO numbers start from 1 */ + {.start = 23, .end = 24}, + {.start = 35, .end = 40}, +}; + +static struct ab8500_gpio_irq_cluster ab9540_irq_clusters[] = { + {.start = 5, .end = 12}, /* GPIO numbers start from 1 */ + {.start = 23, .end = 24}, + {.start = 35, .end = 40}, + {.start = 49, .end = 53}, }; + /** * to_ab8500_gpio() - get the pointer to ab8500_gpio * @chip: Member of the structure ab8500_gpio @@ -162,28 +206,13 @@ static int ab8500_gpio_direction_input(struct gpio_chip *chip, unsigned offset) static int ab8500_gpio_to_irq(struct gpio_chip *chip, unsigned offset) { - /* - * Only some GPIOs are interrupt capable, and they are - * organized in discontiguous clusters: - * - * GPIO6 to GPIO13 - * GPIO24 and GPIO25 - * GPIO36 to GPIO41 - */ - static struct ab8500_gpio_irq_cluster { - int start; - int end; - } clusters[] = { - {.start = 5, .end = 12}, /* GPIO numbers start from 1 */ - {.start = 23, .end = 24}, - {.start = 35, .end = 40}, - }; struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip); int base = ab8500_gpio->irq_base; int i; - for (i = 0; i < ARRAY_SIZE(clusters); i++) { - struct ab8500_gpio_irq_cluster *cluster = &clusters[i]; + for (i = 0; i < ab8500_gpio->irq_cluster_size; i++) { + struct ab8500_gpio_irq_cluster *cluster = + &ab8500_gpio->irq_cluster[i]; if (offset >= cluster->start && offset <= cluster->end) return base + offset - cluster->start; @@ -412,6 +441,8 @@ static int __devinit ab8500_gpio_probe(struct platform_device *pdev) struct ab8500_gpio *ab8500_gpio; int ret; int i; + int last_gpio_sel_reg; + int altfun_reg_index; pdata = ab8500_pdata->gpio; if (!pdata) { @@ -427,10 +458,27 @@ static int __devinit ab8500_gpio_probe(struct platform_device *pdev) ab8500_gpio->dev = &pdev->dev; ab8500_gpio->parent = dev_get_drvdata(pdev->dev.parent); ab8500_gpio->chip = ab8500gpio_chip; - ab8500_gpio->chip.ngpio = AB8500_NUM_GPIO; ab8500_gpio->chip.dev = &pdev->dev; ab8500_gpio->chip.base = pdata->gpio_base; ab8500_gpio->irq_base = pdata->irq_base; + + /* Configure GPIO Settings for specific AB devices */ + if (cpu_is_u9540()) { + ab8500_gpio->chip.ngpio = AB9540_NUM_GPIO; + ab8500_gpio->irq_cluster = ab9540_irq_clusters; + ab8500_gpio->irq_cluster_size = + ARRAY_SIZE(ab9540_irq_clusters); + last_gpio_sel_reg = AB9540_GPIO_SEL7_REG; + altfun_reg_index = AB9540_ALTFUN_REG_INDEX; + } else { + ab8500_gpio->chip.ngpio = AB8500_NUM_GPIO; + ab8500_gpio->irq_cluster = ab8500_irq_clusters; + ab8500_gpio->irq_cluster_size = + ARRAY_SIZE(ab8500_irq_clusters); + last_gpio_sel_reg = AB8500_GPIO_SEL6_REG; + altfun_reg_index = AB8500_ALTFUN_REG_INDEX; + } + /* initialize the lock */ mutex_init(&ab8500_gpio->lock); /* @@ -439,7 +487,7 @@ static int __devinit ab8500_gpio_probe(struct platform_device *pdev) * These values are for selecting the PINs as * GPIO or alternate function */ - for (i = AB8500_GPIO_SEL1_REG; i <= AB8500_GPIO_SEL6_REG; i++) { + for (i = AB8500_GPIO_SEL1_REG; i <= last_gpio_sel_reg; i++) { ret = abx500_set_register_interruptible(ab8500_gpio->dev, AB8500_MISC, i, pdata->config_reg[i]); @@ -460,7 +508,7 @@ static int __devinit ab8500_gpio_probe(struct platform_device *pdev) } ret = abx500_set_register_interruptible(ab8500_gpio->dev, AB8500_MISC, AB8500_GPIO_ALTFUN_REG, - pdata->config_reg[ALTFUN_REG_INDEX]); + pdata->config_reg[altfun_reg_index]); if (ret < 0) goto out_free; -- cgit v1.2.3 From ca1e86c165384cf0aaa2825977546757e65c9b77 Mon Sep 17 00:00:00 2001 From: Michel JAOUEN Date: Thu, 19 Jan 2012 17:33:37 +0100 Subject: gpio: mach-ux500: support ape u9450 id, cpu, irq, reg, timer, uart, l2 cache. ST-Ericsson ID: 409625 Signed-off-by: Michel JAOUEN --- arch/arm/Kconfig | 2 +- arch/arm/mach-ux500/include/mach/gpio.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index dfb0312f4e7..628a42836e6 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1577,7 +1577,7 @@ config LOCAL_TIMERS config ARCH_NR_GPIO int default 1024 if ARCH_SHMOBILE || ARCH_TEGRA - default 350 if ARCH_U8500 + default 366 if ARCH_U8500 default 0 help Maximum number of GPIOs in the system. diff --git a/arch/arm/mach-ux500/include/mach/gpio.h b/arch/arm/mach-ux500/include/mach/gpio.h index 2d3bb8f47ce..e0d903af605 100644 --- a/arch/arm/mach-ux500/include/mach/gpio.h +++ b/arch/arm/mach-ux500/include/mach/gpio.h @@ -9,7 +9,7 @@ #if CONFIG_ARCH_NR_GPIO > 0 #define ARCH_NR_GPIOS CONFIG_ARCH_NR_GPIO #else -#define ARCH_NR_GPIOS 355 +#define ARCH_NR_GPIOS 366 #endif #define NOMADIK_NR_GPIO 288 -- cgit v1.2.3 From fb5bfed075cbabac72a40cda7db90bf77393fe8d Mon Sep 17 00:00:00 2001 From: Naga Radhesh Date: Wed, 22 Feb 2012 15:18:51 +0530 Subject: gpio-ab8500:Add support for AB8505 Chip Number of gpio pins has been changed for AB8505, so change gpio configurations according to AB8505. ST-Ericsson ID: 366316 ST-Ericsson Linux next: NA ST-Ericsson FOSS-OUT ID: Trivial Change-Id:Ifcd5068e4b12de262942ab647c007cf909cbe243 Signed-off-by: Naga Radhesh Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/45797 Reviewed-by: QATOOLS Reviewed-by: QABUILD Reviewed-by: Bibek BASU Reviewed-by: Jonas ABERG Reviewed-by: Srinidhi KASAGAR --- drivers/gpio/gpio-ab8500.c | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c index b78cf2f9530..86163681c24 100644 --- a/drivers/gpio/gpio-ab8500.c +++ b/drivers/gpio/gpio-ab8500.c @@ -77,6 +77,7 @@ #define AB9540_ALTFUN_REG_INDEX 7 #define AB8500_NUM_GPIO 42 #define AB9540_NUM_GPIO 54 +#define AB8505_NUM_GPIO 53 #define AB8500_NUM_VIR_GPIO_IRQ 16 enum ab8500_gpio_action { @@ -127,6 +128,24 @@ static struct ab8500_gpio_irq_cluster ab9540_irq_clusters[] = { {.start = 49, .end = 53}, }; +/* + * For AB8505 Only some GPIOs are interrupt capable, and they are + * organized in discontiguous clusters: + * + * GPIO10 to GPIO11 + * GPIO13 + * GPIO40 and GPIO41 + * GPIO50 + * GPIO52 to GPIO53 + */ +static struct ab8500_gpio_irq_cluster ab8505_irq_clusters[] = { + {.start = 9, .end = 10}, /* GPIO numbers start from 1 */ + {.start = 12, .end = 12}, + {.start = 39, .end = 40}, + {.start = 49, .end = 49}, + {.start = 51, .end = 52}, +}; + /** * to_ab8500_gpio() - get the pointer to ab8500_gpio * @chip: Member of the structure ab8500_gpio @@ -435,6 +454,7 @@ static void ab8500_gpio_irq_remove(struct ab8500_gpio *ab8500_gpio) static int __devinit ab8500_gpio_probe(struct platform_device *pdev) { + struct ab8500 *parent = dev_get_drvdata(pdev->dev.parent); struct ab8500_platform_data *ab8500_pdata = dev_get_platdata(pdev->dev.parent); struct ab8500_gpio_platform_data *pdata; @@ -471,12 +491,21 @@ static int __devinit ab8500_gpio_probe(struct platform_device *pdev) last_gpio_sel_reg = AB9540_GPIO_SEL7_REG; altfun_reg_index = AB9540_ALTFUN_REG_INDEX; } else { - ab8500_gpio->chip.ngpio = AB8500_NUM_GPIO; - ab8500_gpio->irq_cluster = ab8500_irq_clusters; - ab8500_gpio->irq_cluster_size = - ARRAY_SIZE(ab8500_irq_clusters); - last_gpio_sel_reg = AB8500_GPIO_SEL6_REG; - altfun_reg_index = AB8500_ALTFUN_REG_INDEX; + if (is_ab8505(parent)) { + ab8500_gpio->chip.ngpio = AB8505_NUM_GPIO; + ab8500_gpio->irq_cluster = ab8505_irq_clusters; + ab8500_gpio->irq_cluster_size = + ARRAY_SIZE(ab8505_irq_clusters); + last_gpio_sel_reg = AB9540_GPIO_SEL7_REG; + altfun_reg_index = AB9540_ALTFUN_REG_INDEX; + } else { + ab8500_gpio->chip.ngpio = AB8500_NUM_GPIO; + ab8500_gpio->irq_cluster = ab8500_irq_clusters; + ab8500_gpio->irq_cluster_size = + ARRAY_SIZE(ab8500_irq_clusters); + last_gpio_sel_reg = AB8500_GPIO_SEL6_REG; + altfun_reg_index = AB8500_ALTFUN_REG_INDEX; + } } /* initialize the lock */ -- cgit v1.2.3 From 1133af78634d3bcfaf3af12eb208d906af36efb5 Mon Sep 17 00:00:00 2001 From: Paer-Olof Haakansson Date: Tue, 28 Feb 2012 16:37:25 +0100 Subject: ab8500-gpio: allow gpios waking system from suspend ST-Ericsson Linux next: NA Depends-On: I5ae895adc38fd2128953010342930cd0c92d27be ST-Ericsson ID: 399003 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I361ace3fc37b010d544a1d906adbce535078dd14 Signed-off-by: Paer-Olof Haakansson Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/50783 Reviewed-by: QABUILD Reviewed-by: Jonas ABERG --- drivers/gpio/gpio-ab8500.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c index 86163681c24..ef75984486c 100644 --- a/drivers/gpio/gpio-ab8500.c +++ b/drivers/gpio/gpio-ab8500.c @@ -329,12 +329,12 @@ static void ab8500_gpio_irq_sync_unlock(struct irq_data *data) if (rising) ret = request_threaded_irq(irq_to_rising(irq), NULL, handle_rising, - IRQF_TRIGGER_RISING, + IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND, "ab8500-gpio-r", ab8500_gpio); if (falling) ret = request_threaded_irq(irq_to_falling(irq), NULL, handle_falling, - IRQF_TRIGGER_FALLING, + IRQF_TRIGGER_FALLING | IRQF_NO_SUSPEND, "ab8500-gpio-f", ab8500_gpio); break; case SHUTDOWN: -- cgit v1.2.3