Skip to content

Commit 00055d1

Browse files
ubiedafabiobaltieri
authored andcommitted
afbr-s50: Add graceful error-handling on data-ready
Whenever the data-ready callback is invoked, there's a common pattern that needs to take place: - Stop measurement timer (to stop on-coming samples), which could be restored by the application re-submitting the request. - Set iodev_sqe to NULL, so new requests can come in. - Report the error on the SQE. This has been refactored in handle_error_on_result() and now it's invoked throughout the code. Signed-off-by: Luis Ubieda <[email protected]>
1 parent ab67081 commit 00055d1

File tree

1 file changed

+33
-16
lines changed

1 file changed

+33
-16
lines changed

drivers/sensor/broadcom/afbr_s50/afbr_s50.c

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ struct afbr_s50_data {
4040
* for platform abstractions present under modules sub-directory.
4141
*/
4242
struct afbr_s50_platform_data platform;
43+
/** Required in order to flush the data if resources are run out.
44+
* In any case we must call `Argus_EvaluateData` to free up the internal
45+
* buffers.
46+
*/
47+
struct argus_results_t buf;
4348
};
4449

4550
struct afbr_s50_config {
@@ -58,6 +63,23 @@ struct afbr_s50_config {
5863
} settings;
5964
};
6065

66+
static inline void handle_error_on_result(struct afbr_s50_data *data, int result)
67+
{
68+
struct rtio_iodev_sqe *iodev_sqe = data->rtio.iodev_sqe;
69+
status_t status;
70+
71+
(void)Argus_StopMeasurementTimer(data->platform.argus.handle);
72+
do {
73+
/** Flush the existing data moving forward so the
74+
* internal buffers can be re-used afterwards.
75+
*/
76+
status = Argus_EvaluateData(data->platform.argus.handle, &data->buf);
77+
} while (status == STATUS_OK);
78+
79+
data->rtio.iodev_sqe = NULL;
80+
rtio_iodev_sqe_err(iodev_sqe, result);
81+
}
82+
6183
static void data_ready_work_handler(struct rtio_iodev_sqe *iodev_sqe)
6284
{
6385
const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data;
@@ -77,9 +99,7 @@ static void data_ready_work_handler(struct rtio_iodev_sqe *iodev_sqe)
7799

78100
CHECKIF(err || !edata || edata_len < sizeof(struct afbr_s50_edata)) {
79101
LOG_ERR("Failed to get buffer for edata");
80-
81-
data->rtio.iodev_sqe = NULL;
82-
rtio_iodev_sqe_err(iodev_sqe, -ENOMEM);
102+
handle_error_on_result(data, -ENOMEM);
83103
return;
84104
}
85105

@@ -88,6 +108,7 @@ static void data_ready_work_handler(struct rtio_iodev_sqe *iodev_sqe)
88108
err = sensor_clock_get_cycles(&cycles);
89109
CHECKIF(err != 0) {
90110
LOG_ERR("Failed to get sensor clock cycles");
111+
handle_error_on_result(data, -EIO);
91112
return;
92113
}
93114

@@ -100,12 +121,10 @@ static void data_ready_work_handler(struct rtio_iodev_sqe *iodev_sqe)
100121
status = Argus_EvaluateData(data->platform.argus.handle, &edata->payload);
101122
if (status != STATUS_OK || edata->payload.Status != STATUS_OK) {
102123
LOG_ERR("Data not valid: %d, %d", status, edata->payload.Status);
103-
104-
data->rtio.iodev_sqe = NULL;
105-
rtio_iodev_sqe_err(iodev_sqe, -EIO);
106-
} else {
107-
data->rtio.iodev_sqe = NULL;
108-
rtio_iodev_sqe_ok(iodev_sqe, 0);
124+
handle_error_on_result(data, -EIO);
125+
}
126+
CHECKIF(Argus_IsDataEvaluationPending(data->platform.argus.handle)) {
127+
LOG_WRN("Overrun. More pending data than what we've served.");
109128
}
110129

111130
/** After freeing the buffer with EvaluateData, decide whether to
@@ -117,6 +136,9 @@ static void data_ready_work_handler(struct rtio_iodev_sqe *iodev_sqe)
117136

118137
(void)Argus_StopMeasurementTimer(data->platform.argus.handle);
119138
}
139+
140+
data->rtio.iodev_sqe = NULL;
141+
rtio_iodev_sqe_ok(iodev_sqe, 0);
120142
}
121143

122144
static status_t data_ready_callback(status_t status, argus_hnd_t *hnd)
@@ -140,10 +162,7 @@ static status_t data_ready_callback(status_t status, argus_hnd_t *hnd)
140162

141163
if (status != STATUS_OK) {
142164
LOG_ERR("Measurement failed: %d", status);
143-
144-
data->rtio.iodev_sqe = NULL;
145-
rtio_iodev_sqe_err(iodev_sqe, -EIO);
146-
165+
handle_error_on_result(data, -EIO);
147166
return status;
148167
}
149168

@@ -156,9 +175,7 @@ static status_t data_ready_callback(status_t status, argus_hnd_t *hnd)
156175
CHECKIF(!req) {
157176
LOG_ERR("RTIO work item allocation failed. Consider to increase "
158177
"CONFIG_RTIO_WORKQ_POOL_ITEMS");
159-
160-
data->rtio.iodev_sqe = NULL;
161-
rtio_iodev_sqe_err(iodev_sqe, -ENOMEM);
178+
handle_error_on_result(data, -ENOMEM);
162179
return ERROR_FAIL;
163180
}
164181

0 commit comments

Comments
 (0)