From dacdc96cd33dee876c704aaed78f41515abe8a81 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Fri, 3 Dec 2010 20:35:37 +0530 Subject: nomadik-gpio: allow sleep mode dir/pull to differ from normal mode In the nomadik GPIO pin configuration, allow the sleep mode direction and pull configurations to differ from the ones for the normal state. PIN_SLPM_PULL_*, PIN_SLPM_INPUT, PIN_SLPM_OUTPUT* macros are provided for this. Since the hardware does not allow seperate configurations for sleep mode and normal mode, this is implemented by having software remux the configurations as necessary. Reviewed-by: Srinidhi KASAGAR Signed-off-by: Rabin Vincent Signed-off-by: Mian Yousaf Kaukab Signed-off-by: Linus Walleij --- arch/arm/plat-nomadik/gpio.c | 50 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) (limited to 'arch/arm/plat-nomadik/gpio.c') diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index 85e6fd212a4..5fc8e4d8cd2 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c @@ -119,7 +119,7 @@ static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip, } static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, - pin_cfg_t cfg) + pin_cfg_t cfg, bool sleep) { static const char *afnames[] = { [NMK_GPIO_ALT_GPIO] = "GPIO", @@ -145,11 +145,34 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, int output = PIN_DIR(cfg); int val = PIN_VAL(cfg); - dev_dbg(nmk_chip->chip.dev, "pin %d: af %s, pull %s, slpm %s (%s%s)\n", - pin, afnames[af], pullnames[pull], slpmnames[slpm], + dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: af %s, pull %s, slpm %s (%s%s)\n", + pin, cfg, afnames[af], pullnames[pull], slpmnames[slpm], output ? "output " : "input", output ? (val ? "high" : "low") : ""); + if (sleep) { + int slpm_pull = PIN_SLPM_PULL(cfg); + int slpm_output = PIN_SLPM_DIR(cfg); + int slpm_val = PIN_SLPM_VAL(cfg); + + /* + * The SLPM_* values are normal values + 1 to allow zero to + * mean "same as normal". + */ + if (slpm_pull) + pull = slpm_pull - 1; + if (slpm_output) + output = slpm_output - 1; + if (slpm_val) + val = slpm_val - 1; + + dev_dbg(nmk_chip->chip.dev, "pin %d: sleep pull %s, dir %s, val %s\n", + pin, + slpm_pull ? pullnames[pull] : "same", + slpm_output ? (output ? "output" : "input") : "same", + slpm_val ? (val ? "high" : "low") : "same"); + } + if (output) __nmk_gpio_make_output(nmk_chip, offset, val); else { @@ -175,7 +198,7 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, * side-effects. The gpio can be manipulated later using standard GPIO API * calls. */ -int nmk_config_pin(pin_cfg_t cfg) +int nmk_config_pin(pin_cfg_t cfg, bool sleep) { struct nmk_gpio_chip *nmk_chip; int gpio = PIN_NUM(cfg); @@ -186,7 +209,7 @@ int nmk_config_pin(pin_cfg_t cfg) return -EINVAL; spin_lock_irqsave(&nmk_chip->lock, flags); - __nmk_config_pin(nmk_chip, gpio - nmk_chip->chip.base, cfg); + __nmk_config_pin(nmk_chip, gpio - nmk_chip->chip.base, cfg, sleep); spin_unlock_irqrestore(&nmk_chip->lock, flags); return 0; @@ -207,7 +230,7 @@ int nmk_config_pins(pin_cfg_t *cfgs, int num) int i; for (i = 0; i < num; i++) { - int ret = nmk_config_pin(cfgs[i]); + ret = nmk_config_pin(cfgs[i], false); if (ret) break; } @@ -216,6 +239,21 @@ int nmk_config_pins(pin_cfg_t *cfgs, int num) } EXPORT_SYMBOL(nmk_config_pins); +int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num) +{ + int ret = 0; + int i; + + for (i = 0; i < num; i++) { + ret = nmk_config_pin(cfgs[i], true); + if (ret) + break; + } + + return ret; +} +EXPORT_SYMBOL(nmk_config_pins_sleep); + /** * nmk_gpio_set_slpm() - configure the sleep mode of a pin * @gpio: pin number -- cgit v1.2.3-70-g09d2 From 8d568ae5362c00c5b0b8e61bceb1829c8051002e Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Wed, 8 Dec 2010 11:07:54 +0530 Subject: nomadik-gpio: use dev name if no name is specified Platforms may choose not to provide an additional name for the GPIO block. Signed-off-by: Rabin Vincent Signed-off-by: Linus Walleij --- arch/arm/plat-nomadik/gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/plat-nomadik/gpio.c') diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index 5fc8e4d8cd2..eda4e3a11a3 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c @@ -672,7 +672,7 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) chip = &nmk_chip->chip; chip->base = pdata->first_gpio; - chip->label = pdata->name; + chip->label = pdata->name ?: dev_name(&dev->dev); chip->dev = &dev->dev; chip->owner = THIS_MODULE; -- cgit v1.2.3-70-g09d2 From f272c00e6b72a27035b39d30ecb73dee93d6760f Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Mon, 29 Nov 2010 11:16:48 +0100 Subject: ARM: plat-nomadik: irq_data conversion. Signed-off-by: Lennert Buytenhek Acked-by: Rabin Vincent --- arch/arm/plat-nomadik/gpio.c | 56 ++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'arch/arm/plat-nomadik/gpio.c') diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index eda4e3a11a3..1e88ecb846d 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c @@ -356,13 +356,13 @@ static inline int nmk_gpio_get_bitmask(int gpio) return 1 << (gpio % 32); } -static void nmk_gpio_irq_ack(unsigned int irq) +static void nmk_gpio_irq_ack(struct irq_data *d) { int gpio; struct nmk_gpio_chip *nmk_chip; - gpio = NOMADIK_IRQ_TO_GPIO(irq); - nmk_chip = get_irq_chip_data(irq); + gpio = NOMADIK_IRQ_TO_GPIO(d->irq); + nmk_chip = irq_data_get_irq_chip_data(d); if (!nmk_chip) return; writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC); @@ -401,7 +401,7 @@ static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip, } } -static int nmk_gpio_irq_modify(unsigned int irq, enum nmk_gpio_irq_type which, +static int nmk_gpio_irq_modify(struct irq_data *d, enum nmk_gpio_irq_type which, bool enable) { int gpio; @@ -409,8 +409,8 @@ static int nmk_gpio_irq_modify(unsigned int irq, enum nmk_gpio_irq_type which, unsigned long flags; u32 bitmask; - gpio = NOMADIK_IRQ_TO_GPIO(irq); - nmk_chip = get_irq_chip_data(irq); + gpio = NOMADIK_IRQ_TO_GPIO(d->irq); + nmk_chip = irq_data_get_irq_chip_data(d); bitmask = nmk_gpio_get_bitmask(gpio); if (!nmk_chip) return -EINVAL; @@ -422,24 +422,24 @@ static int nmk_gpio_irq_modify(unsigned int irq, enum nmk_gpio_irq_type which, return 0; } -static void nmk_gpio_irq_mask(unsigned int irq) +static void nmk_gpio_irq_mask(struct irq_data *d) { - nmk_gpio_irq_modify(irq, NORMAL, false); + nmk_gpio_irq_modify(d, NORMAL, false); } -static void nmk_gpio_irq_unmask(unsigned int irq) +static void nmk_gpio_irq_unmask(struct irq_data *d) { - nmk_gpio_irq_modify(irq, NORMAL, true); + nmk_gpio_irq_modify(d, NORMAL, true); } -static int nmk_gpio_irq_set_wake(unsigned int irq, unsigned int on) +static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on) { struct nmk_gpio_chip *nmk_chip; unsigned long flags; int gpio; - gpio = NOMADIK_IRQ_TO_GPIO(irq); - nmk_chip = get_irq_chip_data(irq); + gpio = NOMADIK_IRQ_TO_GPIO(d->irq); + nmk_chip = irq_data_get_irq_chip_data(d); if (!nmk_chip) return -EINVAL; @@ -457,9 +457,9 @@ static int nmk_gpio_irq_set_wake(unsigned int irq, unsigned int on) return 0; } -static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) +static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type) { - struct irq_desc *desc = irq_to_desc(irq); + struct irq_desc *desc = irq_to_desc(d->irq); bool enabled = !(desc->status & IRQ_DISABLED); bool wake = desc->wake_depth; int gpio; @@ -467,8 +467,8 @@ static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) unsigned long flags; u32 bitmask; - gpio = NOMADIK_IRQ_TO_GPIO(irq); - nmk_chip = get_irq_chip_data(irq); + gpio = NOMADIK_IRQ_TO_GPIO(d->irq); + nmk_chip = irq_data_get_irq_chip_data(d); bitmask = nmk_gpio_get_bitmask(gpio); if (!nmk_chip) return -EINVAL; @@ -507,11 +507,11 @@ static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) static struct irq_chip nmk_gpio_irq_chip = { .name = "Nomadik-GPIO", - .ack = nmk_gpio_irq_ack, - .mask = nmk_gpio_irq_mask, - .unmask = nmk_gpio_irq_unmask, - .set_type = nmk_gpio_irq_set_type, - .set_wake = nmk_gpio_irq_set_wake, + .irq_ack = nmk_gpio_irq_ack, + .irq_mask = nmk_gpio_irq_mask, + .irq_unmask = nmk_gpio_irq_unmask, + .irq_set_type = nmk_gpio_irq_set_type, + .irq_set_wake = nmk_gpio_irq_set_wake, }; static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) @@ -522,12 +522,12 @@ static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) u32 pending; unsigned int first_irq; - if (host_chip->mask_ack) - host_chip->mask_ack(irq); + if (host_chip->irq_mask_ack) + host_chip->irq_mask_ack(&desc->irq_data); else { - host_chip->mask(irq); - if (host_chip->ack) - host_chip->ack(irq); + host_chip->irq_mask(&desc->irq_data); + if (host_chip->irq_ack) + host_chip->irq_ack(&desc->irq_data); } nmk_chip = get_irq_data(irq); @@ -537,7 +537,7 @@ static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) generic_handle_irq(gpio_irq); } - host_chip->unmask(irq); + host_chip->irq_unmask(&desc->irq_data); } static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip) -- cgit v1.2.3-70-g09d2