ITE: drivers/gpio: Add critical section to avoid race condition
This gpio data register and keyboard scan out register are shared register. To prevent race condition caused by access from different thread, add critical section. Signed-off-by: Tim Lin <tim2.lin@ite.corp-partner.google.com>
This commit is contained in:
parent
b18f229fc8
commit
7a2e86f563
|
@ -11,6 +11,7 @@
|
|||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/drivers/gpio/gpio_utils.h>
|
||||
#include <zephyr/dt-bindings/gpio/ite-it8xxx2-gpio.h>
|
||||
#include <zephyr/irq.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/types.h>
|
||||
|
||||
|
@ -68,6 +69,8 @@ static int gpio_kscan_it8xxx2_configure(const struct device *dev,
|
|||
*reg_ksi_kso_gpod &= ~mask;
|
||||
}
|
||||
|
||||
unsigned int key = irq_lock();
|
||||
|
||||
/* Set level before change to output */
|
||||
if (flags & GPIO_OUTPUT_INIT_HIGH) {
|
||||
*reg_ksi_kso_gdat |= mask;
|
||||
|
@ -75,6 +78,8 @@ static int gpio_kscan_it8xxx2_configure(const struct device *dev,
|
|||
*reg_ksi_kso_gdat &= ~mask;
|
||||
}
|
||||
|
||||
irq_unlock(key);
|
||||
|
||||
/* Set output mode */
|
||||
*reg_ksi_kso_goen |= mask;
|
||||
} else {
|
||||
|
@ -156,11 +161,14 @@ static int gpio_kscan_it8xxx2_port_set_masked_raw(const struct device *dev,
|
|||
{
|
||||
const struct gpio_kscan_cfg *const config = dev->config;
|
||||
volatile uint8_t *reg_ksi_kso_gdat = config->reg_ksi_kso_gdat;
|
||||
unsigned int key = irq_lock();
|
||||
uint8_t out = *reg_ksi_kso_gdat;
|
||||
|
||||
/* Set high/low level to mask pins of the port */
|
||||
*reg_ksi_kso_gdat = ((out & ~mask) | (value & mask));
|
||||
|
||||
irq_unlock(key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -169,10 +177,13 @@ static int gpio_kscan_it8xxx2_port_set_bits_raw(const struct device *dev,
|
|||
{
|
||||
const struct gpio_kscan_cfg *const config = dev->config;
|
||||
volatile uint8_t *reg_ksi_kso_gdat = config->reg_ksi_kso_gdat;
|
||||
unsigned int key = irq_lock();
|
||||
|
||||
/* Set high level to pins of the port */
|
||||
*reg_ksi_kso_gdat |= pins;
|
||||
|
||||
irq_unlock(key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -181,10 +192,13 @@ static int gpio_kscan_it8xxx2_port_clear_bits_raw(const struct device *dev,
|
|||
{
|
||||
const struct gpio_kscan_cfg *const config = dev->config;
|
||||
volatile uint8_t *reg_ksi_kso_gdat = config->reg_ksi_kso_gdat;
|
||||
unsigned int key = irq_lock();
|
||||
|
||||
/* Set low level to pins of the port */
|
||||
*reg_ksi_kso_gdat &= ~pins;
|
||||
|
||||
irq_unlock(key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -193,10 +207,13 @@ static int gpio_kscan_it8xxx2_port_toggle_bits(const struct device *dev,
|
|||
{
|
||||
const struct gpio_kscan_cfg *const config = dev->config;
|
||||
volatile uint8_t *reg_ksi_kso_gdat = config->reg_ksi_kso_gdat;
|
||||
unsigned int key = irq_lock();
|
||||
|
||||
/* Toggle output level to pins of the port */
|
||||
*reg_ksi_kso_gdat ^= pins;
|
||||
|
||||
irq_unlock(key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue