Commit 76101fa0 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'iio-fixes-for-6.7a' of...

Merge tag 'iio-fixes-for-6.7a' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into char-misc-linus

Jonathan writes:

First set of IIO fixes for the 6.7 cycle.

Usual mixed bunch of driver bugs.  The core bug probably isn't hit
with upstream drivers, but good to get fix in place anyway.

iio-core
- Fix potential freeing of wrong iio buffer when multiple buffers used.
adi,adis16475
- Add missing spi_device_id table need for module auto-loading
- Fix untended BIT(BIT()) due to wrong macro definitions.
amlogic,meson
- Add a chip specific config for AXG soc familly which needs
  a vref_select to work.
freescale,mp6050
- Fix eating of error code on failure to read from sensor.
kionixq,kx022a
- Fix scaling to comply with ABI (m/s^2 rather than micro m/s^2)
measspec,ms_sensors
- Fix wrong conversion times due to strange value mapping.
microchip,mcp3564
- Fix previously impossible to fail check on limits.
- Fix identification logic.
nxp,imx93
- Add missing channels for i.mx95.
ti,am335x
- Fix handling of error for tiadc_request_dma().
ti,tmag5273
- Fix incorrect temperature offset.

* tag 'iio-fixes-for-6.7a' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio:
  iio: adc: MCP3564: fix hardware identification logic
  iio: adc: MCP3564: fix calib_bias and calib_scale range checks
  iio: adc: meson: add separate config for axg SoC family
  iio: adc: imx93: add four channels for imx93 adc
  iio: adc: ti_am335x_adc: Fix return value check of tiadc_request_dma()
  iio: triggered-buffer: prevent possible freeing of wrong buffer
  iio: imu: inv_mpu6050: fix an error code problem in inv_mpu6050_read_raw
  iio: imu: adis16475: use bit numbers in assign_bit()
  iio: imu: adis16475: add spi_device_id table
  iio: tmag5273: fix temperature offset
  iio: common: ms_sensors: ms_sensors_i2c: fix humidity conversion time table
  iio: kx022a: Fix acceleration value scaling
