drivers: adc: make a copy of sequence struct
We should not be storing the sequence pointer, as adc_read_async() returns immediately. The memory could be heap allocated, or on a call stack. Make a copy of it instead. Fixes: #15039 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
26a335c2e8
commit
1efaae5949
5 changed files with 22 additions and 20 deletions
|
@ -54,7 +54,8 @@ struct adc_context {
|
|||
bool asynchronous;
|
||||
#endif /* CONFIG_ADC_ASYNC */
|
||||
|
||||
const struct adc_sequence *sequence;
|
||||
struct adc_sequence sequence;
|
||||
struct adc_sequence_options options;
|
||||
u16_t sampling_index;
|
||||
};
|
||||
|
||||
|
@ -91,7 +92,7 @@ static inline void adc_context_request_next_sampling(struct adc_context *ctx)
|
|||
#ifdef ADC_CONTEXT_USES_KERNEL_TIMER
|
||||
static inline void adc_context_enable_timer(struct adc_context *ctx)
|
||||
{
|
||||
u32_t interval_us = ctx->sequence->options->interval_us;
|
||||
u32_t interval_us = ctx->options.interval_us;
|
||||
u32_t interval_ms = ceiling_fraction(interval_us, 1000UL);
|
||||
|
||||
k_timer_start(&ctx->timer, 0, interval_ms);
|
||||
|
@ -181,13 +182,15 @@ static inline void adc_context_complete(struct adc_context *ctx, int status)
|
|||
static inline void adc_context_start_read(struct adc_context *ctx,
|
||||
const struct adc_sequence *sequence)
|
||||
{
|
||||
ctx->sequence = sequence;
|
||||
ctx->sequence = *sequence;
|
||||
ctx->status = 0;
|
||||
|
||||
if (ctx->sequence->options) {
|
||||
if (sequence->options) {
|
||||
ctx->options = *sequence->options;
|
||||
ctx->sequence.options = &ctx->options;
|
||||
ctx->sampling_index = 0U;
|
||||
|
||||
if (ctx->sequence->options->interval_us != 0U) {
|
||||
if (ctx->options.interval_us != 0U) {
|
||||
atomic_set(&ctx->sampling_requested, 0);
|
||||
adc_context_enable_timer(ctx);
|
||||
return;
|
||||
|
@ -205,16 +208,15 @@ static inline void adc_context_start_read(struct adc_context *ctx,
|
|||
static inline void adc_context_on_sampling_done(struct adc_context *ctx,
|
||||
struct device *dev)
|
||||
{
|
||||
if (ctx->sequence->options) {
|
||||
adc_sequence_callback callback =
|
||||
ctx->sequence->options->callback;
|
||||
if (ctx->sequence.options) {
|
||||
adc_sequence_callback callback = ctx->options.callback;
|
||||
enum adc_action action;
|
||||
bool finish = false;
|
||||
bool repeat = false;
|
||||
|
||||
if (callback) {
|
||||
action = callback(dev,
|
||||
ctx->sequence,
|
||||
&ctx->sequence,
|
||||
ctx->sampling_index);
|
||||
} else {
|
||||
action = ADC_ACTION_CONTINUE;
|
||||
|
@ -229,7 +231,7 @@ static inline void adc_context_on_sampling_done(struct adc_context *ctx,
|
|||
break;
|
||||
default: /* ADC_ACTION_CONTINUE */
|
||||
if (ctx->sampling_index <
|
||||
ctx->sequence->options->extra_samplings) {
|
||||
ctx->options.extra_samplings) {
|
||||
++ctx->sampling_index;
|
||||
} else {
|
||||
finish = true;
|
||||
|
@ -244,7 +246,7 @@ static inline void adc_context_on_sampling_done(struct adc_context *ctx,
|
|||
* a zero interval or if the timer expired again while
|
||||
* the current sampling was in progress.
|
||||
*/
|
||||
if (ctx->sequence->options->interval_us == 0U) {
|
||||
if (ctx->options.interval_us == 0U) {
|
||||
adc_context_start_sampling(ctx);
|
||||
} else if (atomic_dec(&ctx->sampling_requested) > 1) {
|
||||
adc_context_start_sampling(ctx);
|
||||
|
@ -253,7 +255,7 @@ static inline void adc_context_on_sampling_done(struct adc_context *ctx,
|
|||
return;
|
||||
}
|
||||
|
||||
if (ctx->sequence->options->interval_us != 0U) {
|
||||
if (ctx->options.interval_us != 0U) {
|
||||
adc_context_disable_timer(ctx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -366,7 +366,7 @@ static void adc_context_start_sampling(struct adc_context *ctx)
|
|||
struct adc_quark_d2000_info *info =
|
||||
CONTAINER_OF(ctx, struct adc_quark_d2000_info, ctx);
|
||||
|
||||
info->channels = ctx->sequence->channels;
|
||||
info->channels = ctx->sequence.channels;
|
||||
|
||||
adc_quark_d2000_start_conversion(info->dev);
|
||||
}
|
||||
|
@ -376,7 +376,7 @@ static void adc_context_update_buffer_pointer(struct adc_context *ctx,
|
|||
{
|
||||
struct adc_quark_d2000_info *info =
|
||||
CONTAINER_OF(ctx, struct adc_quark_d2000_info, ctx);
|
||||
const struct adc_sequence *entry = ctx->sequence;
|
||||
const struct adc_sequence *entry = &ctx->sequence;
|
||||
|
||||
if (repeat) {
|
||||
info->buffer = (u16_t *)entry->buffer;
|
||||
|
|
|
@ -441,7 +441,7 @@ static void adc_quark_se_ss_start_conversion(struct device *dev)
|
|||
{
|
||||
struct adc_info *info = dev->driver_data;
|
||||
const struct adc_config *config = info->dev->config->config_info;
|
||||
const struct adc_sequence *entry = info->ctx.sequence;
|
||||
const struct adc_sequence *entry = &info->ctx.sequence;
|
||||
u32_t adc_base = config->reg_base;
|
||||
u32_t ctrl, tmp_val, sample_window;
|
||||
|
||||
|
@ -492,7 +492,7 @@ static void adc_context_start_sampling(struct adc_context *ctx)
|
|||
{
|
||||
struct adc_info *info = CONTAINER_OF(ctx, struct adc_info, ctx);
|
||||
|
||||
info->channels = ctx->sequence->channels;
|
||||
info->channels = ctx->sequence.channels;
|
||||
|
||||
adc_quark_se_ss_start_conversion(info->dev);
|
||||
}
|
||||
|
@ -501,7 +501,7 @@ static void adc_context_update_buffer_pointer(struct adc_context *ctx,
|
|||
bool repeat)
|
||||
{
|
||||
struct adc_info *info = CONTAINER_OF(ctx, struct adc_info, ctx);
|
||||
const struct adc_sequence *entry = ctx->sequence;
|
||||
const struct adc_sequence *entry = &ctx->sequence;
|
||||
|
||||
if (repeat) {
|
||||
info->buffer = (u16_t *)entry->buffer;
|
||||
|
@ -556,7 +556,7 @@ static void adc_quark_se_ss_rx_isr(void *arg)
|
|||
struct device *dev = (struct device *)arg;
|
||||
struct adc_info *info = dev->driver_data;
|
||||
const struct adc_config *config = dev->config->config_info;
|
||||
const struct adc_sequence *seq = info->ctx.sequence;
|
||||
struct adc_sequence *seq = &info->ctx.sequence;
|
||||
u32_t adc_base = config->reg_base;
|
||||
u32_t reg_val;
|
||||
|
||||
|
|
|
@ -183,7 +183,7 @@ static void adc_context_start_sampling(struct adc_context *ctx)
|
|||
struct mcux_adc16_data *data =
|
||||
CONTAINER_OF(ctx, struct mcux_adc16_data, ctx);
|
||||
|
||||
data->channels = ctx->sequence->channels;
|
||||
data->channels = ctx->sequence.channels;
|
||||
data->repeat_buffer = data->buffer;
|
||||
|
||||
mcux_adc16_start_channel(data->dev);
|
||||
|
|
|
@ -150,7 +150,7 @@ static void adc_context_start_sampling(struct adc_context *ctx)
|
|||
{
|
||||
struct adc_sam_data *data = CONTAINER_OF(ctx, struct adc_sam_data, ctx);
|
||||
|
||||
data->channels = ctx->sequence->channels;
|
||||
data->channels = ctx->sequence.channels;
|
||||
|
||||
adc_sam_start_conversion(data->dev);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue