iio: adc: qcom-spmi-adc5-gen3: Fix __tm_handler_work() loop conditions

Currently __tm_handler_work() assumes that each element in chan_props[]
represents 1 SDAM register. However, chan_props[] has an element for every
ADC and ADC TM channel. Since every ADC channel shares the same SDAM
register the loop within __tm_handler_work() has incorrect conditions. Fix
this.

While at it, remove __tm_handler_work() which was invoked for every SDAM
as tm_handler_work() goes through all channels.

Change-Id: I5f3444ab831ff2067a1a53f49dea0c5dbbdc8758
Signed-off-by: Anjelique Melendez <quic_amelende@quicinc.com>
This commit is contained in:
Anjelique Melendez 2022-03-09 13:00:47 -08:00 committed by David Collins
parent d43304f631
commit 23dbb35078

View File

@ -592,50 +592,15 @@ static irqreturn_t adc5_gen3_isr(int irq, void *dev_id)
return IRQ_NONE;
}
static void __tm_handler_work(struct adc5_chip *adc, unsigned int sdam_index)
static void tm_handler_work(struct work_struct *work)
{
struct adc5_channel_prop *chan_prop;
u8 tm_status[2], buf[16], val;
int ret, i;
int ret, i, sdam_index = -1;
struct adc5_chip *adc = container_of(work, struct adc5_chip,
tm_handler_work);
mutex_lock(&adc->lock);
ret = adc5_read(adc, sdam_index, ADC5_GEN3_TM_HIGH_STS, tm_status, 2);
if (ret < 0) {
pr_err("adc read TM status failed with %d\n", ret);
goto work_unlock;
}
ret = adc5_write(adc, sdam_index, ADC5_GEN3_TM_HIGH_STS_CLR, tm_status, 2);
if (ret < 0) {
pr_err("adc write TM status failed with %d\n", ret);
goto work_unlock;
}
/* To indicate conversion request is only to clear a status */
val = 0;
ret = adc5_write(adc, sdam_index, ADC5_GEN3_PERPH_CH, &val, 1);
if (ret < 0) {
pr_err("adc write status clear conv_req failed with %d\n", ret);
goto work_unlock;
}
val = ADC5_GEN3_CONV_REQ_REQ;
ret = adc5_write(adc, sdam_index, ADC5_GEN3_CONV_REQ, &val, 1);
if (ret < 0) {
pr_err("adc write conv_req failed with %d\n", ret);
goto work_unlock;
}
ret = adc5_read(adc, sdam_index, ADC5_GEN3_CH0_DATA0, buf, sizeof(buf));
if (ret < 0) {
pr_err("adc read data failed with %d\n", ret);
goto work_unlock;
}
mutex_unlock(&adc->lock);
for (i = sdam_index * 8; i < (sdam_index + 1) * 8; i++) {
for (i = 0; i < adc->nchannels; i++) {
bool upper_set = false, lower_set = false;
u8 data_low = 0, data_high = 0;
u16 code = 0;
@ -643,10 +608,47 @@ static void __tm_handler_work(struct adc5_chip *adc, unsigned int sdam_index)
chan_prop = &adc->chan_props[i];
offset = chan_prop->tm_chan_index;
if (!chan_prop->adc_tm)
if (chan_prop->adc_tm != ADC_TM && chan_prop->adc_tm != ADC_TM_NON_THERMAL)
continue;
mutex_lock(&adc->lock);
if (chan_prop->sdam_index != sdam_index) {
sdam_index = chan_prop->sdam_index;
ret = adc5_read(adc, sdam_index, ADC5_GEN3_TM_HIGH_STS, tm_status, 2);
if (ret < 0) {
pr_err("adc read TM status failed with %d\n", ret);
goto work_unlock;
}
ret = adc5_write(adc, sdam_index, ADC5_GEN3_TM_HIGH_STS_CLR, tm_status, 2);
if (ret < 0) {
pr_err("adc write TM status failed with %d\n", ret);
goto work_unlock;
}
/* To indicate conversion request is only to clear a status */
val = 0;
ret = adc5_write(adc, sdam_index, ADC5_GEN3_PERPH_CH, &val, 1);
if (ret < 0) {
pr_err("adc write status clear conv_req failed with %d\n", ret);
goto work_unlock;
}
val = ADC5_GEN3_CONV_REQ_REQ;
ret = adc5_write(adc, sdam_index, ADC5_GEN3_CONV_REQ, &val, 1);
if (ret < 0) {
pr_err("adc write conv_req failed with %d\n", ret);
goto work_unlock;
}
ret = adc5_read(adc, sdam_index, ADC5_GEN3_CH0_DATA0, buf, sizeof(buf));
if (ret < 0) {
pr_err("adc read data failed with %d\n", ret);
goto work_unlock;
}
}
if ((tm_status[0] & BIT(offset)) && (chan_prop->high_thr_en))
upper_set = true;
@ -703,16 +705,6 @@ static void __tm_handler_work(struct adc5_chip *adc, unsigned int sdam_index)
mutex_unlock(&adc->lock);
}
static void tm_handler_work(struct work_struct *work)
{
int i;
struct adc5_chip *adc = container_of(work, struct adc5_chip,
tm_handler_work);
for (i = 0; i < adc->num_sdams; i++)
__tm_handler_work(adc, i);
}
static int adc5_gen3_of_xlate(struct iio_dev *indio_dev,
const struct of_phandle_args *iiospec)
{
@ -1575,7 +1567,7 @@ static int adc5_get_dt_data(struct adc5_chip *adc, struct device_node *node)
{
const struct adc5_channels *adc_chan;
struct iio_chan_spec *iio_chan;
struct adc5_channel_prop prop, *chan_props;
struct adc5_channel_prop *chan_props;
struct device_node *child;
unsigned int index = 0;
const struct of_device_id *id;
@ -1607,21 +1599,20 @@ static int adc5_get_dt_data(struct adc5_chip *adc, struct device_node *node)
adc->data = data;
for_each_available_child_of_node(node, child) {
ret = adc5_get_dt_channel_data(adc, &prop, child, data);
ret = adc5_get_dt_channel_data(adc, chan_props, child, data);
if (ret < 0) {
of_node_put(child);
return ret;
}
prop.chip = adc;
if (prop.scale_fn_type == -EINVAL)
prop.scale_fn_type =
data->adc_chans[prop.channel].scale_fn_type;
*chan_props = prop;
adc_chan = &data->adc_chans[prop.channel];
iio_chan->channel = prop.channel;
iio_chan->datasheet_name = prop.datasheet_name;
iio_chan->extend_name = prop.datasheet_name;
chan_props->chip = adc;
if (chan_props->scale_fn_type == -EINVAL)
chan_props->scale_fn_type =
data->adc_chans[chan_props->channel].scale_fn_type;
adc_chan = &data->adc_chans[chan_props->channel];
iio_chan->channel = chan_props->channel;
iio_chan->datasheet_name = chan_props->datasheet_name;
iio_chan->extend_name = chan_props->datasheet_name;
iio_chan->info_mask_separate = adc_chan->info_mask;
iio_chan->type = adc_chan->type;
iio_chan->address = index;