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; |
