From 328274f4e0f835112b41901e106884adb1fffa08 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 fd0ba2d130f49f50be42c1ceb70c49e80daa0eac 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 e38029e2d7fce203cf2af29b24f0f487f475ac57 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 9ab268f9e19b472fdccb80ec005f48ce5150fa7f 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 8dd8abfdd80dd35842e85c738dffee2876645124 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 e03653d6935..6226d0cd30a 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -504,7 +504,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 57d8c523fcbd4aecda7c623b9c0e249bbf3cb359 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 de42fd4eff98d879c5b849838c65757ba8a542f4 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 0099b43a30a8466328fcea4cd48de272bec59a39 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 2387c207ea8..5caa615158d 100644 --- a/include/linux/mfd/abx500/ab8500-gpio.h +++ b/include/linux/mfd/abx500/ab8500-gpio.h @@ -20,4 +20,55 @@ struct ab8500_gpio_platform_data { u8 config_reg[8]; }; +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 1bea4f028ddf0adab93f6d96c35273f531f6db27 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 0de47761adc5b60a3e09304979e78d25f17297a9 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 c982d313ab5cf4349fc6e0cb4b1597427212a980 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 5caa615158d..94e85caf71f 100644 --- a/include/linux/mfd/abx500/ab8500-gpio.h +++ b/include/linux/mfd/abx500/ab8500-gpio.h @@ -18,6 +18,8 @@ struct ab8500_gpio_platform_data { int gpio_base; u32 irq_base; u8 config_reg[8]; + u8 config_direction[6]; + u8 config_pullups[6]; }; enum ab8500_pin { -- cgit v1.2.3 From bd55bf15187ac6f4fd87717018dea162b3290d80 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 94e85caf71f..48325dbce17 100644 --- a/include/linux/mfd/abx500/ab8500-gpio.h +++ b/include/linux/mfd/abx500/ab8500-gpio.h @@ -67,6 +67,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 f51908bfe78a9ceabd197dfcf6aa67b430de277a 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 f54bb9b1eb976f00c8460b7ba834b61bceb30ef8 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 48325dbce17..c362b805104 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. * Array sizes are large enough to contain all AB8500 and AB9540 GPIO @@ -23,7 +25,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 86be4a50f345ae5b3283a6f84775620797fc0756 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 12f0c3bd27e0687c58831413c8192841f68832b2 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 fcfae79728374fea7ccab95f2e08cabc203c92ea 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 b1c4c311f0040e398e1c27d77b442b8c19d30e86 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 d0771611b09d9cb17ec508a2b761416ba7221c83 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 b4950ad9966ed00df6153956b831874708ea3122 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 36586dba6fa..ef2ea147047 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1609,7 +1609,7 @@ config LOCAL_TIMERS config ARCH_NR_GPIO int default 1024 if ARCH_SHMOBILE || ARCH_TEGRA - default 355 if ARCH_U8500 + default 366 if ARCH_U8500 default 264 if MACH_H4700 default 0 help 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 22042f07e714d64427fe1e0c4dd7b37f2eaf229d 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 84ad014b2308a14a0696b52480d7fee03bca4b96 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 From 441386c9d8d142c903361360065cbbe2fbe57a6b Mon Sep 17 00:00:00 2001 From: Philippe Langlais Date: Mon, 23 Apr 2012 14:39:31 +0200 Subject: gpio/nomadik: use ioremap() instead of static mappings We were using a custom io_p2v() (physical-to-virtual) translation macro, but it's fully possible to just ioremap() this memory now, so skip use of static addresses altogether. Signed-off-by: Linus Walleij --- drivers/gpio/gpio-nomadik.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c index 50693a46d1b..f2fbb9e3027 100644 --- a/drivers/gpio/gpio-nomadik.c +++ b/drivers/gpio/gpio-nomadik.c @@ -28,7 +28,6 @@ #include #include -#include #include /* @@ -1146,6 +1145,7 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) struct resource *res; struct clk *clk; int secondary_irq; + void __iomem *base; int irq; int ret; @@ -1176,10 +1176,16 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) goto out; } + base = ioremap(res->start, resource_size(res)); + if (!base) { + ret = -ENOMEM; + goto out_release; + } + clk = clk_get(&dev->dev, NULL); if (IS_ERR(clk)) { ret = PTR_ERR(clk); - goto out_release; + goto out_unmap; } nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL); @@ -1193,7 +1199,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 = base; nmk_chip->chip = nmk_gpio_template; nmk_chip->parent_irq = irq; nmk_chip->secondary_parent_irq = secondary_irq; @@ -1233,6 +1239,8 @@ out_free: out_clk: clk_disable(clk); clk_put(clk); +out_unmap: + iounmap(base); out_release: release_mem_region(res->start, resource_size(res)); out: -- cgit v1.2.3