diff options
Diffstat (limited to 'drivers/mfd/ucb1x00-core.c')
-rw-r--r-- | drivers/mfd/ucb1x00-core.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c index 8ebda97981e1..febc90cdef7e 100644 --- a/drivers/mfd/ucb1x00-core.c +++ b/drivers/mfd/ucb1x00-core.c | |||
@@ -148,16 +148,22 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset | |||
148 | { | 148 | { |
149 | struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); | 149 | struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); |
150 | unsigned long flags; | 150 | unsigned long flags; |
151 | unsigned old, mask = 1 << offset; | ||
151 | 152 | ||
152 | spin_lock_irqsave(&ucb->io_lock, flags); | 153 | spin_lock_irqsave(&ucb->io_lock, flags); |
153 | ucb->io_dir |= (1 << offset); | 154 | old = ucb->io_out; |
154 | ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); | ||
155 | |||
156 | if (value) | 155 | if (value) |
157 | ucb->io_out |= 1 << offset; | 156 | ucb->io_out |= mask; |
158 | else | 157 | else |
159 | ucb->io_out &= ~(1 << offset); | 158 | ucb->io_out &= ~mask; |
160 | ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); | 159 | |
160 | if (old != ucb->io_out) | ||
161 | ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); | ||
162 | |||
163 | if (!(ucb->io_dir & mask)) { | ||
164 | ucb->io_dir |= mask; | ||
165 | ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); | ||
166 | } | ||
161 | spin_unlock_irqrestore(&ucb->io_lock, flags); | 167 | spin_unlock_irqrestore(&ucb->io_lock, flags); |
162 | 168 | ||
163 | return 0; | 169 | return 0; |