diff options
Diffstat (limited to 'arch/arm/plat-nomadik/gpio.c')
-rw-r--r-- | arch/arm/plat-nomadik/gpio.c | 74 |
1 files changed, 59 insertions, 15 deletions
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index 977c8f9a07a2..85e6fd212a41 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c | |||
@@ -102,6 +102,22 @@ static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip, | |||
102 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC); | 102 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC); |
103 | } | 103 | } |
104 | 104 | ||
105 | static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip, | ||
106 | unsigned offset, int val) | ||
107 | { | ||
108 | if (val) | ||
109 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATS); | ||
110 | else | ||
111 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATC); | ||
112 | } | ||
113 | |||
114 | static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip, | ||
115 | unsigned offset, int val) | ||
116 | { | ||
117 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS); | ||
118 | __nmk_gpio_set_output(nmk_chip, offset, val); | ||
119 | } | ||
120 | |||
105 | static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | 121 | static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, |
106 | pin_cfg_t cfg) | 122 | pin_cfg_t cfg) |
107 | { | 123 | { |
@@ -118,20 +134,29 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | |||
118 | [3] /* illegal */ = "??" | 134 | [3] /* illegal */ = "??" |
119 | }; | 135 | }; |
120 | static const char *slpmnames[] = { | 136 | static const char *slpmnames[] = { |
121 | [NMK_GPIO_SLPM_INPUT] = "input", | 137 | [NMK_GPIO_SLPM_INPUT] = "input/wakeup", |
122 | [NMK_GPIO_SLPM_NOCHANGE] = "no-change", | 138 | [NMK_GPIO_SLPM_NOCHANGE] = "no-change/no-wakeup", |
123 | }; | 139 | }; |
124 | 140 | ||
125 | int pin = PIN_NUM(cfg); | 141 | int pin = PIN_NUM(cfg); |
126 | int pull = PIN_PULL(cfg); | 142 | int pull = PIN_PULL(cfg); |
127 | int af = PIN_ALT(cfg); | 143 | int af = PIN_ALT(cfg); |
128 | int slpm = PIN_SLPM(cfg); | 144 | int slpm = PIN_SLPM(cfg); |
145 | int output = PIN_DIR(cfg); | ||
146 | int val = PIN_VAL(cfg); | ||
129 | 147 | ||
130 | dev_dbg(nmk_chip->chip.dev, "pin %d: af %s, pull %s, slpm %s\n", | 148 | dev_dbg(nmk_chip->chip.dev, "pin %d: af %s, pull %s, slpm %s (%s%s)\n", |
131 | pin, afnames[af], pullnames[pull], slpmnames[slpm]); | 149 | pin, afnames[af], pullnames[pull], slpmnames[slpm], |
150 | output ? "output " : "input", | ||
151 | output ? (val ? "high" : "low") : ""); | ||
152 | |||
153 | if (output) | ||
154 | __nmk_gpio_make_output(nmk_chip, offset, val); | ||
155 | else { | ||
156 | __nmk_gpio_make_input(nmk_chip, offset); | ||
157 | __nmk_gpio_set_pull(nmk_chip, offset, pull); | ||
158 | } | ||
132 | 159 | ||
133 | __nmk_gpio_make_input(nmk_chip, offset); | ||
134 | __nmk_gpio_set_pull(nmk_chip, offset, pull); | ||
135 | __nmk_gpio_set_slpm(nmk_chip, offset, slpm); | 160 | __nmk_gpio_set_slpm(nmk_chip, offset, slpm); |
136 | __nmk_gpio_set_mode(nmk_chip, offset, af); | 161 | __nmk_gpio_set_mode(nmk_chip, offset, af); |
137 | } | 162 | } |
@@ -200,6 +225,10 @@ EXPORT_SYMBOL(nmk_config_pins); | |||
200 | * changed to an input (with pullup/down enabled) in sleep and deep sleep. If | 225 | * changed to an input (with pullup/down enabled) in sleep and deep sleep. If |
201 | * @mode is NMK_GPIO_SLPM_NOCHANGE, the pin remains in the state it was | 226 | * @mode is NMK_GPIO_SLPM_NOCHANGE, the pin remains in the state it was |
202 | * configured even when in sleep and deep sleep. | 227 | * configured even when in sleep and deep sleep. |
228 | * | ||
229 | * On DB8500v2 onwards, this setting loses the previous meaning and instead | ||
230 | * indicates if wakeup detection is enabled on the pin. Note that | ||
231 | * enable_irq_wake() will automatically enable wakeup detection. | ||
203 | */ | 232 | */ |
204 | int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode) | 233 | int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode) |
205 | { | 234 | { |
@@ -367,7 +396,27 @@ static void nmk_gpio_irq_unmask(unsigned int irq) | |||
367 | 396 | ||
368 | static int nmk_gpio_irq_set_wake(unsigned int irq, unsigned int on) | 397 | static int nmk_gpio_irq_set_wake(unsigned int irq, unsigned int on) |
369 | { | 398 | { |
370 | return nmk_gpio_irq_modify(irq, WAKE, on); | 399 | struct nmk_gpio_chip *nmk_chip; |
400 | unsigned long flags; | ||
401 | int gpio; | ||
402 | |||
403 | gpio = NOMADIK_IRQ_TO_GPIO(irq); | ||
404 | nmk_chip = get_irq_chip_data(irq); | ||
405 | if (!nmk_chip) | ||
406 | return -EINVAL; | ||
407 | |||
408 | spin_lock_irqsave(&nmk_chip->lock, flags); | ||
409 | #ifdef CONFIG_ARCH_U8500 | ||
410 | if (cpu_is_u8500v2()) { | ||
411 | __nmk_gpio_set_slpm(nmk_chip, gpio, | ||
412 | on ? NMK_GPIO_SLPM_WAKEUP_ENABLE | ||
413 | : NMK_GPIO_SLPM_WAKEUP_DISABLE); | ||
414 | } | ||
415 | #endif | ||
416 | __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on); | ||
417 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | ||
418 | |||
419 | return 0; | ||
371 | } | 420 | } |
372 | 421 | ||
373 | static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) | 422 | static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) |
@@ -495,12 +544,8 @@ static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset, | |||
495 | { | 544 | { |
496 | struct nmk_gpio_chip *nmk_chip = | 545 | struct nmk_gpio_chip *nmk_chip = |
497 | container_of(chip, struct nmk_gpio_chip, chip); | 546 | container_of(chip, struct nmk_gpio_chip, chip); |
498 | u32 bit = 1 << offset; | ||
499 | 547 | ||
500 | if (val) | 548 | __nmk_gpio_set_output(nmk_chip, offset, val); |
501 | writel(bit, nmk_chip->addr + NMK_GPIO_DATS); | ||
502 | else | ||
503 | writel(bit, nmk_chip->addr + NMK_GPIO_DATC); | ||
504 | } | 549 | } |
505 | 550 | ||
506 | static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset, | 551 | static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset, |
@@ -509,8 +554,7 @@ static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset, | |||
509 | struct nmk_gpio_chip *nmk_chip = | 554 | struct nmk_gpio_chip *nmk_chip = |
510 | container_of(chip, struct nmk_gpio_chip, chip); | 555 | container_of(chip, struct nmk_gpio_chip, chip); |
511 | 556 | ||
512 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS); | 557 | __nmk_gpio_make_output(nmk_chip, offset, val); |
513 | nmk_gpio_set_output(chip, offset, val); | ||
514 | 558 | ||
515 | return 0; | 559 | return 0; |
516 | } | 560 | } |
@@ -534,7 +578,7 @@ static struct gpio_chip nmk_gpio_template = { | |||
534 | .can_sleep = 0, | 578 | .can_sleep = 0, |
535 | }; | 579 | }; |
536 | 580 | ||
537 | static int __init nmk_gpio_probe(struct platform_device *dev) | 581 | static int __devinit nmk_gpio_probe(struct platform_device *dev) |
538 | { | 582 | { |
539 | struct nmk_gpio_platform_data *pdata = dev->dev.platform_data; | 583 | struct nmk_gpio_platform_data *pdata = dev->dev.platform_data; |
540 | struct nmk_gpio_chip *nmk_chip; | 584 | struct nmk_gpio_chip *nmk_chip; |