parents e1b2fa61 408d4b33
...@@ -393,17 +393,17 @@ static const unsigned int kx022a_odrs[] = { ...@@ -393,17 +393,17 @@ static const unsigned int kx022a_odrs[] = {
* (range / 2^bits) * g = (range / 2^bits) * 9.80665 m/s^2 * (range / 2^bits) * g = (range / 2^bits) * 9.80665 m/s^2
* => KX022A uses 16 bit (HiRes mode - assume the low 8 bits are zeroed * => KX022A uses 16 bit (HiRes mode - assume the low 8 bits are zeroed
* in low-power mode(?) ) * in low-power mode(?) )
* => +/-2G => 4 / 2^16 * 9,80665 * 10^6 (to scale to micro) * => +/-2G => 4 / 2^16 * 9,80665
* => +/-2G - 598.550415 * => +/-2G - 0.000598550415
* +/-4G - 1197.10083 * +/-4G - 0.00119710083
* +/-8G - 2394.20166 * +/-8G - 0.00239420166
* +/-16G - 4788.40332 * +/-16G - 0.00478840332
*/ */
static const int kx022a_scale_table[][2] = { static const int kx022a_scale_table[][2] = {
{ 598, 550415 }, { 0, 598550 },
{ 1197, 100830 }, { 0, 1197101 },
{ 2394, 201660 }, { 0, 2394202 },
{ 4788, 403320 }, { 0, 4788403 },
}; };
static int kx022a_read_avail(struct iio_dev *indio_dev, static int kx022a_read_avail(struct iio_dev *indio_dev,
...@@ -422,7 +422,7 @@ static int kx022a_read_avail(struct iio_dev *indio_dev, ...@@ -422,7 +422,7 @@ static int kx022a_read_avail(struct iio_dev *indio_dev,
*vals = (const int *)kx022a_scale_table; *vals = (const int *)kx022a_scale_table;
*length = ARRAY_SIZE(kx022a_scale_table) * *length = ARRAY_SIZE(kx022a_scale_table) *
ARRAY_SIZE(kx022a_scale_table[0]); ARRAY_SIZE(kx022a_scale_table[0]);
*type = IIO_VAL_INT_PLUS_MICRO; *type = IIO_VAL_INT_PLUS_NANO;
return IIO_AVAIL_LIST; return IIO_AVAIL_LIST;
default: default:
return -EINVAL; return -EINVAL;
...@@ -485,6 +485,20 @@ static int kx022a_turn_on_unlock(struct kx022a_data *data) ...@@ -485,6 +485,20 @@ static int kx022a_turn_on_unlock(struct kx022a_data *data)
return ret; return ret;
} }
static int kx022a_write_raw_get_fmt(struct iio_dev *idev,
struct iio_chan_spec const *chan,
long mask)
{
switch (mask) {
case IIO_CHAN_INFO_SCALE:
return IIO_VAL_INT_PLUS_NANO;
case IIO_CHAN_INFO_SAMP_FREQ:
return IIO_VAL_INT_PLUS_MICRO;
default:
return -EINVAL;
}
}
static int kx022a_write_raw(struct iio_dev *idev, static int kx022a_write_raw(struct iio_dev *idev,
struct iio_chan_spec const *chan, struct iio_chan_spec const *chan,
int val, int val2, long mask) int val, int val2, long mask)
...@@ -629,7 +643,7 @@ static int kx022a_read_raw(struct iio_dev *idev, ...@@ -629,7 +643,7 @@ static int kx022a_read_raw(struct iio_dev *idev,
kx022a_reg2scale(regval, val, val2); kx022a_reg2scale(regval, val, val2);
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_NANO;
} }
return -EINVAL; return -EINVAL;
...@@ -856,6 +870,7 @@ static int kx022a_fifo_flush(struct iio_dev *idev, unsigned int samples) ...@@ -856,6 +870,7 @@ static int kx022a_fifo_flush(struct iio_dev *idev, unsigned int samples)
static const struct iio_info kx022a_info = { static const struct iio_info kx022a_info = {
.read_raw = &kx022a_read_raw, .read_raw = &kx022a_read_raw,
.write_raw = &kx022a_write_raw, .write_raw = &kx022a_write_raw,
.write_raw_get_fmt = &kx022a_write_raw_get_fmt,
.read_avail = &kx022a_read_avail, .read_avail = &kx022a_read_avail,
.validate_trigger = iio_validate_own_trigger, .validate_trigger = iio_validate_own_trigger,
......
...@@ -93,6 +93,10 @@ static const struct iio_chan_spec imx93_adc_iio_channels[] = { ...@@ -93,6 +93,10 @@ static const struct iio_chan_spec imx93_adc_iio_channels[] = {
IMX93_ADC_CHAN(1), IMX93_ADC_CHAN(1),
IMX93_ADC_CHAN(2), IMX93_ADC_CHAN(2),
IMX93_ADC_CHAN(3), IMX93_ADC_CHAN(3),
IMX93_ADC_CHAN(4),
IMX93_ADC_CHAN(5),
IMX93_ADC_CHAN(6),
IMX93_ADC_CHAN(7),
}; };
static void imx93_adc_power_down(struct imx93_adc *adc) static void imx93_adc_power_down(struct imx93_adc *adc)
......
...@@ -918,7 +918,7 @@ static int mcp3564_write_raw(struct iio_dev *indio_dev, ...@@ -918,7 +918,7 @@ static int mcp3564_write_raw(struct iio_dev *indio_dev,
mutex_unlock(&adc->lock); mutex_unlock(&adc->lock);
return ret; return ret;
case IIO_CHAN_INFO_CALIBBIAS: case IIO_CHAN_INFO_CALIBBIAS:
if (val < mcp3564_calib_bias[0] && val > mcp3564_calib_bias[2]) if (val < mcp3564_calib_bias[0] || val > mcp3564_calib_bias[2])
return -EINVAL; return -EINVAL;
mutex_lock(&adc->lock); mutex_lock(&adc->lock);
...@@ -928,7 +928,7 @@ static int mcp3564_write_raw(struct iio_dev *indio_dev, ...@@ -928,7 +928,7 @@ static int mcp3564_write_raw(struct iio_dev *indio_dev,
mutex_unlock(&adc->lock); mutex_unlock(&adc->lock);
return ret; return ret;
case IIO_CHAN_INFO_CALIBSCALE: case IIO_CHAN_INFO_CALIBSCALE:
if (val < mcp3564_calib_scale[0] && val > mcp3564_calib_scale[2]) if (val < mcp3564_calib_scale[0] || val > mcp3564_calib_scale[2])
return -EINVAL; return -EINVAL;
if (adc->calib_scale == val) if (adc->calib_scale == val)
...@@ -1122,7 +1122,7 @@ static int mcp3564_config(struct iio_dev *indio_dev) ...@@ -1122,7 +1122,7 @@ static int mcp3564_config(struct iio_dev *indio_dev)
enum mcp3564_ids ids; enum mcp3564_ids ids;
int ret = 0; int ret = 0;
unsigned int tmp = 0x01; unsigned int tmp = 0x01;
bool err = true; bool err = false;
/* /*
* The address is set on a per-device basis by fuses in the factory, * The address is set on a per-device basis by fuses in the factory,
...@@ -1509,5 +1509,5 @@ static struct spi_driver mcp3564_driver = { ...@@ -1509,5 +1509,5 @@ static struct spi_driver mcp3564_driver = {
module_spi_driver(mcp3564_driver); module_spi_driver(mcp3564_driver);
MODULE_AUTHOR("Marius Cristea <marius.cristea@microchip.com>"); MODULE_AUTHOR("Marius Cristea <marius.cristea@microchip.com>");
MODULE_DESCRIPTION("Microchip MCP346x/MCP346xR and MCP356x/MCP346xR ADCs"); MODULE_DESCRIPTION("Microchip MCP346x/MCP346xR and MCP356x/MCP356xR ADCs");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
...@@ -1241,6 +1241,20 @@ static const struct meson_sar_adc_param meson_sar_adc_gxl_param = { ...@@ -1241,6 +1241,20 @@ static const struct meson_sar_adc_param meson_sar_adc_gxl_param = {
.cmv_select = 1, .cmv_select = 1,
}; };
static const struct meson_sar_adc_param meson_sar_adc_axg_param = {
.has_bl30_integration = true,
.clock_rate = 1200000,
.bandgap_reg = MESON_SAR_ADC_REG11,
.regmap_config = &meson_sar_adc_regmap_config_gxbb,
.resolution = 12,
.disable_ring_counter = 1,
.has_reg11 = true,
.vref_volatge = 1,
.has_vref_select = true,
.vref_select = VREF_VDDA,
.cmv_select = 1,
};
static const struct meson_sar_adc_param meson_sar_adc_g12a_param = { static const struct meson_sar_adc_param meson_sar_adc_g12a_param = {
.has_bl30_integration = false, .has_bl30_integration = false,
.clock_rate = 1200000, .clock_rate = 1200000,
...@@ -1285,7 +1299,7 @@ static const struct meson_sar_adc_data meson_sar_adc_gxm_data = { ...@@ -1285,7 +1299,7 @@ static const struct meson_sar_adc_data meson_sar_adc_gxm_data = {
}; };
static const struct meson_sar_adc_data meson_sar_adc_axg_data = { static const struct meson_sar_adc_data meson_sar_adc_axg_data = {
.param = &meson_sar_adc_gxl_param, .param = &meson_sar_adc_axg_param,
.name = "meson-axg-saradc", .name = "meson-axg-saradc",
}; };
......
...@@ -670,8 +670,10 @@ static int tiadc_probe(struct platform_device *pdev) ...@@ -670,8 +670,10 @@ static int tiadc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, indio_dev); platform_set_drvdata(pdev, indio_dev);
err = tiadc_request_dma(pdev, adc_dev); err = tiadc_request_dma(pdev, adc_dev);
if (err && err == -EPROBE_DEFER) if (err && err != -ENODEV) {
dev_err_probe(&pdev->dev, err, "DMA request failed\n");
goto err_dma; goto err_dma;
}
return 0; return 0;
......
...@@ -46,6 +46,16 @@ int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev, ...@@ -46,6 +46,16 @@ int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev,
struct iio_buffer *buffer; struct iio_buffer *buffer;
int ret; int ret;
/*
* iio_triggered_buffer_cleanup() assumes that the buffer allocated here
* is assigned to indio_dev->buffer but this is only the case if this
* function is the first caller to iio_device_attach_buffer(). If
* indio_dev->buffer is already set then we can't proceed otherwise the
* cleanup function will try to free a buffer that was not allocated here.
*/
if (indio_dev->buffer)
return -EADDRINUSE;
buffer = iio_kfifo_allocate(); buffer = iio_kfifo_allocate();
if (!buffer) { if (!buffer) {
ret = -ENOMEM; ret = -ENOMEM;
......
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
/* Conversion times in us */ /* Conversion times in us */
static const u16 ms_sensors_ht_t_conversion_time[] = { 50000, 25000, static const u16 ms_sensors_ht_t_conversion_time[] = { 50000, 25000,
13000, 7000 }; 13000, 7000 };
static const u16 ms_sensors_ht_h_conversion_time[] = { 16000, 3000, static const u16 ms_sensors_ht_h_conversion_time[] = { 16000, 5000,
5000, 8000 }; 3000, 8000 };
static const u16 ms_sensors_tp_conversion_time[] = { 500, 1100, 2100, static const u16 ms_sensors_tp_conversion_time[] = { 500, 1100, 2100,
4100, 8220, 16440 }; 4100, 8220, 16440 };
......
...@@ -70,8 +70,8 @@ ...@@ -70,8 +70,8 @@
#define ADIS16475_MAX_SCAN_DATA 20 #define ADIS16475_MAX_SCAN_DATA 20
/* spi max speed in brust mode */ /* spi max speed in brust mode */
#define ADIS16475_BURST_MAX_SPEED 1000000 #define ADIS16475_BURST_MAX_SPEED 1000000
#define ADIS16475_LSB_DEC_MASK BIT(0) #define ADIS16475_LSB_DEC_MASK 0
#define ADIS16475_LSB_FIR_MASK BIT(1) #define ADIS16475_LSB_FIR_MASK 1
#define ADIS16500_BURST_DATA_SEL_0_CHN_MASK GENMASK(5, 0) #define ADIS16500_BURST_DATA_SEL_0_CHN_MASK GENMASK(5, 0)
#define ADIS16500_BURST_DATA_SEL_1_CHN_MASK GENMASK(12, 7) #define ADIS16500_BURST_DATA_SEL_1_CHN_MASK GENMASK(12, 7)
...@@ -1406,50 +1406,6 @@ static int adis16475_config_irq_pin(struct adis16475 *st) ...@@ -1406,50 +1406,6 @@ static int adis16475_config_irq_pin(struct adis16475 *st)
return 0; return 0;
} }
static const struct of_device_id adis16475_of_match[] = {
{ .compatible = "adi,adis16470",
.data = &adis16475_chip_info[ADIS16470] },
{ .compatible = "adi,adis16475-1",
.data = &adis16475_chip_info[ADIS16475_1] },
{ .compatible = "adi,adis16475-2",
.data = &adis16475_chip_info[ADIS16475_2] },
{ .compatible = "adi,adis16475-3",
.data = &adis16475_chip_info[ADIS16475_3] },
{ .compatible = "adi,adis16477-1",
.data = &adis16475_chip_info[ADIS16477_1] },
{ .compatible = "adi,adis16477-2",
.data = &adis16475_chip_info[ADIS16477_2] },
{ .compatible = "adi,adis16477-3",
.data = &adis16475_chip_info[ADIS16477_3] },
{ .compatible = "adi,adis16465-1",
.data = &adis16475_chip_info[ADIS16465_1] },
{ .compatible = "adi,adis16465-2",
.data = &adis16475_chip_info[ADIS16465_2] },
{ .compatible = "adi,adis16465-3",
.data = &adis16475_chip_info[ADIS16465_3] },
{ .compatible = "adi,adis16467-1",
.data = &adis16475_chip_info[ADIS16467_1] },
{ .compatible = "adi,adis16467-2",
.data = &adis16475_chip_info[ADIS16467_2] },
{ .compatible = "adi,adis16467-3",
.data = &adis16475_chip_info[ADIS16467_3] },
{ .compatible = "adi,adis16500",
.data = &adis16475_chip_info[ADIS16500] },
{ .compatible = "adi,adis16505-1",
.data = &adis16475_chip_info[ADIS16505_1] },
{ .compatible = "adi,adis16505-2",
.data = &adis16475_chip_info[ADIS16505_2] },
{ .compatible = "adi,adis16505-3",
.data = &adis16475_chip_info[ADIS16505_3] },
{ .compatible = "adi,adis16507-1",
.data = &adis16475_chip_info[ADIS16507_1] },
{ .compatible = "adi,adis16507-2",
.data = &adis16475_chip_info[ADIS16507_2] },
{ .compatible = "adi,adis16507-3",
.data = &adis16475_chip_info[ADIS16507_3] },
{ },
};
MODULE_DEVICE_TABLE(of, adis16475_of_match);
static int adis16475_probe(struct spi_device *spi) static int adis16475_probe(struct spi_device *spi)
{ {
...@@ -1463,7 +1419,7 @@ static int adis16475_probe(struct spi_device *spi) ...@@ -1463,7 +1419,7 @@ static int adis16475_probe(struct spi_device *spi)
st = iio_priv(indio_dev); st = iio_priv(indio_dev);
st->info = device_get_match_data(&spi->dev); st->info = spi_get_device_match_data(spi);
if (!st->info) if (!st->info)
return -EINVAL; return -EINVAL;
...@@ -1503,12 +1459,83 @@ static int adis16475_probe(struct spi_device *spi) ...@@ -1503,12 +1459,83 @@ static int adis16475_probe(struct spi_device *spi)
return 0; return 0;
} }
static const struct of_device_id adis16475_of_match[] = {
{ .compatible = "adi,adis16470",
.data = &adis16475_chip_info[ADIS16470] },
{ .compatible = "adi,adis16475-1",
.data = &adis16475_chip_info[ADIS16475_1] },
{ .compatible = "adi,adis16475-2",
.data = &adis16475_chip_info[ADIS16475_2] },
{ .compatible = "adi,adis16475-3",
.data = &adis16475_chip_info[ADIS16475_3] },
{ .compatible = "adi,adis16477-1",
.data = &adis16475_chip_info[ADIS16477_1] },
{ .compatible = "adi,adis16477-2",
.data = &adis16475_chip_info[ADIS16477_2] },
{ .compatible = "adi,adis16477-3",
.data = &adis16475_chip_info[ADIS16477_3] },
{ .compatible = "adi,adis16465-1",
.data = &adis16475_chip_info[ADIS16465_1] },
{ .compatible = "adi,adis16465-2",
.data = &adis16475_chip_info[ADIS16465_2] },
{ .compatible = "adi,adis16465-3",
.data = &adis16475_chip_info[ADIS16465_3] },
{ .compatible = "adi,adis16467-1",
.data = &adis16475_chip_info[ADIS16467_1] },
{ .compatible = "adi,adis16467-2",
.data = &adis16475_chip_info[ADIS16467_2] },
{ .compatible = "adi,adis16467-3",
.data = &adis16475_chip_info[ADIS16467_3] },
{ .compatible = "adi,adis16500",
.data = &adis16475_chip_info[ADIS16500] },
{ .compatible = "adi,adis16505-1",
.data = &adis16475_chip_info[ADIS16505_1] },
{ .compatible = "adi,adis16505-2",
.data = &adis16475_chip_info[ADIS16505_2] },
{ .compatible = "adi,adis16505-3",
.data = &adis16475_chip_info[ADIS16505_3] },
{ .compatible = "adi,adis16507-1",
.data = &adis16475_chip_info[ADIS16507_1] },
{ .compatible = "adi,adis16507-2",
.data = &adis16475_chip_info[ADIS16507_2] },
{ .compatible = "adi,adis16507-3",
.data = &adis16475_chip_info[ADIS16507_3] },
{ },
};
MODULE_DEVICE_TABLE(of, adis16475_of_match);
static const struct spi_device_id adis16475_ids[] = {
{ "adis16470", (kernel_ulong_t)&adis16475_chip_info[ADIS16470] },
{ "adis16475-1", (kernel_ulong_t)&adis16475_chip_info[ADIS16475_1] },
{ "adis16475-2", (kernel_ulong_t)&adis16475_chip_info[ADIS16475_2] },
{ "adis16475-3", (kernel_ulong_t)&adis16475_chip_info[ADIS16475_3] },
{ "adis16477-1", (kernel_ulong_t)&adis16475_chip_info[ADIS16477_1] },
{ "adis16477-2", (kernel_ulong_t)&adis16475_chip_info[ADIS16477_2] },
{ "adis16477-3", (kernel_ulong_t)&adis16475_chip_info[ADIS16477_3] },
{ "adis16465-1", (kernel_ulong_t)&adis16475_chip_info[ADIS16465_1] },
{ "adis16465-2", (kernel_ulong_t)&adis16475_chip_info[ADIS16465_2] },
{ "adis16465-3", (kernel_ulong_t)&adis16475_chip_info[ADIS16465_3] },
{ "adis16467-1", (kernel_ulong_t)&adis16475_chip_info[ADIS16467_1] },
{ "adis16467-2", (kernel_ulong_t)&adis16475_chip_info[ADIS16467_2] },
{ "adis16467-3", (kernel_ulong_t)&adis16475_chip_info[ADIS16467_3] },
{ "adis16500", (kernel_ulong_t)&adis16475_chip_info[ADIS16500] },
{ "adis16505-1", (kernel_ulong_t)&adis16475_chip_info[ADIS16505_1] },
{ "adis16505-2", (kernel_ulong_t)&adis16475_chip_info[ADIS16505_2] },
{ "adis16505-3", (kernel_ulong_t)&adis16475_chip_info[ADIS16505_3] },
{ "adis16507-1", (kernel_ulong_t)&adis16475_chip_info[ADIS16507_1] },
{ "adis16507-2", (kernel_ulong_t)&adis16475_chip_info[ADIS16507_2] },
{ "adis16507-3", (kernel_ulong_t)&adis16475_chip_info[ADIS16507_3] },
{ }
};
MODULE_DEVICE_TABLE(spi, adis16475_ids);
static struct spi_driver adis16475_driver = { static struct spi_driver adis16475_driver = {
.driver = { .driver = {
.name = "adis16475", .name = "adis16475",
.of_match_table = adis16475_of_match, .of_match_table = adis16475_of_match,
}, },
.probe = adis16475_probe, .probe = adis16475_probe,
.id_table = adis16475_ids,
}; };
module_spi_driver(adis16475_driver); module_spi_driver(adis16475_driver);
......
...@@ -750,13 +750,13 @@ inv_mpu6050_read_raw(struct iio_dev *indio_dev, ...@@ -750,13 +750,13 @@ inv_mpu6050_read_raw(struct iio_dev *indio_dev,
ret = inv_mpu6050_sensor_show(st, st->reg->gyro_offset, ret = inv_mpu6050_sensor_show(st, st->reg->gyro_offset,
chan->channel2, val); chan->channel2, val);
mutex_unlock(&st->lock); mutex_unlock(&st->lock);
return IIO_VAL_INT; return ret;
case IIO_ACCEL: case IIO_ACCEL:
mutex_lock(&st->lock); mutex_lock(&st->lock);
ret = inv_mpu6050_sensor_show(st, st->reg->accl_offset, ret = inv_mpu6050_sensor_show(st, st->reg->accl_offset,
chan->channel2, val); chan->channel2, val);
mutex_unlock(&st->lock); mutex_unlock(&st->lock);
return IIO_VAL_INT; return ret;
default: default:
return -EINVAL; return -EINVAL;
......
...@@ -356,7 +356,7 @@ static int tmag5273_read_raw(struct iio_dev *indio_dev, ...@@ -356,7 +356,7 @@ static int tmag5273_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_OFFSET: case IIO_CHAN_INFO_OFFSET:
switch (chan->type) { switch (chan->type) {
case IIO_TEMP: case IIO_TEMP:
*val = -266314; *val = -16005;
return IIO_VAL_INT; return IIO_VAL_INT;
default: default:
return -EINVAL; return -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment