drivers: gpio: altera_pio add spinlock
Add spinlock for write access to register Signed-off-by: Goh Shun Jing <shun.jing.goh@intel.com>
This commit is contained in:
parent
11a8c5cd9e
commit
029e756009
1 changed files with 29 additions and 2 deletions
|
@ -111,6 +111,10 @@ static int gpio_altera_port_get_raw(const struct device *dev, uint32_t *value)
|
|||
|
||||
addr = reg_base + ALTERA_AVALON_PIO_DATA_OFFSET;
|
||||
|
||||
if (value == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*value = sys_read32((addr));
|
||||
|
||||
return 0;
|
||||
|
@ -119,10 +123,12 @@ static int gpio_altera_port_get_raw(const struct device *dev, uint32_t *value)
|
|||
static int gpio_altera_port_set_bits_raw(const struct device *dev, gpio_port_pins_t mask)
|
||||
{
|
||||
const struct gpio_altera_config *cfg = dev->config;
|
||||
const int outset = cfg->outset;
|
||||
struct gpio_altera_data * const data = dev->data;
|
||||
const uint8_t outset = cfg->outset;
|
||||
const int port_pin_mask = cfg->common.port_pin_mask;
|
||||
uintptr_t reg_base = cfg->reg_base;
|
||||
uint32_t addr;
|
||||
k_spinlock_key_t key;
|
||||
|
||||
if ((port_pin_mask & mask) == 0) {
|
||||
return -EINVAL;
|
||||
|
@ -132,6 +138,8 @@ static int gpio_altera_port_set_bits_raw(const struct device *dev, gpio_port_pin
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
key = k_spin_lock(&data->lock);
|
||||
|
||||
if (outset) {
|
||||
addr = reg_base + ALTERA_AVALON_PIO_SET_BITS;
|
||||
sys_write32(mask, addr);
|
||||
|
@ -140,16 +148,20 @@ static int gpio_altera_port_set_bits_raw(const struct device *dev, gpio_port_pin
|
|||
sys_set_bits(addr, mask);
|
||||
}
|
||||
|
||||
k_spin_unlock(&data->lock, key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_altera_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t mask)
|
||||
{
|
||||
const struct gpio_altera_config *cfg = dev->config;
|
||||
const int outclear = cfg->outclear;
|
||||
struct gpio_altera_data * const data = dev->data;
|
||||
const uint8_t outclear = cfg->outclear;
|
||||
const int port_pin_mask = cfg->common.port_pin_mask;
|
||||
uintptr_t reg_base = cfg->reg_base;
|
||||
uint32_t addr;
|
||||
k_spinlock_key_t key;
|
||||
|
||||
/* Check if mask range within 32 */
|
||||
if ((port_pin_mask & mask) == 0) {
|
||||
|
@ -160,6 +172,8 @@ static int gpio_altera_port_clear_bits_raw(const struct device *dev, gpio_port_p
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
key = k_spin_lock(&data->lock);
|
||||
|
||||
if (outclear) {
|
||||
addr = reg_base + ALTERA_AVALON_PIO_CLEAR_BITS;
|
||||
sys_write32(mask, addr);
|
||||
|
@ -168,6 +182,8 @@ static int gpio_altera_port_clear_bits_raw(const struct device *dev, gpio_port_p
|
|||
sys_clear_bits(addr, mask);
|
||||
}
|
||||
|
||||
k_spin_unlock(&data->lock, key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -189,9 +205,11 @@ static int gpio_altera_pin_interrupt_configure(const struct device *dev,
|
|||
ARG_UNUSED(trig);
|
||||
|
||||
const struct gpio_altera_config *cfg = dev->config;
|
||||
struct gpio_altera_data * const data = dev->data;
|
||||
uintptr_t reg_base = cfg->reg_base;
|
||||
const int port_pin_mask = cfg->common.port_pin_mask;
|
||||
uint32_t addr;
|
||||
k_spinlock_key_t key;
|
||||
|
||||
/* Check if pin number is within range */
|
||||
if ((port_pin_mask & BIT(pin)) == 0) {
|
||||
|
@ -204,6 +222,8 @@ static int gpio_altera_pin_interrupt_configure(const struct device *dev,
|
|||
|
||||
addr = reg_base + ALTERA_AVALON_PIO_IRQ_OFFSET;
|
||||
|
||||
key = k_spin_lock(&data->lock);
|
||||
|
||||
switch (mode) {
|
||||
case GPIO_INT_MODE_DISABLED:
|
||||
/* Disable interrupt of pin */
|
||||
|
@ -220,6 +240,8 @@ static int gpio_altera_pin_interrupt_configure(const struct device *dev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
k_spin_unlock(&data->lock, key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -240,13 +262,18 @@ static void gpio_altera_irq_handler(const struct device *dev)
|
|||
uintptr_t reg_base = cfg->reg_base;
|
||||
uint32_t port_value;
|
||||
uint32_t addr;
|
||||
k_spinlock_key_t key;
|
||||
|
||||
addr = reg_base + ALTERA_AVALON_PIO_IRQ_OFFSET;
|
||||
|
||||
key = k_spin_lock(&data->lock);
|
||||
|
||||
port_value = sys_read32(addr);
|
||||
|
||||
sys_clear_bits(addr, port_value);
|
||||
|
||||
k_spin_unlock(&data->lock, key);
|
||||
|
||||
/* Call the corresponding callback registered for the pin */
|
||||
gpio_fire_callbacks(&data->cb, dev, port_value);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue