summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorPavel Pisa <ppisa@pikron.com>2016-05-19 10:34:18 +0200
committerPavel Pisa <ppisa@pikron.com>2016-05-19 13:21:40 +0200
commit12582291e00261511e7d95636a6498d6cab40615 (patch)
tree756391074b6a495c0558fb7c39ad3b26c43b12a6 /c
parentarm/raspberrypi: correct GPIO pin function selection. (diff)
downloadrtems-12582291e00261511e7d95636a6498d6cab40615.tar.bz2
arm/raspberrypi: add locking around GPIO pin function selection.
This is required if function or direction is changed by some driver after start of thread multitasking or in interrupts drivers. There can be problem with calling GPIO function selection before data section is initialized. But actual ticket lock implementation seems to be compatible even with memory initialized to zero oven on SMP.
Diffstat (limited to 'c')
-rw-r--r--c/src/lib/libbsp/arm/raspberrypi/gpio/rpi-gpio.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/arm/raspberrypi/gpio/rpi-gpio.c b/c/src/lib/libbsp/arm/raspberrypi/gpio/rpi-gpio.c
index 40acd84483..2788d36237 100644
--- a/c/src/lib/libbsp/arm/raspberrypi/gpio/rpi-gpio.c
+++ b/c/src/lib/libbsp/arm/raspberrypi/gpio/rpi-gpio.c
@@ -21,6 +21,8 @@
#include <stdlib.h>
+RTEMS_INTERRUPT_LOCK_DEFINE( static, rtems_gpio_bsp_lock, "rtems_gpio_bsp_lock" );
+
/* Calculates a bitmask to assign an alternate function to a given pin. */
#define SELECT_PIN_FUNCTION(fn, pn) (fn << ((pn % 10) * 3))
@@ -56,11 +58,14 @@ static rtems_status_code rpi_select_pin_function(
(pin / 10);
uint32_t reg_old;
uint32_t reg_new;
+ rtems_interrupt_lock_context lock_context;
+ rtems_interrupt_lock_acquire(&rtems_gpio_bsp_lock, &lock_context);
reg_new = reg_old = *pin_addr;
reg_new &= ~SELECT_PIN_FUNCTION(RPI_ALT_FUNC_MASK, pin);
reg_new |= SELECT_PIN_FUNCTION(type, pin);
*pin_addr = reg_new;
+ rtems_interrupt_lock_release(&rtems_gpio_bsp_lock, &lock_context);
return RTEMS_SUCCESSFUL;
}