aboutsummaryrefslogtreecommitdiffstats
path: root/arch/avr32/mach-at32ap/pio.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/avr32/mach-at32ap/pio.c')
-rw-r--r--arch/avr32/mach-at32ap/pio.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c
index ed81a8bcb22d..09a274c9d0b7 100644
--- a/arch/avr32/mach-at32ap/pio.c
+++ b/arch/avr32/mach-at32ap/pio.c
@@ -167,22 +167,29 @@ void at32_deselect_pin(unsigned int pin)
167} 167}
168 168
169/* Reserve a pin, preventing anyone else from changing its configuration. */ 169/* Reserve a pin, preventing anyone else from changing its configuration. */
170void __init at32_reserve_pin(unsigned int pin) 170void __init at32_reserve_pin(unsigned int port, u32 pin_mask)
171{ 171{
172 struct pio_device *pio; 172 struct pio_device *pio;
173 unsigned int pin_index = pin & 0x1f;
174 173
175 pio = gpio_to_pio(pin); 174 /* assign and verify pio */
175 pio = gpio_to_pio(port);
176 if (unlikely(!pio)) { 176 if (unlikely(!pio)) {
177 printk("pio: invalid pin %u\n", pin); 177 printk(KERN_WARNING "pio: invalid port %u\n", port);
178 goto fail; 178 goto fail;
179 } 179 }
180 180
181 if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) { 181 /* Test if any of the requested pins is already muxed */
182 printk("%s: pin %u is busy\n", pio->name, pin_index); 182 spin_lock(&pio_lock);
183 if (unlikely(pio->pinmux_mask & pin_mask)) {
184 printk(KERN_WARNING "%s: pin(s) busy (req. 0x%x, busy 0x%x)\n",
185 pio->name, pin_mask, pio->pinmux_mask & pin_mask);
186 spin_unlock(&pio_lock);
183 goto fail; 187 goto fail;
184 } 188 }
185 189
190 /* Reserve pins */
191 pio->pinmux_mask |= pin_mask;
192 spin_unlock(&pio_lock);
186 return; 193 return;
187 194
188fail: 195fail: