drivers: rtc: rtc_emul: replace mutex with spinlock

Replaces the mutex with a lightweight spinlock.

Fixes: #59901

Signed-off-by: Florian Grandel <fgrandel@code-for-humans.de>
This commit is contained in:
Florian Grandel 2023-07-10 13:23:20 +02:00 committed by Carles Cufí
commit ff2b5cebb7

View file

@ -30,7 +30,7 @@ struct rtc_emul_data {
struct rtc_time datetime; struct rtc_time datetime;
struct k_mutex lock; struct k_spinlock lock;
struct rtc_emul_work_delayable dwork; struct rtc_emul_work_delayable dwork;
@ -253,8 +253,7 @@ static void rtc_emul_update(struct k_work *work)
k_work_schedule(&work_delayable->dwork, K_MSEC(1000)); k_work_schedule(&work_delayable->dwork, K_MSEC(1000));
k_mutex_lock(&data->lock, K_FOREVER); K_SPINLOCK(&data->lock) {
rtc_emul_increment_tm(&data->datetime); rtc_emul_increment_tm(&data->datetime);
#ifdef CONFIG_RTC_ALARM #ifdef CONFIG_RTC_ALARM
@ -264,8 +263,7 @@ static void rtc_emul_update(struct k_work *work)
#ifdef CONFIG_RTC_UPDATE #ifdef CONFIG_RTC_UPDATE
rtc_emul_invoke_update_callback(dev); rtc_emul_invoke_update_callback(dev);
#endif /* CONFIG_RTC_UPDATE */ #endif /* CONFIG_RTC_UPDATE */
}
k_mutex_unlock(&data->lock);
} }
static int rtc_emul_set_time(const struct device *dev, const struct rtc_time *timeptr) static int rtc_emul_set_time(const struct device *dev, const struct rtc_time *timeptr)
@ -277,15 +275,14 @@ static int rtc_emul_set_time(const struct device *dev, const struct rtc_time *ti
return -EINVAL; return -EINVAL;
} }
k_mutex_lock(&data->lock, K_FOREVER); K_SPINLOCK(&data->lock)
{
data->datetime = (*timeptr); data->datetime = (*timeptr);
data->datetime.tm_isdst = -1; data->datetime.tm_isdst = -1;
data->datetime.tm_nsec = 0; data->datetime.tm_nsec = 0;
data->datetime_set = true; data->datetime_set = true;
}
k_mutex_unlock(&data->lock);
return 0; return 0;
} }
@ -293,26 +290,26 @@ static int rtc_emul_set_time(const struct device *dev, const struct rtc_time *ti
static int rtc_emul_get_time(const struct device *dev, struct rtc_time *timeptr) static int rtc_emul_get_time(const struct device *dev, struct rtc_time *timeptr)
{ {
struct rtc_emul_data *data = (struct rtc_emul_data *)dev->data; struct rtc_emul_data *data = (struct rtc_emul_data *)dev->data;
int ret = 0;
/* Validate arguments */ /* Validate arguments */
if (timeptr == NULL) { if (timeptr == NULL) {
return -EINVAL; return -EINVAL;
} }
k_mutex_lock(&data->lock, K_FOREVER); K_SPINLOCK(&data->lock)
{
/* Validate RTC time is set */ /* Validate RTC time is set */
if (data->datetime_set == false) { if (data->datetime_set == false) {
k_mutex_unlock(&data->lock); ret = -ENODATA;
return -ENODATA; K_SPINLOCK_BREAK;
} }
(*timeptr) = data->datetime; (*timeptr) = data->datetime;
}
k_mutex_unlock(&data->lock); return ret;
return 0;
} }
#ifdef CONFIG_RTC_ALARM #ifdef CONFIG_RTC_ALARM
@ -354,15 +351,14 @@ static int rtc_emul_alarm_set_time(const struct device *dev, uint16_t id, uint16
} }
} }
k_mutex_lock(&data->lock, K_FOREVER); K_SPINLOCK(&data->lock)
{
data->alarms[id].mask = mask; data->alarms[id].mask = mask;
if (timeptr != NULL) { if (timeptr != NULL) {
data->alarms[id].datetime = *timeptr; data->alarms[id].datetime = *timeptr;
} }
}
k_mutex_unlock(&data->lock);
return 0; return 0;
} }
@ -376,12 +372,11 @@ static int rtc_emul_alarm_get_time(const struct device *dev, uint16_t id, uint16
return -EINVAL; return -EINVAL;
} }
k_mutex_lock(&data->lock, K_FOREVER); K_SPINLOCK(&data->lock)
{
(*timeptr) = data->alarms[id].datetime; (*timeptr) = data->alarms[id].datetime;
(*mask) = data->alarms[id].mask; (*mask) = data->alarms[id].mask;
}
k_mutex_unlock(&data->lock);
return 0; return 0;
} }
@ -389,19 +384,18 @@ static int rtc_emul_alarm_get_time(const struct device *dev, uint16_t id, uint16
static int rtc_emul_alarm_is_pending(const struct device *dev, uint16_t id) static int rtc_emul_alarm_is_pending(const struct device *dev, uint16_t id)
{ {
struct rtc_emul_data *data = (struct rtc_emul_data *)dev->data; struct rtc_emul_data *data = (struct rtc_emul_data *)dev->data;
int ret; int ret = 0;
if (data->alarms_count <= id) { if (data->alarms_count <= id) {
return -EINVAL; return -EINVAL;
} }
k_mutex_lock(&data->lock, K_FOREVER); K_SPINLOCK(&data->lock)
{
ret = (data->alarms[id].pending == true) ? 1 : 0; ret = (data->alarms[id].pending == true) ? 1 : 0;
data->alarms[id].pending = false; data->alarms[id].pending = false;
}
k_mutex_unlock(&data->lock);
return ret; return ret;
} }
@ -415,12 +409,11 @@ static int rtc_emul_alarm_set_callback(const struct device *dev, uint16_t id,
return -EINVAL; return -EINVAL;
} }
k_mutex_lock(&data->lock, K_FOREVER); K_SPINLOCK(&data->lock)
{
data->alarms[id].callback = callback; data->alarms[id].callback = callback;
data->alarms[id].user_data = user_data; data->alarms[id].user_data = user_data;
}
k_mutex_unlock(&data->lock);
return 0; return 0;
} }
@ -432,12 +425,11 @@ static int rtc_emul_update_set_callback(const struct device *dev,
{ {
struct rtc_emul_data *data = (struct rtc_emul_data *)dev->data; struct rtc_emul_data *data = (struct rtc_emul_data *)dev->data;
k_mutex_lock(&data->lock, K_FOREVER); K_SPINLOCK(&data->lock)
{
data->update_callback = callback; data->update_callback = callback;
data->update_callback_user_data = user_data; data->update_callback_user_data = user_data;
}
k_mutex_unlock(&data->lock);
return 0; return 0;
} }
@ -448,11 +440,10 @@ static int rtc_emul_set_calibration(const struct device *dev, int32_t calibratio
{ {
struct rtc_emul_data *data = (struct rtc_emul_data *)dev->data; struct rtc_emul_data *data = (struct rtc_emul_data *)dev->data;
k_mutex_lock(&data->lock, K_FOREVER); K_SPINLOCK(&data->lock)
{
data->calibration = calibration; data->calibration = calibration;
}
k_mutex_unlock(&data->lock);
return 0; return 0;
} }
@ -461,11 +452,10 @@ static int rtc_emul_get_calibration(const struct device *dev, int32_t *calibrati
{ {
struct rtc_emul_data *data = (struct rtc_emul_data *)dev->data; struct rtc_emul_data *data = (struct rtc_emul_data *)dev->data;
k_mutex_lock(&data->lock, K_FOREVER); K_SPINLOCK(&data->lock)
{
(*calibration) = data->calibration; (*calibration) = data->calibration;
}
k_mutex_unlock(&data->lock);
return 0; return 0;
} }
@ -494,8 +484,6 @@ int rtc_emul_init(const struct device *dev)
{ {
struct rtc_emul_data *data = (struct rtc_emul_data *)dev->data; struct rtc_emul_data *data = (struct rtc_emul_data *)dev->data;
k_mutex_init(&data->lock);
data->dwork.dev = dev; data->dwork.dev = dev;
k_work_init_delayable(&data->dwork.dwork, rtc_emul_update); k_work_init_delayable(&data->dwork.dwork, rtc_emul_update);